Compare commits

...
Author SHA1 Message Date
apnadkarni 6134622b61 Merge 8.7 2023-03-18 02:36:42 +00:00
jan.nijtmans bdad96ab69 Few more arm64e -> arm64 2023-03-17 20:10:29 +00:00
jan.nijtmans c0a02fd487 Merge 8.6 2023-03-17 20:09:18 +00:00
jan.nijtmans 453c27a88e arm64e -> arm64, since arm64e is not available yet on MacOS (Thanks to Stefan Sobernig) 2023-03-17 20:04:48 +00:00
jan.nijtmans ac93862047 Merge 8.7 2023-03-17 19:43:07 +00:00
jan.nijtmans e9ccf557eb Fix [6390566ecd]: Testcase cmdAH-4.3.13.00DC0000.tail.utf-32.tcl8.a fails sometimes 2023-03-17 16:12:23 +00:00
dgp 5b8c37d24f merge 8.6 2023-03-17 14:38:16 +00:00
dgp 13b1529c7b Clean up after events to avoid errors in later tests that use an event loop. 2023-03-17 14:22:44 +00:00
dgp 1ee3af2d3d merge mark 2023-03-17 12:40:12 +00:00
dgp 87b6456684 unbreak the build 2023-03-17 12:35:51 +00:00
jan.nijtmans 4f2de3dfc9 merge-mark 2023-03-17 08:25:56 +00:00
jan.nijtmans 4aa63fcc25 Don't return from a void function 2023-03-17 08:24:59 +00:00
jan.nijtmans 3d439d74da Merge-mark 2023-03-17 08:06:13 +00:00
jan.nijtmans 9c8a1292c0 Don't introduce size_t in a header-file which didn't use it before. Make more clear that those are unsupported internal functions. 2023-03-17 07:57:14 +00:00
jan.nijtmans 3129864cc2 If TCL_UTF_MAX=4, don't set 'exact' to 1 2023-03-16 20:12:23 +00:00
apnadkarni 5655318f50 Merge 8.7 2023-03-16 17:29:12 +00:00
jan.nijtmans ae0471127e Prevent extensions compiled with TCL_UTF_MAX=4 (See [https://core.tcl-lang.org/tips/doc/trunk/tip/542.md|TIP #542]) from running in Tcl 8.6. 2023-03-16 15:36:55 +00:00
jan.nijtmans 1a6f1d5c40 Add some undocumented stub functions. Those can prevent a crash like [http://paste.tclers.tk/5763|this] example, when compiled with 8.7 headers but running it in Tcl 8.6. 2023-03-16 15:12:17 +00:00
jan.nijtmans e019e5bd1d Fix (minor) warning on 32-bit platforms 2023-03-16 11:29:14 +00:00
pooryorick 5846b1666f Make valgrind_foreach target in Makefile.in properly handle interrupted tests. 2023-03-16 08:15:03 +00:00
apnadkarni a3c59e320d Change -encodingprofile to -profile 2023-03-16 03:08:12 +00:00
pooryorick 70cf69246f New script used in the "valgrind_each" target in Makefile.in 2023-03-15 20:13:22 +00:00
jan.nijtmans 7543a1313f Merge 8.6 2023-03-15 16:23:22 +00:00
jan.nijtmans e0e09638fe Remove _LARGEFILE_SOURCE64 usage. See [d690400d07] 2023-03-15 16:21:53 +00:00
dgp 6d3b66ad23 Merge in constraint spelling fix. Keep it in case the knownBug constraint is ever removed. 2023-03-15 13:28:55 +00:00
dgp 6bd8763c2d Misspelled constraint created testing noise. 2023-03-15 12:53:03 +00:00
jan.nijtmans 23a421a9c1 Merge-mark. @nathan, please do forward merges from core-8-6-branch -> core-8-branch -> trunk. Fossil is not so intelligent, figuring out what's happening here. 2023-03-15 09:32:02 +00:00
pooryorick ba737587a8 Further fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client socket. 2023-03-15 09:25:15 +00:00
pooryorick 6ded4b92be Further fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client socket. 2023-03-15 08:42:11 +00:00
pooryorick 6cf4a0dea3 Merge core-8-branch. 2023-03-14 20:37:45 +00:00
pooryorick fdcb9621bb Further fix for issue [ea69b0258a9833cb], crash when using a channel
transformation on TCP client socket.
2023-03-14 20:30:34 +00:00
pooryorick 3aef0c58f9 Further fix for issue [ea69b0258a9833cb], crash when using a channel transformation on TCP client socket. 2023-03-14 20:27:04 +00:00
apnadkarni 87b3bcc550 Merge 8.7 2023-03-14 15:34:42 +00:00
jan.nijtmans b05b4cf948 Since "unicode" is deprecated, use "utf-16" in testcases. Otherwise -DTCL_NO_DEPRECATED build fails. 2023-03-14 10:30:59 +00:00
jan.nijtmans 18a99f2522 Add "ucs-2" constraint to encoding-bug-183a1adcc0-5 testcase, otherwise it fails with TCL_UTF_MAX>3.
Broken by [47857515422b8519|this] commit
2023-03-14 10:05:24 +00:00
pooryorick 953a44bc6e Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on
TCP client socket.
2023-03-13 19:19:32 +00:00
pooryorick 5094fb7825 Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on
TCP client socket.
2023-03-13 19:07:25 +00:00
apnadkarni 95158a2d57 Fix passing of encoding state in testencoding Tcl_UtfToExternal 2023-03-13 16:32:55 +00:00
apnadkarni d53dfb14c7 Merge 8.6: Bug [183a1adcc0]. Buffer overflow in Tcl_UtfToExternal 2023-03-13 15:34:22 +00:00
apnadkarni 6d74232282 Bug [183a1adcc0]. Buffer overflow in Tcl_UtfToExternal 2023-03-13 13:44:35 +00:00
pooryorick df8a3a6ea4 Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on
TCP client socket.
2023-03-13 13:36:52 +00:00
pooryorick 967e55306e Fix for issue [ea69b0258a9833cb], crash when using a channel transformation on
TCP client socket.
2023-03-13 12:22:06 +00:00
apnadkarni 22239fb7d2 Start on Tcl_ExternalToUtf/Tcl_UtfToExternal tests 2023-03-12 16:47:08 +00:00
jan.nijtmans 131176ce2f Backport [6fb14ee3e876978c]. Add testcases 2023-03-12 16:37:12 +00:00
jan.nijtmans 77e951f2b8 Fix [db7a085bd9]: encoding convertfrom -strict utf-16 accepts partial surrogates 2023-03-12 12:37:29 +00:00
jan.nijtmans 8bf2e2ace2 Forgot that \x00 is not printable anyway 2023-03-12 11:32:52 +00:00
jan.nijtmans b7f151f126 Make test-output more readable when it contains non-printable characters (stolen from TIP #656 impl, thanks Ashok!)
tcltest -> 2.5.6
2023-03-12 11:24:24 +00:00
jan.nijtmans 8c5fc11b5a Always output 2 hex characters in "unexpected byte sequence" exception message.
make testcases io-38.3/chan-io-38.3 independant from system encoding
2023-03-12 10:49:18 +00:00
jan.nijtmans 1889ded114 Proposed fix for [db7a085bd9]: encoding convertfrom -strict utf-16 accepts partial surrogates. TODO: testcases, and implement for 8.7 too 2023-03-11 22:00:29 +00:00
apnadkarni 6f85588bab Add testencoding Tcl_ExternalToUtf/Tcl_UtfToExternal for raw testing of corresponding C functions 2023-03-11 16:43:36 +00:00
dgp 21388fa31e merge 8.7 2023-03-10 13:45:01 +00:00
dgp 0951d3f692 merge 8.6 2023-03-10 13:33:19 +00:00
dgp 93bf87ed85 Make test less fragile to changing set of options. 2023-03-10 13:32:47 +00:00
apnadkarni d06a38ae5d Merge 8.7 2023-03-10 09:53:32 +00:00
jan.nijtmans 494b4c8127 Fix cmdAH-4.3.13.00D80000.solo.utf-32le.tcl8.a testcase from tip-656-tcl9 branch, when TCL_UTF_MAX=3 2023-03-09 20:55:43 +00:00
apnadkarni 56f5c7751c Fix SetChannelOption parsing of -encoding* to match GetChannelOption 2023-03-09 10:47:12 +00:00
jan.nijtmans bd3a6be21b Merge 8.7 2023-03-09 10:22:55 +00:00
jan.nijtmans 962d8aed89 Merge 8.6 2023-03-09 10:21:54 +00:00
jan.nijtmans 5b0be62536 Adapt 2 testcases (io-39.16/io-39.16a), showing that "-encoding" can be shortened to "-en", but not to "-e" (because there is -eofchar too) 2023-03-09 10:08:02 +00:00
jan.nijtmans a1fb554585 Fix tests/tcltest.test testcases (missing "namespace import") 2023-03-09 09:39:59 +00:00
apnadkarni 552d2bb53f Merge 8.7 - winFCmd-1.24 differs in error code on Win 11 2023-03-09 02:52:51 +00:00
apnadkarni 1b7f525ec7 Merge 8.6 - winFCmd-1.24 differs in error code on Win 11 2023-03-09 02:50:32 +00:00
apnadkarni 38555b60a2 winFCmd-1.24 has different error code on Win 11 2023-03-09 02:47:53 +00:00
jan.nijtmans 9f1cf8d5ef Merge 8.7 2023-03-08 20:40:23 +00:00
jan.nijtmans c3da6c8fed Merge core-8-branch 2023-03-08 20:16:32 +00:00
jan.nijtmans 468e5148b3 Merge 8.6 2023-03-08 20:15:43 +00:00
jan.nijtmans 7ed7017d94 Add "notWsl" test constraints. Clean up many testcases 2023-03-08 19:58:08 +00:00
jan.nijtmans 10f4d4565d More -Wconversion warning fixes 2023-03-08 15:01:20 +00:00
jan.nijtmans fa28b1f243 Merge 8.7 2023-03-08 11:12:04 +00:00
jan.nijtmans 3203978c65 Add "teststringobj newunicode". Not used in testcases yet. 2023-03-08 11:02:27 +00:00
jan.nijtmans 8dbd350305 Merge 8.7 2023-03-07 20:14:23 +00:00
jan.nijtmans 9aea48988c Merge 8.7 2023-03-07 20:10:15 +00:00
jan.nijtmans 0e0d74624b Fix [b4af93cd9f]: uninitialized bytes in http11-1.13.0 2023-03-07 20:09:30 +00:00
jan.nijtmans fffb0bdce5 Merge 8.7 2023-03-07 18:23:15 +00:00
jan.nijtmans 82acd6a35a Merge 8.6 2023-03-07 18:14:39 +00:00
jan.nijtmans 5cf1eed910 Fix a few -Wconversion warnings 2023-03-07 17:56:45 +00:00
apnadkarni 8c5476848a Merge 8.7 - testchmod fixes 2023-03-07 12:53:58 +00:00
apnadkarni 4df874dd7f Merge 8.6 - testchmod fixes 2023-03-07 12:28:40 +00:00
apnadkarni 906268caa7 Merge testchmod fix 2023-03-07 10:46:31 +00:00
jan.nijtmans 1ae5fd8198 Merge 8.7 2023-03-07 07:41:26 +00:00
jan.nijtmans 01d6e02666 Merge 8.6 2023-03-07 07:34:21 +00:00
jan.nijtmans e10915b565 Fix [95e287b956]: uninit value use in stringObj-4.2 2023-03-07 07:23:10 +00:00
jan.nijtmans 03618f8c95 merge-mark 2023-03-07 07:06:51 +00:00
jan.nijtmans 071917e1b2 Fix [f3cb2a32d6]: uninitialized value in format-2.18. Also remove repeated call to Tcl_DStringInit() 2023-03-07 07:03:36 +00:00
apnadkarni 1f6cec5ff3 Fix testchmod and associated tests that always failed on Windows 2023-03-07 02:52:26 +00:00
apnadkarni fe7ee54772 Create new branch named "bug-win-testchmod" 2023-03-07 02:27:43 +00:00
jan.nijtmans f5ba8a8478 Proposed fix for [95e287b956]: uninit value use in stringObj-4.2 2023-03-06 21:01:45 +00:00
jan.nijtmans f4450abcf9 Proposed fix for [f3cb2a32d6]: uninitialized value in format-2.18 2023-03-06 19:58:53 +00:00
dgp 5e095a3a4d [b4af93cd9f] Proposed fix from apnadkarni. It works! 2023-03-06 18:17:19 +00:00
jan.nijtmans 3eb68691b8 ckfree() -> Tcl_Free() 2023-03-06 10:30:41 +00:00
jan.nijtmans f0e415c1e1 Merge 8.7 2023-03-06 10:28:47 +00:00
jan.nijtmans cfa443421b Tcl_WinTCharToUtf() is deprecated, so use Tcl_WCharToUtfDString() in stead. 2023-03-06 10:24:15 +00:00
pooryorick 296e4767ea Add new valgrind suppression items. 2023-03-06 07:00:48 +00:00
pooryorick fa795b478a Add new valgrind suppression items. 2023-03-06 06:59:52 +00:00
pooryorick 40e214cd76 Add new valgrind suppression items. 2023-03-06 06:58:13 +00:00
jan.nijtmans 7ec4501d37 Merge 8.7 2023-03-05 21:27:49 +00:00
jan.nijtmans 9e0cc9d630 Merge-mark (but also remove some lost spacing) 2023-03-05 21:16:33 +00:00
jan.nijtmans 9d2cc36a0e Fix [57bfcf43dd]: Remove unreachable code in Tcl_SetWideIntObj() 2023-03-05 21:09:46 +00:00
jan.nijtmans e4e1062338 Another round of -1 -> TCL_INDEX_NONE 2023-03-05 19:57:48 +00:00
apnadkarni 0968aa6de7 Merge 8.7: Bug [9c5a00c69d]. Fix ~user on Windows 2023-03-05 11:42:31 +00:00
pooryorick f736bb9d86 A better fix for Valgrind "still reachable" report in TestcmdtokenCmd(). 2023-03-05 11:39:36 +00:00
apnadkarni 6e7d72c158 Merge 8.6: Bug [9c5a00c69d]. Fix ~user on Windows 2023-03-05 11:09:10 +00:00
apnadkarni 1f7d2aae34 Bug [9c5a00c69d]. Fix ~user on Windows 2023-03-05 09:57:29 +00:00
pooryorick 76edd58c3e A better fix for Valgrind "still reachable" report in TestcmdtokenCmd(). 2023-03-05 07:11:15 +00:00
jan.nijtmans 923ff1e3ca More -1 -> TCL_INDEX_NONE 2023-03-05 00:26:54 +00:00
jan.nijtmans 33d81b98be Make dltest/pkg*.c simple example how to use Tcl_Size with Tcl_GetStringFromObj() 2023-03-04 18:12:49 +00:00
apnadkarni 234394e2df Merge 8.7 - Protect zlib errors with check for null interp 2023-03-04 16:33:36 +00:00
apnadkarni 7b3ef36925 Protect zlib errors with check for null interp 2023-03-04 16:26:00 +00:00
apnadkarni c862e57095 Add test for [9c5a00c69d], tilde expansion of ~user 2023-03-04 15:11:01 +00:00
apnadkarni 0229ba1283 Bug [9c5a00c69d]. Tilde expansion on Windows 2023-03-04 12:13:31 +00:00
jan.nijtmans 4e84e02684 Merge 8.7 2023-03-04 10:20:34 +00:00
jan.nijtmans 80b392ba8e Merge 8.6 2023-03-04 10:19:44 +00:00
jan.nijtmans e13edcba86 Test constraint notInCIenv no longer necessary (due to previous fix) 2023-03-04 10:18:41 +00:00
jan.nijtmans e95b015990 Merge 8.7 2023-03-04 10:13:19 +00:00
jan.nijtmans aebb7627f5 Merge 8.6 2023-03-04 10:09:21 +00:00
jan.nijtmans 6285c13367 Fix [1b8df10110]: Tcl_GetTime returns wrong usec value on Windows 2023-03-04 10:08:18 +00:00
jan.nijtmans 8f18e27691 Adapt type-casts to Tcl 9.0 signature of Tcl_Free/Tcl_Realloc/Tcl_AttemptRealloc 2023-03-03 13:04:11 +00:00
jan.nijtmans 7f3d1257ff ckfree() shouldn't be used in Tcl 9 core code any more 2023-03-03 13:03:02 +00:00
pooryorick e7b37f1737 Fix Valgrind "still reachable" report in TestcmdtokenCmd(). 2023-03-03 12:39:09 +00:00
pooryorick 18385b8363 Fix Valgrind "still reachable" report in TestcmdtokenCmd(). 2023-03-03 12:17:15 +00:00
pooryorick d3aa6839f4 Fix Valgrind "still reachable" report in TestcmdtokenCmd(). 2023-03-03 12:15:11 +00:00
apnadkarni cb3d36ad5a Bug [9a978f8323]: Fix large reads > 2GB 2023-03-03 10:47:51 +00:00
apnadkarni 1ad16ea481 Merge 8.7 - disable tests on WSL 2023-03-02 07:46:17 +00:00
apnadkarni b464703493 Merge 8.7: Disable more file permissions tests for WSL (not supported in WSL/NTFS) 2023-03-02 07:32:04 +00:00
apnadkarni 4d67456953 Disable more file permissions tests for WSL (not supported in WSL/NTFS) 2023-03-02 07:08:48 +00:00
apnadkarni 44fdf09f7b Bug [e778e3f804]. Fix error message for invalid profile name. 2023-03-02 06:41:39 +00:00
apnadkarni b2cdedcec2 Eliminate TCL_ENCODING_MODIFIED flag 2023-03-02 04:16:44 +00:00
apnadkarni 1d9ebbc740 Merge mark with core-8-branch 2023-03-01 14:57:20 +00:00
apnadkarni 5a3e0c869e Cherrypick [f1dd5f1cc7]: constrain tests not supported on WSL 2023-03-01 14:55:13 +00:00
apnadkarni 64e7f77040 Disable file permission tests under WSL as WSL does not support Unix file attrs without special config 2023-03-01 13:58:52 +00:00
apnadkarni cc5dd09db3 Merge trunk 2023-03-01 13:41:44 +00:00
apnadkarni 30a9b333ba Bug [9a978f8323]: crash reading large files 2023-03-01 13:18:17 +00:00
jan.nijtmans 261c174d97 Fix msvc build (with OPTS=symbols) 2023-03-01 11:06:17 +00:00
apnadkarni a6b4ef3d29 Fix [f8ef6b3670] crash. TclpSysAlloc macro was truncating size request to 32 bits on Windows. 2023-03-01 07:56:03 +00:00
apnadkarni 74b7d6bc14 Merge 8.7 2023-02-28 15:39:09 +00:00
apnadkarni 3d177bd8b5 int -> Tcl_Size to match TIP 2023-02-28 14:08:19 +00:00
jan.nijtmans 62d9150ef5 Merge 8.7 2023-02-28 13:36:00 +00:00
jan.nijtmans 4227ef37bb Put back testcase io-52.20, and re-fix [4a7397e0b3] 2023-02-28 13:33:04 +00:00
apnadkarni 1652c942d8 Merge 8.7 2023-02-28 13:25:34 +00:00
apnadkarni 5d56a5b435 Merge 8.7 2023-02-28 13:24:18 +00:00
jan.nijtmans 7c9fe49b51 Merge 8.7 2023-02-28 12:45:06 +00:00
jan.nijtmans bb80189110 Missing ')' 2023-02-28 12:43:53 +00:00
apnadkarni 1eac8ab060 Move setting of profile in flags parameter to lower level functions in case they are called directly 2023-02-28 12:25:34 +00:00
jan.nijtmans 1923d22832 Merge 8.7 2023-02-28 12:20:34 +00:00
jan.nijtmans 70e40dd53d Restore previous behavior for non-blocking mode, as for this mode the semantics of [read]/[gets] were not broken. This was the 'some agreement'.
The change in line 8286 is necessary for both blocking and non-blocking mode: Whenver the encoding change we need to reset the CHANNEL_ENCODING_ERROR flag.
2023-02-28 12:16:10 +00:00
pooryorick 7661972907 Reverted [d156af9fb76dd2f4] and removed tests io-52.20 io-75.6 io-75.7, as this
commit, intended to fix issue [b8f575aa2398b0e4], breaks the semantics of
[read] and [gets].  Such a change would require an accepted TIP. See [b8f575aa2398b0e4] for further discussion.

jn: @pouryorick See [b8f575aa2398b0e4] for the reason why this commit is not appropriate: It gets core-8-branch back in the buggy state it was, without even providing a real solution everyone agrees on. You shouldn't revert my patch just because I reverted yours.

pooryorick:  As I explained, the reason for this reversion is that it hard-codes an unapproved change in the semantics of [read] and [gets] into the test suite.  Jan, your statement that it's a "revenge" reversion is false.  I spent a month trying to find some alternative to this reversion before actually performing it.  A commit that codifes in its tests changes in semantcs to [read]/[gets] simply shouldn't be on core-8-branch.
2023-02-28 11:57:03 +00:00
pooryorick bb2f06fc73 Reverted [d156af9fb76dd2f4] and removed tests io-52.20 io-75.6 io-75.7, as this
commit, intended to fix issue [b8f575aa2398b0e4], breaks the semantics of
[read] and [gets].  Such a change would require an accepted TIP. See [b8f575aa2398b0e4] for further discussion.

jn: @pouryorick See [b8f575aa2398b0e4] for the reason why this commit is not appropriate: It gets core-8-branch back in the buggy state it was, without even providing a real solution everyone agrees on. You shouldn't revert my patch just because I reverted yours.

pooryorick:  As I explained, the reason for this reversion is that it hard-codes an unapproved change in the semantics of [read] and [gets] into the test suite.  Jan, your statement that it's a "revenge" reversion is false.  I spent a month trying to find some alternative to this reversion before actually performing it.  A commit that codifes in its tests changes in semantcs to [read]/[gets] simply shouldn't be on core-8-branch.
2023-02-28 11:42:15 +00:00
jan.nijtmans fadb24f26a Merge 8.7. And fix Tcl_UtfToExternal()/Tcl_ExternalToUtf() (at least - sufficient for tclZlib.c), such that it now returns an error when src and dst *both* exceed INT_MAX. To be discussed further. 2023-02-28 11:00:44 +00:00
jan.nijtmans 5d8ae9bf17 Merge 8.6 2023-02-28 10:36:25 +00:00
apnadkarni 8e139e5cd7 Merge bug-fb368527ae. Bug [fb368527ae] Large string truncation 2023-02-28 10:28:28 +00:00
jan.nijtmans da55e192ba Fix [f9eafc3886]: Error handling in zlib comment/filename 2023-02-28 10:18:28 +00:00
pooryorick 57d266423a Make the descriptions in doc/Tcl.n more concise and intuitive. 2023-02-28 10:13:25 +00:00
pooryorick d29598480f Make the descriptions in doc/Tcl.n more concise and intuitive. 2023-02-28 10:06:22 +00:00
pooryorick 7d6cf09e02 Make the descriptions in doc/Tcl.n more concise and intuitive. 2023-02-28 10:04:49 +00:00
pooryorick 8b417f0e1e Fix formatting issue in Tcl.n 2023-02-28 09:59:29 +00:00
pooryorick e743d3e487 Fix formatting issue in Tcl.n 2023-02-28 09:57:22 +00:00
jan.nijtmans a947270ff7 In case of combining TIP #494 (TCL_8_COMPAT) and #628 (building for Tcl 8.7 with 9.0 headers), ignore TCL_8_COMPAT macro. More Tcl_Size usage. 2023-02-28 07:45:27 +00:00
jan.nijtmans a1fe72fa4a Fix testcases 2023-02-27 20:50:33 +00:00
apnadkarni 85bf0db1e8 Fix crash. int->size_t needs +1 in comparisons. 2023-02-27 12:31:49 +00:00
jan.nijtmans c6bb33407a Fix [3d01d51bc4]: Tcl 9: Cannot write large strings to file. Also some size_t -> Tcl_Size changes. 2023-02-27 11:59:54 +00:00
apnadkarni e2d89615d5 Tests for encoding strings > 4GB (under perf constraint) 2023-02-27 04:15:07 +00:00
apnadkarni ed360ca42f Add perf constraint to large io tests to prevent memory faults on systems with limited memory 2023-02-27 03:13:38 +00:00
jan.nijtmans 6b172a2131 fill in bug ticket-nr 2023-02-26 21:37:15 +00:00
jan.nijtmans e7b8b9d2dd Proposed fix for [f9eafc3886]: Error handling in zlib comment/filename. With testcases 2023-02-26 20:12:43 +00:00
jan.nijtmans 152d7203ac Handle Tcl_UtfToExternal error in tclZlib.c 2023-02-26 17:19:07 +00:00
jan.nijtmans baf9b5e9bb Handle statePtr != NULL as well 2023-02-26 16:54:02 +00:00
jan.nijtmans cbda5cb9b2 Make Tcl_UtfToExternal()/Tcl_ExternalToUtf() report the error, if srcLen and dstLen are both > INT_MAX and therefore not all characters can be handled by this function. 2023-02-26 16:41:06 +00:00
jan.nijtmans 6ab1efe806 merge-mark 2023-02-26 16:04:57 +00:00
jan.nijtmans 08a6b105e5 Merge 8.6 2023-02-26 16:04:03 +00:00
jan.nijtmans 8fdf20ec2b More dstring testcases, extracted from [46dda6fc29] 2023-02-26 16:01:29 +00:00
apnadkarni 4e6558b44a Fix [46dda6fc29] - trace crash caused by TclScanElement 2023-02-26 15:42:37 +00:00
jan.nijtmans 5ffda39949 Move the "srcLen -= srcChunkRead;" past the "if ((result != TCL_CONVERT_NOSPACE)..." (where it originally was), since this isn't needed if the loop ends anyway. 2023-02-26 12:56:18 +00:00
jan.nijtmans 79cbdf745a (size_t) -1 -> TCL_INDEX_NONE 2023-02-26 12:27:43 +00:00
apnadkarni deec081e74 Also fix [90ff9b7f73] - writes of exactly 4294967295 bytes 2023-02-26 07:15:06 +00:00
apnadkarni 2fb6b99620 Minor refactor, add tests 2023-02-26 06:26:01 +00:00
apnadkarni 7b0b2ebd37 Fix large writes to file. Need to break into INT_MAX size chunks. 2023-02-25 17:23:42 +00:00
apnadkarni 2a5b403768 Experimental fix for [fb368527ae] - length truncation 2023-02-25 16:29:09 +00:00
apnadkarni aa2b48262b Fix and tests for [46dda6fc29] 2023-02-25 09:26:06 +00:00
apnadkarni a826e66f11 Add tests for Bug [46dda6fc29] 2023-02-25 08:58:31 +00:00
apnadkarni 8390c51fca Fix [1d074b177a]. Failure to read .tclshrc 2023-02-25 07:35:21 +00:00
apnadkarni 58db3d68eb Add teststringobj newunicode command to test invalid input to Tcl_NewUnicodeObj 2023-02-24 13:34:15 +00:00
apnadkarni 99a24e7883 Raise error on invalid flags 2023-02-24 10:32:37 +00:00
apnadkarni 76adf3151b Merge 8.7 2023-02-24 09:57:07 +00:00
apnadkarni 854369a67c Factor out encoding test vectors into separate file so they can be used for file IO tests 2023-02-24 09:35:09 +00:00
jan.nijtmans d5e9da898f Merge 8.7 2023-02-24 08:33:24 +00:00
jan.nijtmans 1c3c25097b int -> Tcl_Size in tclEncoding.c (making the diff between Tcl 8.7 and 9.0 smaller) 2023-02-24 08:25:27 +00:00
apnadkarni 485bc2fd88 Bug [40c61a5d10]. Fix syntax error message. 2023-02-24 03:35:31 +00:00
apnadkarni fe5707421f Merge [bug-dab7fd5973]. Pick up memory leak fix from 8.7. Thanks, Jan 2023-02-24 03:10:16 +00:00
jan.nijtmans 6caf484379 -strictencoding 1 -> -encodingprofile strict (since the testcases placed back in previous commit didn't have that yet) 2023-02-23 21:31:04 +00:00
jan.nijtmans 10c559acbf Remove left-over traces of [0a74820b6d], which was merged into the apn-encoding-profile and landed into tip-656. This commit was merged premature into core-8-branch, leaving a [dab7fd5973|memory leak] 2023-02-23 21:20:21 +00:00
apnadkarni 186cc71273 Had forgotten to remove disabled code 2023-02-23 13:24:58 +00:00
apnadkarni da915fdadf New signature for Tcl_ExternalToUtfDStringEx and Tcl_UtfToExternalDStringEx as per TIP 656 2023-02-23 13:19:45 +00:00
apnadkarni e469cdf190 Merge 8.7 2023-02-23 11:22:22 +00:00
jan.nijtmans 190f9219d5 Merge 8.7 2023-02-23 11:02:00 +00:00
jan.nijtmans 956059093c Fix [4bea02e811]: encoding convertfrom -strict ascii \x7f generates exception
Many other encodings had the same problem, and also the reverse happened: encodings which should throw an exception with -strict but didn't (within range 0x80-0x9F)
2023-02-23 11:00:48 +00:00
jan.nijtmans ce349b05df merge-mark 2023-02-23 10:45:56 +00:00
jan.nijtmans bf7b1adb89 See [d19fe0a5b] for follow-up to previous commit 2023-02-23 10:44:56 +00:00
apnadkarni d1920b380d Fix gcc warnings and encoding error message (bug [40c61a5d10]) 2023-02-23 10:22:58 +00:00
jan.nijtmans 9ae7f4dc4f merge-mark 2023-02-22 20:46:01 +00:00
jan.nijtmans 1d76ffb03b minor bug-fix in utf-16/utf-32: 2 testcases failed in Tcl 9 compatibility mode (-DTCL_NO_DEPRECATED) 2023-02-22 20:44:13 +00:00
jan.nijtmans 7c6f71019a Merge 8.7 2023-02-22 20:27:34 +00:00
jan.nijtmans 8f37d5c24e Merge 8.6 2023-02-22 17:56:42 +00:00
jan.nijtmans c3e063b0aa Fix [d19fe0a5b]: Handling incomplete byte sequences for utf-16/utf-32 2023-02-22 17:34:22 +00:00
apnadkarni 320eaab501 Merge 8.7 2023-02-22 15:28:00 +00:00
apnadkarni 2935048126 Add ICU tests for unmapped characters. 2023-02-22 13:42:55 +00:00
jan.nijtmans 12345dfed8 re-generate macDingbats.enc, so it can now throw exceptions for the range 0x8E-0x9F 2023-02-22 13:34:04 +00:00
jan.nijtmans 78db448fff Make txt2enc smarter, so we don't have to add DELETE any more in all original tables, better keep them as-is. 2023-02-22 13:31:41 +00:00
jan.nijtmans 58f1209a70 Merge 8.7. Adapt more testcases not to depend on the system encoding any more 2023-02-22 13:03:31 +00:00
jan.nijtmans e106525498 Merge 8.7 2023-02-22 07:48:10 +00:00
jan.nijtmans f0284298ad Fix [5607d6482c]: strict ucs-2 never implemented (TIP #346/#656) 2023-02-22 07:28:27 +00:00
jan.nijtmans 03a9d6928d Merge 8.6 2023-02-22 07:24:42 +00:00
jan.nijtmans 5219c94af5 Fix [534172ff5b]: Crash in DeleteReflectedChannelMap (introduced via tcllib 1.21) 2023-02-22 07:21:15 +00:00
jan.nijtmans a970bffd00 Add 0x7F: DELETE to more mac* encodings (so re-generating doesn't remove it again) 2023-02-21 23:22:45 +00:00
jan.nijtmans f95599f4d4 More encoding fixes, e.g. range 0x80-0x9F for dingbats and symbol. Remove "-m" option from txt2enc.c tool, since the same is already handled in the table encoding code in Tcl itself. This was wat prevent Tcl to handle throwing exceptions correctly 2023-02-21 23:16:14 +00:00
jan.nijtmans c606ae1574 Proposed fix for [d19fe0a5b]: Handling incomplete byte sequences for utf-16/utf-32 2023-02-21 17:50:36 +00:00
apnadkarni 9b8fa27457 Rework ICU tests to check validity of whole charmap in one test, else too many tests. 2023-02-21 17:27:16 +00:00
jan.nijtmans 42956f6f09 Some test-cases start failing in 9.0-compatibility-mode (-DTCL_NO_DEPRECATED), if the system encoding is one with gaps. So, better use iso8859-1 for those testcases 2023-02-21 16:58:13 +00:00
jan.nijtmans 417f868693 Proposed fix for [534172ff5b]: Crash in DeleteReflectedChannelMap (introduced via tcllib 1.21) 2023-02-21 16:09:18 +00:00
apnadkarni 4d644dfb73 Generate test data from ICU UCM data files. SBCS only for now 2023-02-21 16:03:18 +00:00
jan.nijtmans 3315012c95 re-generated 8 more encodings 2023-02-20 21:43:29 +00:00
jan.nijtmans 8660fd1af2 Two more files, re-generated 2023-02-20 20:52:06 +00:00
jan.nijtmans 280034d2ab Proposed fix for [4bea02e811]: encoding convertfrom -strict ascii \x7f generates exception 2023-02-20 20:41:00 +00:00
apnadkarni fa9ac8a850 Fix replace profile handling of truncated surrogates 2023-02-20 15:41:15 +00:00
apnadkarni 41af9f9e84 Add UTF16 and UTF32 tests 2023-02-20 15:08:58 +00:00
jan.nijtmans 23d9ca0ec4 Proposed fix for [5607d6482c]: strict ucs-2 never implemented (TIP #346/#656) 2023-02-19 11:41:44 +00:00
apnadkarni 9f595d2fa3 Remove knownBug test constraints now that fix has been merged from core-8-branch 2023-02-19 07:40:29 +00:00
apnadkarni 41c5d1cd91 Minor refactoring/fixes after merge 2023-02-18 17:41:44 +00:00
apnadkarni 933e1c8e0c Merge 8.7 to pick up UTF-8 encoding fix 2023-02-18 17:34:25 +00:00
apnadkarni 3d2dc70845 Done with invalid utf-8 table 2023-02-18 16:25:57 +00:00
jan.nijtmans 0892c6f37c Merge 8.7 2023-02-17 19:15:28 +00:00
jan.nijtmans c731ca1ffd Fix for [885c86a9a0]: convertfrom utf8 breaks for 4 byte utf encodings 2023-02-17 19:14:42 +00:00
apnadkarni fdbb12eced Part way through utf-8 test equivalence classes 2023-02-17 18:59:28 +00:00
apnadkarni 359092510b Merge 8.7 2023-02-17 11:08:17 +00:00
jan.nijtmans 45796af99d complete fix 2023-02-16 21:50:53 +00:00
jan.nijtmans 6bcdbfbf84 Merge 8.7 2023-02-16 21:41:49 +00:00
jan.nijtmans 6d674a96a1 Final part of [10c2c17c32]: UTF-LE32 encoder mapping of surrogates. Problem was in testcase, not in actual code 2023-02-16 21:29:07 +00:00
jan.nijtmans a3f58db271 Merge 8.7 2023-02-16 21:14:24 +00:00
jan.nijtmans 2c3252bc5c Fix [5e6ae6e05e]: Implement -strict correctly for cesu-8 2023-02-16 21:03:48 +00:00
jan.nijtmans d790e81db2 Fix [33ab6d08eb]: Inconsistent behavior with encoding convertfrom -failindex 2023-02-16 20:57:47 +00:00
apnadkarni 684cbb8f5c Bit more work on encoding test framework. Long way to go. 2023-02-16 17:15:35 +00:00
jan.nijtmans 0563a78902 Fix [5e6ae6e05e]: Implement -strict correctly for cesu-8 2023-02-16 16:59:10 +00:00
jan.nijtmans 5053891183 Try to fix [885c86a9a0]. Doesn't work completely yet. 2023-02-16 07:59:09 +00:00
jan.nijtmans f06c5e7af1 Fix for [33ab6d08eb]: Inconsistent behavior with encoding convertfrom -failindex 2023-02-15 20:26:10 +00:00
apnadkarni 96e60d29b7 Start on expanding encoding tests 2023-02-15 17:27:55 +00:00
jan.nijtmans 7fb1760f42 Merge 8.7. Test-case only 2023-02-15 07:30:03 +00:00
jan.nijtmans 4c2d834fca Ticket [10c2c17c32] follow-up. One output char too much with -failindex. 2023-02-15 07:21:55 +00:00
apnadkarni 6aed3e7d30 Merge 8.7 2023-02-15 05:24:48 +00:00
jan.nijtmans fb260e8382 Merge 8.7 2023-02-14 22:06:32 +00:00
jan.nijtmans 5040a69c28 Fix for [bd1a60eb9c]: convertfrom utf-8 strict mode allows surrogates in input sequence 2023-02-14 21:42:01 +00:00
jan.nijtmans 38df355850 Complete fix for [bd1a60eb9c]. Also fix a bug in the tableencoding. With testcases. 2023-02-14 20:50:26 +00:00
apnadkarni 891d60a9ad Remove obsolete comment 2023-02-14 11:56:49 +00:00
apnadkarni a750ed2c24 Fix uniqueness parsing fconfigure -encoding / -encodingprofile options 2023-02-14 11:39:35 +00:00
apnadkarni 85320f8fd0 Bug [bd1a60eb9c]. Eliminate TCL_ENCODING_UTF. 2023-02-14 11:37:35 +00:00
jan.nijtmans 2974b57279 Make a start fixing [bd1a60eb9c]. WIP 2023-02-14 07:29:36 +00:00
jan.nijtmans 0c306c8f81 Merge 8.7. Mark (new) testcase encoding-16.15 as "knownBug": still needs a fix. 2023-02-13 10:12:45 +00:00
jan.nijtmans 05f4bc701f Fix for [10c2c17c32]: UTF-LE32 encoder mapping of surrogates. With testcases (both for utf-32 and utf-16, which had the same bug) 2023-02-13 08:39:29 +00:00
apnadkarni 86d84d444c Tentative fix for [bd1a60eb9] - surrogates in strict utf-8 2023-02-12 17:34:58 +00:00
apnadkarni 0c764d2b03 Minor fixes and tests 2023-02-12 16:56:17 +00:00
apnadkarni bf448a6421 Added 'encoding profiles' 2023-02-12 11:04:16 +00:00
apnadkarni b5095134df Minor readability changes 2023-02-12 06:15:59 +00:00
jan.nijtmans bfaa709c2e Merge 8.7 2023-02-12 01:00:58 +00:00
jan.nijtmans 3954b7c2a3 Proposed fix (and testcases) for [4a7397e0b3]: Tcl 9: fcopy with -strictencoding 1 UTF-8 channels 2023-02-12 00:49:22 +00:00
apnadkarni 727887b6dc Partial implementation of replace profile 2023-02-11 17:38:07 +00:00
apnadkarni c2f0e2f8da Eliminate TCL_ENCODING_{STRICT,NOCOMPLAIN} 2023-02-11 01:51:32 +00:00
jan.nijtmans bab9170bdc Proposed fix (and testcases) for [4a7397e0b3]: Tcl 9: fcopy with -strictencoding 1 UTF-8 channels 2023-02-10 20:22:07 +00:00
apnadkarni e26214c287 Phase out (almost) STRICT and NOCOMPLAIN flags. 2023-02-10 17:07:12 +00:00
jan.nijtmans fd83fb931e Add 4 more testcases, showing that the same bug is present in utf-16 as well. Also fix the bug (really, now!) 2023-02-09 19:52:00 +00:00
apnadkarni 9d1ba01f11 Modify encoding C API to use profiles (in progress) 2023-02-09 17:04:33 +00:00
apnadkarni d46a244159 Add equivalent tests from ff630bf370 2023-02-09 17:03:31 +00:00
jan.nijtmans b185a55c3b Add 4 testcases, showing that the bug fix introduces another (minor) problem. To be fixed soon 2023-02-09 07:55:29 +00:00
apnadkarni 4294befd8b Do not have -failindex imply -strict 2023-02-09 07:27:43 +00:00
apnadkarni d04dfba748 Merge bug-10c2c17c32 2023-02-09 06:56:39 +00:00
apnadkarni 615082f1fa Merge core-8-branch 2023-02-07 17:10:07 +00:00
apnadkarni b741dab392 Fix tcltest to not exit on encoding errors when printing to stdout 2023-02-07 11:25:22 +00:00
apnadkarni e0ee29b9b6 Refactor encoding tests for broader coverage and easier test case management 2023-02-07 11:23:52 +00:00
apnadkarni 694ae19131 Fix call to EncodingConvertParseOption for decoding 2023-02-07 11:22:08 +00:00
jan.nijtmans f5f5ff4257 Proposed fix for [10c2c17c32]: UTF-LE32 encoder mapping of surrogates. TODO: testcase 2023-02-06 22:43:30 +00:00
pooryorick 597d3b9e7b Fix for [b8f575aa2398b0e4] and [154ed7ce564a7b4c], double-[read]/[gets]
problem. Partial-read functionality commented out.
2023-02-04 14:10:40 +00:00
pooryorick f238eb1dbc Fix test io-75.14. 2023-02-04 00:28:12 +00:00
pooryorick 4b5b655e61 Fix for [b8f575aa2398b0e4] and [154ed7ce564a7b4c], double-[read]/[gets]
problem. Partial-read functionality commented out.

jn: First, see broken build [https://github.com/tcltk/tcl/actions/runs/4082362246/jobs/7036637005|here]. Second: Moving this to core-8-branch is getting TIP #653 into 8.7 without being voted upon. It's simply not ready.

pooryorick:  That second statement is false. The parts of this fix that implement TIP #653 are specifically commented out.
2023-02-03 22:15:25 +00:00
pooryorick 52fc9a970c Fix for [b8f575aa2398b0e4] and [154ed7ce564a7b4c], double-[read]/[gets]
problem.  Partial-read functionality commented out.
2023-02-02 22:51:26 +00:00
apnadkarni 100d8ce724 Update tests to use -encodingprofile 2023-02-02 16:43:12 +00:00
apnadkarni e31133e3b0 Change encoding error options to fconfigure to encoding profiles 2023-02-02 15:37:21 +00:00
apnadkarni 26e89b4b3c Use common option parsing for ConvertfromObjCmd. Fix test error messages. 2023-02-02 12:23:37 +00:00
apnadkarni 637e7224c9 Replace encoding -strict etc. with -profile 2023-02-02 11:52:31 +00:00
jan.nijtmans c529405c65 Merge 8.7 2023-02-02 07:17:06 +00:00
jan.nijtmans de0a637d7c Fix documentation on "encoding" command 2023-02-02 07:12:34 +00:00
jan.nijtmans 536651d954 Merge 8.7 2023-02-01 23:02:16 +00:00
jan.nijtmans b9c893dbc9 Renumber testscase, sync with Tcl 9.0 2023-02-01 21:01:51 +00:00
jan.nijtmans 6b6d121149 merge-mark 2023-02-01 08:13:06 +00:00
jan.nijtmans 3eaad4bbc9 (cherry-pick) Make Tcl_UniCharToUtf more readable and add test to exercise surrogate handling. (test-case was still missing, which cannot be used in Tcl 8.6) 2023-02-01 08:10:12 +00:00
jan.nijtmans 44dd5d86bc merge-mark 2023-02-01 07:33:13 +00:00
jan.nijtmans 537c8e77ba (cherry-pick) Make Tcl_UniCharToUtf more readable and add test to exercise surrogate handling. 2023-02-01 07:32:14 +00:00
jan.nijtmans 5866ef6d2a (Cherry-pick) Make Tcl_UniCharToUtf more readable. 2023-02-01 07:29:48 +00:00
pooryorick 0184ebda4f Make Tcl_UniCharToUtf more readable and add test to exercise surrogate
handling.
2023-01-31 23:04:56 +00:00
pooryorick 078a694834 Fix error introduced in [3e5e37f83b058f3d] for Tcl_UniCharToUtf, and add test. 2023-01-31 22:15:02 +00:00
jan.nijtmans e5272c9be6 Remove incorrect comment. See: [https://www.magicsplat.com/tcl9/tcl9unicode.html#surrogates-as-literals]. Thanks, Ashok, for noticing this! 2023-01-31 17:34:05 +00:00
jan.nijtmans 596e33bb9e Remove incorrect comment. See: [https://www.magicsplat.com/tcl9/tcl9unicode.html#surrogates-as-literals]. Thanks, Ashok, for noticing this! 2023-01-31 17:30:59 +00:00
jan.nijtmans 081c085c0f merge-mark 2023-01-31 08:14:00 +00:00
jan.nijtmans 64e3a23bfd SetFlag -> GotFlag (since SetFlag always returns 1, this is nonsence in an if() statement). Also add test-case, showing that it was actually wrong, in behavior too. 2023-01-31 07:49:16 +00:00
dgp 58446472bb merge 8.7 2023-01-30 15:57:39 +00:00
dgp d3dae9eba4 silence compiler warning 2023-01-30 15:37:41 +00:00
pooryorick 8c0f76a7de A few more readability changes to Tcl_UniCharToUtf()
jn: Please, don't do that here. Tcl_UniCharToUtf() is shared between 8.6, 8.7 and 9.0. So if you want to make it easier to read, it should be done on all 3 branches. I know you only care about "trunk", but it makes maintenance on 8.6/8.7/9.0 harder than it already is. I don't want to spend time on reviewing such kind of changes, and no-one else is doing it. Thanks for understanding (I hope)!
2023-01-30 11:59:41 +00:00
pooryorick 4d235ca93a Make Tcl_UniCharToUtf() a little easier to read. 2023-01-30 11:22:28 +00:00
jan.nijtmans 5b86b255d4 Another situation where TCL_COMBINE handling gives a strange result (utf-32 encoder) 2023-01-28 20:50:36 +00:00
jan.nijtmans 468b1a4346 Fix "format %c 0x10000041", should give the same answer as in Tcl 8.6 (Handling of TCL_COMBINE flag should not be visible at script level) 2023-01-28 18:50:32 +00:00
pooryorick 7f87f0f8ea Add some comments and tidy code. 2023-01-27 19:15:09 +00:00
jan.nijtmans 5d13f6b527 Merge 8.7 2023-01-27 15:10:36 +00:00
jan.nijtmans 0318ff75d9 Fix off-by-one error in tclCmdAH.c, with testcases showing that it works now. 2023-01-27 14:48:37 +00:00
jan.nijtmans 06de3a9ba1 new testcase encoding-18.1. Testcase cleanup 2023-01-27 14:23:08 +00:00
jan.nijtmans d838764849 Update fcopy documentation regarding -size argument 2023-01-27 08:20:57 +00:00
jan.nijtmans 8ea5f2cfce Update fcopy documentation regarding -size argument 2023-01-27 08:17:34 +00:00
pooryorick 23e46e5885 Merge 8.7 2023-01-27 00:46:36 +00:00
pooryorick d271c9f407 Fix for [ee08ed090b0a5408], sporadic segmentation fault in
coroutine.test/coroutine-7.4.
2023-01-26 23:55:30 +00:00
jan.nijtmans 97041036d3 Merge 8.7 2023-01-24 20:05:00 +00:00
pooryorick 805fa175fc For [read] and [gets] encoding errors, use "-result read" in return options
dictionary instead of just "-result".
2023-01-08 10:07:46 +00:00
pooryorick 985ea00b16 Merge py-b8f575aa23: Fix for [154ed7ce56], Tcl 9: [gets] on -strictencoding 1 configured channel. 2023-01-02 23:12:02 +00:00
pooryorick 3919b0a0b4 Add test for [gets] in non-strict mode after an encoding error. 2022-12-30 21:53:47 +00:00
pooryorick 63e04b3c2d New test, io-12.9.strict, for issue report [1bedc53c8cb878f0]. 2022-12-30 21:05:56 +00:00
pooryorick a801c2d474 Fix DoReadChars() to correctly discard encoding errors after eofchar has been seen, and add new test, io-75.8.invalid. 2022-12-30 20:27:47 +00:00
pooryorick 3b45005127 Arrange new code in DoReadChars to ensure that final steps are always taken. 2022-12-29 22:59:10 +00:00
pooryorick 0f0fc59c9f merge py-b8f575aa23 after updating fix so that all tests pass.
jn: let's wait for more review, since test-cases were modified. This is more than only a bug-fix
2022-12-28 22:58:53 +00:00
pooryorick f2cc84c99a Update fix so that the two failing tests, iocmd-23.8 and iortrans-4.7 now pass. 2022-12-28 22:46:37 +00:00
pooryorick 4a8b2cf10f A better fix for [b8f575aa23], as it maintains the expectation that synchronous
[read] results in an error when invalid data is encountered.

someone other than pooryorick:  Pushed this check-in back on to a review branch.  It needs more baking/review.
As is, it makes two tests fail, and it introduces a new element "-result" to
the return options dictionary.
2022-12-28 12:07:18 +00:00
93 changed files with 6545 additions and 1775 deletions
+3 -3
View File
@@ -19,7 +19,7 @@ jobs:
- name: Build
run: make all
env:
CFLAGS: -arch x86_64 -arch arm64e
CFLAGS: -arch x86_64 -arch arm64
- name: Run Tests
run: make test styles=develop
env:
@@ -51,13 +51,13 @@ jobs:
# Note that macOS is always a 64 bit platform
run: ./configure --enable-dtrace --enable-framework ${CFGOPT} "--prefix=$HOME/install" || (cat config.log && exit 1)
env:
CFLAGS: -arch x86_64 -arch arm64e
CFLAGS: -arch x86_64 -arch arm64
CFGOPT: ${{ matrix.cfgopt }}
- name: Build
run: |
make all tcltest
env:
CFLAGS: -arch x86_64 -arch arm64e
CFLAGS: -arch x86_64 -arch arm64
- name: Run Tests
run: |
make test
+1 -1
View File
@@ -62,7 +62,7 @@ jobs:
sudo chmod a+x /usr/local/bin/macher
echo "VER_PATH=$(cd tools; pwd)/addVerToFile.tcl" >> $GITHUB_ENV
echo "CREATE_DMG=$(cd create-dmg;pwd)/create-dmg" >> $GITHUB_ENV
echo "CFLAGS=-arch x86_64 -arch arm64e" >> $GITHUB_ENV
echo "CFLAGS=-arch x86_64 -arch arm64" >> $GITHUB_ENV
- name: Configure
run: ./configure --disable-symbols --disable-shared --enable-zipfs
working-directory: unix
+126 -202
View File
@@ -1,6 +1,7 @@
'\"
'\" Copyright (c) 1993 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\" Copyright (c) 2023 Nathan Coulter
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -16,176 +17,152 @@ Summary of Tcl language syntax.
.SH DESCRIPTION
.PP
The following rules define the syntax and semantics of the Tcl language:
.IP "[1] \fBCommands.\fR"
A Tcl script is a string containing one or more commands.
Semi-colons and newlines are command separators unless quoted as
described below.
Close brackets are command terminators during command substitution
(see below) unless quoted.
.IP "[2] \fBEvaluation.\fR"
A command is evaluated in two steps.
First, the Tcl interpreter breaks the command into \fIwords\fR
and performs substitutions as described below.
These substitutions are performed in the same way for all
commands.
Secondly, the first word is used to locate a routine to
carry out the command, and the remaining words of the command are
passed to that routine.
The routine is free to interpret each of its words
in any way it likes, such as an integer, variable name, list,
or Tcl script.
Different commands interpret their words differently.
.IP "[3] \fBWords.\fR"
Words of a command are separated by white space (except for
newlines, which are command separators).
.IP "[4] \fBDouble quotes.\fR"
If the first character of a word is double-quote
.PQ \N'34'
then the word is terminated by the next double-quote character.
If semi-colons, close brackets, or white space characters
(including newlines) appear between the quotes then they are treated
as ordinary characters and included in the word.
Command substitution, variable substitution, and backslash substitution
are performed on the characters between the quotes as described below.
The double-quotes are not retained as part of the word.
.IP "[5] \fBArgument expansion.\fR"
If a word starts with the string
.QW {*}
followed by a non-whitespace character, then the leading
.QW {*}
is removed and the rest of the word is parsed and substituted as any other
word. After substitution, the word is parsed as a list (without command or
variable substitutions; backslash substitutions are performed as is normal for
a list and individual internal words may be surrounded by either braces or
double-quote characters), and its words are added to the command being
substituted. For instance,
.QW "cmd a {*}{b [c]} d {*}{$e f {g h}}"
is equivalent to
.QW "cmd a b {[c]} d {$e} f {g h}" .
.IP "[6] \fBBraces.\fR"
If the first character of a word is an open brace
.
.IP "[1] \fBScript.\fR"
A script is composed of zero or more commands delimited by semi-colons or
newlines.
.IP "[2] \fBCommand.\fR"
A command is composed of zero or more words delimited by whitespace. The
replacement for a substitution is included verbatim in the word. For example, a
space in the replacement is included in the word rather than becoming a
delimiter, and \fI\\\\\fR becomes a single backslash in the word. Each word is
processed from left to right and each substitution is performed as soon as it
is complete.
For example, the command
.RS
.PP
.CS
set y [set x 0][incr x][incr x]
.CE
.PP
is composed of three words, and sets the value of \fIy\fR to \fI012\fR.
.PP
If hash
.PQ #
is the first character of what would otherwise be the first word of a command,
all characters up to the next newline are ignored.
.RE
.
.IP "[3] \fBBraced word.\fR"
If a word is enclosed in braces
.PQ {
and rule [5] does not apply, then
the word is terminated by the matching close brace
.PQ } "" .
Braces nest within the word: for each additional open
brace there must be an additional close brace (however,
if an open brace or close brace within the word is
quoted with a backslash then it is not counted in locating the
matching close brace).
No substitutions are performed on the characters between the
braces except for backslash-newline substitutions described
below, nor do semi-colons, newlines, close brackets,
or white space receive any special interpretation.
The word will consist of exactly the characters between the
outer braces, not including the braces themselves.
.IP "[7] \fBCommand substitution.\fR"
If a word contains an open bracket
and
.PQ } ""
, the braces are removed and the enclosed characters become the word. No
substitutions are performed. Nested pairs of braces may occur within the word.
A brace preceded by an odd number of backslashes is not considered part of a
pair, and neither brace nor the backslashes are removed from the word.
.
.IP "[4] \fBQuoted word.\fR"
If a word is enclosed in double quotes
.PQ \N'34'
, the double quotes are removed and the enclosed characters become the word.
Substitutions are performed.
.
.IP "[5] \fBList.\fR"
A list has the form of a single command. Newline is whitespace, and semicolon
has no special interpretation. There is no script evaluation so there is no
argument expansion, variable substitution, or command substitution: Dollar-sign
and open bracket have no special interpretation, and what would be argument
expansion in a script is invalid in a list.
.
.IP "[6] \fBArgument expansion.\fR"
If
.QW {*}
prefixes a word, it is removed. After any remaining enclosing braces or quotes
are processed and applicable substitutions performed, the word, which must
be a list, is removed from the command, and in its place each word in the
list becomes an additional word in the command. For example,
.CS
cmd a {*}{b [c]} d {*}{$e f {g h}}
.CE
is equivalent to
.CS
cmd a b {[c]} d {$e} f {g h} .
.CE
.
.IP "[7] \fBEvaluation.\fR"
To evaluate a script, an interpreter evaluates each successive command. The
first word identifies a procedure, and the remaining words are passed to that
procedure for further evaluation. The procedure interprets each argument in
its own way, e.g. as an integer, variable name, list, mathematical expression,
script, or in some other arbitrary way. The result of the last command is the
result of the script.
.
.IP "[8] \fBCommand substitution.\fR"
Each pair of brackets
.PQ [
then Tcl performs \fIcommand substitution\fR.
To do this it invokes the Tcl interpreter recursively to process
the characters following the open bracket as a Tcl script.
The script may contain any number of commands and must be terminated
by a close bracket
.PQ ] "" .
The result of the script (i.e. the result of its last command) is
substituted into the word in place of the brackets and all of the
characters between them.
There may be any number of command substitutions in a single word.
Command substitution is not performed on words enclosed in braces.
.IP "[8] \fBVariable substitution.\fR"
If a word contains a dollar-sign
and
.PQ ] ""
encloses a script and is replaced by the result of that script.
.IP "[9] \fBVariable substitution.\fR"
Each of the following forms begins with dollar sign
.PQ $
followed by one of the forms
described below, then Tcl performs \fIvariable
substitution\fR: the dollar-sign and the following characters are
replaced in the word by the value of a variable.
Variable substitution may take any of the following forms:
and is replaced by the value of the identified variable. \fIname\fR names the
variable and is composed of ASCII letters (\fBA\fR\(en\fBZ\fR and
\fBa\fR\(en\fBz\fR), digits (\fB0\fR\(en\fB9\fR), underscores, or namespace
delimiters (two or more colons). \fIindex\fR is the name of an individual
variable within an array variable, and may be empty.
.RS
.TP 15
\fB$\fIname\fR
.
\fIName\fR is the name of a scalar variable; the name is a sequence
of one or more characters that are a letter, digit, underscore,
or namespace separators (two or more colons).
Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\(en\fB9\fR,
\fBA\fR\(en\fBZ\fR and \fBa\fR\(en\fBz\fR).
\fIname\fR may not be empty.
.TP 15
\fB$\fIname\fB(\fIindex\fB)\fR
.
\fIName\fR gives the name of an array variable and \fIindex\fR gives
the name of an element within that array.
\fIName\fR must contain only letters, digits, underscores, and
namespace separators, and may be an empty string.
Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\(en\fB9\fR,
\fBA\fR\(en\fBZ\fR and \fBa\fR\(en\fBz\fR).
Command substitutions, variable substitutions, and backslash
substitutions are performed on the characters of \fIindex\fR.
\fIname\fR may be empty. Substitutions are performed on \fIindex\fR.
.TP 15
\fB${\fIname\fB}\fR
\fIname\fR may be empty.
.TP 15
\fB${\fIname(index)\fB}\fR
.
\fIName\fR is the name of a scalar variable or array element. It may contain
any characters whatsoever except for close braces. It indicates an array
element if \fIname\fR is in the form
.QW \fIarrayName\fB(\fIindex\fB)\fR
where \fIarrayName\fR does not contain any open parenthesis characters,
.QW \fB(\fR ,
or close brace characters,
.QW \fB}\fR ,
and \fIindex\fR can be any sequence of characters except for close brace
characters. No further
substitutions are performed during the parsing of \fIname\fR.
.PP
There may be any number of variable substitutions in a single word.
Variable substitution is not performed on words enclosed in braces.
.PP
Note that variables may contain character sequences other than those listed
above, but in that case other mechanisms must be used to access them (e.g.,
via the \fBset\fR command's single-argument form).
\fIname\fR may be empty. No substitutions are performed.
.RE
.IP "[9] \fBBackslash substitution.\fR"
If a backslash
Variables that are not accessible through one of the forms above may be
accessed through other mechanisms, e.g. the \fBset\fR command.
.IP "[10] \fBBackslash substitution.\fR"
Each backslash
.PQ \e
appears within a word then \fIbackslash substitution\fR occurs.
In all cases but those described below the backslash is dropped and
the following character is treated as an ordinary
character and included in the word.
This allows characters such as double quotes, close brackets,
and dollar signs to be included in words without triggering
special processing.
The following table lists the backslash sequences that are
handled specially, along with the value that replaces each sequence.
that is not part of one of the forms listed below is removed, and the next
character is included in the word verbatim, which allows the inclusion of
characters that would normally be interpreted, namely whitespace, braces,
brackets, double quote, dollar sign, and backslash. The following sequences
are replaced as described:
.RS
.RS
.RS
.TP 7
\e\fBa\fR
Audible alert (bell) (Unicode U+000007).
Audible alert (bell) (U+7).
.TP 7
\e\fBb\fR
Backspace (Unicode U+000008).
Backspace (U+8).
.TP 7
\e\fBf\fR
Form feed (Unicode U+00000C).
Form feed (U+C).
.TP 7
\e\fBn\fR
Newline (Unicode U+00000A).
Newline (U+A).
.TP 7
\e\fBr\fR
Carriage-return (Unicode U+00000D).
Carriage-return (U+D).
.TP 7
\e\fBt\fR
Tab (Unicode U+000009).
Tab (U+9).
.TP 7
\e\fBv\fR
Vertical tab (Unicode U+00000B).
Vertical tab (U+B).
.TP 7
\e\fB<newline>\fIwhiteSpace\fR
.
A single space character replaces the backslash, newline, and all spaces
and tabs after the newline. This backslash sequence is unique in that it
is replaced in a separate pre-pass before the command is actually parsed.
This means that it will be replaced even when it occurs between braces,
and the resulting space will be treated as a word separator if it is not
in braces or quotes.
Newline preceded by an odd number of backslashes, along with the consecutive
spaces and tabs that immediately follow it, is replaced by a single space.
Because this happens before the command is split into words, it occurs even
within braced words, and if the resulting space may subsequently be treated as
a word delimiter.
.TP 7
\e\e
Backslash
@@ -193,83 +170,30 @@ Backslash
.TP 7
\e\fIooo\fR
.
The digits \fIooo\fR (one, two, or three of them) give a eight-bit octal
value for the Unicode character that will be inserted, in the range
\fI000\fR\(en\fI377\fR (i.e., the range U+000000\(enU+0000FF).
The parser will stop just before this range overflows, or when
the maximum of three digits is reached. The upper bits of the Unicode
character will be 0.
Up to three octal digits form an eight-bit value for a Unicode character in the
range \fI0\fR\(en\fI377\fR, i.e. U+0\(enU+FF. Only the digits that result in a
number in this range are consumed.
.TP 7
\e\fBx\fIhh\fR
.
The hexadecimal digits \fIhh\fR (one or two of them) give an eight-bit
hexadecimal value for the Unicode character that will be inserted. The upper
bits of the Unicode character will be 0 (i.e., the character will be in the
range U+000000\(enU+0000FF).
Up to two hexadecimal digits form an eight-bit value for a Unicode character in
the range \fI0\fR\(en\fIFF\fR.
.TP 7
\e\fBu\fIhhhh\fR
.
The hexadecimal digits \fIhhhh\fR (one, two, three, or four of them) give a
sixteen-bit hexadecimal value for the Unicode character that will be
inserted. The upper bits of the Unicode character will be 0 (i.e., the
character will be in the range U+000000\(enU+00FFFF).
Up to four hexadecimal digits form a 16-bit value for a Unicode character in
the range \fI0\fR\(en\fIFFFF\fR.
.TP 7
\e\fBU\fIhhhhhhhh\fR
.
The hexadecimal digits \fIhhhhhhhh\fR (one up to eight of them) give a
twenty-one-bit hexadecimal value for the Unicode character that will be
inserted, in the range U+000000\(enU+10FFFF. The parser will stop just
before this range overflows, or when the maximum of eight digits
is reached. The upper bits of the Unicode character will be 0.
.RS
.PP
The range U+00D800\(enU+00DFFF is reserved for surrogates, which
are illegal on their own. Therefore, such sequences will result in
the replacement character U+FFFD. Surrogate pairs should be
encoded as single \e\fBU\fIhhhhhhhh\fR character.
Up to eight hexadecimal digits form a 21-bit value for a Unicode character in
the range \fI0\fR\(en\fI10FFFF\fR. Only the digits that result in a number in
this range are consumed.
.RE
.RE
.PP
Backslash substitution is not performed on words enclosed in braces,
except for backslash-newline as described above.
.RE
.IP "[10] \fBComments.\fR"
If a hash character
.PQ #
appears at a point where Tcl is
expecting the first character of the first word of a command,
then the hash character and the characters that follow it, up
through the next newline, are treated as a comment and ignored.
The comment character only has significance when it appears
at the beginning of a command.
.IP "[11] \fBOrder of substitution.\fR"
Each character is processed exactly once by the Tcl interpreter
as part of creating the words of a command.
For example, if variable substitution occurs then no further
substitutions are performed on the value of the variable; the
value is inserted into the word verbatim.
If command substitution occurs then the nested command is
processed entirely by the recursive call to the Tcl interpreter;
no substitutions are performed before making the recursive
call and no additional substitutions are performed on the result
of the nested script.
.RS
.PP
Substitutions take place from left to right, and each substitution is
evaluated completely before attempting to evaluate the next. Thus, a
sequence like
.PP
.CS
set y [set x 0][incr x][incr x]
.CE
.PP
will always set the variable \fIy\fR to the value, \fI012\fR.
.RE
.IP "[12] \fBSubstitution and word boundaries.\fR"
Substitutions do not affect the word boundaries of a command,
except for argument expansion as specified in rule [5].
For example, during variable substitution the entire value of
the variable becomes part of a single word, even if the variable's
value contains spaces.
.
.SH KEYWORDS
backslash, command, comment, script, substitution, variable
'\" Local Variables:
+13 -15
View File
@@ -39,9 +39,9 @@ system encoding is used.
.VS "TCL8.7 TIP346, TIP607, TIP601"
.PP
.RS
The command does not fail on encoding errors. Instead, any not convertable bytes
(like incomplete UTF-8 sequences, see example below) are put as byte values into
the output stream.
The command does not fail on encoding errors (unless \fB-strict\fR is specified).
Instead, any not convertable bytes (like incomplete UTF-8 sequences, see example
below) are put as byte values into the output stream.
.PP
If the option \fB-failindex\fR with a variable name is given, the error reporting
is changed in the following manner:
@@ -51,9 +51,8 @@ converted characters until the first error position.
In case of no error, the value \fI-1\fR is written to the variable. This option
may not be used together with \fB-nocomplain\fR.
.PP
The option \fB-nocomplain\fR has no effect and is available for compatibility with
TCL 9. In TCL 9, the encoding command fails with an error on any encoding issue.
This switch restores the TCL8.7 behaviour.
The option \fB-nocomplain\fR has no effect, but assures to get the same result
in Tcl 9.
.PP
The \fB-strict\fR option follows more strict rules in conversion. For the \fButf-8\fR
encoder, it disallows invalid byte sequences and surrogates (which -
@@ -74,9 +73,9 @@ specified, the current system encoding is used.
.VS "TCL8.7 TIP346, TIP607, TIP601"
.PP
.RS
The command does not fail on encoding errors. Instead, the replacement character
\fB?\fR is output for any not representable character (like the dot \fB\\U2022\fR
in \fBiso-8859-1\fR encoding, see example below).
The command does not fail on encoding errors (unless \fB-strict\fR is specified).
Instead, the replacement character \fB?\fR is output for any not representable
character (like the dot \fB\\U2022\fR in \fBiso-8859-1\fR encoding, see example below).
.PP
If the option \fB-failindex\fR with a variable name is given, the error reporting
is changed in the following manner:
@@ -86,9 +85,8 @@ converted bytes until the first error position. No error condition is raised.
In case of no error, the value \fI-1\fR is written to the variable. This option
may not be used together with \fB-nocomplain\fR.
.PP
The option \fB-nocomplain\fR has no effect and is available for compatibility with
TCL 9. In TCL 9, the encoding command fails with an error on any encoding issue.
This switch restores the TCL8.7 behaviour.
The option \fB-nocomplain\fR has no effect, but assures to get the same result
in Tcl 9.
.PP
The \fB-strict\fR option follows more strict rules in conversion. For the \fButf-8\fR
encoder, it disallows surrogates (which - otherwise - are just passed through). This
@@ -157,7 +155,7 @@ Example 4: detect the error location while transforming to ISO8859-1
(ISO-Latin 1):
.PP
.CS
% set s [\fBencoding convertto\fR -failindex i utf-8 "A\eu0141"]
% set s [\fBencoding convertto\fR -failindex i iso8859-1 "A\eu0141"]
A
% set i
1
@@ -166,11 +164,11 @@ A
Example 5: replace a not representable character by the replacement character:
.PP
.CS
% set s [\fBencoding convertto\fR -nocomplain utf-8 "A\eu0141"]
% set s [\fBencoding convertto\fR -nocomplain iso8859-1 "A\eu0141"]
A?
.CE
The option \fB-nocomplain\fR has no effect, but assures to get the same result
with TCL9.
in Tcl 9.
.VE "TCL8.7 TIP346, TIP607, TIP601"
.PP
.SH "SEE ALSO"
+3 -2
View File
@@ -26,8 +26,9 @@ network sockets.
The \fBfcopy\fR
command transfers data from \fIinchan\fR until end of file
or \fIsize\fR bytes or characters have been
transferred; \fIsize\fR is in bytes if the two channels are using the
same encoding, and is in characters otherwise.
transferred; \fIsize\fR is in bytes if the input channel is in binary mode,
or if the two channels are using the same encoding and -strict is not specified.
Otherwise, size is in characters.
If no \fB\-size\fR argument is given,
then the copy goes until end of file.
All the data read from \fIinchan\fR is copied to \fIoutchan\fR.
+8 -4
View File
@@ -2441,13 +2441,17 @@ declare 656 {
declare 657 {
int Tcl_UniCharIsUnicode(int ch)
}
# TIP 656
declare 658 {
Tcl_Size Tcl_ExternalToUtfDStringEx(Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr)
int Tcl_ExternalToUtfDStringEx(Tcl_Interp *interp, Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr,
Tcl_Size *errorLocationPtr)
}
declare 659 {
Tcl_Size Tcl_UtfToExternalDStringEx(Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr)
int Tcl_UtfToExternalDStringEx(Tcl_Interp *interp, Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr,
Tcl_Size *errorLocationPtr)
}
# TIP #511
+32 -15
View File
@@ -2123,18 +2123,12 @@ typedef struct Tcl_EncodingType {
* content. Otherwise, the number of chars
* produced is controlled only by other limiting
* factors.
* TCL_ENCODING_MODIFIED - Convert NULL bytes to \xC0\x80 in stead of
* 0x00. Only valid for "utf-8" and "cesu-8".
* This flag is implicit for external -> internal conversions,
* optional for internal -> external conversions.
* TCL_ENCODING_NOCOMPLAIN - If set, the converter
* substitutes the problematic character(s) with
* one or more "close" characters in the
* destination buffer and then continues to
* convert the source. If clear, the converter returns
* immediately upon encountering an invalid byte sequence
* or a source character that has no mapping in the
* target encoding. Only for Tcl 9.x.
* TCL_ENCODING_PROFILE_* - Mutually exclusive encoding profile ids. Note
* these are bit masks.
*
* NOTE: THESE BIT DEFINITIONS SHOULD NOT OVERLAP WITH INTERNAL USE BITS
* DEFINED IN tclEncoding.c (ENCODING_INPUT et al). Be cognizant of this
* when adding bits.
*/
#define TCL_ENCODING_START 0x01
@@ -2142,9 +2136,25 @@ typedef struct Tcl_EncodingType {
#define TCL_ENCODING_STOPONERROR 0x04
#define TCL_ENCODING_NO_TERMINATE 0x08
#define TCL_ENCODING_CHAR_LIMIT 0x10
#define TCL_ENCODING_MODIFIED 0x20
#define TCL_ENCODING_NOCOMPLAIN 0x40
#define TCL_ENCODING_STRICT 0x44
/* Internal use bits, do not define bits in this space. See above comment */
#define TCL_ENCODING_INTERNAL_USE_MASK 0xFF00
/* Reserve top byte for profile values (disjoint, not a mask) */
#define TCL_ENCODING_PROFILE_TCL8 0x01000000
#define TCL_ENCODING_PROFILE_STRICT 0x02000000
#define TCL_ENCODING_PROFILE_REPLACE 0x03000000
#define TCL_ENCODING_PROFILE_MASK 0xFF000000
#define TCL_ENCODING_PROFILE_GET(flags_) ((flags_) & TCL_ENCODING_PROFILE_MASK)
#define TCL_ENCODING_PROFILE_SET(flags_, profile_) \
do { \
(flags_) &= ~TCL_ENCODING_PROFILE_MASK; \
(flags_) |= profile_; \
} while (0)
/* Still being argued - For Tcl9, is the default strict? TODO */
#if TCL_MAJOR_VERSION < 9
#define TCL_ENCODING_PROFILE_DEFAULT TCL_ENCODING_PROFILE_TCL8
#else
#define TCL_ENCODING_PROFILE_DEFAULT TCL_ENCODING_PROFILE_TCL8 /* STRICT? REPLACE? TODO */
#endif
/*
* The following definitions are the error codes returned by the conversion
@@ -2417,10 +2427,17 @@ const char * TclTomMathInitializeStubs(Tcl_Interp *interp,
#endif
#ifdef USE_TCL_STUBS
# if TCL_UTF_MAX < 4
# define Tcl_InitStubs(interp, version, exact) \
(Tcl_InitStubs)(interp, version, \
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
TCL_STUB_MAGIC)
# else
# define Tcl_InitStubs(interp, version, exact) \
(Tcl_InitStubs)(interp, TCL_PATCH_LEVEL, \
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
TCL_STUB_MAGIC)
# endif
#else
# define Tcl_InitStubs(interp, version, exact) \
Tcl_PkgInitStubsCheck(interp, version, \
+3 -1
View File
@@ -9716,6 +9716,7 @@ TclNRYieldToObjCmd(
*/
iPtr->execEnvPtr = corPtr->callerEEPtr;
/* Not calling Tcl_IncrRefCount(listPtr) here because listPtr is private */
TclSetTailcall(interp, listPtr);
corPtr->yieldPtr = listPtr;
iPtr->execEnvPtr = corPtr->eePtr;
@@ -9918,8 +9919,8 @@ TclNRCoroutineActivateCallback(
if (corPtr->yieldPtr) {
for (runPtr = TOP_CB(interp); runPtr; runPtr = runPtr->nextPtr) {
if (runPtr->data[1] == corPtr->yieldPtr) {
Tcl_DecrRefCount((Tcl_Obj *)runPtr->data[1]);
runPtr->data[1] = NULL;
Tcl_DecrRefCount(corPtr->yieldPtr);
corPtr->yieldPtr = NULL;
break;
}
@@ -10520,6 +10521,7 @@ TclNRCoroutineObjCmd(
corPtr->running.lineLABCPtr = corPtr->lineLABCPtr;
corPtr->stackLevel = NULL;
corPtr->auxNumLevels = 0;
corPtr->yieldPtr = NULL;
/*
* Create the coro's execEnv, switch to it to push the exit and coro
+232 -201
View File
@@ -51,6 +51,7 @@ static Tcl_ObjCmdProc EncodingConvertfromObjCmd;
static Tcl_ObjCmdProc EncodingConverttoObjCmd;
static Tcl_ObjCmdProc EncodingDirsObjCmd;
static Tcl_ObjCmdProc EncodingNamesObjCmd;
static Tcl_ObjCmdProc EncodingProfilesObjCmd;
static Tcl_ObjCmdProc EncodingSystemObjCmd;
static inline int ForeachAssignments(Tcl_Interp *interp,
struct ForeachState *statePtr);
@@ -519,6 +520,7 @@ TclInitEncodingCmd(
{"convertto", EncodingConverttoObjCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
{"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
{"names", EncodingNamesObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"profiles", EncodingProfilesObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
{"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
{NULL, NULL, NULL, NULL, NULL, 0}
};
@@ -526,6 +528,116 @@ TclInitEncodingCmd(
return TclMakeEnsemble(interp, "encoding", encodingImplMap);
}
/*
*------------------------------------------------------------------------
*
* EncodingConvertParseOptions --
*
* Common routine for parsing arguments passed to encoding convertfrom
* and encoding convertto.
*
* Results:
* TCL_OK or TCL_ERROR.
*
* Side effects:
* On success,
* - *encPtr is set to the encoding. Must be freed with Tcl_FreeEncoding
* if non-NULL
* - *dataObjPtr is set to the Tcl_Obj containing the data to encode or
* decode
* - *profilePtr is set to encoding error handling profile
* - *failVarPtr is set to -failindex option value or NULL
* On error, all of the above are uninitialized.
*
*------------------------------------------------------------------------
*/
static int
EncodingConvertParseOptions (
Tcl_Interp *interp, /* For error messages. May be NULL */
int objc, /* Number of arguments */
Tcl_Obj *const objv[], /* Argument objects as passed to command. */
Tcl_Encoding *encPtr, /* Where to store the encoding */
Tcl_Obj **dataObjPtr, /* Where to store ptr to Tcl_Obj containing data */
int *profilePtr, /* Bit mask of encoding option profile */
Tcl_Obj **failVarPtr /* Where to store -failindex option value */
)
{
static const char *const options[] = {"-profile", "-failindex", NULL};
enum convertfromOptions { PROFILE, FAILINDEX } optIndex;
Tcl_Encoding encoding;
Tcl_Obj *dataObj;
Tcl_Obj *failVarObj;
#if TCL_MAJOR_VERSION > 8 || defined(TCL_NO_DEPRECATED)
int profile = TCL_ENCODING_PROFILE_TCL8; /* TODO - default for Tcl9? */
#else
int profile = TCL_ENCODING_PROFILE_TCL8;
#endif
/*
* Possible combinations:
* 1) data -> objc = 2
* 2) ?options? encoding data -> objc >= 3
* It is intentional that specifying option forces encoding to be
* specified. Less prone to user error. This should have always been
* the case even in 8.6 imho where there were no options (ie (1)
* should never have been allowed)
*/
if (objc == 1) {
numArgsError: /* ONLY jump here if nothing needs to be freed!!! */
Tcl_WrongNumArgs(interp,
1,
objv,
"?-profile profile? ?-failindex var? encoding data");
((Interp *)interp)->flags |= INTERP_ALTERNATE_WRONG_ARGS;
Tcl_WrongNumArgs(interp, 1, objv, "data");
return TCL_ERROR;
}
failVarObj = NULL;
if (objc == 2) {
encoding = Tcl_GetEncoding(interp, NULL);
dataObj = objv[1];
} else {
int argIndex;
for (argIndex = 1; argIndex < (objc-2); ++argIndex) {
if (Tcl_GetIndexFromObj(
interp, objv[argIndex], options, "option", 0, &optIndex)
!= TCL_OK) {
return TCL_ERROR;
}
if (++argIndex == (objc - 2)) {
goto numArgsError;
}
switch (optIndex) {
case PROFILE:
if (TclEncodingProfileNameToId(interp,
Tcl_GetString(objv[argIndex]),
&profile) != TCL_OK) {
return TCL_ERROR;
}
break;
case FAILINDEX:
failVarObj = objv[argIndex];
break;
}
}
/* Get encoding after opts so no need to free it on option error */
if (Tcl_GetEncodingFromObj(interp, objv[objc - 2], &encoding)
!= TCL_OK) {
return TCL_ERROR;
}
dataObj = objv[objc - 1];
}
*encPtr = encoding;
*dataObjPtr = dataObj;
*profilePtr = profile;
*failVarPtr = failVarObj;
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
@@ -552,122 +664,72 @@ EncodingConvertfromObjCmd(
Tcl_Encoding encoding; /* Encoding to use */
int length; /* Length of the byte array being converted */
const char *bytesPtr; /* Pointer to the first byte of the array */
#if TCL_MAJOR_VERSION > 8 || defined(TCL_NO_DEPRECATED)
int flags = TCL_ENCODING_STOPONERROR;
#else
int flags = TCL_ENCODING_NOCOMPLAIN;
#endif
int flags;
int result;
Tcl_Obj *failVarObj = NULL;
/*
* Decode parameters:
* Possible combinations:
* 1) data -> objc = 2
* 2) encoding data -> objc = 3
* 3) -nocomplain data -> objc = 3
* 4) -nocomplain encoding data -> objc = 4
* 5) -strict data -> objc = 3
* 6) -strict encoding data -> objc = 4
* 7) -failindex val data -> objc = 4
* 8) -failindex val encoding data -> objc = 5
*/
Tcl_Obj *failVarObj;
Tcl_Size errorLocation;
if (objc == 2) {
encoding = Tcl_GetEncoding(interp, NULL);
data = objv[1];
} else if (objc > 2 && objc < 7) {
int objcUnprocessed = objc;
data = objv[objc - 1];
bytesPtr = Tcl_GetString(objv[1]);
if (bytesPtr[0] == '-' && bytesPtr[1] == 'n'
&& !strncmp(bytesPtr, "-nocomplain", strlen(bytesPtr))) {
flags = TCL_ENCODING_NOCOMPLAIN;
objcUnprocessed--;
} else if (bytesPtr[0] == '-' && bytesPtr[1] == 's'
&& !strncmp(bytesPtr, "-strict", strlen(bytesPtr))) {
flags = TCL_ENCODING_STRICT;
objcUnprocessed--;
bytesPtr = Tcl_GetString(objv[2]);
if (bytesPtr[0] == '-' && bytesPtr[1] == 'f'
&& !strncmp(bytesPtr, "-failindex", strlen(bytesPtr))) {
/* at least two additional arguments needed */
if (objc < 6) {
goto encConvFromError;
}
failVarObj = objv[3];
objcUnprocessed -= 2;
}
} else if (bytesPtr[0] == '-' && bytesPtr[1] == 'f'
&& !strncmp(bytesPtr, "-failindex", strlen(bytesPtr))) {
/* at least two additional arguments needed */
if (objc < 4) {
goto encConvFromError;
}
failVarObj = objv[2];
flags = ENCODING_FAILINDEX;
objcUnprocessed -= 2;
bytesPtr = Tcl_GetString(objv[3]);
if (bytesPtr[0] == '-' && bytesPtr[1] == 's'
&& !strncmp(bytesPtr, "-strict", strlen(bytesPtr))) {
flags = TCL_ENCODING_STRICT;
objcUnprocessed --;
}
}
switch (objcUnprocessed) {
case 3:
if (Tcl_GetEncodingFromObj(interp, objv[objc - 2], &encoding) != TCL_OK) {
return TCL_ERROR;
}
break;
case 2:
encoding = Tcl_GetEncoding(interp, NULL);
break;
default:
goto encConvFromError;
}
} else {
encConvFromError:
Tcl_WrongNumArgs(interp, 1, objv, "?-strict? ?-failindex var? ?encoding? data");
((Interp *) interp)->flags |= INTERP_ALTERNATE_WRONG_ARGS;
Tcl_WrongNumArgs(interp, 1, objv, "-nocomplain ?encoding? data");
if (EncodingConvertParseOptions(
interp, objc, objv, &encoding, &data, &flags, &failVarObj)
!= TCL_OK) {
return TCL_ERROR;
}
/*
* Convert the string into a byte array in 'ds'
* Convert the string into a byte array in 'ds'.
*/
#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
if (!(flags & TCL_ENCODING_STOPONERROR)) {
if (TCL_ENCODING_PROFILE_GET(flags) == TCL_ENCODING_PROFILE_TCL8) {
/* Permits high bits to be non-0 in byte array (Tcl 8 style) */
bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
} else
}
else
#endif
bytesPtr = (char *) TclGetBytesFromObj(interp, data, &length);
bytesPtr = (char *) TclGetBytesFromObj(interp, data, &length);
if (bytesPtr == NULL) {
return TCL_ERROR;
}
result = Tcl_ExternalToUtfDStringEx(encoding, bytesPtr, length,
flags, &ds);
if ((!(flags & TCL_ENCODING_NOCOMPLAIN) || ((flags & TCL_ENCODING_STRICT) == TCL_ENCODING_STRICT)) && (result != TCL_INDEX_NONE)) {
if (failVarObj != NULL) {
if (Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewWideIntObj(result), TCL_LEAVE_ERR_MSG) == NULL) {
return TCL_ERROR;
}
} else {
char buf[TCL_INTEGER_SPACE];
sprintf(buf, "%u", result);
Tcl_SetObjResult(interp, Tcl_ObjPrintf("unexpected byte sequence starting at index %"
"u: '\\x%X'", result, UCHAR(bytesPtr[result])));
Tcl_SetErrorCode(interp, "TCL", "ENCODING", "ILLEGALSEQUENCE",
buf, NULL);
Tcl_DStringFree(&ds);
result = Tcl_ExternalToUtfDStringEx(interp, encoding, bytesPtr, length, flags,
&ds, failVarObj ? &errorLocation : NULL);
/* NOTE: ds must be freed beyond this point even on error */
switch (result) {
case TCL_OK:
errorLocation = TCL_INDEX_NONE;
break;
case TCL_ERROR:
/* Error in parameters. Should not happen. interp will have error */
Tcl_DStringFree(&ds);
return TCL_ERROR;
default:
/*
* One of the TCL_CONVERT_* errors. If we were not interested in the
* error location, interp result would already have been filled in
* and we can just return the error. Otherwise, we have to return
* what could be decoded and the returned error location.
*/
if (failVarObj == NULL) {
Tcl_DStringFree(&ds);
return TCL_ERROR;
}
} else if (failVarObj != NULL) {
if (Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewIntObj(-1), TCL_LEAVE_ERR_MSG) == NULL) {
break;
}
/*
* TCL_OK or a TCL_CONVERT_* error where the caller wants back as much
* data as was converted.
*/
if (failVarObj) {
/* I hope, wide int will cover Tcl_Size data type */
if (Tcl_ObjSetVar2(interp,
failVarObj,
NULL,
Tcl_NewWideIntObj(errorLocation),
TCL_LEAVE_ERR_MSG) == NULL) {
Tcl_DStringFree(&ds);
return TCL_ERROR;
}
}
/*
* Note that we cannot use Tcl_DStringResult here because it will
* truncate the string at the first null byte.
@@ -675,9 +737,7 @@ EncodingConvertfromObjCmd(
Tcl_SetObjResult(interp, Tcl_DStringToObj(&ds));
/*
* We're done with the encoding
*/
/* We're done with the encoding */
Tcl_FreeEncoding(encoding);
return TCL_OK;
@@ -711,83 +771,13 @@ EncodingConverttoObjCmd(
int length; /* Length of the string being converted */
const char *stringPtr; /* Pointer to the first byte of the string */
int result;
#if TCL_MAJOR_VERSION > 8 || defined(TCL_NO_DEPRECATED)
int flags = TCL_ENCODING_STOPONERROR;
#else
int flags = TCL_ENCODING_NOCOMPLAIN;
#endif
Tcl_Obj *failVarObj = NULL;
/*
* Decode parameters:
* Possible combinations:
* 1) data -> objc = 2
* 2) encoding data -> objc = 3
* 3) -nocomplain data -> objc = 3
* 4) -nocomplain encoding data -> objc = 4
* 5) -failindex val data -> objc = 4
* 6) -failindex val encoding data -> objc = 5
*/
if (objc == 2) {
encoding = Tcl_GetEncoding(interp, NULL);
data = objv[1];
} else if (objc > 2 && objc < 6) {
int objcUnprocessed = objc;
data = objv[objc - 1];
stringPtr = Tcl_GetString(objv[1]);
if (stringPtr[0] == '-' && stringPtr[1] == 'n'
&& !strncmp(stringPtr, "-nocomplain", strlen(stringPtr))) {
flags = TCL_ENCODING_NOCOMPLAIN;
objcUnprocessed--;
} else if (stringPtr[0] == '-' && stringPtr[1] == 's'
&& !strncmp(stringPtr, "-strict", strlen(stringPtr))) {
flags = TCL_ENCODING_STRICT;
objcUnprocessed--;
stringPtr = Tcl_GetString(objv[2]);
if (stringPtr[0] == '-' && stringPtr[1] == 'f'
&& !strncmp(stringPtr, "-failindex", strlen(stringPtr))) {
/* at least two additional arguments needed */
if (objc < 6) {
goto encConvToError;
}
failVarObj = objv[3];
objcUnprocessed -= 2;
}
} else if (stringPtr[0] == '-' && stringPtr[1] == 'f'
&& !strncmp(stringPtr, "-failindex", strlen(stringPtr))) {
/* at least two additional arguments needed */
if (objc < 4) {
goto encConvToError;
}
failVarObj = objv[2];
flags = TCL_ENCODING_STOPONERROR;
objcUnprocessed -= 2;
stringPtr = Tcl_GetString(objv[3]);
if (stringPtr[0] == '-' && stringPtr[1] == 's'
&& !strncmp(stringPtr, "-strict", strlen(stringPtr))) {
flags = TCL_ENCODING_STRICT;
objcUnprocessed --;
}
}
switch (objcUnprocessed) {
case 3:
if (Tcl_GetEncodingFromObj(interp, objv[objc - 2], &encoding) != TCL_OK) {
return TCL_ERROR;
}
break;
case 2:
encoding = Tcl_GetEncoding(interp, NULL);
break;
default:
goto encConvToError;
}
} else {
encConvToError:
Tcl_WrongNumArgs(interp, 1, objv, "?-strict? ?-failindex var? ?encoding? data");
((Interp *) interp)->flags |= INTERP_ALTERNATE_WRONG_ARGS;
Tcl_WrongNumArgs(interp, 1, objv, "-nocomplain ?encoding? data");
int flags;
Tcl_Obj *failVarObj;
Tcl_Size errorLocation;
if (EncodingConvertParseOptions(
interp, objc, objv, &encoding, &data, &flags, &failVarObj)
!= TCL_OK) {
return TCL_ERROR;
}
@@ -796,40 +786,53 @@ EncodingConverttoObjCmd(
*/
stringPtr = TclGetStringFromObj(data, &length);
result = Tcl_UtfToExternalDStringEx(encoding, stringPtr, length,
flags, &ds);
if ((!(flags & TCL_ENCODING_NOCOMPLAIN) || ((flags & TCL_ENCODING_STRICT) == TCL_ENCODING_STRICT)) && (result != TCL_INDEX_NONE)) {
if (failVarObj != NULL) {
/* I hope, wide int will cover size_t data type */
if (Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewWideIntObj(result), TCL_LEAVE_ERR_MSG) == NULL) {
return TCL_ERROR;
}
} else {
size_t pos = Tcl_NumUtfChars(stringPtr, result);
int ucs4;
char buf[TCL_INTEGER_SPACE];
TclUtfToUCS4(&stringPtr[result], &ucs4);
sprintf(buf, "%u", result);
Tcl_SetObjResult(interp, Tcl_ObjPrintf("unexpected character at index %"
TCL_Z_MODIFIER "u: 'U+%06X'", pos, ucs4));
Tcl_SetErrorCode(interp, "TCL", "ENCODING", "ILLEGALSEQUENCE",
buf, NULL);
Tcl_DStringFree(&ds);
result = Tcl_UtfToExternalDStringEx(interp, encoding, stringPtr, length, flags,
&ds, failVarObj ? &errorLocation : NULL);
/* NOTE: ds must be freed beyond this point even on error */
switch (result) {
case TCL_OK:
errorLocation = TCL_INDEX_NONE;
break;
case TCL_ERROR:
/* Error in parameters. Should not happen. interp will have error */
Tcl_DStringFree(&ds);
return TCL_ERROR;
default:
/*
* One of the TCL_CONVERT_* errors. If we were not interested in the
* error location, interp result would already have been filled in
* and we can just return the error. Otherwise, we have to return
* what could be decoded and the returned error location.
*/
if (failVarObj == NULL) {
Tcl_DStringFree(&ds);
return TCL_ERROR;
}
} else if (failVarObj != NULL) {
if (Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewIntObj(-1), TCL_LEAVE_ERR_MSG) == NULL) {
break;
}
/*
* TCL_OK or a TCL_CONVERT_* error where the caller wants back as much
* data as was converted.
*/
if (failVarObj) {
/* I hope, wide int will cover Tcl_Size data type */
if (Tcl_ObjSetVar2(interp,
failVarObj,
NULL,
Tcl_NewWideIntObj(errorLocation),
TCL_LEAVE_ERR_MSG) == NULL) {
Tcl_DStringFree(&ds);
return TCL_ERROR;
}
}
Tcl_SetObjResult(interp,
Tcl_NewByteArrayObj((unsigned char*) Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds)));
Tcl_DStringFree(&ds);
/*
* We're done with the encoding
*/
/* We're done with the encoding */
Tcl_FreeEncoding(encoding);
return TCL_OK;
@@ -911,6 +914,34 @@ EncodingNamesObjCmd(
return TCL_OK;
}
/*
*-----------------------------------------------------------------------------
*
* EncodingProfilesObjCmd --
*
* This command returns a list of the available encoding profiles
*
* Results:
* Returns a standard Tcl result
*
*-----------------------------------------------------------------------------
*/
int
EncodingProfilesObjCmd(
TCL_UNUSED(void *),
Tcl_Interp* interp, /* Tcl interpreter */
int objc, /* Number of command line args */
Tcl_Obj* const objv[]) /* Vector of command line args */
{
if (objc > 1) {
Tcl_WrongNumArgs(interp, 1, objv, NULL);
return TCL_ERROR;
}
TclGetEncodingProfiles(interp);
return TCL_OK;
}
/*
*-----------------------------------------------------------------------------
*
+14 -10
View File
@@ -1955,13 +1955,17 @@ EXTERN const char * Tcl_UtfPrev(const char *src, const char *start);
/* 657 */
EXTERN int Tcl_UniCharIsUnicode(int ch);
/* 658 */
EXTERN Tcl_Size Tcl_ExternalToUtfDStringEx(Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen, int flags,
Tcl_DString *dsPtr);
EXTERN int Tcl_ExternalToUtfDStringEx(Tcl_Interp *interp,
Tcl_Encoding encoding, const char *src,
Tcl_Size srcLen, int flags,
Tcl_DString *dsPtr,
Tcl_Size *errorLocationPtr);
/* 659 */
EXTERN Tcl_Size Tcl_UtfToExternalDStringEx(Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen, int flags,
Tcl_DString *dsPtr);
EXTERN int Tcl_UtfToExternalDStringEx(Tcl_Interp *interp,
Tcl_Encoding encoding, const char *src,
Tcl_Size srcLen, int flags,
Tcl_DString *dsPtr,
Tcl_Size *errorLocationPtr);
/* 660 */
EXTERN int Tcl_AsyncMarkFromSignal(Tcl_AsyncHandler async,
int sigNumber);
@@ -2741,8 +2745,8 @@ typedef struct TclStubs {
const char * (*tcl_UtfNext) (const char *src); /* 655 */
const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 656 */
int (*tcl_UniCharIsUnicode) (int ch); /* 657 */
Tcl_Size (*tcl_ExternalToUtfDStringEx) (Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr); /* 658 */
Tcl_Size (*tcl_UtfToExternalDStringEx) (Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr); /* 659 */
int (*tcl_ExternalToUtfDStringEx) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr); /* 658 */
int (*tcl_UtfToExternalDStringEx) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr); /* 659 */
int (*tcl_AsyncMarkFromSignal) (Tcl_AsyncHandler async, int sigNumber); /* 660 */
int (*tclListObjGetElements) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *objcPtr, Tcl_Obj ***objvPtr); /* 661 */
int (*tclListObjLength) (Tcl_Interp *interp, Tcl_Obj *listPtr, size_t *lengthPtr); /* 662 */
@@ -4317,14 +4321,14 @@ extern const TclStubs *tclStubsPtr;
/* Handle Win64 tk.dll being loaded in Cygwin64. */
# define Tcl_GetTime(t) \
do { \
union { \
struct { \
Tcl_Time now; \
long long reserved; \
} _t; \
_t.reserved = -1; \
tclStubsPtr->tcl_GetTime((&_t.now)); \
if (_t.reserved != -1) { \
_t.now.usec = _t.reserved; \
_t.now.usec = (long) _t.reserved; \
} \
*(t) = _t.now; \
} while (0)
+718 -203
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -2503,8 +2503,8 @@ TEBCresume(
* 'yieldParameter').
*/
Tcl_IncrRefCount(valuePtr);
iPtr->execEnvPtr = corPtr->callerEEPtr;
Tcl_IncrRefCount(valuePtr);
TclSetTailcall(interp, valuePtr);
corPtr->yieldPtr = valuePtr;
iPtr->execEnvPtr = corPtr->eePtr;
+120 -155
View File
@@ -165,6 +165,7 @@ static int CheckForDeadChannel(Tcl_Interp *interp,
static void CheckForStdChannelsBeingClosed(Tcl_Channel chan);
static void CleanupChannelHandlers(Tcl_Interp *interp,
Channel *chanPtr);
static void CleanupTimerHandler(ChannelState *statePtr);
static int CloseChannel(Tcl_Interp *interp, Channel *chanPtr,
int errorCode);
static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr,
@@ -172,6 +173,7 @@ static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr,
static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr);
static void CommonGetsCleanup(Channel *chanPtr);
static int CopyData(CopyState *csPtr, int mask);
static void DeleteTimerHandler(ChannelState *statePtr);
static int MoveBytes(CopyState *csPtr);
static void MBCallback(CopyState *csPtr, Tcl_Obj *errObj);
@@ -1700,8 +1702,12 @@ Tcl_CreateChannel(
}
statePtr->inputEncodingState = NULL;
statePtr->inputEncodingFlags = TCL_ENCODING_START;
TCL_ENCODING_PROFILE_SET(statePtr->inputEncodingFlags,
TCL_ENCODING_PROFILE_DEFAULT);
statePtr->outputEncodingState = NULL;
statePtr->outputEncodingFlags = TCL_ENCODING_START;
TCL_ENCODING_PROFILE_SET(statePtr->outputEncodingFlags,
TCL_ENCODING_PROFILE_DEFAULT);
/*
* Set the channel up initially in AUTO input translation mode to accept
@@ -1730,6 +1736,7 @@ Tcl_CreateChannel(
statePtr->scriptRecordPtr = NULL;
statePtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;
statePtr->timer = NULL;
statePtr->timerChanPtr = NULL;
statePtr->csPtrR = NULL;
statePtr->csPtrW = NULL;
statePtr->outputStage = NULL;
@@ -3187,8 +3194,8 @@ CloseChannel(
/*
* Cancel any outstanding timer.
*/
DeleteTimerHandler(statePtr);
Tcl_DeleteTimerHandler(statePtr->timer);
/*
* Mark the channel as deleted by clearing the type structure.
@@ -3540,7 +3547,7 @@ Tcl_Close(
/*
* Cancel any outstanding timer.
*/
Tcl_DeleteTimerHandler(statePtr->timer);
DeleteTimerHandler(statePtr);
/*
* Invoke the registered close callbacks and delete their records.
@@ -4015,8 +4022,7 @@ Tcl_ClearChannelHandlers(
/*
* Cancel any outstanding timer.
*/
Tcl_DeleteTimerHandler(statePtr->timer);
DeleteTimerHandler(statePtr);
/*
* Remove any references to channel handlers for this channel that may be
@@ -4393,21 +4399,6 @@ Write(
WillWrite(chanPtr);
}
/*
* Transfer encoding nocomplain/strict option to the encoding flags
*/
if (GotFlag(statePtr, CHANNEL_ENCODING_STRICT)) {
statePtr->outputEncodingFlags |= TCL_ENCODING_STRICT;
#ifdef TCL_NO_DEPRECATED
} else if (GotFlag(statePtr, CHANNEL_ENCODING_NOCOMPLAIN)) {
statePtr->outputEncodingFlags &= ~TCL_ENCODING_STRICT;
statePtr->outputEncodingFlags |= TCL_ENCODING_NOCOMPLAIN;
#endif
} else {
statePtr->outputEncodingFlags &= ~TCL_ENCODING_STRICT;
}
/*
* Write the terminated escape sequence even if srcLen is 0.
*/
@@ -4730,21 +4721,6 @@ Tcl_GetsObj(
encoding = GetBinaryEncoding();
}
/*
* Transfer encoding nocomplain/strict option to the encoding flags
*/
if (GotFlag(statePtr, CHANNEL_ENCODING_STRICT)) {
statePtr->inputEncodingFlags |= TCL_ENCODING_STRICT;
#ifdef TCL_NO_DEPRECATED
} else if (GotFlag(statePtr, CHANNEL_ENCODING_NOCOMPLAIN)) {
statePtr->inputEncodingFlags &= ~TCL_ENCODING_STRICT;
statePtr->inputEncodingFlags |= TCL_ENCODING_NOCOMPLAIN;
#endif
} else {
statePtr->inputEncodingFlags &= ~TCL_ENCODING_STRICT;
}
/*
* Object used by FilterInputBytes to keep track of how much data has been
* consumed from the channel buffers.
@@ -5504,21 +5480,6 @@ FilterInputBytes(
}
gsPtr->state = statePtr->inputEncodingState;
/*
* Transfer encoding nocomplain/strict option to the encoding flags
*/
if (GotFlag(statePtr, CHANNEL_ENCODING_STRICT)) {
statePtr->inputEncodingFlags |= TCL_ENCODING_STRICT;
#ifdef TCL_NO_DEPRECATED
} else if (GotFlag(statePtr, CHANNEL_ENCODING_NOCOMPLAIN)) {
statePtr->inputEncodingFlags &= ~TCL_ENCODING_STRICT;
statePtr->inputEncodingFlags |= TCL_ENCODING_NOCOMPLAIN;
#endif
} else {
statePtr->inputEncodingFlags &= ~TCL_ENCODING_STRICT;
}
result = Tcl_ExternalToUtf(NULL, gsPtr->encoding, raw, rawLen,
statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE,
&statePtr->inputEncodingState, dst, spaceLeft, &gsPtr->rawRead,
@@ -6304,21 +6265,6 @@ ReadChars(
dst = TclGetString(objPtr) + numBytes;
}
/*
* Transfer encoding nocomplain/strict option to the encoding flags
*/
if (GotFlag(statePtr, CHANNEL_ENCODING_STRICT)) {
statePtr->inputEncodingFlags |= TCL_ENCODING_STRICT;
#ifdef TCL_NO_DEPRECATED
} else if (GotFlag(statePtr, CHANNEL_ENCODING_NOCOMPLAIN)) {
statePtr->inputEncodingFlags &= ~TCL_ENCODING_STRICT;
statePtr->inputEncodingFlags |= TCL_ENCODING_NOCOMPLAIN;
#endif
} else {
statePtr->inputEncodingFlags &= ~TCL_ENCODING_STRICT;
}
/*
* This routine is burdened with satisfying several constraints. It cannot
* append more than 'charsToRead` chars onto objPtr. This is measured
@@ -7588,7 +7534,11 @@ Tcl_Eof(
ChannelState *statePtr = ((Channel *) chan)->state;
/* State of real channel structure. */
return (GotFlag(statePtr, CHANNEL_EOF) && !GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) ? 1 : 0;
if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_FCOPY)
&& GotFlag(statePtr, CHANNEL_ENCODING_ERROR)) {
return 0;
}
return GotFlag(statePtr, CHANNEL_EOF) ? 1 : 0;
}
/*
@@ -7862,7 +7812,7 @@ Tcl_BadChannelOption(
{
if (interp != NULL) {
const char *genericopt =
"blocking buffering buffersize encoding eofchar nocomplainencoding strictencoding translation";
"blocking buffering buffersize encoding eofchar profile translation";
const char **argv;
int argc, i;
Tcl_DString ds;
@@ -8060,27 +8010,19 @@ Tcl_GetChannelOption(
return TCL_OK;
}
}
if (len == 0 || HaveOpt(1, "-nocomplainencoding")) {
if (len == 0 || HaveOpt(1, "-profile")) {
int profile;
const char *profileName;
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-nocomplainencoding");
Tcl_DStringAppendElement(dsPtr, "-profile");
}
#ifdef TCL_NO_DEPRECATED
Tcl_DStringAppendElement(dsPtr,
(flags & CHANNEL_ENCODING_NOCOMPLAIN) ? "1" : "0");
#else
Tcl_DStringAppendElement(dsPtr,
(flags & CHANNEL_ENCODING_STRICT) ? "0" : "1");
#endif
if (len > 0) {
return TCL_OK;
/* Note currently input and output profiles are same */
profile = TCL_ENCODING_PROFILE_GET(statePtr->inputEncodingFlags);
profileName = TclEncodingProfileIdToName(interp, profile);
if (profileName == NULL) {
return TCL_ERROR;
}
}
if (len == 0 || HaveOpt(1, "-strictencoding")) {
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-strictencoding");
}
Tcl_DStringAppendElement(dsPtr,
(flags & CHANNEL_ENCODING_STRICT) ? "1" : "0");
Tcl_DStringAppendElement(dsPtr, profileName);
if (len > 0) {
return TCL_OK;
}
@@ -8256,6 +8198,7 @@ Tcl_SetChannelOption(
return TCL_OK;
} else if (HaveOpt(2, "-encoding")) {
Tcl_Encoding encoding;
int profile;
if ((newValue[0] == '\0') || (strcmp(newValue, "binary") == 0)) {
encoding = NULL;
@@ -8280,9 +8223,12 @@ Tcl_SetChannelOption(
Tcl_FreeEncoding(statePtr->encoding);
statePtr->encoding = encoding;
statePtr->inputEncodingState = NULL;
profile = TCL_ENCODING_PROFILE_GET(statePtr->inputEncodingFlags);
statePtr->inputEncodingFlags = TCL_ENCODING_START;
TCL_ENCODING_PROFILE_SET(statePtr->inputEncodingFlags, profile);
statePtr->outputEncodingState = NULL;
statePtr->outputEncodingFlags = TCL_ENCODING_START;
TCL_ENCODING_PROFILE_SET(statePtr->outputEncodingFlags, profile); /* Same as input */
ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA|CHANNEL_ENCODING_ERROR);
UpdateInterest(chanPtr);
return TCL_OK;
@@ -8341,43 +8287,13 @@ Tcl_SetChannelOption(
ResetFlag(statePtr, CHANNEL_EOF|CHANNEL_STICKY_EOF|CHANNEL_BLOCKED);
statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
return TCL_OK;
} else if (HaveOpt(1, "-nocomplainencoding")) {
int newMode;
if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) {
} else if (HaveOpt(1, "-profile")) {
int profile;
if (TclEncodingProfileNameToId(interp, newValue, &profile) != TCL_OK) {
return TCL_ERROR;
}
if (newMode) {
ResetFlag(statePtr, CHANNEL_ENCODING_STRICT);
SetFlag(statePtr, CHANNEL_ENCODING_NOCOMPLAIN);
} else {
#ifdef TCL_NO_DEPRECATED
ResetFlag(statePtr, CHANNEL_ENCODING_NOCOMPLAIN);
#else
if (SetFlag(statePtr, CHANNEL_ENCODING_STRICT)) {
if (interp) {
Tcl_SetObjResult(interp, Tcl_NewStringObj(
"bad value for -nocomplainencoding: only true allowed",
TCL_INDEX_NONE));
}
return TCL_ERROR;
}
#endif
}
ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA|CHANNEL_ENCODING_ERROR);
return TCL_OK;
} else if (HaveOpt(1, "-strictencoding")) {
int newMode;
if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) {
return TCL_ERROR;
}
if (newMode) {
ResetFlag(statePtr, CHANNEL_ENCODING_NOCOMPLAIN);
SetFlag(statePtr, CHANNEL_ENCODING_STRICT);
} else {
ResetFlag(statePtr, CHANNEL_ENCODING_STRICT);
}
TCL_ENCODING_PROFILE_SET(statePtr->inputEncodingFlags, profile);
TCL_ENCODING_PROFILE_SET(statePtr->outputEncodingFlags, profile);
ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA|CHANNEL_ENCODING_ERROR);
return TCL_OK;
} else if (HaveOpt(1, "-translation")) {
@@ -8800,8 +8716,10 @@ UpdateInterest(
mask &= ~TCL_EXCEPTION;
if (!statePtr->timer) {
TclChannelPreserve((Tcl_Channel)chanPtr);
statePtr->timerChanPtr = chanPtr;
statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
ChannelTimerProc, chanPtr);
ChannelTimerProc, chanPtr);
}
}
}
@@ -8810,6 +8728,8 @@ UpdateInterest(
&& mask & TCL_WRITABLE
&& GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
TclChannelPreserve((Tcl_Channel)chanPtr);
statePtr->timerChanPtr = chanPtr;
statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
ChannelTimerProc,chanPtr);
}
@@ -8840,48 +8760,75 @@ ChannelTimerProc(
void *clientData)
{
Channel *chanPtr = (Channel *)clientData;
/* State info for channel */
ChannelState *statePtr = chanPtr->state;
/* Preserve chanPtr to guard against deallocation in Tcl_NotifyChannel. */
TclChannelPreserve((Tcl_Channel)chanPtr);
Tcl_Preserve(statePtr);
statePtr->timer = NULL;
if (statePtr->interestMask & TCL_WRITABLE
&& GotFlag(statePtr, CHANNEL_NONBLOCKING)
&& !GotFlag(statePtr, BG_FLUSH_SCHEDULED)
) {
/*
* Restart the timer in case a channel handler reenters the event loop
* before UpdateInterest gets called by Tcl_NotifyChannel.
*/
statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
ChannelTimerProc,chanPtr);
Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_WRITABLE);
}
/* TclChannelPreserve() must be called before the current function was
* scheduled, is already in effect. In this function it guards against
* deallocation in Tcl_NotifyChannel and also keps the channel preserved
* until ChannelTimerProc is later called again.
*/
/* The channel may have just been closed from within Tcl_NotifyChannel */
if (!GotFlag(statePtr, CHANNEL_INCLOSE)) {
if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA)
&& (statePtr->interestMask & TCL_READABLE)
&& (statePtr->inQueueHead != NULL)
&& IsBufferReady(statePtr->inQueueHead)) {
if (chanPtr->typePtr == NULL) {
CleanupTimerHandler(statePtr);
} else {
Tcl_Preserve(statePtr);
statePtr->timer = NULL;
if (statePtr->interestMask & TCL_WRITABLE
&& GotFlag(statePtr, CHANNEL_NONBLOCKING)
&& !GotFlag(statePtr, BG_FLUSH_SCHEDULED)
) {
/*
* Restart the timer in case a channel handler reenters the event loop
* before UpdateInterest gets called by Tcl_NotifyChannel.
*/
statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
ChannelTimerProc,chanPtr);
Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
ChannelTimerProc,chanPtr);
Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_WRITABLE);
} else {
UpdateInterest(chanPtr);
}
}
/* The channel may have just been closed from within Tcl_NotifyChannel */
if (!GotFlag(statePtr, CHANNEL_INCLOSE)) {
if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA)
&& (statePtr->interestMask & TCL_READABLE)
&& (statePtr->inQueueHead != NULL)
&& IsBufferReady(statePtr->inQueueHead)) {
/*
* Restart the timer in case a channel handler reenters the event loop
* before UpdateInterest gets called by Tcl_NotifyChannel.
*/
Tcl_Release(statePtr);
TclChannelRelease((Tcl_Channel)chanPtr);
statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
ChannelTimerProc,chanPtr);
Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
} else {
CleanupTimerHandler(statePtr);
UpdateInterest(chanPtr);
}
} else {
CleanupTimerHandler(statePtr);
}
}
Tcl_Release(statePtr);
}
}
static void
DeleteTimerHandler(
ChannelState *statePtr
)
{
if (statePtr->timer != NULL) {
Tcl_DeleteTimerHandler(statePtr->timer);
CleanupTimerHandler(statePtr);
}
}
static void
CleanupTimerHandler(
ChannelState *statePtr
){
TclChannelRelease((Tcl_Channel)statePtr->timerChanPtr);
statePtr->timer = NULL;
statePtr->timerChanPtr = NULL;
}
/*
@@ -9469,12 +9416,17 @@ TclCopyChannel(
* of the bytes themselves.
*/
/*
* TODO - should really only allow lossless profiles. Below reflects
* Tcl 8.7 alphas prior to encoding profiles
*/
moveBytes = inStatePtr->inEofChar == '\0' /* No eofChar to stop input */
&& inStatePtr->inputTranslation == TCL_TRANSLATE_LF
&& outStatePtr->outputTranslation == TCL_TRANSLATE_LF
&& inStatePtr->encoding == outStatePtr->encoding
&& (inStatePtr->flags & TCL_ENCODING_STRICT) != TCL_ENCODING_STRICT
&& outStatePtr->flags & TCL_ENCODING_NOCOMPLAIN;
&& TCL_ENCODING_PROFILE_GET(inStatePtr->flags) != TCL_ENCODING_PROFILE_STRICT
&& TCL_ENCODING_PROFILE_GET(outStatePtr->flags) == TCL_ENCODING_PROFILE_TCL8;
/*
* Allocate a new CopyState to maintain info about the current copy in
@@ -9799,11 +9751,12 @@ CopyData(
* the bottom of the stack.
*/
SetFlag(inStatePtr, CHANNEL_FCOPY);
inBinary = (inStatePtr->encoding == NULL);
outBinary = (outStatePtr->encoding == NULL);
sameEncoding = inStatePtr->encoding == outStatePtr->encoding
&& (inStatePtr->flags & TCL_ENCODING_STRICT) != TCL_ENCODING_STRICT
&& outStatePtr->flags & TCL_ENCODING_NOCOMPLAIN;
&& TCL_ENCODING_PROFILE_GET(inStatePtr->flags) != TCL_ENCODING_PROFILE_STRICT
&& TCL_ENCODING_PROFILE_GET(outStatePtr->flags) == TCL_ENCODING_PROFILE_TCL8;
if (!(inBinary || sameEncoding)) {
TclNewObj(bufObj);
@@ -9820,12 +9773,20 @@ CopyData(
Tcl_SetErrno(inStatePtr->unreportedError);
inStatePtr->unreportedError = 0;
goto readError;
} else if (inStatePtr->flags & CHANNEL_ENCODING_ERROR) {
Tcl_SetErrno(EILSEQ);
inStatePtr->flags &= ~CHANNEL_ENCODING_ERROR;
goto readError;
}
Tcl_GetChannelError(outChan, &msg);
if ((outStatePtr->unreportedError != 0) || (msg != NULL)) {
Tcl_SetErrno(outStatePtr->unreportedError);
outStatePtr->unreportedError = 0;
goto writeError;
} else if (outStatePtr->flags & CHANNEL_ENCODING_ERROR) {
Tcl_SetErrno(EILSEQ);
outStatePtr->flags &= ~CHANNEL_ENCODING_ERROR;
goto writeError;
}
if (cmdPtr && (mask == 0)) {
@@ -9906,6 +9867,7 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
}
@@ -9997,6 +9959,7 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
@@ -10019,6 +9982,7 @@ CopyData(
TclDecrRefCount(bufObj);
bufObj = NULL;
}
ResetFlag(inStatePtr, CHANNEL_FCOPY);
return TCL_OK;
}
} /* while */
@@ -10071,6 +10035,7 @@ CopyData(
}
}
}
ResetFlag(inStatePtr, CHANNEL_FCOPY);
return result;
}
+5 -5
View File
@@ -188,6 +188,9 @@ typedef struct ChannelState {
* handlers ("fileevent") on this channel. */
Tcl_Size bufSize; /* What size buffers to allocate? */
Tcl_TimerToken timer; /* Handle to wakeup timer for this channel. */
Channel *timerChanPtr; /* Needed in order to decrement the refCount of
the right channel when the timer is
deleted. */
struct CopyState *csPtrR; /* State of background copy for which channel
* is input, or NULL. */
struct CopyState *csPtrW; /* State of background copy for which channel
@@ -233,6 +236,8 @@ typedef struct ChannelState {
* flushed after every newline. */
#define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always
* be flushed immediately. */
#define CHANNEL_FCOPY (1<<6) /* Channel is currently doing an fcopy
* mode. */
#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the queued
* output buffers has been
* scheduled. */
@@ -275,16 +280,11 @@ typedef struct ChannelState {
* encountered an encoding error */
#define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is
* being used. */
#define CHANNEL_ENCODING_NOCOMPLAIN (1<<17) /* set if option
* -nocomplainencoding is set to 1 */
#define CHANNEL_ENCODING_STRICT (1<<18) /* set if option
* -strictencoding is set to 1 */
#define CHANNEL_INCLOSE (1<<19) /* Channel is currently being closed.
* Its structures are still live and
* usable, but it may not be closed
* again from within the close
* handler. */
#define ENCODING_FAILINDEX (1<<20) /* Internal flag, fail on Invalid bytes only */
#define CHANNEL_CLOSEDWRITE (1<<21) /* Channel write side has been closed.
* No further Tcl-level write IO on
* the channel is allowed. */
+2
View File
@@ -2830,6 +2830,7 @@ DeleteThreadReflectedChannelMap(
Tcl_ThreadId self = Tcl_GetCurrentThread();
ReflectedChannelMap *rcmPtr; /* The map */
ForwardingResult *resultPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* The origin thread for one or more reflected channels is gone.
@@ -2909,6 +2910,7 @@ DeleteThreadReflectedChannelMap(
*/
rcmPtr = GetThreadReflectedChannelMap();
tsdPtr->rcmPtr = NULL;
for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
hPtr != NULL;
hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
+14
View File
@@ -2879,7 +2879,19 @@ MODULE_SCOPE int tclFindExecutableSearchDone;
MODULE_SCOPE char *tclMemDumpFileName;
MODULE_SCOPE TclPlatformType tclPlatform;
/*
* Declarations related to internal encoding functions.
*/
MODULE_SCOPE Tcl_Encoding tclIdentityEncoding;
MODULE_SCOPE int
TclEncodingProfileNameToId(Tcl_Interp *interp,
const char *profileName,
int *profilePtr);
MODULE_SCOPE const char *TclEncodingProfileIdToName(Tcl_Interp *interp,
int profileId);
MODULE_SCOPE int TclEncodingSetProfileFlags(int flags);
MODULE_SCOPE void TclGetEncodingProfiles(Tcl_Interp *interp);
/*
* TIP #233 (Virtualized Time)
@@ -4787,6 +4799,8 @@ MODULE_SCOPE Tcl_LibraryInitProc TclThread_Init;
MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_Init;
MODULE_SCOPE Tcl_LibraryInitProc Procbodytest_SafeInit;
/*
*----------------------------------------------------------------
* Macro used by the Tcl core to check whether a pattern has any characters
+2
View File
@@ -417,6 +417,8 @@ Tcl_PopCallFrame(
framePtr->nsPtr = NULL;
if (framePtr->tailcallPtr) {
/* Reusing the existing reference count from framePtr->tailcallPtr, so
* no need to Tcl_IncrRefCount(framePtr->tailcallPtr)*/
TclSetTailcall(interp, framePtr->tailcallPtr);
}
}
+1
View File
@@ -4849,6 +4849,7 @@ ExtendStringRepWithUnicode(
copyBytes:
dst = objPtr->bytes + origLength;
*dst = '\0';
for (i = 0; i < numChars; i++) {
dst += Tcl_UniCharToUtf(unicode[i], dst);
}
+294 -17
View File
@@ -70,6 +70,7 @@ static Tcl_Interp *delInterp;
typedef struct TestCommandTokenRef {
int id; /* Identifier for this reference. */
Tcl_Command token; /* Tcl's token for the command. */
const char *value;
struct TestCommandTokenRef *nextPtr;
/* Next in list of references. */
} TestCommandTokenRef;
@@ -1178,6 +1179,18 @@ TestcmdinfoCmd(
return TCL_OK;
}
static int
CmdProc0(
void *clientData, /* String to return. */
Tcl_Interp *interp, /* Current interpreter. */
TCL_UNUSED(int) /*argc*/,
TCL_UNUSED(const char **) /*argv*/)
{
TestCommandTokenRef *refPtr = (TestCommandTokenRef *) clientData;
Tcl_AppendResult(interp, "CmdProc1 ", refPtr->value, NULL);
return TCL_OK;
}
static int
CmdProc1(
void *clientData, /* String to return. */
@@ -1189,6 +1202,7 @@ CmdProc1(
return TCL_OK;
}
static int
CmdProc2(
void *clientData, /* String to return. */
@@ -1200,6 +1214,28 @@ CmdProc2(
return TCL_OK;
}
static void
CmdDelProc0(
void *clientData) /* String to save. */
{
TestCommandTokenRef *thisRefPtr, *prevRefPtr = NULL;
TestCommandTokenRef *refPtr = (TestCommandTokenRef *) clientData;
int id = refPtr->id;
for (thisRefPtr = firstCommandTokenRef; refPtr != NULL;
thisRefPtr = thisRefPtr->nextPtr) {
if (thisRefPtr->id == id) {
if (prevRefPtr != NULL) {
prevRefPtr->nextPtr = thisRefPtr->nextPtr;
} else {
firstCommandTokenRef = thisRefPtr->nextPtr;
}
break;
}
prevRefPtr = thisRefPtr;
}
ckfree(refPtr);
}
static void
CmdDelProc1(
void *clientData) /* String to save. */
@@ -1253,17 +1289,16 @@ TestcmdtokenCmd(
}
if (strcmp(argv[1], "create") == 0) {
refPtr = (TestCommandTokenRef *)Tcl_Alloc(sizeof(TestCommandTokenRef));
refPtr->token = Tcl_CreateCommand(interp, argv[2], CmdProc1,
(void *) "original", NULL);
refPtr->token = Tcl_CreateCommand(interp, argv[2], CmdProc0,
refPtr, CmdDelProc0);
refPtr->id = nextCommandTokenRefId;
refPtr->value = "original";
nextCommandTokenRefId++;
refPtr->nextPtr = firstCommandTokenRef;
firstCommandTokenRef = refPtr;
sprintf(buf, "%d", refPtr->id);
Tcl_AppendResult(interp, buf, NULL);
} else if (strcmp(argv[1], "name") == 0) {
Tcl_Obj *objPtr;
} else {
if (sscanf(argv[2], "%d", &id) != 1) {
Tcl_AppendResult(interp, "bad command token \"", argv[2],
"\"", NULL);
@@ -1283,18 +1318,23 @@ TestcmdtokenCmd(
return TCL_ERROR;
}
objPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, refPtr->token, objPtr);
if (strcmp(argv[1], "name") == 0) {
Tcl_Obj *objPtr;
Tcl_AppendElement(interp,
Tcl_GetCommandName(interp, refPtr->token));
Tcl_AppendElement(interp, Tcl_GetString(objPtr));
Tcl_DecrRefCount(objPtr);
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
"\": must be create or name", NULL);
return TCL_ERROR;
objPtr = Tcl_NewObj();
Tcl_GetCommandFullName(interp, refPtr->token, objPtr);
Tcl_AppendElement(interp,
Tcl_GetCommandName(interp, refPtr->token));
Tcl_AppendElement(interp, Tcl_GetString(objPtr));
Tcl_DecrRefCount(objPtr);
} else {
Tcl_AppendResult(interp, "bad option \"", argv[1],
"\": must be create, name, or free", NULL);
return TCL_ERROR;
}
}
return TCL_OK;
}
@@ -1975,6 +2015,238 @@ static void SpecialFree(
ckfree(blockPtr - 16);
}
/*
*------------------------------------------------------------------------
*
* UtfTransformFn --
*
* Implements a direct call into Tcl_UtfToExternal and Tcl_ExternalToUtf
* as otherwise there is no script level command that directly exercises
* these functions (i/o command cannot test all combinations)
* The arguments at the script level are roughly those of the above
* functions:
* encodingname srcbytes flags state dstlen ?srcreadvar? ?dstwrotevar? ?dstcharsvar?
*
* Results:
* TCL_OK or TCL_ERROR. This any errors running the test, NOT the
* result of Tcl_UtfToExternal or Tcl_ExternalToUtf.
*
* Side effects:
*
* The result in the interpreter is a list of the return code from the
* Tcl_UtfToExternal/Tcl_ExternalToUtf functions, the encoding state, and
* an encoded binary string of length dstLen. Note the string is the
* entire output buffer, not just the part containing the decoded
* portion. This allows for additional checks at test script level.
*
* If any of the srcreadvar, dstwrotevar and
* dstcharsvar are specified and not empty, they are treated as names
* of variables where the *srcRead, *dstWrote and *dstChars output
* from the functions are stored.
*
* The function also checks internally whether nuls are correctly
* appended as requested but the TCL_ENCODING_NO_TERMINATE flag
* and that no buffer overflows occur.
*------------------------------------------------------------------------
*/
typedef int
UtfTransformFn(Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_EncodingState *statePtr,
char *dst, Tcl_Size dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr);
static int UtfExtWrapper(
Tcl_Interp *interp, UtfTransformFn *transformer, int objc, Tcl_Obj *const objv[])
{
Tcl_Encoding encoding;
Tcl_EncodingState encState, *encStatePtr;
Tcl_Size srcLen, bufLen;
const unsigned char *bytes;
unsigned char *bufPtr;
int srcRead, dstLen, dstWrote, dstChars;
Tcl_Obj *srcReadVar, *dstWroteVar, *dstCharsVar;
int result;
int flags;
Tcl_Obj **flagObjs;
int nflags;
if (objc < 7 || objc > 10) {
Tcl_WrongNumArgs(interp,
2,
objv,
"encoding srcbytes flags state dstlen ?srcreadvar? ?dstwrotevar? ?dstcharsvar?");
return TCL_ERROR;
}
if (Tcl_GetEncodingFromObj(interp, objv[2], &encoding) != TCL_OK) {
return TCL_ERROR;
}
/* Flags may be specified as list of integers and keywords */
flags = 0;
if (Tcl_ListObjGetElements(interp, objv[4], &nflags, &flagObjs) != TCL_OK) {
return TCL_ERROR;
}
struct {
const char *flagKey;
int flag;
} flagMap[] = {
{"start", TCL_ENCODING_START},
{"end", TCL_ENCODING_END},
{"stoponerror", TCL_ENCODING_STOPONERROR},
{"noterminate", TCL_ENCODING_NO_TERMINATE},
{"charlimit", TCL_ENCODING_CHAR_LIMIT},
{"profiletcl8", TCL_ENCODING_PROFILE_TCL8},
{"profilestrict", TCL_ENCODING_PROFILE_STRICT},
{"profilereplace", TCL_ENCODING_PROFILE_REPLACE},
{NULL, 0}
};
int i;
for (i = 0; i < nflags; ++i) {
int flag;
if (Tcl_GetIntFromObj(NULL, flagObjs[i], &flag) == TCL_OK) {
flags |= flag;
}
else {
int idx;
if (Tcl_GetIndexFromObjStruct(interp,
flagObjs[i],
flagMap,
sizeof(flagMap[0]),
"flag",
0,
&idx) != TCL_OK) {
return TCL_ERROR;
}
flags |= flagMap[idx].flag;
}
}
/* Assumes state is integer if not "" */
Tcl_WideInt wide;
if (Tcl_GetWideIntFromObj(interp, objv[5], &wide) == TCL_OK) {
encState = (Tcl_EncodingState)(size_t)wide;
encStatePtr = &encState;
} else if (Tcl_GetCharLength(objv[5]) == 0) {
encStatePtr = NULL;
} else {
return TCL_ERROR;
}
if (Tcl_GetIntFromObj(interp, objv[6], &dstLen) != TCL_OK) {
return TCL_ERROR;
}
srcReadVar = NULL;
dstWroteVar = NULL;
dstCharsVar = NULL;
if (objc > 7) {
/* Has caller requested srcRead? */
if (Tcl_GetCharLength(objv[7])) {
srcReadVar = objv[7];
}
if (objc > 8) {
/* Ditto for dstWrote */
if (Tcl_GetCharLength(objv[8])) {
dstWroteVar = objv[8];
}
if (objc > 9) {
if (Tcl_GetCharLength(objv[9])) {
dstCharsVar = objv[9];
}
}
}
}
if (flags & TCL_ENCODING_CHAR_LIMIT) {
/* Caller should have specified the dest char limit */
Tcl_Obj *valueObj;
if (dstCharsVar == NULL ||
(valueObj = Tcl_ObjGetVar2(interp, dstCharsVar, NULL, 0)) == NULL
) {
Tcl_SetResult(interp,
"dstCharsVar must be specified with integer value if "
"TCL_ENCODING_CHAR_LIMIT set in flags.", TCL_STATIC);
return TCL_ERROR;
}
if (Tcl_GetIntFromObj(interp, valueObj, &dstChars) != TCL_OK) {
return TCL_ERROR;
}
} else {
dstChars = 0; /* Only used for output */
}
bufLen = dstLen + 4; /* 4 -> overflow detection */
bufPtr = (unsigned char *) ckalloc(bufLen);
memset(bufPtr, 0xFF, dstLen); /* Need to check nul terminator */
memmove(bufPtr + dstLen, "\xAB\xCD\xEF\xAB", 4); /* overflow detection */
bytes = Tcl_GetByteArrayFromObj(objv[3], &srcLen); /* Last! to avoid shimmering */
result = (*transformer)(interp, encoding, (const char *)bytes, srcLen, flags,
encStatePtr, (char *) bufPtr, dstLen,
srcReadVar ? &srcRead : NULL,
&dstWrote,
dstCharsVar ? &dstChars : NULL);
if (memcmp(bufPtr + bufLen - 4, "\xAB\xCD\xEF\xAB", 4)) {
Tcl_SetResult(interp,
"Tcl_ExternalToUtf wrote past output buffer",
TCL_STATIC);
result = TCL_ERROR;
} else if (result != TCL_ERROR) {
Tcl_Obj *resultObjs[3];
switch (result) {
case TCL_OK:
resultObjs[0] = Tcl_NewStringObj("ok", -1);
break;
case TCL_CONVERT_MULTIBYTE:
resultObjs[0] = Tcl_NewStringObj("multibyte", -1);
break;
case TCL_CONVERT_SYNTAX:
resultObjs[0] = Tcl_NewStringObj("syntax", -1);
break;
case TCL_CONVERT_UNKNOWN:
resultObjs[0] = Tcl_NewStringObj("unknown", -1);
break;
case TCL_CONVERT_NOSPACE:
resultObjs[0] = Tcl_NewStringObj("nospace", -1);
break;
default:
resultObjs[0] = Tcl_NewIntObj(result);
break;
}
result = TCL_OK;
resultObjs[1] =
encStatePtr ? Tcl_NewWideIntObj((Tcl_WideInt)(size_t)encState) : Tcl_NewObj();
resultObjs[2] = Tcl_NewByteArrayObj(bufPtr, dstLen);
if (srcReadVar) {
if (Tcl_ObjSetVar2(interp,
srcReadVar,
NULL,
Tcl_NewIntObj(srcRead),
TCL_LEAVE_ERR_MSG) == NULL) {
result = TCL_ERROR;
}
}
if (dstWroteVar) {
if (Tcl_ObjSetVar2(interp,
dstWroteVar,
NULL,
Tcl_NewIntObj(dstWrote),
TCL_LEAVE_ERR_MSG) == NULL) {
result = TCL_ERROR;
}
}
if (dstCharsVar) {
if (Tcl_ObjSetVar2(interp,
dstCharsVar,
NULL,
Tcl_NewIntObj(dstChars),
TCL_LEAVE_ERR_MSG) == NULL) {
result = TCL_ERROR;
}
}
Tcl_SetObjResult(interp, Tcl_NewListObj(3, resultObjs));
}
ckfree(bufPtr);
Tcl_FreeEncoding(encoding); /* Free returned reference */
return result;
}
/*
*----------------------------------------------------------------------
*
@@ -2004,10 +2276,10 @@ TestencodingObjCmd(
const char *string;
TclEncoding *encodingPtr;
static const char *const optionStrings[] = {
"create", "delete", "nullength", NULL
"create", "delete", "nullength", "Tcl_ExternalToUtf", "Tcl_UtfToExternal", NULL
};
enum options {
ENC_CREATE, ENC_DELETE, ENC_NULLENGTH
ENC_CREATE, ENC_DELETE, ENC_NULLENGTH, ENC_EXTTOUTF, ENC_UTFTOEXT
};
if (objc < 2) {
@@ -2076,6 +2348,11 @@ TestencodingObjCmd(
Tcl_SetObjResult(interp,
Tcl_NewIntObj(Tcl_GetEncodingNulLength(encoding)));
Tcl_FreeEncoding(encoding);
break;
case ENC_EXTTOUTF:
return UtfExtWrapper(interp,Tcl_ExternalToUtf,objc,objv);
case ENC_UTFTOEXT:
return UtfExtWrapper(interp,Tcl_UtfToExternal,objc,objv);
}
return TCL_OK;
}
+19 -2
View File
@@ -1269,7 +1269,7 @@ TeststringobjCmd(
static const char *const options[] = {
"append", "appendstrings", "get", "get2", "length", "length2",
"set", "set2", "setlength", "maxchars", "range", "appendself",
"appendself2", NULL
"appendself2", "newunicode", NULL
};
if (objc < 3) {
@@ -1513,7 +1513,24 @@ TeststringobjCmd(
Tcl_AppendUnicodeToObj(varPtr[varIndex], unicode + length, size - length);
Tcl_SetObjResult(interp, varPtr[varIndex]);
break;
}
case 13: /* newunicode*/
unicode = (unsigned short *) ckalloc((objc - 3) * sizeof(unsigned short));
for (i = 0; i < (objc - 3); ++i) {
int val;
if (Tcl_GetIntFromObj(interp, objv[i + 3], &val) != TCL_OK) {
break;
}
unicode[i] = (unsigned short)val;
}
if (i < (objc-3)) {
ckfree(unicode);
return TCL_ERROR;
}
SetVarToObj(varPtr, varIndex, Tcl_NewUnicodeObj(unicode, objc - 3));
Tcl_SetObjResult(interp, varPtr[varIndex]);
ckfree(unicode);
break;
}
return TCL_OK;
}
+36 -35
View File
@@ -182,25 +182,22 @@ Invalid(
*
* Tcl_UniCharToUtf --
*
* Store the given Tcl_UniChar as a sequence of UTF-8 bytes in the
* Stores the given Tcl_UniChar as a sequence of UTF-8 bytes in the
* provided buffer. Equivalent to Plan 9 runetochar().
*
* Special handling of Surrogate pairs is handled as follows:
* When this function is called for ch being a high surrogate,
* the first byte of the 4-byte UTF-8 sequence is produced and
* the function returns 1. Calling the function again with a
* low surrogate, the remaining 3 bytes of the 4-byte UTF-8
* sequence is produced, and the function returns 3. The buffer
* is used to remember the high surrogate between the two calls.
* Surrogate pairs are handled as follows: When ch is a high surrogate,
* the first byte of the 4-byte UTF-8 sequence is stored in the buffer and
* the function returns 1. If the function is called again with a low
* surrogate and the same buffer, the remaining 3 bytes of the 4-byte
* UTF-8 sequence are produced.
*
* If no low surrogate follows the high surrogate (which is actually
* illegal), this can be handled reasonably by calling Tcl_UniCharToUtf
* again with ch = -1. This will produce a 3-byte UTF-8 sequence
* again with ch = -1. This produces a 3-byte UTF-8 sequence
* representing the high surrogate.
*
* Results:
* The return values is the number of bytes in the buffer that were
* consumed.
* Returns the number of bytes stored into the buffer.
*
* Side effects:
* None.
@@ -223,18 +220,19 @@ Tcl_UniCharToUtf(
}
if (ch >= 0) {
if (ch <= 0x7FF) {
buf[1] = (char) ((ch | 0x80) & 0xBF);
buf[0] = (char) ((ch >> 6) | 0xC0);
buf[1] = (char) (0x80 | (0x3F & ch));
buf[0] = (char) (0xC0 | (ch >> 6));
return 2;
}
if (ch <= 0xFFFF) {
if ((ch & 0xF800) == 0xD800) {
if (ch & 0x0400) {
/* Low surrogate */
if (((buf[0] & 0xC0) == 0x80) && ((buf[1] & 0xCF) == 0)) {
if ( (0x80 == (0xC0 & buf[0]))
&& (0 == (0xCF & buf[1]))) {
/* Previous Tcl_UniChar was a high surrogate, so combine */
buf[2] = (char) ((ch & 0x3F) | 0x80);
buf[1] |= (char) (((ch >> 6) & 0x0F) | 0x80);
buf[2] = (char) (0x80 | (0x3F & ch));
buf[1] |= (char) (0x80 | (0x0F & (ch >> 6)));
return 3;
}
/* Previous Tcl_UniChar was not a high surrogate, so just output */
@@ -244,37 +242,40 @@ Tcl_UniCharToUtf(
/* 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);
buf[1] = (char) (0x80 | (0x3F & (ch >> 2)));
buf[0] = (char) (0xF0 | (0x07 & (ch >> 8)));
return 1;
}
}
goto three;
}
if (ch <= 0x10FFFF) {
buf[3] = (char) ((ch | 0x80) & 0xBF);
buf[2] = (char) (((ch >> 6) | 0x80) & 0xBF);
buf[1] = (char) (((ch >> 12) | 0x80) & 0xBF);
buf[0] = (char) ((ch >> 18) | 0xF0);
buf[3] = (char) (0x80 | (0x3F & ch));
buf[2] = (char) (0x80 | (0x3F & (ch >> 6)));
buf[1] = (char) (0x80 | (0x3F & (ch >> 12)));
buf[0] = (char) (0xF0 | (ch >> 18));
return 4;
}
} else if (ch == -1) {
if (((buf[0] & 0xC0) == 0x80) && ((buf[1] & 0xCF) == 0)
&& ((buf[-1] & 0xF8) == 0xF0)) {
ch = 0xD7C0 + ((buf[-1] & 0x07) << 8) + ((buf[0] & 0x3F) << 2)
+ ((buf[1] & 0x30) >> 4);
buf[1] = (char) ((ch | 0x80) & 0xBF);
buf[0] = (char) (((ch >> 6) | 0x80) & 0xBF);
buf[-1] = (char) ((ch >> 12) | 0xE0);
if ( (0x80 == (0xC0 & buf[0]))
&& (0 == (0xCF & buf[1]))
&& (0xF0 == (0xF8 & buf[-1]))) {
ch = 0xD7C0
+ ((0x07 & buf[-1]) << 8)
+ ((0x3F & buf[0]) << 2)
+ ((0x30 & buf[1]) >> 4);
buf[1] = (char) (0x80 | (0x3F & ch));
buf[0] = (char) (0x80 | (0x3F & (ch >> 6)));
buf[-1] = (char) (0xE0 | (ch >> 12));
return 2;
}
}
ch = 0xFFFD;
three:
buf[2] = (char) ((ch | 0x80) & 0xBF);
buf[1] = (char) (((ch >> 6) | 0x80) & 0xBF);
buf[0] = (char) ((ch >> 12) | 0xE0);
buf[2] = (char) (0x80 | (0x3F & ch));
buf[1] = (char) (0x80 | (0x3F & (ch >> 6)));
buf[0] = (char) (0xE0 | (ch >> 12));
return 3;
}
@@ -2948,7 +2949,7 @@ TclUniCharMatch(
*
* TclUtfToUCS4 --
*
* Extract the 4-byte codepoint from the leading bytes of the
* Extracts the 4-byte codepoint from the leading bytes of the
* Modified UTF-8 string "src". This is a utility routine to
* contain the surrogate gymnastics in one place.
*
@@ -2960,8 +2961,8 @@ TclUniCharMatch(
* enough bytes remain in the string.
*
* Results:
* *usc4Ptr is filled with the UCS4 code point, and the return value is
* the number of bytes from the UTF-8 string that were consumed.
* Fills *usc4Ptr with the UCS4 code point and returns the number of bytes
* consumed from the source string.
*
* Side effects:
* None.
+47 -9
View File
@@ -442,10 +442,25 @@ GenerateHeader(
if (GetValue(interp, dictObj, "comment", &value) != TCL_OK) {
goto error;
} else if (value != NULL) {
Tcl_EncodingState state;
valueStr = TclGetStringFromObj(value, &len);
Tcl_UtfToExternal(NULL, latin1enc, valueStr, len, 0, NULL,
result = Tcl_UtfToExternal(NULL, latin1enc, valueStr, len,
TCL_ENCODING_START|TCL_ENCODING_END|TCL_ENCODING_PROFILE_STRICT, &state,
headerPtr->nativeCommentBuf, MAX_COMMENT_LEN-1, NULL, &len,
NULL);
if (result != TCL_OK) {
if (interp) {
if (result == TCL_CONVERT_UNKNOWN) {
Tcl_AppendResult(
interp, "Comment contains characters > 0xFF", NULL);
}
else {
Tcl_AppendResult(interp, "Comment too large for zip", NULL);
}
}
result = TCL_ERROR; /* TCL_CONVERT_* -> TCL_ERROR*/
goto error;
}
headerPtr->nativeCommentBuf[len] = '\0';
headerPtr->header.comment = (Bytef *) headerPtr->nativeCommentBuf;
if (extraSizePtr != NULL) {
@@ -463,9 +478,26 @@ GenerateHeader(
if (GetValue(interp, dictObj, "filename", &value) != TCL_OK) {
goto error;
} else if (value != NULL) {
Tcl_EncodingState state;
valueStr = TclGetStringFromObj(value, &len);
Tcl_UtfToExternal(NULL, latin1enc, valueStr, len, 0, NULL,
headerPtr->nativeFilenameBuf, MAXPATHLEN-1, NULL, &len, NULL);
result = Tcl_UtfToExternal(NULL, latin1enc, valueStr, len,
TCL_ENCODING_START|TCL_ENCODING_END|TCL_ENCODING_PROFILE_STRICT, &state,
headerPtr->nativeFilenameBuf, MAXPATHLEN-1, NULL, &len,
NULL);
if (result != TCL_OK) {
if (interp) {
if (result == TCL_CONVERT_UNKNOWN) {
Tcl_AppendResult(
interp, "Filename contains characters > 0xFF", NULL);
}
else {
Tcl_AppendResult(
interp, "Filename too large for zip", NULL);
}
}
result = TCL_ERROR; /* TCL_CONVERT_* -> TCL_ERROR*/
goto error;
}
headerPtr->nativeFilenameBuf[len] = '\0';
headerPtr->header.name = (Bytef *) headerPtr->nativeFilenameBuf;
if (extraSizePtr != NULL) {
@@ -1196,7 +1228,8 @@ Tcl_ZlibStreamPut(
{
ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
char *dataTmp = NULL;
int e, size, outSize, toStore;
int e;
int size, outSize, toStore;
unsigned char *bytes;
if (zshPtr->streamEnd) {
@@ -1325,7 +1358,8 @@ Tcl_ZlibStreamGet(
* may get less! */
{
ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
int e, i, listLen, itemLen, dataPos = 0;
int e;
int i, listLen, itemLen, dataPos = 0;
Tcl_Obj *itemObj;
unsigned char *dataPtr, *itemPtr;
int existing;
@@ -1576,7 +1610,8 @@ Tcl_ZlibDeflate(
int level,
Tcl_Obj *gzipHeaderDictObj)
{
int wbits = 0, inLen = 0, e = 0, extraSize = 0;
int wbits = 0, e = 0, extraSize = 0;
int inLen = 0;
Byte *inData = NULL;
z_stream stream;
GzipHeader header;
@@ -1730,7 +1765,8 @@ Tcl_ZlibInflate(
int bufferSize,
Tcl_Obj *gzipHeaderDictObj)
{
int wbits = 0, inLen = 0, e = 0, newBufferSize;
int wbits = 0, e = 0;
int inLen = 0, newBufferSize;
Byte *inData = NULL, *outData = NULL, *newOutData = NULL;
z_stream stream;
gz_header header, *headerPtr = NULL;
@@ -2400,7 +2436,8 @@ ZlibPushSubcmd(
const char *const *pushOptions = pushDecompressOptions;
enum pushOptionsEnum {poDictionary, poHeader, poLevel, poLimit};
Tcl_Obj *headerObj = NULL, *compDictObj = NULL;
int limit = DEFAULT_BUFFER_SIZE, dummy;
int limit = DEFAULT_BUFFER_SIZE;
int dummy;
if (objc < 4) {
Tcl_WrongNumArgs(interp, 2, objv, "mode channel ?options...?");
@@ -2942,7 +2979,8 @@ ZlibTransformClose(
int flags)
{
ZlibChannelData *cd = (ZlibChannelData *)instanceData;
int e, written, result = TCL_OK;
int e, result = TCL_OK;
int written;
if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
return EINVAL;
+1 -1
View File
@@ -9,7 +9,7 @@ S
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E0000
0070007100720073007400750076007700780079007A007B007C007D007E007F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+2 -2
View File
@@ -10,8 +10,8 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC0081201A0083201E2026202020210088203001602039015A0164017D0179
009020182019201C201D202220132014009821220161203A015B0165017E017A
20AC0000201A0000201E2026202020210000203001602039015A0164017D0179
000020182019201C201D202220132014000021220161203A015B0165017E017A
00A002C702D8014100A4010400A600A700A800A9015E00AB00AC00AD00AE017B
00B000B102DB014200B400B500B600B700B80105015F00BB013D02DD013E017C
015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
+1 -1
View File
@@ -11,7 +11,7 @@ S
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
04020403201A0453201E20262020202120AC203004092039040A040C040B040F
045220182019201C201D202220132014009821220459203A045A045C045B045F
045220182019201C201D202220132014000021220459203A045A045C045B045F
00A0040E045E040800A4049000A600A7040100A9040400AB00AC00AD00AE0407
00B000B104060456049100B500B600B704512116045400BB0458040504550457
0410041104120413041404150416041704180419041A041B041C041D041E041F
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC0081201A0192201E20262020202102C62030016020390152008D017D008F
009020182019201C201D20222013201402DC21220161203A0153009D017E0178
20AC0000201A0192201E20262020202102C620300160203901520000017D0000
000020182019201C201D20222013201402DC21220161203A01530000017E0178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC0081201A0192201E20262020202100882030008A2039008C008D008E008F
009020182019201C201D20222013201400982122009A203A009C009D009E009F
20AC0000201A0192201E20262020202100002030000020390000000000000000
000020182019201C201D202220132014000021220000203A0000000000000000
00A00385038600A300A400A500A600A700A800A9000000AB00AC00AD00AE2015
00B000B100B200B3038400B500B600B703880389038A00BB038C00BD038E038F
0390039103920393039403950396039703980399039A039B039C039D039E039F
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC0081201A0192201E20262020202102C62030016020390152008D008E008F
009020182019201C201D20222013201402DC21220161203A0153009D009E0178
20AC0000201A0192201E20262020202102C62030016020390152000000000000
000020182019201C201D20222013201402DC21220161203A0153000000000178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC0081201A0192201E20262020202102C62030008A2039008C008D008E008F
009020182019201C201D20222013201402DC2122009A203A009C009D009E009F
20AC0000201A0192201E20262020202102C62030000020390000000000000000
000020182019201C201D20222013201402DC21220000203A0000000000000000
00A000A100A200A320AA00A500A600A700A800A900D700AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900F700BB00BC00BD00BE00BF
05B005B105B205B305B405B505B605B705B805B9000005BB05BC05BD05BE05BF
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC0081201A0083201E20262020202100882030008A2039008C00A802C700B8
009020182019201C201D20222013201400982122009A203A009C00AF02DB009F
20AC0000201A0000201E2026202020210000203000002039000000A802C700B8
000020182019201C201D202220132014000021220000203A000000AF02DB0000
00A0000000A200A300A4000000A600A700D800A9015600AB00AC00AD00AE00C6
00B000B100B200B300B400B500B600B700F800B9015700BB00BC00BD00BE00E6
0104012E0100010600C400C501180112010C00C90179011601220136012A013B
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC0081201A0192201E20262020202102C62030008A20390152008D008E008F
009020182019201C201D20222013201402DC2122009A203A0153009D009E0178
20AC0000201A0192201E20262020202102C62030000020390152000000000000
000020182019201C201D20222013201402DC21220000203A0153000000000178
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
00C000C100C2010200C400C500C600C700C800C900CA00CB030000CD00CE00CF
+1 -1
View File
@@ -11,7 +11,7 @@ S
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
00B000B72219221A259225002502253C2524252C251C25342510250C25142518
03B2221E03C600B100BD00BC224800AB00BBFEF7FEF8009B009CFEFBFEFC009F
03B2221E03C600B100BD00BC224800AB00BBFEF7FEF800000000FEFBFEFC0000
00A000ADFE8200A300A4FE8400000000FE8EFE8FFE95FE99060CFE9DFEA1FEA5
0660066106620663066406650666066706680669FED1061BFEB1FEB5FEB9061F
00A2FE80FE81FE83FE85FECAFE8BFE8DFE91FE93FE97FE9BFE9FFEA3FEA7FEA9
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850386008700B700AC00A620182019038820150389
038A03AA038C00930094038E03AB00A9038F00B200B303AC00A303AD03AE03AF
0000000000000000000000000386000000B700AC00A620182019038820150389
038A03AA038C00000000038E03AB00A9038F00B200B303AC00A303AD03AE03AF
03CA039003CC03CD039103920393039403950396039700BD0398039900AB00BB
25912592259325022524039A039B039C039D256325512557255D039E039F2510
25142534252C251C2500253C03A003A1255A25542569256625602550256C03A3
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
20AC008100820083008420260086008700880089008A008B008C008D008E008F
009020182019201C201D20222013201400980099009A009B009C009D009E009F
20AC000000000000000020260000000000000000000000000000000000000000
000020182019201C201D20222013201400000000000000000000000000000000
00A00E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
0E100E110E120E130E140E150E160E170E180E190E1A0E1B0E1C0E1D0E1E0E1F
0E200E210E220E230E240E250E260E270E280E290E2A0E2B0E2C0E2D0E2E0E2F
+1 -1
View File
@@ -10,7 +10,7 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000850086000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+1 -1
View File
@@ -10,7 +10,7 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+2 -2
View File
@@ -10,8 +10,8 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+2 -2
View File
@@ -10,8 +10,8 @@ S
2730273127322733273427352736273727382739273A273B273C273D273E273F
2740274127422743274427452746274727482749274A274B25CF274D25A0274F
27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000276127622763276427652766276726632666266526602460246124622463
2464246524662467246824692776277727782779277A277B277C277D277E277F
2780278127822783278427852786278727882789278A278B278C278D278E278F
+1
View File
@@ -1,3 +1,4 @@
# Encoding file: ebcdic, single-byte
S
006F 0 1
00
+2 -2
View File
@@ -10,8 +10,8 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+2 -2
View File
@@ -10,8 +10,8 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D0000008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+2 -2
View File
@@ -10,8 +10,8 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D203E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+2 -2
View File
@@ -10,8 +10,8 @@ S
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D203E007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+2 -2
View File
@@ -10,8 +10,8 @@ S
2730273127322733273427352736273727382739273A273B273C273D273E273F
2740274127422743274427452746274727482749274A274B25CF274D25A0274F
27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
F8D7F8D8F8D9F8DAF8DBF8DCF8DDF8DEF8DFF8E0F8E1F8E2F8E3F8E4008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
F8D7F8D8F8D9F8DAF8DBF8DCF8DDF8DEF8DFF8E0F8E1F8E2F8E3F8E400000000
0000000000000000000000000000000000000000000000000000000000000000
0000276127622763276427652766276726632666266526602460246124622463
2464246524662467246824692776277727782779277A277B277C277D277E277F
2780278127822783278427852786278727882789278A278B278C278D278E278F
+1 -1
View File
@@ -10,7 +10,7 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00A0FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+1 -1
View File
@@ -10,7 +10,7 @@ M
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
0080000000000000000000850086008700000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+2 -2
View File
@@ -10,8 +10,8 @@ S
03A0039803A103A303A403A503C203A9039E03A80396005B2234005D22A5005F
F8E503B103B203C703B403B503C603B303B703B903D503BA03BB03BC03BD03BF
03C003B803C103C303C403C503D603C903BE03C803B6007B007C007D223C007F
0080008100820083008400850086008700880089008A008B008C008D008E008F
0090009100920093009400950096009700980099009A009B009C009D009E009F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000003D2203222642044221E0192266326662665266021942190219121922193
00B000B12033226500D7221D2202202200F72260226122482026F8E6F8E721B5
21352111211C21182297229522052229222A2283228722842282228622082209
+1 -1
View File
@@ -9,7 +9,7 @@ S
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E0000
0070007100720073007400750076007700780079007A007B007C007D007E007F
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
+1 -1
View File
@@ -12,7 +12,7 @@ apply {{dir} {
0 tcl::idna 1.0.1 {cookiejar idna.tcl}
0 platform 1.0.19 {platform platform.tcl}
0 platform::shell 1.1.4 {platform shell.tcl}
1 tcltest 2.5.5 {tcltest tcltest.tcl}
1 tcltest 2.5.6 {tcltest tcltest.tcl}
} {
if {$isafe && !$safe} continue
package ifneeded $package $version [list source [file join $dir {*}$file]]
+1 -1
View File
@@ -9,4 +9,4 @@
# full path name of this file's directory.
if {![package vsatisfies [package provide Tcl] 8.5-]} {return}
package ifneeded tcltest 2.5.5 [list source [file join $dir tcltest.tcl]]
package ifneeded tcltest 2.5.6 [list source [file join $dir tcltest.tcl]]
+35 -3
View File
@@ -22,7 +22,7 @@ namespace eval tcltest {
# When the version number changes, be sure to update the pkgIndex.tcl file,
# and the install directory in the Makefiles. When the minor version
# changes (new feature) be sure to update the man page as well.
variable Version 2.5.5
variable Version 2.5.6
# Compatibility support for dumb variables defined in tcltest 1
# Do not use these. Call [package provide Tcl] and [info patchlevel]
@@ -1134,6 +1134,38 @@ proc tcltest::SafeFetch {n1 n2 op} {
}
}
# tcltest::Asciify --
#
# Transforms the passed string to contain only printable ascii characters.
# Useful for printing to terminals. Non-printables are mapped to
# \x, \u or \U sequences.
#
# Arguments:
# s - string to transform
#
# Results:
# The transformed strings
#
# Side effects:
# None.
proc tcltest::Asciify {s} {
set print ""
foreach c [split $s ""] {
set i [scan $c %c]
if {[string is print $c] && ($i <= 127)} {
append print $c
} elseif {$i <= 0xFF} {
append print \\x[format %02X $i]
} elseif {$i <= 0xFFFF} {
append print \\u[format %04X $i]
} else {
append print \\U[format %08X $i]
}
}
return $print
}
# tcltest::ConstraintInitializer --
#
# Get or set a script that when evaluated in the tcltest namespace
@@ -2221,9 +2253,9 @@ proc tcltest::test {name description args} {
if {$scriptCompare} {
puts [outputChannel] "---- Error testing result: $scriptMatch"
} else {
puts [outputChannel] "---- Result was:\n$actualAnswer"
puts [outputChannel] "---- Result was:\n[Asciify $actualAnswer]"
puts [outputChannel] "---- Result should have been\
($match matching):\n$result"
($match matching):\n[Asciify $result]"
}
}
if {$errorCodeFailure} {
+2 -2
View File
@@ -113,7 +113,7 @@ your ${USER}.pbxuser file (located inside the Tcl.xcodeproj bundle directory)
with a text editor.
- To build universal binaries outside of the Xcode IDE, set CFLAGS as follows:
export CFLAGS="-arch x86_64 -arch arm64e"
export CFLAGS="-arch x86_64 -arch arm64"
This requires Mac OS X 10.6 and Xcode 10.2 and will work on any architecture.
Note that configure requires CFLAGS to contain a least one architecture that can
be run on the build machine (i.e. x86_64 on Core2/Xeon).
@@ -133,7 +133,7 @@ If you are building from CVS, omit this step (CVS source tree names usually do
not contain a version number).
- Setup environment variables as desired, e.g. for a universal build on 10.5:
CFLAGS="-arch x86_64 -arch arm64e -mmacosx-version-min=10.5"
CFLAGS="-arch x86_64 -arch arm64 -mmacosx-version-min=10.5"
export CFLAGS
- Change to the directory containing the Tcl source tree and build:
+5 -5
View File
@@ -2132,7 +2132,7 @@
baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CFLAGS = "-arch x86_64 -arch arm64e $(CFLAGS)";
CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
MACOSX_DEPLOYMENT_TARGET = 10.6;
PREBINDING = NO;
};
@@ -2517,7 +2517,7 @@
baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CFLAGS = "-arch x86_64 -arch arm64e $(CFLAGS)";
CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
GCC_VERSION = 4.0;
MACOSX_DEPLOYMENT_TARGET = 10.6;
PREBINDING = NO;
@@ -2555,7 +2555,7 @@
baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CFLAGS = "-arch x86_64 -arch arm64e $(CFLAGS)";
CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
DEBUG_INFORMATION_FORMAT = dwarf;
GCC = "llvm-gcc";
GCC_OPTIMIZATION_LEVEL = 4;
@@ -2695,7 +2695,7 @@
ARCHS = (
"$(NATIVE_ARCH_64_BIT)",
);
CFLAGS = "-arch x86_64 -arch arm64e $(CFLAGS)";
CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
DEBUG_INFORMATION_FORMAT = dwarf;
GCC = clang;
GCC_OPTIMIZATION_LEVEL = 4;
@@ -2762,7 +2762,7 @@
baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CFLAGS = "-arch x86_64 -arch arm64e $(CFLAGS)";
CFLAGS = "-arch x86_64 -arch arm64 $(CFLAGS)";
CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
MACOSX_DEPLOYMENT_TARGET = 10.5;
PREBINDING = NO;
+1 -1
View File
@@ -348,7 +348,7 @@ test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespac
test basic-20.3 {Tcl_GetCommandInfo, #-quoting} testcmdtoken {
catch {rename \# ""}
set x [testcmdtoken create \#]
testcmdtoken name $x
return [testcmdtoken name $x]
} {{#} ::#}
test basic-21.1 {Tcl_GetCommandName} {emptyTest} {
+27 -25
View File
@@ -50,6 +50,8 @@ namespace eval ::tcl::test::io {
testConstraint notWinCI [expr {
$::tcl_platform(platform) ne "windows" || ![info exists ::env(CI)]}]
testConstraint notOSX [expr {$::tcl_platform(os) ne "Darwin"}]
# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]
testConstraint specialfiles [expr {[file exists /dev/zero] || [file exists NUL]}]
# You need a *very* special environment to do some tests. In particular,
@@ -119,7 +121,7 @@ test chan-io-1.6 {Tcl_WriteChars: WriteBytes} {
chan puts -nonewline $f "a\x4D\x00"
chan close $f
contents $path(test1)
} "aM\x00"
} aM\x00
test chan-io-1.7 {Tcl_WriteChars: WriteChars} {
set f [open $path(test1) w]
chan configure $f -encoding shiftjis
@@ -252,7 +254,7 @@ test chan-io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} -bod
test chan-io-3.4 {WriteChars: loop over stage buffer} -body {
# stage buffer maps to more than can be queued at once.
set f [open $path(test1) w]
chan configure $f -encoding jis0208 -buffersize 16 -nocomplainencoding 1
chan configure $f -encoding jis0208 -buffersize 16 -profile tcl8
chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
chan close $f
@@ -265,7 +267,7 @@ test chan-io-3.5 {WriteChars: saved != 0} -body {
# be moved to beginning of next channel buffer to preserve requested
# buffersize.
set f [open $path(test1) w]
chan configure $f -encoding jis0208 -buffersize 17 -nocomplainencoding 1
chan configure $f -encoding jis0208 -buffersize 17 -profile tcl8
chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
chan close $f
@@ -284,7 +286,7 @@ test chan-io-3.6 {WriteChars: (stageRead + dstWrote == 0)} -body {
# last byte of A plus the all of B) appended.
set f [open $path(test1) w]
chan configure $f -encoding shiftjis -buffersize 16
chan puts -nonewline $f "12345678901234AB"
chan puts -nonewline $f 12345678901234AB
set x [list [contents $path(test1)]]
chan close $f
lappend x [contents $path(test1)]
@@ -298,7 +300,7 @@ test chan-io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} -body {
# on flush. The truncated bytes are moved to the beginning of the next
# channel buffer.
set f [open $path(test1) w]
chan configure $f -encoding jis0208 -buffersize 17 -nocomplainencoding 1
chan configure $f -encoding jis0208 -buffersize 17 -profile tcl8
chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
chan close $f
@@ -1216,7 +1218,7 @@ test chan-io-8.7 {PeekAhead: cleanup} -setup {
chan puts -nonewline $f "abcdefghijklmno\r"
# here
lappend x [chan gets $f line] $line [testchannel queuedcr $f]
chan puts -nonewline $f "\x1A"
chan puts -nonewline $f \x1A
lappend x [chan gets $f line] $line
} -cleanup {
chan close $f
@@ -1372,22 +1374,22 @@ test chan-io-12.4 {ReadChars: split-up char} -setup {
chan configure $f -encoding shiftjis
vwait [namespace which -variable x]
chan configure $f -encoding binary -blocking 1
chan puts -nonewline $f "\x7B"
chan puts -nonewline $f \x7B
after 500 ;# Give the cat process time to catch up
chan configure $f -encoding shiftjis -blocking 0
vwait [namespace which -variable x]
return $x
} -cleanup {
chan close $f
} -result [list "123456789012345" 1 "本" 0]
} -result [list "123456789012345" 1 本 0]
test chan-io-12.5 {ReadChars: chan events on partial characters} -setup {
variable x {}
} -constraints {stdio fileevent} -body {
set path(test1) [makeFile {
chan configure stdout -encoding binary -buffering none
chan gets stdin; chan puts -nonewline "\xE7"
chan gets stdin; chan puts -nonewline "\x89"
chan gets stdin; chan puts -nonewline "\xA6"
chan gets stdin; chan puts -nonewline \xE7
chan gets stdin; chan puts -nonewline \x89
chan gets stdin; chan puts -nonewline \xA6
} test1]
set f [openpipe r+ $path(test1)]
chan event $f readable [namespace code {
@@ -4980,7 +4982,7 @@ test chan-io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} -setup {
test chan-io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
# This test crashes the interp if Bug #427196 is not fixed
set chan [open [info script] r]
chan configure $chan -buffersize 10
chan configure $chan -buffersize 10 -encoding utf-8
set var [chan read $chan 2]
chan configure $chan -buffersize 32
append var [chan read $chan]
@@ -5211,7 +5213,7 @@ test chan-io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_
} -constraints {stdio fileevent} -body {
set f [openpipe r+ $path(cat)]
chan configure $f -encoding binary
chan puts -nonewline $f "\xE7"
chan puts -nonewline $f \xE7
chan flush $f
chan configure $f -encoding utf-8 -blocking 0
chan event $f readable [namespace code { lappend x [chan read $f] }]
@@ -5348,7 +5350,7 @@ test chan-io-40.1 {POSIX open access modes: RDWR} -setup {
} -result {zzy abzzy}
test chan-io-40.2 {POSIX open access modes: CREAT} -setup {
file delete $path(test3)
} -constraints {unix} -body {
} -constraints {unix notWsl} -body {
set f [open $path(test3) {WRONLY CREAT} 0o600]
file stat $path(test3) stats
set x [format 0o%03o [expr {$stats(mode) & 0o777}]]
@@ -5361,7 +5363,7 @@ test chan-io-40.2 {POSIX open access modes: CREAT} -setup {
} -result {0o600 {line 1}}
test chan-io-40.3 {POSIX open access modes: CREAT} -setup {
file delete $path(test3)
} -constraints {unix umask} -body {
} -constraints {unix umask notWsl} -body {
# This test only works if your umask is 2, like ouster's.
chan close [open $path(test3) {WRONLY CREAT}]
file stat $path(test3) stats
@@ -6736,8 +6738,8 @@ test chan-io-52.5 {TclCopyChannel, all} -constraints {fcopy} -setup {
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan configure $f1 -translation lf -encoding iso8859-1 -blocking 0
chan configure $f2 -translation lf -encoding iso8859-1 -blocking 0
chan copy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
@@ -6752,8 +6754,8 @@ test chan-io-52.5a {TclCopyChannel, all, other negative value} -setup {
} -constraints {fcopy} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan configure $f1 -translation lf -encoding iso8859-1 -blocking 0
chan configure $f2 -translation lf -encoding iso8859-1 -blocking 0
chan copy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
@@ -6768,8 +6770,8 @@ test chan-io-52.5b {TclCopyChannel, all, wrap to negative value} -setup {
} -constraints {fcopy} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan configure $f1 -translation lf -encoding iso8859-1 -blocking 0
chan configure $f2 -translation lf -encoding iso8859-1 -blocking 0
chan copy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
chan close $f1
@@ -6802,8 +6804,8 @@ test chan-io-52.7 {TclCopyChannel} -constraints {fcopy} -setup {
} -body {
set f1 [open $thisScript]
set f2 [open $path(test1) w]
chan configure $f1 -translation lf -blocking 0
chan configure $f2 -translation lf -blocking 0
chan configure $f1 -translation lf -encoding iso8859-1 -blocking 0
chan configure $f2 -translation lf -encoding iso8859-1 -blocking 0
chan copy $f1 $f2
set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
if {[file size $thisScript] == [file size $path(test1)]} {
@@ -6848,7 +6850,7 @@ set path(utf8-rp.txt) [makeFile {} utf8-rp.txt]
# Create kyrillic file, use lf translation to avoid os eol issues
set out [open $path(kyrillic.txt) w]
chan configure $out -encoding koi8-r -translation lf
chan puts $out "АА"
chan puts $out АА
chan close $out
test chan-io-52.9 {TclCopyChannel & encodings} {fcopy} {
# Copy kyrillic to UTF-8, using chan copy.
@@ -6886,7 +6888,7 @@ test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} {
test chan-io-52.11 {TclCopyChannel & encodings} -setup {
set f [open $path(utf8-fcopy.txt) w]
fconfigure $f -encoding utf-8 -translation lf
puts $f "АА"
puts $f АА
close $f
} -constraints {fcopy} -body {
# binary to encoding => the input has to be in utf-8 to make sense to the
+496 -219
View File
@@ -32,6 +32,8 @@ testConstraint linkDirectory [expr {
&& [lindex [file system [temporaryDirectory]] 1] eq "NTFS")
}]
testConstraint notWine [expr {![info exists ::env(CI_USING_WINE)]}]
# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]
global env
set cmdAHwd [pwd]
@@ -171,63 +173,153 @@ test cmdAH-3.2 {Tcl_ContinueObjCmd, success} {
list [catch {continue} msg] $msg
} {4 {}}
test cmdAH-4.1 {Tcl_EncodingObjCmd} -returnCodes error -body {
###
# encoding command
set "numargErrors(encoding system)" {^wrong # args: should be "(encoding |::tcl::encoding::)system \?encoding\?"$}
set "numargErrors(encoding convertfrom)" {wrong # args: should be "(encoding |::tcl::encoding::)convertfrom \?-profile profile\? \?-failindex var\? encoding data" or "(encoding |::tcl::encoding::)convertfrom data"}
set "numargErrors(encoding convertto)" {wrong # args: should be "(encoding |::tcl::encoding::)convertto \?-profile profile\? \?-failindex var\? encoding data" or "(encoding |::tcl::encoding::)convertto data"}
set "numargErrors(encoding names)" {wrong # args: should be "encoding names"}
set "numargErrors(encoding profiles)" {wrong # args: should be "encoding profiles"}
source [file join [file dirname [info script]] encodingVectors.tcl]
# Maps utf-{16,32}{le,be} to utf-16, utf-32 and
# others to "". Used to test utf-16, utf-32 based
# on system endianness
proc endianUtf {enc} {
if {$::tcl_platform(byteOrder) eq "littleEndian"} {
set endian le
} else {
set endian be
}
if {$enc eq "utf-16$endian" || $enc eq "utf-32$endian"} {
return [string range $enc 0 5]
}
return ""
}
# Map arbitrary strings to printable form in ASCII.
proc printable {s} {
set print ""
foreach c [split $s ""] {
set i [scan $c %c]
if {[string is print $c] && ($i <= 127)} {
append print $c
} elseif {$i <= 0xff} {
append print \\x[format %02X $i]
} elseif {$i <= 0xffff} {
append print \\u[format %04X $i]
} else {
append print \\U[format %08X $i]
}
}
return $print
}
#
# Check errors for invalid number of arguments
proc badnumargs {id cmd cmdargs} {
variable numargErrors
test $id.a "Syntax error: $cmd $cmdargs" \
-body [list {*}$cmd {*}$cmdargs] \
-result $numargErrors($cmd) \
-match regexp \
-returnCodes error
test $id.b "Syntax error: $cmd (byte compiled)" \
-setup [list proc compiled_proc {} [list {*}$cmd {*}$cmdargs]] \
-body {compiled_proc} \
-cleanup {rename compiled_proc {}} \
-result $numargErrors($cmd) \
-match regexp \
-returnCodes error
}
# Wraps tests resulting in unknown encoding errors
proc unknownencodingtest {id cmd} {
set result "unknown encoding \"[lindex $cmd end-1]\""
test $id.a "Unknown encoding error: $cmd" \
-body [list encoding {*}$cmd] \
-result $result \
-returnCodes error
test $id.b "Syntax error: $cmd (byte compiled)" \
-setup [list proc encoding_test {} [list encoding {*}$cmd]] \
-body {encoding_test} \
-cleanup {rename encoding_test {}} \
-result $result \
-returnCodes error
}
# Wraps tests for conversion, successful or not.
# Really more general than just for encoding conversion.
proc testconvert {id body result args} {
test $id.a $body \
-body $body \
-result $result \
{*}$args
dict append args -setup \n[list proc compiled_script {} $body]
dict append args -cleanup "\nrename compiled_script {}"
test $id.b "$body (byte compiled)" \
-body {compiled_script} \
-result $result \
{*}$args
}
# Wrapper to verify encoding convert{to,from} ?-profile?
# Generates tests for compiled and uncompiled implementation.
# Also generates utf-{16,32} tests if passed encoding is utf-{16,32}{le,be}
# The enc and profile are appended to id to generate the test id
proc testprofile {id converter enc profile data result args} {
testconvert $id.$enc.$profile [list encoding $converter -profile $profile $enc $data] $result {*}$args
if {[set enc2 [endianUtf $enc]] ne ""} {
# If utf{16,32}-{le,be}, also do utf{16,32}
testconvert $id.$enc2.$profile [list encoding $converter -profile $profile $enc2 $data] $result {*}$args
}
# If this is the default profile, generate a test without specifying profile
if {$profile eq $::encDefaultProfile} {
testconvert $id.$enc.default [list encoding $converter $enc $data] $result {*}$args
if {[set enc2 [endianUtf $enc]] ne ""} {
# If utf{16,32}-{le,be}, also do utf{16,32}
testconvert $id.$enc2.default [list encoding $converter $enc2 $data] $result {*}$args
}
}
}
# Wrapper to verify encoding convert{to,from} -failindex ?-profile?
# Generates tests for compiled and uncompiled implementation.
# Also generates utf-{16,32} tests if passed encoding is utf-{16,32}{le,be}
# The enc and profile are appended to id to generate the test id
proc testfailindex {id converter enc data result failidx {profile default}} {
testconvert $id.$enc.$profile "list \[encoding $converter -profile $profile -failindex idx $enc [list $data]\] \[set idx\]" [list $result $failidx]
if {[set enc2 [endianUtf $enc]] ne ""} {
# If utf{16,32}-{le,be}, also do utf{16,32}
testconvert $id.$enc2.$profile "list \[encoding $converter -profile $profile -failindex idx $enc2 [list $data]\] \[set idx]" [list $result $failidx]
}
# If this is the default profile, generate a test without specifying profile
if {$profile eq $::encDefaultProfile} {
testconvert $id.$enc.default "list \[encoding $converter -failindex idx $enc [list $data]\] \[set idx]" [list $result $failidx]
if {[set enc2 [endianUtf $enc]] ne ""} {
# If utf{16,32}-{le,be}, also do utf{16,32}
testconvert $id.$enc2.default "list \[encoding $converter -failindex idx $enc2 [list $data]\] \[set idx]" [list $result $failidx]
}
}
}
test cmdAH-4.1.1 {encoding} -returnCodes error -body {
encoding
} -result {wrong # args: should be "encoding subcommand ?arg ...?"}
test cmdAH-4.2 {Tcl_EncodingObjCmd} -returnCodes error -body {
test cmdAH-4.1.2 {Tcl_EncodingObjCmd} -returnCodes error -body {
encoding foo
} -result {unknown or ambiguous subcommand "foo": must be convertfrom, convertto, dirs, names, or system}
test cmdAH-4.3 {Tcl_EncodingObjCmd} -returnCodes error -body {
encoding convertto
} -result {wrong # args: should be "encoding convertto ?-strict? ?-failindex var? ?encoding? data" or "encoding convertto -nocomplain ?encoding? data"}
test cmdAH-4.4 {Tcl_EncodingObjCmd} -returnCodes error -body {
encoding convertto foo bar
} -result {unknown encoding "foo"}
test cmdAH-4.5 {Tcl_EncodingObjCmd} -setup {
set system [encoding system]
} -body {
encoding system jis0208
encoding convertto 乎
} -cleanup {
encoding system $system
} -result 8C
test cmdAH-4.6 {Tcl_EncodingObjCmd} -setup {
set system [encoding system]
} -body {
encoding system iso8859-1
encoding convertto jis0208 乎
} -cleanup {
encoding system $system
} -result 8C
test cmdAH-4.7 {Tcl_EncodingObjCmd} -returnCodes error -body {
encoding convertfrom
} -result {wrong # args: should be "encoding convertfrom ?-strict? ?-failindex var? ?encoding? data" or "encoding convertfrom -nocomplain ?encoding? data"}
test cmdAH-4.8 {Tcl_EncodingObjCmd} -returnCodes error -body {
encoding convertfrom foo bar
} -result {unknown encoding "foo"}
test cmdAH-4.9 {Tcl_EncodingObjCmd} -setup {
set system [encoding system]
} -body {
encoding system jis0208
encoding convertfrom 8C
} -cleanup {
encoding system $system
} -result 乎
test cmdAH-4.10 {Tcl_EncodingObjCmd} -setup {
set system [encoding system]
} -body {
encoding system iso8859-1
encoding convertfrom jis0208 8C
} -cleanup {
encoding system $system
} -result 乎
test cmdAH-4.11 {Tcl_EncodingObjCmd} -returnCodes error -body {
encoding names foo
} -result {wrong # args: should be "encoding names"}
test cmdAH-4.12 {Tcl_EncodingObjCmd} -returnCodes error -body {
encoding system foo bar
} -result {wrong # args: should be "encoding system ?encoding?"}
test cmdAH-4.13 {Tcl_EncodingObjCmd} -setup {
} -result {unknown or ambiguous subcommand "foo": must be convertfrom, convertto, dirs, names, profiles, or system}
#
# encoding system 4.2.*
badnumargs cmdAH-4.2.1 {encoding system} {ascii ascii}
test cmdAH-4.2.2 {Tcl_EncodingObjCmd} -setup {
set system [encoding system]
} -body {
encoding system iso8859-1
@@ -236,173 +328,358 @@ test cmdAH-4.13 {Tcl_EncodingObjCmd} -setup {
encoding system $system
} -result iso8859-1
test cmdAH-4.14.1 {Syntax error, -nocomplain and -failindex, no encoding} -body {
encoding convertfrom -nocomplain -failindex 2 ABC
} -returnCodes 1 -result {wrong # args: should be "encoding convertfrom ?-strict? ?-failindex var? ?encoding? data" or "encoding convertfrom -nocomplain ?encoding? data"}
test cmdAH-4.14.2 {Syntax error, -nocomplain and -failindex, no encoding} -body {
encoding convertto -nocomplain -failindex 2 ABC
} -returnCodes 1 -result {wrong # args: should be "encoding convertto ?-strict? ?-failindex var? ?encoding? data" or "encoding convertto -nocomplain ?encoding? data"}
test cmdAH-4.15.1 {Syntax error, -failindex and -nocomplain, no encoding} -body {
encoding convertfrom -failindex 2 -nocomplain ABC
} -returnCodes 1 -result {unknown encoding "-nocomplain"}
test cmdAH-4.15.2 {Syntax error, -failindex and -nocomplain, no encoding} -body {
encoding convertto -failindex 2 -nocomplain ABC
} -returnCodes 1 -result {unknown encoding "-nocomplain"}
test cmdAH-4.16.1 {Syntax error, -nocomplain and -failindex, encoding} -body {
encoding convertfrom -nocomplain -failindex 2 utf-8 ABC
} -returnCodes 1 -result {wrong # args: should be "encoding convertfrom ?-strict? ?-failindex var? ?encoding? data" or "encoding convertfrom -nocomplain ?encoding? data"}
test cmdAH-4.16.2 {Syntax error, -nocomplain and -failindex, encoding} -body {
encoding convertto -nocomplain -failindex 2 utf-8 ABC
} -returnCodes 1 -result {wrong # args: should be "encoding convertto ?-strict? ?-failindex var? ?encoding? data" or "encoding convertto -nocomplain ?encoding? data"}
test cmdAH-4.17.1 {Syntax error, -failindex and -nocomplain, encoding} -body {
encoding convertfrom -failindex 2 -nocomplain utf-8 ABC
} -returnCodes 1 -result {wrong # args: should be "encoding convertfrom ?-strict? ?-failindex var? ?encoding? data" or "encoding convertfrom -nocomplain ?encoding? data"}
test cmdAH-4.17.2 {Syntax error, -failindex and -nocomplain, encoding} -body {
encoding convertto -failindex 2 -nocomplain utf-8 ABC
} -returnCodes 1 -result {wrong # args: should be "encoding convertto ?-strict? ?-failindex var? ?encoding? data" or "encoding convertto -nocomplain ?encoding? data"}
test cmdAH-4.18.1 {Syntax error, -failindex with no var, no encoding} -body {
encoding convertfrom -failindex ABC
} -returnCodes 1 -result {wrong # args: should be "::tcl::encoding::convertfrom ?-strict? ?-failindex var? ?encoding? data" or "::tcl::encoding::convertfrom -nocomplain ?encoding? data"}
test cmdAH-4.18.2 {Syntax error, -failindex with no var, no encoding (byte compiled)} -setup {
proc encoding_test {} {
encoding convertfrom -failindex ABC
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 1 -result {wrong # args: should be "::tcl::encoding::convertfrom ?-strict? ?-failindex var? ?encoding? data" or "::tcl::encoding::convertfrom -nocomplain ?encoding? data"} -cleanup {
rename encoding_test ""
}
test cmdAH-4.18.3 {Syntax error, -failindex with no var, no encoding} -body {
encoding convertto -failindex ABC
} -returnCodes 1 -result {wrong # args: should be "::tcl::encoding::convertto ?-strict? ?-failindex var? ?encoding? data" or "::tcl::encoding::convertto -nocomplain ?encoding? data"}
test cmdAH-4.18.4 {Syntax error, -failindex with no var, no encoding (byte compiled)} -setup {
proc encoding_test {} {
encoding convertto -failindex ABC
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 1 -result {wrong # args: should be "::tcl::encoding::convertto ?-strict? ?-failindex var? ?encoding? data" or "::tcl::encoding::convertto -nocomplain ?encoding? data"} -cleanup {
rename encoding_test ""
}
test cmdAH-4.19.1 {convertrom -failindex with correct data} -body {
encoding convertfrom -failindex test ABC
set test
} -returnCodes 0 -result -1
test cmdAH-4.19.2 {convertrom -failindex with correct data (byt compiled)} -setup {
proc encoding_test {} {
encoding convertfrom -failindex test ABC
set test
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 0 -result -1 -cleanup {
rename encoding_test ""
}
test cmdAH-4.19.3 {convertrom -failindex with correct data} -body {
encoding convertto -failindex test ABC
set test
} -returnCodes 0 -result -1
test cmdAH-4.19.4 {convertrom -failindex with correct data (byt compiled)} -setup {
proc encoding_test {} {
encoding convertto -failindex test ABC
set test
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 0 -result -1 -cleanup {
rename encoding_test ""
}
test cmdAH-4.20.1 {convertrom -failindex with incomplete utf8} -body {
set x [encoding convertfrom -failindex i utf-8 A\xc3]
binary scan $x H* y
list $y $i
} -returnCodes 0 -result {41 1}
test cmdAH-4.20.2 {convertrom -failindex with incomplete utf8 (byte compiled)} -setup {
proc encoding_test {} {
set x [encoding convertfrom -failindex i utf-8 A\xc3]
binary scan $x H* y
list $y $i
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 0 -result {41 1} -cleanup {
rename encoding_test ""
}
test cmdAH-4.20.3 {convertrom -failindex with incomplete utf8} -body {
set x [encoding convertfrom -strict -failindex i utf-8 A\xc3]
binary scan $x H* y
list $y $i
} -returnCodes 0 -result {41 1}
test cmdAH-4.20.4 {convertrom -failindex with incomplete utf8 (byte compiled)} -setup {
proc encoding_test {} {
set x [encoding convertfrom -strict -failindex i utf-8 A\xc3]
binary scan $x H* y
list $y $i
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 0 -result {41 1} -cleanup {
rename encoding_test ""
}
test cmdAH-4.20.5 {convertrom -failindex with incomplete utf8} -body {
set x [encoding convertfrom -failindex i -strict utf-8 A\xc3]
binary scan $x H* y
list $y $i
} -returnCodes 0 -result {41 1}
test cmdAH-4.20.6 {convertrom -failindex with incomplete utf8 (byte compiled)} -setup {
proc encoding_test {} {
set x [encoding convertfrom -failindex i -strict utf-8 A\xc3]
binary scan $x H* y
list $y $i
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 0 -result {41 1} -cleanup {
rename encoding_test ""
}
test cmdAH-4.21.1 {convertto -failindex with wrong character} -body {
set x [encoding convertto -failindex i iso8859-1 A\u0141]
binary scan $x H* y
list $y $i
} -returnCodes 0 -result {41 1}
test cmdAH-4.21.2 {convertto -failindex with wrong character (byte compiled)} -setup {
proc encoding_test {} {
set x [encoding convertto -failindex i iso8859-1 A\u0141]
binary scan $x H* y
list $y $i
}
} -body {
# Compile and execute
encoding_test
} -returnCodes 0 -result {41 1} -cleanup {
rename encoding_test ""
}
test cmdAH-4.22 {convertfrom -strict} -body {
encoding convertfrom -strict utf-8 A\x00B
} -result A\x00B
#
# encoding convertfrom 4.3.*
test cmdAH-4.23 {convertfrom -strict} -body {
encoding convertfrom -strict utf-8 A\xC0\x80B
} -returnCodes error -result {unexpected byte sequence starting at index 1: '\xC0'}
# Odd number of args is always invalid since last two args
# are ENCODING DATA and all options take a value
badnumargs cmdAH-4.3.1 {encoding convertfrom} {}
badnumargs cmdAH-4.3.2 {encoding convertfrom} {-failindex VAR ABC}
badnumargs cmdAH-4.3.3 {encoding convertfrom} {-profile VAR ABC}
badnumargs cmdAH-4.3.4 {encoding convertfrom} {-failindex VAR -profile strict ABC}
badnumargs cmdAH-4.3.5 {encoding convertfrom} {-profile strict -failindex VAR ABC}
test cmdAH-4.24 {convertto -strict} -body {
encoding convertto -strict utf-8 A\x00B
} -result A\x00B
# Test that last two args always treated as ENCODING DATA
unknownencodingtest cmdAH-4.3.6 {convertfrom -failindex ABC}
unknownencodingtest cmdAH-4.3.7 {convertfrom -profile ABC}
unknownencodingtest cmdAH-4.3.8 {convertfrom nosuchencoding ABC}
unknownencodingtest cmdAH-4.3.9 {convertfrom -failindex VAR -profile ABC}
unknownencodingtest cmdAH-4.3.10 {convertfrom -profile strict -failindex ABC}
testconvert cmdAH-4.3.11 {
encoding convertfrom jis0208 \x38\x43
} \u4e4e -setup {
set system [encoding system]
encoding system iso8859-1
} -cleanup {
encoding system $system
}
test cmdAH-4.25 {convertfrom -strict} -constraints knownBug -body {
encoding convertfrom -strict utf-8 A\x80B
# Verify single arg defaults to system encoding
testconvert cmdAH-4.3.12 {
encoding convertfrom \x38\x43
} \u4e4e -setup {
set system [encoding system]
encoding system jis0208
} -cleanup {
encoding system $system
}
# convertfrom ?-profile? : valid byte sequences
foreach {enc str hex ctrl comment} $encValidStrings {
if {"knownBug" in $ctrl} continue
set bytes [binary decode hex $hex]
set prefix A
set suffix B
set prefix_bytes [encoding convertto $enc A]
set suffix_bytes [encoding convertto $enc B]
foreach profile $encProfiles {
testprofile cmdAH-4.3.13.$hex.solo convertfrom $enc $profile $bytes $str
testprofile cmdAH-4.3.13.$hex.lead convertfrom $enc $profile $bytes$suffix_bytes $str$suffix
testprofile cmdAH-4.3.13.$hex.tail convertfrom $enc $profile $prefix_bytes$bytes $prefix$str
testprofile cmdAH-4.3.13.$hex.middle convertfrom $enc $profile $prefix_bytes$bytes$suffix_bytes $prefix$str$suffix
}
}
# convertfrom ?-profile? : invalid byte sequences
foreach {enc hex profile str failidx ctrl comment} $encInvalidBytes {
if {"knownBug" in $ctrl} continue
set bytes [binary format H* $hex]
set prefix A
set suffix B
set prefix_bytes [encoding convertto $enc $prefix]
set suffix_bytes [encoding convertto $enc $suffix]
set prefixLen [string length $prefix_bytes]
set result [list $str]
# TODO - if the bad byte is unprintable, tcltest errors out when printing a mismatch
# so glob it out in error message pattern for now.
set errorWithoutPrefix [list "unexpected byte sequence starting at index $failidx: *" -returnCodes error -match glob]
set errorWithPrefix [list "unexpected byte sequence starting at index [expr {$failidx+$prefixLen}]: *" -returnCodes error -match glob]
if {$ctrl eq {} || "solo" in $ctrl} {
if {$failidx == -1} {
set result [list $str]
} else {
set result $errorWithoutPrefix
}
testprofile cmdAH-4.3.13.$hex.solo convertfrom $enc $profile $bytes {*}$result
}
if {$ctrl eq {} || "lead" in $ctrl} {
if {$failidx == -1} {
set result [list $str$suffix]
} else {
set result $errorWithoutPrefix
}
testprofile cmdAH-4.3.13.$hex.lead convertfrom $enc $profile $bytes$suffix_bytes {*}$result
}
if {$ctrl eq {} || "tail" in $ctrl} {
if {$failidx == -1} {
set result [list $prefix$str]
} else {
set result $errorWithPrefix
}
testprofile cmdAH-4.3.13.$hex.tail convertfrom $enc $profile $prefix_bytes$bytes {*}$result
}
if {$ctrl eq {} || "middle" in $ctrl} {
if {$failidx == -1} {
set result [list $prefix$str$suffix]
} else {
set result $errorWithPrefix
}
testprofile cmdAH-4.3.13.$hex.middle convertfrom $enc $profile $prefix_bytes$bytes$suffix_bytes {*}$result
}
}
# convertfrom -failindex ?-profile? - valid data
foreach {enc str hex ctrl comment} $encValidStrings {
if {"knownBug" in $ctrl} continue
set bytes [binary decode hex $hex]
set prefix A
set suffix B
set prefix_bytes [encoding convertto $enc $prefix]
set suffix_bytes [encoding convertto $enc $suffix]
foreach profile $encProfiles {
testfailindex cmdAH-4.3.14.$hex.solo convertfrom $enc $bytes $str -1 $profile
testfailindex cmdAH-4.3.14.$hex.lead convertfrom $enc $bytes$suffix_bytes $str$suffix -1 $profile
testfailindex cmdAH-4.3.14.$hex.tail convertfrom $enc $prefix_bytes$bytes $prefix$str -1 $profile
testfailindex cmdAH-4.3.14.$hex.middle convertfrom $enc $prefix_bytes$bytes$suffix_bytes $prefix$str$suffix -1 $profile
}
}
# convertfrom -failindex ?-profile? - invalid data
foreach {enc hex profile str failidx ctrl comment} $encInvalidBytes {
if {"knownBug" in $ctrl} continue
# There are multiple test cases based on location of invalid bytes
set bytes [binary decode hex $hex]
set prefix A
set suffix B
set prefix_bytes [encoding convertto $enc $prefix]
set suffix_bytes [encoding convertto $enc $suffix]
set prefixLen [string length $prefix_bytes]
if {$ctrl eq {} || "solo" in $ctrl} {
testfailindex cmdAH-4.3.14.$hex.solo convertfrom $enc $bytes $str $failidx $profile
}
if {$ctrl eq {} || "lead" in $ctrl} {
if {$failidx == -1} {
# If success expected
set result $str$suffix
} else {
# Failure expected
set result ""
}
testfailindex cmdAH-4.3.14.$hex.lead convertfrom $enc $bytes$suffix_bytes $result $failidx $profile
}
if {$ctrl eq {} || "tail" in $ctrl} {
set expected_failidx $failidx
if {$failidx == -1} {
# If success expected
set result $prefix$str
} else {
# Failure expected
set result $prefix
incr expected_failidx $prefixLen
}
testfailindex cmdAH-4.3.14.$hex.tail convertfrom $enc $prefix_bytes$bytes $result $expected_failidx $profile
}
if {$ctrl eq {} || "middle" in $ctrl} {
set expected_failidx $failidx
if {$failidx == -1} {
# If success expected
set result $prefix$str$suffix
} else {
# Failure expected
set result $prefix
incr expected_failidx $prefixLen
}
testfailindex cmdAH-4.3.14.$hex.middle convertfrom $enc $prefix_bytes$bytes$suffix_bytes $result $expected_failidx $profile
}
}
#
# encoding convertto 4.4.*
badnumargs cmdAH-4.4.1 {encoding convertto} {}
badnumargs cmdAH-4.4.2 {encoding convertto} {-failindex VAR ABC}
badnumargs cmdAH-4.4.3 {encoding convertto} {-profile VAR ABC}
badnumargs cmdAH-4.4.4 {encoding convertto} {-failindex VAR -profile strict ABC}
badnumargs cmdAH-4.4.5 {encoding convertto} {-profile strict -failindex VAR ABC}
# Test that last two args always treated as ENCODING DATA
unknownencodingtest cmdAH-4.4.6 {convertto -failindex ABC}
unknownencodingtest cmdAH-4.4.7 {convertto -profile ABC}
unknownencodingtest cmdAH-4.4.8 {convertto nosuchencoding ABC}
unknownencodingtest cmdAH-4.4.9 {convertto -failindex VAR -profile ABC}
unknownencodingtest cmdAH-4.4.10 {convertto -profile strict -failindex ABC}
testconvert cmdAH-4.4.11 {
encoding convertto jis0208 \u4e4e
} \x38\x43 -setup {
set system [encoding system]
encoding system iso8859-1
} -cleanup {
encoding system $system
}
# Verify single arg defaults to system encoding
testconvert cmdAH-4.4.12 {
encoding convertto \u4e4e
} \x38\x43 -setup {
set system [encoding system]
encoding system jis0208
} -cleanup {
encoding system $system
}
# convertto ?-profile? : valid byte sequences
foreach {enc str hex ctrl comment} $encValidStrings {
if {"knownBug" in $ctrl} continue
set bytes [binary decode hex $hex]
set printable [printable $str]
set prefix A
set suffix B
set prefix_bytes [encoding convertto $enc A]
set suffix_bytes [encoding convertto $enc B]
foreach profile $encProfiles {
testprofile cmdAH-4.4.13.$printable.solo convertto $enc $profile $str $bytes
testprofile cmdAH-4.4.13.$printable.lead convertto $enc $profile $str$suffix $bytes$suffix_bytes
testprofile cmdAH-4.4.13.$printable.tail convertto $enc $profile $prefix$str $prefix_bytes$bytes
testprofile cmdAH-4.4.13.$printable.middle convertto $enc $profile $prefix$str$suffix $prefix_bytes$bytes$suffix_bytes
}
}
# convertto ?-profile? : invalid byte sequences
foreach {enc str profile hex failidx ctrl comment} $encUnencodableStrings {
if {"knownBug" in $ctrl} continue
set bytes [binary decode hex $hex]
set printable [printable $str]
set prefix A
set suffix B
set prefix_bytes [encoding convertto $enc $prefix]
set suffix_bytes [encoding convertto $enc $suffix]
set prefixLen [string length $prefix_bytes]
set result [list $bytes]
# TODO - if the bad byte is unprintable, tcltest errors out when printing a mismatch
# so glob it out in error message pattern for now.
set errorWithoutPrefix [list "unexpected character at index $failidx: *" -returnCodes error -match glob]
set errorWithPrefix [list "unexpected character at index [expr {$failidx+$prefixLen}]: *" -returnCodes error -match glob]
if {$ctrl eq {} || "solo" in $ctrl} {
if {$failidx == -1} {
set result [list $bytes]
} else {
set result $errorWithoutPrefix
}
testprofile cmdAH-4.4.13.$printable.solo convertto $enc $profile $str {*}$result
}
if {$ctrl eq {} || "lead" in $ctrl} {
if {$failidx == -1} {
set result [list $bytes$suffix_bytes]
} else {
set result $errorWithoutPrefix
}
testprofile cmdAH-4.4.13.$printable.lead convertto $enc $profile $str$suffix {*}$result
}
if {$ctrl eq {} || "tail" in $ctrl} {
if {$failidx == -1} {
set result [list $prefix_bytes$bytes]
} else {
set result $errorWithPrefix
}
testprofile cmdAH-4.4.13.$printable.tail convertto $enc $profile $prefix$str {*}$result
}
if {$ctrl eq {} || "middle" in $ctrl} {
if {$failidx == -1} {
set result [list $prefix_bytes$bytes$suffix_bytes]
} else {
set result $errorWithPrefix
}
testprofile cmdAH-4.4.13.$printable.middle convertto $enc $profile $prefix$str$suffix {*}$result
}
}
# convertto -failindex ?-profile? - valid data
foreach {enc str hex ctrl comment} $encValidStrings {
if {"knownBug" in $ctrl} continue
set bytes [binary decode hex $hex]
set printable [printable $str]
set prefix A
set suffix B
set prefix_bytes [encoding convertto $enc A]
set suffix_bytes [encoding convertto $enc B]
foreach profile $encProfiles {
testfailindex cmdAH-4.4.14.$enc.$printable.solo convertto $enc $str $bytes -1 $profile
testfailindex cmdAH-4.4.14.$enc.$printable.lead convertto $enc $str$suffix $bytes$suffix_bytes -1 $profile
testfailindex cmdAH-4.4.14.$enc.$printable.tail convertto $enc $prefix$str $prefix_bytes$bytes -1 $profile
testfailindex cmdAH-4.4.14.$enc.$printable.middle convertto $enc $prefix$str$suffix $prefix_bytes$bytes$suffix_bytes -1 $profile
}
}
# convertto -failindex ?-profile? - invalid data
foreach {enc str profile hex failidx ctrl comment} $encUnencodableStrings {
if {"knownBug" in $ctrl} continue
set bytes [binary decode hex $hex]
set printable [printable $str]
set prefix A
set suffix B
set prefixLen [string length [encoding convertto $enc $prefix]]
if {$ctrl eq {} || "solo" in $ctrl} {
testfailindex cmdAH-4.4.14.$printable.solo convertto $enc $str $bytes $failidx $profile
}
if {$ctrl eq {} || "lead" in $ctrl} {
if {$failidx == -1} {
# If success expected
set result $bytes$suffix
} else {
# Failure expected
set result ""
}
testfailindex cmdAH-4.4.14.$printable.lead convertto $enc $str$suffix $result $failidx $profile
}
if {$ctrl eq {} || "tail" in $ctrl} {
set expected_failidx $failidx
if {$failidx == -1} {
# If success expected
set result $prefix$bytes
} else {
# Failure expected
set result $prefix
incr expected_failidx $prefixLen
}
testfailindex cmdAH-4.4.14.$printable.tail convertto $enc $prefix$str $result $expected_failidx $profile
}
if {$ctrl eq {} || "middle" in $ctrl} {
set expected_failidx $failidx
if {$failidx == -1} {
# If success expected
set result $prefix$bytes$suffix
} else {
# Failure expected
set result $prefix
incr expected_failidx $prefixLen
}
testfailindex cmdAH-4.4.14.$printable.middle convertto $enc $prefix$str$suffix $result $expected_failidx $profile
}
}
test cmdAH-4.4.xx {convertto -profile strict} -constraints {testbytestring knownBug} -body {
# TODO - what does testbytestring even test? Invalid UTF8 in the Tcl_Obj bytes field
encoding convertto -profile strict utf-8 A[testbytestring \x80]B
} -returnCodes error -result {unexpected byte sequence starting at index 1: '\x80'}
test cmdAH-4.26 {convertto -strict} -constraints {testbytestring knownBug} -body {
encoding convertto -strict utf-8 A[testbytestring \x80]B
} -returnCodes error -result {unexpected byte sequence starting at index 1: '\x80'}
#
# encoding names 4.5.*
badnumargs cmdAH-4.5.1 {encoding names} {foo}
test cmdAH-4.5.2 {encoding names should include at least utf-8 and iso8859-1 and at least one more} -body {
set names [encoding names]
list [expr {"utf-8" in $names}] [expr {"iso8859-1" in $names}] [expr {[llength $names] > 2}]
} -result {1 1 1}
#
# encoding profiles 4.6.*
badnumargs cmdAH-4.6.1 {encoding profiles} {foo}
test cmdAH-4.6.2 {encoding profiles} -body {
lsort [encoding profiles]
} -result {replace strict tcl8}
#
# file command
test cmdAH-5.1 {Tcl_FileObjCmd} -returnCodes error -body {
file
@@ -1019,7 +1296,7 @@ test cmdAH-16.2 {Tcl_FileObjCmd: readable} {
-result 1
}
test cmdAH-16.3 {Tcl_FileObjCmd: readable} {
-constraints {unix notRoot testchmod}
-constraints {unix notRoot testchmod notWsl}
-setup {testchmod 0o333 $gorpfile}
-body {file readable $gorpfile}
-result 0
@@ -1052,7 +1329,7 @@ set gorpfile [makeFile abcde gorp.file]
test cmdAH-18.1 {Tcl_FileObjCmd: executable} -returnCodes error -body {
file executable a b
} -result {wrong # args: should be "file executable name"}
test cmdAH-18.2 {Tcl_FileObjCmd: executable} {notRoot} {
test cmdAH-18.2 {Tcl_FileObjCmd: executable} {notRoot notWsl} {
file executable $gorpfile
} 0
test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unix testchmod} {
@@ -1600,7 +1877,7 @@ test cmdAH-28.4 {Tcl_FileObjCmd: stat} -setup {
file stat $gorpfile stat
list $stat(nlink) $stat(size) $stat(type)
} -result {1 12 file}
test cmdAH-28.5 {Tcl_FileObjCmd: stat} -constraints {unix} -setup {
test cmdAH-28.5 {Tcl_FileObjCmd: stat} -constraints {unix notWsl} -setup {
unset -nocomplain stat
} -body {
file stat $gorpfile stat
+32
View File
@@ -211,6 +211,38 @@ test dstring-2.15 {appending list elements} -constraints testdstring -setup {
} -cleanup {
testdstring free
} -result {x #}
test dstring-2.16 {appending list elements - bug [46dda6fc29] segfault} -constraints testdstring -setup {
testdstring free
} -body {
testdstring element "\\\n"; # Will setfault
testdstring get
} -cleanup {
testdstring free
} -result \\\\\\n
test dstring-2.17 {appending list elements - bug [46dda6fc29] segfault} -constraints testdstring -setup {
testdstring free
} -body {
testdstring element "\\\{"; # Will setfault
testdstring get
} -cleanup {
testdstring free
} -result [list [list \{]]
test dstring-2.18 {appending list elements - bug [46dda6fc29] segfault} -constraints testdstring -setup {
testdstring free
} -body {
testdstring element "\\\}"; # Will setfault
testdstring get
} -cleanup {
testdstring free
} -result [list [list \}]]
test dstring-2.19 {appending list elements - bug [46dda6fc29] segfault} -constraints testdstring -setup {
testdstring free
} -body {
testdstring element "\\\\"; # Will setfault
testdstring get
} -cleanup {
testdstring free
} -result [list [list \\]]
test dstring-3.1 {nested sublists} -constraints testdstring -setup {
testdstring free
+263 -72
View File
@@ -105,6 +105,14 @@ test encoding-3.2 {Tcl_GetEncodingName, non-null} -setup {
} -cleanup {
fconfigure stdout -encoding $old
} -result {jis0208}
test encoding-3.3 {fconfigure -profile} -setup {
set old [fconfigure stdout -profile]
} -body {
fconfigure stdout -profile replace
fconfigure stdout -profile
} -cleanup {
fconfigure stdout -profile $old
} -result replace
test encoding-4.1 {Tcl_GetEncodingNames} -constraints {testencoding} -setup {
cd [makeDirectory tmp]
@@ -171,7 +179,7 @@ test encoding-6.2 {Tcl_CreateEncoding: replace encoding} {testencoding} {
test encoding-7.1 {Tcl_ExternalToUtfDString: small buffer} {
encoding convertfrom jis0208 8c8c8c8c
} "吾吾吾吾"
} 吾吾吾吾
test encoding-7.2 {Tcl_UtfToExternalDString: big buffer} {
set a 8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C
append a $a
@@ -193,7 +201,7 @@ test encoding-8.1 {Tcl_ExternalToUtf} {
close $f
file delete [file join [temporaryDirectory] dummy]
return $x
} "ab乎g"
} ab乎g
test encoding-9.1 {Tcl_UtfToExternalDString: small buffer} {
encoding convertto jis0208 "吾吾吾吾"
@@ -213,7 +221,7 @@ test encoding-9.2 {Tcl_UtfToExternalDString: big buffer} {
test encoding-10.1 {Tcl_UtfToExternal} {
set f [open [file join [temporaryDirectory] dummy] w]
fconfigure $f -translation binary -encoding shiftjis
puts -nonewline $f "ab乎g"
puts -nonewline $f ab乎g
close $f
set f [open [file join [temporaryDirectory] dummy] r]
fconfigure $f -translation binary -encoding iso8859-1
@@ -248,7 +256,7 @@ test encoding-11.1 {LoadEncodingFile: unknown encoding} {testencoding} {
} {1 {unknown encoding "jis0208"} 8C}
test encoding-11.2 {LoadEncodingFile: single-byte} {
encoding convertfrom jis0201 \xA1
} "。"
} 。
test encoding-11.3 {LoadEncodingFile: double-byte} {
encoding convertfrom jis0208 8C
} 乎
@@ -299,7 +307,7 @@ test encoding-11.11 {encoding: extended Unicode UTF-32} {
test encoding-12.1 {LoadTableEncoding: normal encoding} {
set x [encoding convertto iso8859-3 Ġ]
append x [encoding convertto -nocomplain iso8859-3 Õ]
append x [encoding convertto -profile tcl8 iso8859-3 Õ]
append x [encoding convertfrom iso8859-3 Õ]
} "Õ?Ġ"
test encoding-12.2 {LoadTableEncoding: single-byte encoding} {
@@ -348,67 +356,67 @@ test encoding-15.5 {UtfToUtfProc emoji character input} {
} "4 😂"
test encoding-15.6 {UtfToUtfProc emoji character output} {
set x \uDE02\uD83D\uDE02\uD83D
set y [encoding convertto -nocomplain utf-8 \uDE02\uD83D\uDE02\uD83D]
set y [encoding convertto -profile tcl8 utf-8 \uDE02\uD83D\uDE02\uD83D]
binary scan $y H* z
list [string length $y] $z
} {10 edb882f09f9882eda0bd}
test encoding-15.7 {UtfToUtfProc emoji character output} {
set x \uDE02\uD83D\uD83D
set y [encoding convertto -nocomplain utf-8 \uDE02\uD83D\uD83D]
set y [encoding convertto -profile tcl8 utf-8 \uDE02\uD83D\uD83D]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {3 9 edb882eda0bdeda0bd}
test encoding-15.8 {UtfToUtfProc emoji character output} {
set x \uDE02\uD83Dé
set y [encoding convertto -nocomplain utf-8 \uDE02\uD83Dé]
set y [encoding convertto -profile tcl8 utf-8 \uDE02\uD83Dé]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {3 8 edb882eda0bdc3a9}
test encoding-15.9 {UtfToUtfProc emoji character output} {
set x \uDE02\uD83DX
set y [encoding convertto -nocomplain utf-8 \uDE02\uD83DX]
set y [encoding convertto -profile tcl8 utf-8 \uDE02\uD83DX]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {3 7 edb882eda0bd58}
test encoding-15.10 {UtfToUtfProc high surrogate character output} {
set x \uDE02é
set y [encoding convertto -nocomplain utf-8 \uDE02é]
set y [encoding convertto -profile tcl8 utf-8 \uDE02é]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {2 5 edb882c3a9}
test encoding-15.11 {UtfToUtfProc low surrogate character output} {
set x \uDA02é
set y [encoding convertto -nocomplain utf-8 \uDA02é]
set y [encoding convertto -profile tcl8 utf-8 \uDA02é]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {2 5 eda882c3a9}
test encoding-15.12 {UtfToUtfProc high surrogate character output} {
set x \uDE02Y
set y [encoding convertto -nocomplain utf-8 \uDE02Y]
set y [encoding convertto -profile tcl8 utf-8 \uDE02Y]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {2 4 edb88259}
test encoding-15.13 {UtfToUtfProc low surrogate character output} {
set x \uDA02Y
set y [encoding convertto -nocomplain utf-8 \uDA02Y]
set y [encoding convertto -profile tcl8 utf-8 \uDA02Y]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {2 4 eda88259}
test encoding-15.14 {UtfToUtfProc high surrogate character output} {
set x \uDE02
set y [encoding convertto -nocomplain utf-8 \uDE02]
set y [encoding convertto -profile tcl8 utf-8 \uDE02]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {1 3 edb882}
test encoding-15.15 {UtfToUtfProc low surrogate character output} {
set x \uDA02
set y [encoding convertto -nocomplain utf-8 \uDA02]
set y [encoding convertto -profile tcl8 utf-8 \uDA02]
binary scan $y H* z
list [string length $x] [string length $y] $z
} {1 3 eda882}
test encoding-15.16 {UtfToUtfProc: Invalid 4-byte UTF-8, see [ed29806ba]} {
set x \xF0\xA0\xA1\xC2
set y [encoding convertfrom -nocomplain utf-8 \xF0\xA0\xA1\xC2]
set y [encoding convertfrom -profile tcl8 utf-8 \xF0\xA0\xA1\xC2]
list [string length $x] $y
} "4 \xF0\xA0\xA1\xC2"
test encoding-15.17 {UtfToUtfProc emoji character output} {
@@ -452,6 +460,27 @@ test encoding-15.24 {UtfToUtfProc CESU-8 bug [048dd20b4171c8da]} {
binary scan $y H* z
list [string length $y] $z
} {2 cfbf}
test encoding-15.25 {UtfToUtfProc CESU-8} {
encoding convertfrom cesu-8 \x00
} \x00
test encoding-15.26 {UtfToUtfProc CESU-8} {
encoding convertfrom cesu-8 \xC0\x80
} \x00
test encoding-15.27 {UtfToUtfProc -profile strict CESU-8} {
encoding convertfrom -profile strict cesu-8 \x00
} \x00
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 -profile strict CESU-8} {
encoding convertto -profile strict cesu-8 \x00
} \x00
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 {
set val [encoding convertfrom utf-16 NN]
@@ -481,18 +510,90 @@ test encoding-16.7 {Utf32ToUtfProc} -body {
set val [encoding convertfrom utf-32be \0\0NN]
list $val [format %x [scan $val %c]]
} -result "乎 4e4e"
test encoding-16.8 {Utf32ToUtfProc} -body {
set val [encoding convertfrom -profile tcl8 utf-32 \x41\x00\x00\x41]
list $val [format %x [scan $val %c]]
} -result "\uFFFD fffd"
test encoding-16.9 {Utf32ToUtfProc} -body {
encoding convertfrom utf-32le \x00\xD8\x00\x00
} -result \uD800
test encoding-16.10 {Utf32ToUtfProc} -body {
encoding convertfrom utf-32le \x00\xDC\x00\x00
} -result \uDC00
test encoding-16.11 {Utf32ToUtfProc} -body {
encoding convertfrom utf-32le \x00\xD8\x00\x00\x00\xDC\x00\x00
} -result \uD800\uDC00
test encoding-16.12 {Utf32ToUtfProc} -body {
encoding convertfrom utf-32le \x00\xDC\x00\x00\x00\xD8\x00\x00
} -result \uDC00\uD800
test encoding-16.13 {Utf16ToUtfProc} -body {
encoding convertfrom utf-16le \x00\xD8
} -result \uD800
test encoding-16.14 {Utf16ToUtfProc} -body {
encoding convertfrom utf-16le \x00\xDC
} -result \uDC00
test encoding-16.15 {Utf16ToUtfProc} -body {
encoding convertfrom utf-16le \x00\xD8\x00\xDC
} -result \uD800\uDC00
test encoding-16.16 {Utf16ToUtfProc} -body {
encoding convertfrom utf-16le \x00\xDC\x00\xD8
} -result \uDC00\uD800
test encoding-16.17 {Utf32ToUtfProc} -body {
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 {
Utf16ToUtfProc, Tcl_UniCharToUtf, surrogate pairs in utf-16
} -body {
apply [list {} {
for {set i 0xD800} {$i < 0xDBFF} {incr i} {
for {set j 0xDC00} {$j < 0xDFFF} {incr j} {
set string [binary format S2 [list $i $j]]
set status [catch {
set decoded [encoding convertfrom utf-16be $string]
set encoded [encoding convertto utf-16be $decoded]
}]
if {$status || ( $encoded ne $string )} {
return [list [format %x $i] [format %x $j]]
}
}
}
return done
} [namespace current]]
} -result done
test encoding-16.19 {Utf16ToUtfProc, bug [d19fe0a5b]} -body {
encoding convertfrom utf-16 "\x41\x41\x41"
} -result \u4141\uFFFD
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 {
encoding convertfrom utf-32 "\x00\x00\x00\x00\x41\x41"
} -result \x00\uFFFD
test encoding-16.22 {Utf16ToUtfProc, strict, bug [db7a085bd9]} -body {
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 -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 utf-32 "\xFF\xFF\xFF\xFF"
} -result \uFFFD
test encoding-16.25 {Utf32ToUtfProc} -body {
encoding convertfrom utf-32 "\x01\x00\x00\x01"
} -result \uFFFD
test encoding-17.1 {UtfToUtf16Proc} -body {
encoding convertto utf-16 "\U460DC"
} -result "\xD8\xD8\xDC\xDC"
test encoding-17.2 {UtfToUcs2Proc} -body {
test encoding-17.2 {UtfToUcs2Proc, invalid testcase, see [5607d6482c]} -constraints deprecated -body {
encoding convertfrom utf-16 [encoding convertto ucs-2 "\U460DC"]
} -result "\uFFFD"
test encoding-17.3 {UtfToUtf16Proc} -body {
encoding convertto -nocomplain utf-16be "\uDCDC"
encoding convertto -profile tcl8 utf-16be "\uDCDC"
} -result "\xDC\xDC"
test encoding-17.4 {UtfToUtf16Proc} -body {
encoding convertto -nocomplain utf-16le "\uD8D8"
encoding convertto -profile tcl8 utf-16le "\uD8D8"
} -result "\xD8\xD8"
test encoding-17.5 {UtfToUtf16Proc} -body {
encoding convertto utf-32le "\U460DC"
@@ -501,26 +602,61 @@ test encoding-17.6 {UtfToUtf16Proc} -body {
encoding convertto utf-32be "\U460DC"
} -result "\x00\x04\x60\xDC"
test encoding-17.7 {UtfToUtf16Proc} -body {
encoding convertto -strict 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 -strict 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 -strict 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 -nocomplain utf-32 "\xFF\xFF\xFF\xFF"
encoding convertfrom -profile tcl8 utf-32 "\xFF\xFF\xFF\xFF"
} -result \uFFFD
test encoding-17.11 {Utf32ToUtfProc} -body {
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 -profile strict utf-32le "\x00\xDC\x00\x00"
} -returnCodes error -result {unexpected byte sequence starting at index 0: '\x00'}
test encoding-18.1 {TableToUtfProc error on invalid input with -strict} -body {
list [catch {encoding convertto -strict jis0208 \\} res] $res
test encoding-18.1 {TableToUtfProc on invalid input} -constraints deprecated -body {
list [catch {encoding convertto 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 -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 -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 !) -1}
test encoding-18.6 {TableToUtfProc on invalid input with -profile tcl8} -body {
list [catch {encoding convertto -profile tcl8 jis0208 \\} res] $res
} -result {0 !)}
test encoding-19.1 {TableFromUtfProc} {
} {}
test encoding-19.1 {TableFromUtfProc} -body {
encoding convertfrom ascii AÁ
} -result AÁ
test encoding-19.2 {TableFromUtfProc} -body {
encoding convertfrom -profile tcl8 ascii AÁ
} -result AÁ
test encoding-19.3 {TableFromUtfProc} -body {
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 [list A\xC1 -1]
test encoding-19.5 {TableFromUtfProc} -body {
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 -profile strict ascii AÁB] [set idx]
} -result {A 1}
test encoding-20.1 {TableFreefProc} {
} {}
@@ -632,25 +768,25 @@ test encoding-24.4 {Parse valid or invalid utf-8} {
string length [encoding convertfrom utf-8 "\xC0\x80"]
} 1
test encoding-24.5 {Parse valid or invalid utf-8} {
string length [encoding convertfrom -nocomplain utf-8 "\xC0\x81"]
string length [encoding convertfrom -profile tcl8 utf-8 "\xC0\x81"]
} 2
test encoding-24.6 {Parse valid or invalid utf-8} {
string length [encoding convertfrom -nocomplain utf-8 "\xC1\xBF"]
string length [encoding convertfrom -profile tcl8 utf-8 "\xC1\xBF"]
} 2
test encoding-24.7 {Parse valid or invalid utf-8} {
string length [encoding convertfrom utf-8 "\xC2\x80"]
} 1
test encoding-24.8 {Parse valid or invalid utf-8} {
string length [encoding convertfrom -nocomplain utf-8 "\xE0\x80\x80"]
string length [encoding convertfrom -profile tcl8 utf-8 "\xE0\x80\x80"]
} 3
test encoding-24.9 {Parse valid or invalid utf-8} {
string length [encoding convertfrom -nocomplain utf-8 "\xE0\x9F\xBF"]
string length [encoding convertfrom -profile tcl8 utf-8 "\xE0\x9F\xBF"]
} 3
test encoding-24.10 {Parse valid or invalid utf-8} {
string length [encoding convertfrom utf-8 "\xE0\xA0\x80"]
} 1
test encoding-24.11 {Parse valid or invalid utf-8} {
string length [encoding convertfrom -nocomplain utf-8 "\xEF\xBF\xBF"]
string length [encoding convertfrom -profile tcl8 utf-8 "\xEF\xBF\xBF"]
} 1
test encoding-24.12 {Parse valid or invalid utf-8} -constraints deprecated -body {
encoding convertfrom utf-8 "\xC0\x81"
@@ -663,7 +799,7 @@ test encoding-24.14 {Parse valid or invalid utf-8} {
} 1
test encoding-24.15 {Parse valid or invalid utf-8} -constraints deprecated -body {
encoding convertfrom utf-8 "Z\xE0\x80"
} -result Z\xE0\x80
} -result Z\xE0\u20AC
test encoding-24.16 {Parse valid or invalid utf-8} -constraints testbytestring -body {
encoding convertto utf-8 [testbytestring "Z\u4343\x80"]
} -returnCodes 1 -result {expected byte sequence but character 1 was '䍃€' (U+004343)}
@@ -676,69 +812,84 @@ test encoding-24.18 {Parse valid or invalid utf-8} -constraints testbytestring -
test encoding-24.19 {Parse valid or invalid utf-8} -constraints deprecated -body {
encoding convertto utf-8 "ZX\uD800"
} -result ZX\xED\xA0\x80
test encoding-24.20 {Parse with -nocomplain but without providing encoding} {
string length [encoding convertfrom -nocomplain "\x20"]
} 1
test encoding-24.21 {Parse with -nocomplain but without providing encoding} {
string length [encoding convertto -nocomplain "\x20"]
} 1
test encoding-24.20 {Parse with -profile tcl8 but without providing encoding} -body {
encoding convertfrom -profile tcl8 "\x20"
} -result {wrong # args: should be "::tcl::encoding::convertfrom ?-profile profile? ?-failindex var? encoding data" or "::tcl::encoding::convertfrom data"} -returnCodes error
test encoding-24.21 {Parse with -profile tcl8 but without providing encoding} -body {
string length [encoding convertto -profile tcl8 "\x20"]
} -result {wrong # args: should be "::tcl::encoding::convertto ?-profile profile? ?-failindex var? encoding data" or "::tcl::encoding::convertto data"} -returnCodes error
test encoding-24.22 {Syntax error, two encodings} -body {
encoding convertfrom iso8859-1 utf-8 "ZX\uD800"
} -returnCodes 1 -result {wrong # args: should be "::tcl::encoding::convertfrom ?-strict? ?-failindex var? ?encoding? data" or "::tcl::encoding::convertfrom -nocomplain ?encoding? data"}
} -result {bad option "iso8859-1": must be -profile or -failindex} -returnCodes error
test encoding-24.23 {Syntax error, two encodings} -body {
encoding convertto iso8859-1 utf-8 "ZX\uD800"
} -returnCodes 1 -result {wrong # args: should be "::tcl::encoding::convertto ?-strict? ?-failindex var? ?encoding? data" or "::tcl::encoding::convertto -nocomplain ?encoding? data"}
test encoding-24.24 {Parse invalid utf-8 with -strict} -body {
encoding convertfrom -strict utf-8 "\xC0\x80\x00\x00"
} -result {bad option "iso8859-1": must be -profile or -failindex} -returnCodes error
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 -strict} -body {
encoding convertfrom -strict 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 -strict} -body {
encoding convertfrom -strict 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 -strict} -body {
encoding convertfrom -strict 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 -strict} -body {
encoding convertfrom -strict 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 -strict} -body {
encoding convertfrom -strict 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 -nocomplain} -body {
encoding convertfrom -nocomplain utf-8 \xEF\xBF\xBF
test encoding-24.31 {Parse invalid utf-8 with -profile tcl8} -body {
encoding convertfrom -profile tcl8 utf-8 \xEF\xBF\xBF
} -result \uFFFF
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 -strict} -body {
encoding convertto -strict 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 -nocomplain} -body {
encoding convertto -nocomplain utf-8 \uFFFF
test encoding-24.34 {Try to generate invalid utf-8 with -profile tcl8} -body {
encoding convertto -profile tcl8 utf-8 \uFFFF
} -result \xEF\xBF\xBF
test encoding-24.35 {Parse invalid utf-8} -constraints deprecated -body {
encoding convertfrom utf-8 \xED\xA0\x80
} -result \uD800
test encoding-24.36 {Parse invalid utf-8 with -strict} -body {
encoding convertfrom -strict 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 -nocomplain} -body {
encoding convertfrom -nocomplain utf-8 \xED\xA0\x80
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} -constraints deprecated -body {
encoding convertto utf-8 \uD800
} -result \xED\xA0\x80
test encoding-24.39 {Try to generate invalid utf-8 with -strict} -body {
encoding convertto -strict 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 -nocomplain} -body {
encoding convertto -nocomplain utf-8 \uD800
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 -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
} -result \xF0\u20AC\u20AC\u20AC
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 -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 -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]
@@ -893,18 +1044,58 @@ test encoding-27.2 {encoding dirs basic behavior} -returnCodes error -body {
test encoding-28.0 {all encodings load} -body {
set string hello
foreach name [encoding names] {
incr count
encoding convertto -nocomplain $name $string
if {$name ne "unicode"} {
incr count
}
encoding convertto -profile tcl8 $name $string
# discard the cached internal representation of Tcl_Encoding
# Unfortunately, without this, encoding 2-1 fails.
llength $name
}
return $count
} -result [expr {[info exists ::tcl_precision] ? 92 : 91}]
} -result 91
runtests
test encoding-bug-183a1adcc0-1 {Bug [183a1adcc0] Buffer overflow Tcl_UtfToExternal} -constraints {
testencoding
} -body {
# Note - buffers are initialized to \xff
list [catch {testencoding Tcl_UtfToExternal utf-16 A {start end} {} 1} result] $result
} -result [list 0 [list nospace {} \xff]]
test encoding-bug-183a1adcc0-2 {Bug [183a1adcc0] Buffer overflow Tcl_UtfToExternal} -constraints {
testencoding
} -body {
# Note - buffers are initialized to \xff
list [catch {testencoding Tcl_UtfToExternal utf-16 A {start end} {} 0} result] $result
} -result [list 0 [list nospace {} {}]]
test encoding-bug-183a1adcc0-3 {Bug [183a1adcc0] Buffer overflow Tcl_UtfToExternal} -constraints {
testencoding
} -body {
# Note - buffers are initialized to \xff
list [catch {testencoding Tcl_UtfToExternal utf-16 A {start end} {} 2} result] $result
} -result [list 0 [list nospace {} \x00\x00]]
test encoding-bug-183a1adcc0-4 {Bug [183a1adcc0] Buffer overflow Tcl_UtfToExternal} -constraints {
testencoding
} -body {
# Note - buffers are initialized to \xff
list [catch {testencoding Tcl_UtfToExternal utf-16 A {start end} {} 3} result] $result
} -result [list 0 [list nospace {} \x00\x00\xff]]
test encoding-bug-183a1adcc0-5 {Bug [183a1adcc0] Buffer overflow Tcl_UtfToExternal} -constraints {
testencoding ucs2 knownBug
} -body {
# The knownBug constraint is because test depends on TCL_UTF_MAX and
# also UtfToUtf16 assumes space required in destination buffer is
# sizeof(Tcl_UniChar) which is incorrect when TCL_UTF_MAX==4
# Note - buffers are initialized to \xff
list [catch {testencoding Tcl_UtfToExternal utf-16 A {start end} {} 4} result] $result
} -result [list 0 [list ok {} [expr {$::tcl_platform(byteOrder) eq "littleEndian" ? "\x41\x00" : "\x00\x41"}]\x00\x00]]
}
test encoding-29.0 {get encoding nul terminator lengths} -constraints {
+655
View File
@@ -0,0 +1,655 @@
# This file contains test vectors for verifying various encodings. They are
# stored in a common file so that they can be sourced into the various test
# modules that are dependent on encodings. This file contains statically defined
# test vectors. In addition, it sources the ICU-generated test vectors from
# icuUcmTests.tcl.
#
# Note that sourcing the file will reinitialize any existing encoding test
# vectors.
#
# List of defined encoding profiles
set encProfiles {tcl8 strict replace}
set encDefaultProfile tcl8; # Should reflect the default from implementation
# encValidStrings - Table of valid strings.
#
# Each row is <ENCODING STR BYTES CTRL COMMENT>
# The pair <ENCODING,STR> should be unique for generated test ids to be unique.
# STR is a string that can be encoded in the encoding ENCODING resulting
# in the byte sequence BYTES. The CTRL field is a list that controls test
# generation. It may contain zero or more of `solo`, `lead`, `tail` and
# `middle` indicating that the generated tests should include the string
# by itself, as the lead of a longer string, as the tail of a longer string
# and in the middle of a longer string. If CTRL is empty, it is treated as
# containing all four of the above. The CTRL field may also contain the
# words knownBug or knownW3C which will cause the test generation for that
# vector to be skipped.
#
# utf-16, utf-32 missing because they are automatically
# generated based on le/be versions.
set encValidStrings {}; # Reset the table
lappend encValidStrings {*}{
ascii \u0000 00 {} {Lowest ASCII}
ascii \u007F 7F knownBug {Highest ASCII}
ascii \u007D 7D {} {Brace - just to verify test scripts are escaped correctly}
ascii \u007B 7B {} {Terminating brace - just to verify test scripts are escaped correctly}
utf-8 \u0000 00 {} {Unicode Table 3.7 Row 1}
utf-8 \u007F 7F {} {Unicode Table 3.7 Row 1}
utf-8 \u0080 C280 {} {Unicode Table 3.7 Row 2}
utf-8 \u07FF DFBF {} {Unicode Table 3.7 Row 2}
utf-8 \u0800 E0A080 {} {Unicode Table 3.7 Row 3}
utf-8 \u0FFF E0BFBF {} {Unicode Table 3.7 Row 3}
utf-8 \u1000 E18080 {} {Unicode Table 3.7 Row 4}
utf-8 \uCFFF ECBFBF {} {Unicode Table 3.7 Row 4}
utf-8 \uD000 ED8080 {} {Unicode Table 3.7 Row 5}
utf-8 \uD7FF ED9FBF {} {Unicode Table 3.7 Row 5}
utf-8 \uE000 EE8080 {} {Unicode Table 3.7 Row 6}
utf-8 \uFFFF EFBFBF {} {Unicode Table 3.7 Row 6}
utf-8 \U10000 F0908080 {} {Unicode Table 3.7 Row 7}
utf-8 \U3FFFF F0BFBFBF {} {Unicode Table 3.7 Row 7}
utf-8 \U40000 F1808080 {} {Unicode Table 3.7 Row 8}
utf-8 \UFFFFF F3BFBFBF {} {Unicode Table 3.7 Row 8}
utf-8 \U100000 F4808080 {} {Unicode Table 3.7 Row 9}
utf-8 \U10FFFF F48FBFBF {} {Unicode Table 3.7 Row 9}
utf-8 A\u03A9\u8A9E\U00010384 41CEA9E8AA9EF0908E84 {} {Unicode 2.5}
utf-16le \u0000 0000 {} {Lowest code unit}
utf-16le \uD7FF FFD7 {} {Below high surrogate range}
utf-16le \uE000 00E0 {} {Above low surrogate range}
utf-16le \uFFFF FFFF {} {Highest code unit}
utf-16le \U010000 00D800DC {} {First surrogate pair}
utf-16le \U10FFFF FFDBFFDF {} {First surrogate pair}
utf-16le A\u03A9\u8A9E\U00010384 4100A9039E8A00D884DF {} {Unicode 2.5}
utf-16be \u0000 0000 {} {Lowest code unit}
utf-16be \uD7FF D7FF {} {Below high surrogate range}
utf-16be \uE000 E000 {} {Above low surrogate range}
utf-16be \uFFFF FFFF {} {Highest code unit}
utf-16be \U010000 D800DC00 {} {First surrogate pair}
utf-16be \U10FFFF DBFFDFFF {} {First surrogate pair}
utf-16be A\u03A9\u8A9E\U00010384 004103A98A9ED800DF84 {} {Unicode 2.5}
utf-32le \u0000 00000000 {} {Lowest code unit}
utf-32le \uFFFF FFFF0000 {} {Highest BMP}
utf-32le \U010000 00000100 {} {First supplementary}
utf-32le \U10FFFF ffff1000 {} {Last supplementary}
utf-32le A\u03A9\u8A9E\U00010384 41000000A90300009E8A000084030100 {} {Unicode 2.5}
utf-32be \u0000 00000000 {} {Lowest code unit}
utf-32be \uFFFF 0000FFFF {} {Highest BMP}
utf-32be \U010000 00010000 {} {First supplementary}
utf-32be \U10FFFF 0010FFFF {} {Last supplementary}
utf-32be A\u03A9\u8A9E\U00010384 00000041000003A900008A9E00010384 {} {Unicode 2.5}
}
# encInvalidBytes - Table of invalid byte sequences
# These are byte sequences that should appear for an encoding. Each row is
# of the form
# <ENCODING BYTES PROFILE EXPECTEDRESULT EXPECTEDFAILINDEX CTRL COMMENT>
# The triple <ENCODING,BYTES,PROFILE> should be unique for test ids to be
# unique. BYTES is a byte sequence that is invalid. EXPECTEDRESULT is the
# expected string when the bytes are decoded using the PROFILE profile.
# FAILINDEX gives the expected index of the invalid byte under that profile. The
# CTRL field is a list that controls test generation. It may contain zero or
# more of `solo`, `lead`, `tail` and `middle` indicating that the generated the
# tail of a longer and in the middle of a longer string. If empty, it is treated
# as containing all four of the above. The CTRL field may also contain the words
# knownBug or knownW3C which will cause the test generation for that vector to
# be skipped.
#
# utf-32 missing because they are automatically generated based on le/be
# versions.
set encInvalidBytes {}; # Reset the table
# ascii - Any byte above 127 is invalid and is mapped
# to the same numeric code point except for the range
# 80-9F which is treated as cp1252.
# This tests the TableToUtfProc code path.
lappend encInvalidBytes {*}{
ascii 80 tcl8 \u20AC -1 {knownBug} {map to cp1252}
ascii 80 replace \uFFFD -1 {} {Smallest invalid byte}
ascii 80 strict {} 0 {} {Smallest invalid byte}
ascii 81 tcl8 \u0081 -1 {knownBug} {map to cp1252}
ascii 82 tcl8 \u201A -1 {knownBug} {map to cp1252}
ascii 83 tcl8 \u0192 -1 {knownBug} {map to cp1252}
ascii 84 tcl8 \u201E -1 {knownBug} {map to cp1252}
ascii 85 tcl8 \u2026 -1 {knownBug} {map to cp1252}
ascii 86 tcl8 \u2020 -1 {knownBug} {map to cp1252}
ascii 87 tcl8 \u2021 -1 {knownBug} {map to cp1252}
ascii 88 tcl8 \u0276 -1 {knownBug} {map to cp1252}
ascii 89 tcl8 \u2030 -1 {knownBug} {map to cp1252}
ascii 8A tcl8 \u0160 -1 {knownBug} {map to cp1252}
ascii 8B tcl8 \u2039 -1 {knownBug} {map to cp1252}
ascii 8C tcl8 \u0152 -1 {knownBug} {map to cp1252}
ascii 8D tcl8 \u008D -1 {knownBug} {map to cp1252}
ascii 8E tcl8 \u017D -1 {knownBug} {map to cp1252}
ascii 8F tcl8 \u008F -1 {knownBug} {map to cp1252}
ascii 90 tcl8 \u0090 -1 {knownBug} {map to cp1252}
ascii 91 tcl8 \u2018 -1 {knownBug} {map to cp1252}
ascii 92 tcl8 \u2019 -1 {knownBug} {map to cp1252}
ascii 93 tcl8 \u201C -1 {knownBug} {map to cp1252}
ascii 94 tcl8 \u201D -1 {knownBug} {map to cp1252}
ascii 95 tcl8 \u2022 -1 {knownBug} {map to cp1252}
ascii 96 tcl8 \u2013 -1 {knownBug} {map to cp1252}
ascii 97 tcl8 \u2014 -1 {knownBug} {map to cp1252}
ascii 98 tcl8 \u02DC -1 {knownBug} {map to cp1252}
ascii 99 tcl8 \u2122 -1 {knownBug} {map to cp1252}
ascii 9A tcl8 \u0161 -1 {knownBug} {map to cp1252}
ascii 9B tcl8 \u203A -1 {knownBug} {map to cp1252}
ascii 9C tcl8 \u0153 -1 {knownBug} {map to cp1252}
ascii 9D tcl8 \u009D -1 {knownBug} {map to cp1252}
ascii 9E tcl8 \u017E -1 {knownBug} {map to cp1252}
ascii 9F tcl8 \u0178 -1 {knownBug} {map to cp1252}
ascii FF tcl8 \u00FF -1 {} {Largest invalid byte}
ascii FF replace \uFFFD -1 {} {Largest invalid byte}
ascii FF strict {} 0 {} {Largest invalid byte}
}
# utf-8 - valid sequences based on Table 3.7 in the Unicode
# standard.
#
# Code Points First Second Third Fourth Byte
# U+0000..U+007F 00..7F
# U+0080..U+07FF C2..DF 80..BF
# U+0800..U+0FFF E0 A0..BF 80..BF
# U+1000..U+CFFF E1..EC 80..BF 80..BF
# U+D000..U+D7FF ED 80..9F 80..BF
# U+E000..U+FFFF EE..EF 80..BF 80..BF
# U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
# U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
# U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
#
# Tests below are based on the "gaps" in the above table. Note ascii test
# values are repeated because internally a different code path is used
# (UtfToUtfProc).
# Note C0, C1, F5:FF are invalid bytes ANYWHERE. Exception is C080
lappend encInvalidBytes {*}{
utf-8 80 tcl8 \u20AC -1 {} {map to cp1252}
utf-8 80 replace \uFFFD -1 {} {Smallest invalid byte}
utf-8 80 strict {} 0 {} {Smallest invalid byte}
utf-8 81 tcl8 \u0081 -1 {} {map to cp1252}
utf-8 82 tcl8 \u201A -1 {} {map to cp1252}
utf-8 83 tcl8 \u0192 -1 {} {map to cp1252}
utf-8 84 tcl8 \u201E -1 {} {map to cp1252}
utf-8 85 tcl8 \u2026 -1 {} {map to cp1252}
utf-8 86 tcl8 \u2020 -1 {} {map to cp1252}
utf-8 87 tcl8 \u2021 -1 {} {map to cp1252}
utf-8 88 tcl8 \u02C6 -1 {} {map to cp1252}
utf-8 89 tcl8 \u2030 -1 {} {map to cp1252}
utf-8 8A tcl8 \u0160 -1 {} {map to cp1252}
utf-8 8B tcl8 \u2039 -1 {} {map to cp1252}
utf-8 8C tcl8 \u0152 -1 {} {map to cp1252}
utf-8 8D tcl8 \u008D -1 {} {map to cp1252}
utf-8 8E tcl8 \u017D -1 {} {map to cp1252}
utf-8 8F tcl8 \u008F -1 {} {map to cp1252}
utf-8 90 tcl8 \u0090 -1 {} {map to cp1252}
utf-8 91 tcl8 \u2018 -1 {} {map to cp1252}
utf-8 92 tcl8 \u2019 -1 {} {map to cp1252}
utf-8 93 tcl8 \u201C -1 {} {map to cp1252}
utf-8 94 tcl8 \u201D -1 {} {map to cp1252}
utf-8 95 tcl8 \u2022 -1 {} {map to cp1252}
utf-8 96 tcl8 \u2013 -1 {} {map to cp1252}
utf-8 97 tcl8 \u2014 -1 {} {map to cp1252}
utf-8 98 tcl8 \u02DC -1 {} {map to cp1252}
utf-8 99 tcl8 \u2122 -1 {} {map to cp1252}
utf-8 9A tcl8 \u0161 -1 {} {map to cp1252}
utf-8 9B tcl8 \u203A -1 {} {map to cp1252}
utf-8 9C tcl8 \u0153 -1 {} {map to cp1252}
utf-8 9D tcl8 \u009D -1 {} {map to cp1252}
utf-8 9E tcl8 \u017E -1 {} {map to cp1252}
utf-8 9F tcl8 \u0178 -1 {} {map to cp1252}
utf-8 C0 tcl8 \u00C0 -1 {} {C0 is invalid anywhere}
utf-8 C0 strict {} 0 {} {C0 is invalid anywhere}
utf-8 C0 replace \uFFFD -1 {} {C0 is invalid anywhere}
utf-8 C080 tcl8 \u0000 -1 {} {C080 -> U+0 in Tcl's internal modified UTF8}
utf-8 C080 strict {} 0 {} {C080 -> invalid}
utf-8 C080 replace \uFFFD -1 {} {C080 -> single replacement char}
utf-8 C0A2 tcl8 \u00C0\u00A2 -1 {} {websec.github.io - A}
utf-8 C0A2 replace \uFFFD\uFFFD -1 {} {websec.github.io - A}
utf-8 C0A2 strict {} 0 {} {websec.github.io - A}
utf-8 C0A7 tcl8 \u00C0\u00A7 -1 {} {websec.github.io - double quote}
utf-8 C0A7 replace \uFFFD\uFFFD -1 {} {websec.github.io - double quote}
utf-8 C0A7 strict {} 0 {} {websec.github.io - double quote}
utf-8 C0AE tcl8 \u00C0\u00AE -1 {} {websec.github.io - full stop}
utf-8 C0AE replace \uFFFD\uFFFD -1 {} {websec.github.io - full stop}
utf-8 C0AE strict {} 0 {} {websec.github.io - full stop}
utf-8 C0AF tcl8 \u00C0\u00AF -1 {} {websec.github.io - solidus}
utf-8 C0AF replace \uFFFD\uFFFD -1 {} {websec.github.io - solidus}
utf-8 C0AF strict {} 0 {} {websec.github.io - solidus}
utf-8 C1 tcl8 \u00C1 -1 {} {C1 is invalid everywhere}
utf-8 C1 replace \uFFFD -1 {} {C1 is invalid everywhere}
utf-8 C1 strict {} 0 {} {C1 is invalid everywhere}
utf-8 C181 tcl8 \u00C1\u0081 -1 {} {websec.github.io - base test (A)}
utf-8 C181 replace \uFFFD\uFFFD -1 {} {websec.github.io - base test (A)}
utf-8 C181 strict {} 0 {} {websec.github.io - base test (A)}
utf-8 C19C tcl8 \u00C1\u0153 -1 {} {websec.github.io - reverse solidus}
utf-8 C19C replace \uFFFD\uFFFD -1 {} {websec.github.io - reverse solidus}
utf-8 C19C strict {} 0 {} {websec.github.io - reverse solidus}
utf-8 C2 tcl8 \u00C2 -1 {} {Missing trail byte}
utf-8 C2 replace \uFFFD -1 {} {Missing trail byte}
utf-8 C2 strict {} 0 {} {Missing trail byte}
utf-8 C27F tcl8 \u00C2\x7F -1 {} {Trail byte must be 80:BF}
utf-8 C27F replace \uFFFD\x7F -1 {} {Trail byte must be 80:BF}
utf-8 C27F strict {} 0 {} {Trail byte must be 80:BF}
utf-8 DF tcl8 \u00DF -1 {} {Missing trail byte}
utf-8 DF replace \uFFFD -1 {} {Missing trail byte}
utf-8 DF strict {} 0 {} {Missing trail byte}
utf-8 DF7F tcl8 \u00DF\x7F -1 {} {Trail byte must be 80:BF}
utf-8 DF7F replace \uFFFD\x7F -1 {} {Trail byte must be 80:BF}
utf-8 DF7F strict {} 0 {} {Trail byte must be 80:BF}
utf-8 DFE0A080 tcl8 \u00DF\u0800 -1 {} {Invalid trail byte is start of valid sequence}
utf-8 DFE0A080 replace \uFFFD\u0800 -1 {} {Invalid trail byte is start of valid sequence}
utf-8 DFE0A080 strict {} 0 {} {Invalid trail byte is start of valid sequence}
utf-8 E0 tcl8 \u00E0 -1 {} {Missing trail byte}
utf-8 E0 replace \uFFFD -1 {} {Missing trail byte}
utf-8 E0 strict {} 0 {} {Missing trail byte}
utf-8 E080 tcl8 \u00E0\u20AC -1 {} {First trail byte must be A0:BF}
utf-8 E080 replace \uFFFD\uFFFD -1 {} {First trail byte must be A0:BF}
utf-8 E080 strict {} 0 {} {First trail byte must be A0:BF}
utf-8 E0819C tcl8 \u00E0\u0081\u0153 -1 {} {websec.github.io - reverse solidus}
utf-8 E0819C replace \uFFFD\uFFFD\uFFFD -1 {} {websec.github.io - reverse solidus}
utf-8 E0819C strict {} 0 {} {websec.github.io - reverse solidus}
utf-8 E09F tcl8 \u00E0\u0178 -1 {} {First trail byte must be A0:BF}
utf-8 E09F replace \uFFFD\uFFFD -1 {} {First trail byte must be A0:BF}
utf-8 E09F strict {} 0 {} {First trail byte must be A0:BF}
utf-8 E0A0 tcl8 \u00E0\u00A0 -1 {} {Missing second trail byte}
utf-8 E0A0 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 E0A0 strict {} 0 {} {Missing second trail byte}
utf-8 E0BF tcl8 \u00E0\u00BF -1 {} {Missing second trail byte}
utf-8 E0BF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 E0BF strict {} 0 {} {Missing second trail byte}
utf-8 E0A07F tcl8 \u00E0\u00A0\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 E0A07F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 E0A07F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 E0BF7F tcl8 \u00E0\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 E0BF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 E0BF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 E1 tcl8 \u00E1 -1 {} {Missing trail byte}
utf-8 E1 replace \uFFFD -1 {} {Missing trail byte}
utf-8 E1 strict {} 0 {} {Missing trail byte}
utf-8 E17F tcl8 \u00E1\x7F -1 {} {Trail byte must be 80:BF}
utf-8 E17F replace \uFFFD\x7F -1 {} {Trail byte must be 80:BF}
utf-8 E17F strict {} 0 {} {Trail byte must be 80:BF}
utf-8 E181 tcl8 \u00E1\u0081 -1 {} {Missing second trail byte}
utf-8 E181 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 E181 strict {} 0 {} {Missing second trail byte}
utf-8 E1BF tcl8 \u00E1\u00BF -1 {} {Missing second trail byte}
utf-8 E1BF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 E1BF strict {} 0 {} {Missing second trail byte}
utf-8 E1807F tcl8 \u00E1\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 E1807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 E1807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 E1BF7F tcl8 \u00E1\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 E1BF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 E1BF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 EC tcl8 \u00EC -1 {} {Missing trail byte}
utf-8 EC replace \uFFFD -1 {} {Missing trail byte}
utf-8 EC strict {} 0 {} {Missing trail byte}
utf-8 EC7F tcl8 \u00EC\x7F -1 {} {Trail byte must be 80:BF}
utf-8 EC7F replace \uFFFD\x7F -1 {} {Trail byte must be 80:BF}
utf-8 EC7F strict {} 0 {} {Trail byte must be 80:BF}
utf-8 EC81 tcl8 \u00EC\u0081 -1 {} {Missing second trail byte}
utf-8 EC81 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 EC81 strict {} 0 {} {Missing second trail byte}
utf-8 ECBF tcl8 \u00EC\u00BF -1 {} {Missing second trail byte}
utf-8 ECBF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 ECBF strict {} 0 {} {Missing second trail byte}
utf-8 EC807F tcl8 \u00EC\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 EC807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 EC807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 ECBF7F tcl8 \u00EC\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 ECBF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 ECBF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 ED tcl8 \u00ED -1 {} {Missing trail byte}
utf-8 ED replace \uFFFD -1 {} {Missing trail byte}
utf-8 ED strict {} 0 {} {Missing trail byte}
utf-8 ED7F tcl8 \u00ED\u7F -1 {} {First trail byte must be 80:9F}
utf-8 ED7F replace \uFFFD\u7F -1 {} {First trail byte must be 80:9F}
utf-8 ED7F strict {} 0 {} {First trail byte must be 80:9F}
utf-8 EDA0 tcl8 \u00ED\u00A0 -1 {} {First trail byte must be 80:9F}
utf-8 EDA0 replace \uFFFD\uFFFD -1 {} {First trail byte must be 80:9F}
utf-8 EDA0 strict {} 0 {} {First trail byte must be 80:9F}
utf-8 ED81 tcl8 \u00ED\u0081 -1 {} {Missing second trail byte}
utf-8 ED81 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 ED81 strict {} 0 {} {Missing second trail byte}
utf-8 EDBF tcl8 \u00ED\u00BF -1 {} {Missing second trail byte}
utf-8 EDBF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 EDBF strict {} 0 {} {Missing second trail byte}
utf-8 ED807F tcl8 \u00ED\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 ED807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 ED807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 ED9F7F tcl8 \u00ED\u0178\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 ED9F7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 ED9F7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 EDA080 tcl8 \uD800 -1 {} {High surrogate}
utf-8 EDA080 replace \uFFFD -1 {} {High surrogate}
utf-8 EDA080 strict {} 0 {} {High surrogate}
utf-8 EDAFBF tcl8 \uDBFF -1 {} {High surrogate}
utf-8 EDAFBF replace \uFFFD -1 {} {High surrogate}
utf-8 EDAFBF strict {} 0 {} {High surrogate}
utf-8 EDB080 tcl8 \uDC00 -1 {} {Low surrogate}
utf-8 EDB080 replace \uFFFD -1 {} {Low surrogate}
utf-8 EDB080 strict {} 0 {} {Low surrogate}
utf-8 EDBFBF tcl8 \uDFFF -1 {} {Low surrogate}
utf-8 EDBFBF replace \uFFFD -1 {} {Low surrogate}
utf-8 EDBFBF strict {} 0 {} {Low surrogate}
utf-8 EDA080EDB080 tcl8 \U00010000 -1 {} {High low surrogate pair}
utf-8 EDA080EDB080 replace \uFFFD\uFFFD -1 {} {High low surrogate pair}
utf-8 EDA080EDB080 strict {} 0 {} {High low surrogate pair}
utf-8 EDAFBFEDBFBF tcl8 \U0010FFFF -1 {} {High low surrogate pair}
utf-8 EDAFBFEDBFBF replace \uFFFD\uFFFD -1 {} {High low surrogate pair}
utf-8 EDAFBFEDBFBF strict {} 0 {} {High low surrogate pair}
utf-8 EE tcl8 \u00EE -1 {} {Missing trail byte}
utf-8 EE replace \uFFFD -1 {} {Missing trail byte}
utf-8 EE strict {} 0 {} {Missing trail byte}
utf-8 EE7F tcl8 \u00EE\u7F -1 {} {First trail byte must be 80:BF}
utf-8 EE7F replace \uFFFD\u7F -1 {} {First trail byte must be 80:BF}
utf-8 EE7F strict {} 0 {} {First trail byte must be 80:BF}
utf-8 EED0 tcl8 \u00EE\u00D0 -1 {} {First trail byte must be 80:BF}
utf-8 EED0 replace \uFFFD\uFFFD -1 {} {First trail byte must be 80:BF}
utf-8 EED0 strict {} 0 {} {First trail byte must be 80:BF}
utf-8 EE81 tcl8 \u00EE\u0081 -1 {} {Missing second trail byte}
utf-8 EE81 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 EE81 strict {} 0 {} {Missing second trail byte}
utf-8 EEBF tcl8 \u00EE\u00BF -1 {} {Missing second trail byte}
utf-8 EEBF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 EEBF strict {} 0 {} {Missing second trail byte}
utf-8 EE807F tcl8 \u00EE\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 EE807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 EE807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 EEBF7F tcl8 \u00EE\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 EEBF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 EEBF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 EF tcl8 \u00EF -1 {} {Missing trail byte}
utf-8 EF replace \uFFFD -1 {} {Missing trail byte}
utf-8 EF strict {} 0 {} {Missing trail byte}
utf-8 EF7F tcl8 \u00EF\u7F -1 {} {First trail byte must be 80:BF}
utf-8 EF7F replace \uFFFD\u7F -1 {} {First trail byte must be 80:BF}
utf-8 EF7F strict {} 0 {} {First trail byte must be 80:BF}
utf-8 EFD0 tcl8 \u00EF\u00D0 -1 {} {First trail byte must be 80:BF}
utf-8 EFD0 replace \uFFFD\uFFFD -1 {} {First trail byte must be 80:BF}
utf-8 EFD0 strict {} 0 {} {First trail byte must be 80:BF}
utf-8 EF81 tcl8 \u00EF\u0081 -1 {} {Missing second trail byte}
utf-8 EF81 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 EF81 strict {} 0 {} {Missing second trail byte}
utf-8 EFBF tcl8 \u00EF\u00BF -1 {} {Missing second trail byte}
utf-8 EFBF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 EFBF strict {} 0 {} {Missing second trail byte}
utf-8 EF807F tcl8 \u00EF\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 EF807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 EF807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 EFBF7F tcl8 \u00EF\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 EFBF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 EFBF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F0 tcl8 \u00F0 -1 {} {Missing trail byte}
utf-8 F0 replace \uFFFD -1 {} {Missing trail byte}
utf-8 F0 strict {} 0 {} {Missing trail byte}
utf-8 F080 tcl8 \u00F0\u20AC -1 {} {First trail byte must be 90:BF}
utf-8 F080 replace \uFFFD -1 {knownW3C} {First trail byte must be 90:BF}
utf-8 F080 strict {} 0 {} {First trail byte must be 90:BF}
utf-8 F08F tcl8 \u00F0\u8F -1 {} {First trail byte must be 90:BF}
utf-8 F08F replace \uFFFD -1 {knownW3C} {First trail byte must be 90:BF}
utf-8 F08F strict {} 0 {} {First trail byte must be 90:BF}
utf-8 F0D0 tcl8 \u00F0\u00D0 -1 {} {First trail byte must be 90:BF}
utf-8 F0D0 replace \uFFFD\uFFFD -1 {} {First trail byte must be 90:BF}
utf-8 F0D0 strict {} 0 {} {First trail byte must be 90:BF}
utf-8 F090 tcl8 \u00F0\u0090 -1 {} {Missing second trail byte}
utf-8 F090 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F090 strict {} 0 {} {Missing second trail byte}
utf-8 F0BF tcl8 \u00F0\u00BF -1 {} {Missing second trail byte}
utf-8 F0BF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F0BF strict {} 0 {} {Missing second trail byte}
utf-8 F0907F tcl8 \u00F0\u0090\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F0907F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F0907F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F0BF7F tcl8 \u00F0\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F0BF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F0BF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F090BF tcl8 \u00F0\u0090\u00BF -1 {} {Missing third trail byte}
utf-8 F090BF replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F090BF strict {} 0 {} {Missing third trail byte}
utf-8 F0BF81 tcl8 \u00F0\u00BF\u0081 -1 {} {Missing third trail byte}
utf-8 F0BF81 replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F0BF81 strict {} 0 {} {Missing third trail byte}
utf-8 F0BF807F tcl8 \u00F0\u00BF\u20AC\x7F -1 {} {Third trail byte must be 80:BF}
utf-8 F0BF817F replace \uFFFD\x7F -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F0BF817F strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F090BFD0 tcl8 \u00F0\u0090\u00BF\u00D0 -1 {} {Third trail byte must be 80:BF}
utf-8 F090BFD0 replace \uFFFD -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F090BFD0 strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F1 tcl8 \u00F1 -1 {} {Missing trail byte}
utf-8 F1 replace \uFFFD -1 {} {Missing trail byte}
utf-8 F1 strict {} 0 {} {Missing trail byte}
utf-8 F17F tcl8 \u00F1\u7F -1 {} {First trail byte must be 80:BF}
utf-8 F17F replace \uFFFD -1 {knownW3C} {First trail byte must be 80:BF}
utf-8 F17F strict {} 0 {} {First trail byte must be 80:BF}
utf-8 F1D0 tcl8 \u00F1\u00D0 -1 {} {First trail byte must be 80:BF}
utf-8 F1D0 replace \uFFFD\uFFFD -1 {} {First trail byte must be 80:BF}
utf-8 F1D0 strict {} 0 {} {First trail byte must be 80:BF}
utf-8 F180 tcl8 \u00F1\u20AC -1 {} {Missing second trail byte}
utf-8 F180 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F180 strict {} 0 {} {Missing second trail byte}
utf-8 F1BF tcl8 \u00F1\u00BF -1 {} {Missing second trail byte}
utf-8 F1BF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F1BF strict {} 0 {} {Missing second trail byte}
utf-8 F1807F tcl8 \u00F1\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F1807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F1807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F1BF7F tcl8 \u00F1\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F1BF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F1BF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F180BF tcl8 \u00F1\u20AC\u00BF -1 {} {Missing third trail byte}
utf-8 F180BF replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F180BF strict {} 0 {} {Missing third trail byte}
utf-8 F1BF81 tcl8 \u00F1\u00BF\u0081 -1 {} {Missing third trail byte}
utf-8 F1BF81 replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F1BF81 strict {} 0 {} {Missing third trail byte}
utf-8 F1BF807F tcl8 \u00F1\u00BF\u20AC\x7F -1 {} {Third trail byte must be 80:BF}
utf-8 F1BF817F replace \uFFFD\x7F -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F1BF817F strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F180BFD0 tcl8 \u00F1\u20AC\u00BF\u00D0 -1 {} {Third trail byte must be 80:BF}
utf-8 F180BFD0 replace \uFFFD -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F180BFD0 strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F3 tcl8 \u00F3 -1 {} {Missing trail byte}
utf-8 F3 replace \uFFFD -1 {} {Missing trail byte}
utf-8 F3 strict {} 0 {} {Missing trail byte}
utf-8 F37F tcl8 \u00F3\x7F -1 {} {First trail byte must be 80:BF}
utf-8 F37F replace \uFFFD -1 {knownW3C} {First trail byte must be 80:BF}
utf-8 F37F strict {} 0 {} {First trail byte must be 80:BF}
utf-8 F3D0 tcl8 \u00F3\u00D0 -1 {} {First trail byte must be 80:BF}
utf-8 F3D0 replace \uFFFD\uFFFD -1 {} {First trail byte must be 80:BF}
utf-8 F3D0 strict {} 0 {} {First trail byte must be 80:BF}
utf-8 F380 tcl8 \u00F3\u20AC -1 {} {Missing second trail byte}
utf-8 F380 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F380 strict {} 0 {} {Missing second trail byte}
utf-8 F3BF tcl8 \u00F3\u00BF -1 {} {Missing second trail byte}
utf-8 F3BF replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F3BF strict {} 0 {} {Missing second trail byte}
utf-8 F3807F tcl8 \u00F3\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F3807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F3807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F3BF7F tcl8 \u00F3\u00BF\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F3BF7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F3BF7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F380BF tcl8 \u00F3\u20AC\u00BF -1 {} {Missing third trail byte}
utf-8 F380BF replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F380BF strict {} 0 {} {Missing third trail byte}
utf-8 F3BF81 tcl8 \u00F3\u00BF\u0081 -1 {} {Missing third trail byte}
utf-8 F3BF81 replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F3BF81 strict {} 0 {} {Missing third trail byte}
utf-8 F3BF807F tcl8 \u00F3\u00BF\u20AC\x7F -1 {} {Third trail byte must be 80:BF}
utf-8 F3BF817F replace \uFFFD\x7F -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F3BF817F strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F380BFD0 tcl8 \u00F3\u20AC\u00BF\u00D0 -1 {} {Third trail byte must be 80:BF}
utf-8 F380BFD0 replace \uFFFD -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F380BFD0 strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F4 tcl8 \u00F4 -1 {} {Missing trail byte}
utf-8 F4 replace \uFFFD -1 {} {Missing trail byte}
utf-8 F4 strict {} 0 {} {Missing trail byte}
utf-8 F47F tcl8 \u00F4\u7F -1 {} {First trail byte must be 80:8F}
utf-8 F47F replace \uFFFD\u7F -1 {knownW3C} {First trail byte must be 80:8F}
utf-8 F47F strict {} 0 {} {First trail byte must be 80:8F}
utf-8 F490 tcl8 \u00F4\u0090 -1 {} {First trail byte must be 80:8F}
utf-8 F490 replace \uFFFD\uFFFD -1 {} {First trail byte must be 80:8F}
utf-8 F490 strict {} 0 {} {First trail byte must be 80:8F}
utf-8 F480 tcl8 \u00F4\u20AC -1 {} {Missing second trail byte}
utf-8 F480 replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F480 strict {} 0 {} {Missing second trail byte}
utf-8 F48F tcl8 \u00F4\u008F -1 {} {Missing second trail byte}
utf-8 F48F replace \uFFFD -1 {knownW3C} {Missing second trail byte}
utf-8 F48F strict {} 0 {} {Missing second trail byte}
utf-8 F4807F tcl8 \u00F4\u20AC\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F4807F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F4807F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F48F7F tcl8 \u00F4\u008F\x7F -1 {} {Second trail byte must be 80:BF}
utf-8 F48F7F replace \uFFFD\u7F -1 {knownW3C} {Second trail byte must be 80:BF}
utf-8 F48F7F strict {} 0 {} {Second trail byte must be 80:BF}
utf-8 F48081 tcl8 \u00F4\u20AC\u0081 -1 {} {Missing third trail byte}
utf-8 F48081 replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F48081 strict {} 0 {} {Missing third trail byte}
utf-8 F48F81 tcl8 \u00F4\u008F\u0081 -1 {} {Missing third trail byte}
utf-8 F48F81 replace \uFFFD -1 {knownW3C} {Missing third trail byte}
utf-8 F48F81 strict {} 0 {} {Missing third trail byte}
utf-8 F481817F tcl8 \u00F4\u0081\u0081\x7F -1 {} {Third trail byte must be 80:BF}
utf-8 F480817F replace \uFFFD\x7F -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F480817F strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F48FBFD0 tcl8 \u00F4\u008F\u00BF\u00D0 -1 {} {Third trail byte must be 80:BF}
utf-8 F48FBFD0 replace \uFFFD -1 {knownW3C} {Third trail byte must be 80:BF}
utf-8 F48FBFD0 strict {} 0 {} {Third trail byte must be 80:BF}
utf-8 F5 tcl8 \u00F5 -1 {} {F5:FF are invalid everywhere}
utf-8 F5 replace \uFFFD -1 {} {F5:FF are invalid everywhere}
utf-8 F5 strict {} 0 {} {F5:FF are invalid everywhere}
utf-8 FF tcl8 \u00FF -1 {} {F5:FF are invalid everywhere}
utf-8 FF replace \uFFFD -1 {} {F5:FF are invalid everywhere}
utf-8 FF strict {} 0 {} {F5:FF are invalid everywhere}
utf-8 C0AFE080BFF0818130 replace \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x30 -1 {} {Unicode Table 3-8}
utf-8 EDA080EDBFBFEDAF30 replace \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\x30 -1 {knownW3C} {Unicode Table 3-9}
utf-8 F4919293FF4180BF30 replace \uFFFD\uFFFD\uFFFD\uFFFD\uFFFD\u0041\uFFFD\uFFFD\x30 -1 {} {Unicode Table 3-10}
utf-8 E180E2F09192F1BF30 replace \uFFFD\uFFFD\uFFFD\uFFFD\x30 -1 {knownW3C} {Unicode Table 3.11}
}
# utf16-le and utf16-be test cases. Note utf16 cases are automatically generated
# based on these depending on platform endianness. Note truncated tests can only
# happen when the sequence is at the end (including by itself) Thus {solo tail}
# in some cases.
lappend encInvalidBytes {*}{
utf-16le 41 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-16le 41 replace \uFFFD -1 {solo tail} {Truncated}
utf-16le 41 strict {} 0 {solo tail} {Truncated}
utf-16le 00D8 tcl8 \uD800 -1 {} {Missing low surrogate}
utf-16le 00D8 replace \uFFFD -1 {knownBug} {Missing low surrogate}
utf-16le 00D8 strict {} 0 {knownBug} {Missing low surrogate}
utf-16le 00DC tcl8 \uDC00 -1 {} {Missing high surrogate}
utf-16le 00DC replace \uFFFD -1 {knownBug} {Missing high surrogate}
utf-16le 00DC strict {} 0 {knownBug} {Missing high surrogate}
utf-16be 41 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-16be 41 replace \uFFFD -1 {solo tail} {Truncated}
utf-16be 41 strict {} 0 {solo tail} {Truncated}
utf-16be D800 tcl8 \uD800 -1 {} {Missing low surrogate}
utf-16be D800 replace \uFFFD -1 {knownBug} {Missing low surrogate}
utf-16be D800 strict {} 0 {knownBug} {Missing low surrogate}
utf-16be DC00 tcl8 \uDC00 -1 {} {Missing high surrogate}
utf-16be DC00 replace \uFFFD -1 {knownBug} {Missing high surrogate}
utf-16be DC00 strict {} 0 {knownBug} {Missing high surrogate}
}
# utf32-le and utf32-be test cases. Note utf32 cases are automatically generated
# based on these depending on platform endianness. Note truncated tests can only
# happen when the sequence is at the end (including by itself) Thus {solo tail}
# in some cases.
lappend encInvalidBytes {*}{
utf-32le 41 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-32le 41 replace \uFFFD -1 {solo} {Truncated}
utf-32le 41 strict {} 0 {solo tail} {Truncated}
utf-32le 4100 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-32le 4100 replace \uFFFD -1 {solo} {Truncated}
utf-32le 4100 strict {} 0 {solo tail} {Truncated}
utf-32le 410000 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-32le 410000 replace \uFFFD -1 {solo} {Truncated}
utf-32le 410000 strict {} 0 {solo tail} {Truncated}
utf-32le 00D80000 tcl8 \uD800 -1 {} {High-surrogate}
utf-32le 00D80000 replace \uFFFD -1 {} {High-surrogate}
utf-32le 00D80000 strict {} 0 {} {High-surrogate}
utf-32le 00DC0000 tcl8 \uDC00 -1 {} {Low-surrogate}
utf-32le 00DC0000 replace \uFFFD -1 {} {Low-surrogate}
utf-32le 00DC0000 strict {} 0 {} {Low-surrogate}
utf-32le 00D8000000DC0000 tcl8 \uD800\uDC00 -1 {} {High-low-surrogate-pair}
utf-32le 00D8000000DC0000 replace \uFFFD\uFFFD -1 {} {High-low-surrogate-pair}
utf-32le 00D8000000DC0000 strict {} 0 {} {High-low-surrogate-pair}
utf-32le 00001100 tcl8 \UFFFD -1 {} {Out of range}
utf-32le 00001100 replace \UFFFD -1 {} {Out of range}
utf-32le 00001100 strict {} 0 {} {Out of range}
utf-32le FFFFFFFF tcl8 \UFFFD -1 {} {Out of range}
utf-32le FFFFFFFF replace \UFFFD -1 {} {Out of range}
utf-32le FFFFFFFF strict {} 0 {} {Out of range}
utf-32be 41 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-32be 41 replace \uFFFD -1 {solo tail} {Truncated}
utf-32be 41 strict {} 0 {solo tail} {Truncated}
utf-32be 0041 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-32be 0041 replace \uFFFD -1 {solo} {Truncated}
utf-32be 0041 strict {} 0 {solo tail} {Truncated}
utf-32be 000041 tcl8 \uFFFD -1 {solo tail} {Truncated}
utf-32be 000041 replace \uFFFD -1 {solo} {Truncated}
utf-32be 000041 strict {} 0 {solo tail} {Truncated}
utf-32be 0000D800 tcl8 \uD800 -1 {} {High-surrogate}
utf-32be 0000D800 replace \uFFFD -1 {} {High-surrogate}
utf-32be 0000D800 strict {} 0 {} {High-surrogate}
utf-32be 0000DC00 tcl8 \uDC00 -1 {} {Low-surrogate}
utf-32be 0000DC00 replace \uFFFD -1 {} {Low-surrogate}
utf-32be 0000DC00 strict {} 0 {} {Low-surrogate}
utf-32be 0000D8000000DC00 tcl8 \uD800\uDC00 -1 {} {High-low-surrogate-pair}
utf-32be 0000D8000000DC00 replace \uFFFD\uFFFD -1 {} {High-low-surrogate-pair}
utf-32be 0000D8000000DC00 strict {} 0 {} {High-low-surrogate-pair}
utf-32be 00110000 tcl8 \UFFFD -1 {} {Out of range}
utf-32be 00110000 replace \UFFFD -1 {} {Out of range}
utf-32be 00110000 strict {} 0 {} {Out of range}
utf-32be FFFFFFFF tcl8 \UFFFD -1 {} {Out of range}
utf-32be FFFFFFFF replace \UFFFD -1 {} {Out of range}
utf-32be FFFFFFFF strict {} 0 {} {Out of range}
}
# Strings that cannot be encoded for specific encoding / profiles
# <ENCODING STRING PROFILE EXPECTEDRESULT EXPECTEDFAILINDEX CTRL COMMENT>
# <ENCODING,STRING,PROFILE> should be unique for test ids to be unique.
# See earlier comments about CTRL field.
#
# Note utf-16, utf-32 missing because they are automatically
# generated based on le/be versions.
# TODO - out of range code point (note cannot be generated by \U notation)
lappend encUnencodableStrings {*}{
ascii \u00e0 tcl8 3f -1 {} {unencodable}
ascii \u00e0 strict {} 0 {} {unencodable}
iso8859-1 \u0141 tcl8 3f -1 {} unencodable
iso8859-1 \u0141 strict {} 0 {} unencodable
utf-8 \uD800 tcl8 eda080 -1 {} High-surrogate
utf-8 \uD800 strict {} 0 {} High-surrogate
utf-8 \uDC00 tcl8 edb080 -1 {} High-surrogate
utf-8 \uDC00 strict {} 0 {} High-surrogate
}
# The icuUcmTests.tcl is generated by the tools/ucm2tests.tcl script
# and generates test vectors for the above tables for various encodings
# based on ICU UCM files.
# TODO - commented out for now as generating a lot of mismatches.
# source [file join [file dirname [info script]] icuUcmTests.tcl]
+124 -55
View File
@@ -27,7 +27,7 @@ testConstraint winLessThan10 0
testConstraint notNetworkFilesystem 0
testConstraint reg 0
if {[testConstraint win]} {
catch {
if {[catch {
# Is the registry extension already static to this shell?
try {
load {} Registry
@@ -38,10 +38,16 @@ if {[testConstraint win]} {
load $::reglib Registry
}
testConstraint reg 1
} regError]} {
catch {package require registry; testConstraint reg 1}
}
}
testConstraint notInCIenv [expr {![info exists ::env(CI)] || !$::env(CI)}]
# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]
set tmpspace /tmp;# default value
# Find a group that exists on this Unix system, or else skip tests that
# require Unix groups.
@@ -97,6 +103,45 @@ if {[testConstraint unix]} {
}
}
# Try getting a lower case glob pattern that will match the home directory of
# a given user to test ~user and [file tildeexpand ~user]. Note this may not
# be the same as ~ even when "user" is current user. For example, on Unix
# platforms ~ will return HOME envvar, but ~user will lookup password file
# bypassing HOME. If home directory not found, returns *$user* so caller can
# succeed by using glob matching under the hope that the path contains
# the user name.
proc gethomedirglob {user} {
if {[testConstraint unix]} {
if {![catch {
exec {*}[auto_execok sh] -c "echo ~$user"
} home]} {
set home [string trim $home]
if {$home ne ""} {
# Expect exact match (except case), no glob * added
return [string tolower $home]
}
}
} elseif {[testConstraint reg]} {
# Windows with registry extension loaded
if {![catch {
set sid [exec {*}[auto_execok powershell] -Command "(Get-LocalUser -Name '$user')\[0\].sid.Value"]
set sid [string trim $sid]
# Get path from the Windows registry
set home [registry get "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\$sid" ProfileImagePath]
set home [string trim [string tolower $home]]
} result]} {
if {$home ne ""} {
# file join for \ -> /
return [file join [string tolower $home]]
}
}
}
# Caller will need to use glob matching and hope user
# name is in the home directory path
return *[string tolower $user]*
}
proc createfile {file {string a}} {
set f [open $file w]
puts -nonewline $f $string
@@ -354,7 +399,7 @@ test fCmd-4.10 {TclFileMakeDirsCmd: exists, is dir} -setup {
} -result {1 1}
test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} -setup {
cleanup
} -constraints {unix notRoot testchmod} -returnCodes error -body {
} -constraints {unix notRoot testchmod notWsl} -returnCodes error -body {
file mkdir td1/td2/td3
testchmod 0 td1/td2
file mkdir td1/td2/td3/td4
@@ -372,7 +417,7 @@ test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} -setup {
test fCmd-4.14 {TclFileMakeDirsCmd: TclpCreateDirectory fails} -setup {
cleanup
file delete -force foo
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir foo
file attr foo -perm 0o40000
file mkdir foo/tf1
@@ -384,7 +429,7 @@ test fCmd-4.16 {TclFileMakeDirsCmd: TclpCreateDirectory succeeds} -setup {
} -constraints {notRoot} -body {
file mkdir tf1
file exists tf1
} -result {1}
} -result 1
test fCmd-5.1 {TclFileDeleteCmd: FileForceOption fails} -constraints {notRoot} -body {
file delete -xyz
@@ -497,7 +542,7 @@ test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} -setup {
} -result {tf2}
test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} -setup {
cleanup
} -constraints {unix notRoot testchmod} -body {
} -constraints {unix notRoot testchmod notWsl} -body {
file mkdir td1
testchmod 0 td1
createfile tf1
@@ -616,7 +661,7 @@ test fCmd-6.22 {CopyRenameOneFile: copy/rename: !S_ISDIR(source)} -setup {
} -result [file join $tmpspace tf1]
test fCmd-6.23 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
cleanup $tmpspace
} -constraints {xdev notRoot} -body {
} -constraints {xdev notRoot notWsl} -body {
file mkdir td1/td2/td3
file attributes td1 -permissions 0
file rename td1 $tmpspace
@@ -668,7 +713,7 @@ test fCmd-6.27 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": file already exists}
test fCmd-6.28 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
cleanup $tmpspace
} -constraints {notRoot xdev} -body {
} -constraints {notRoot xdev notWsl} -body {
file mkdir td1/td2/td3
file attributes td1/td2/td3 -permissions 0
file rename td1 $tmpspace
@@ -685,7 +730,7 @@ test fCmd-6.29 {CopyRenameOneFile: TclpCopyDirectory passed} -setup {
} -result [file join $tmpspace td1 td2]
test fCmd-6.30 {CopyRenameOneFile: TclpRemoveDirectory failed} -setup {
cleanup $tmpspace
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir foo/bar
file attr foo -perm 0o40555
file rename foo/bar $tmpspace
@@ -760,7 +805,7 @@ test fCmd-8.3 {file copy and path translation: ensure correct error} -body {
test fCmd-9.1 {file rename: comprehensive: EACCES} -setup {
cleanup
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir td1
file mkdir td2
file attr td2 -perm 0o40000
@@ -786,7 +831,7 @@ test fCmd-9.3 {file rename: comprehensive: file to new name} -setup {
} -result {{tf3 tf4} 1 0}
test fCmd-9.4 {file rename: comprehensive: dir to new name} -setup {
cleanup
} -constraints {unix notRoot testchmod notDarwin9} -body {
} -constraints {unix notRoot testchmod notDarwin9 notWsl} -body {
file mkdir td1 td2
testchmod 0o555 td2
file rename td1 td3
@@ -807,7 +852,7 @@ test fCmd-9.5 {file rename: comprehensive: file to self} -setup {
} -result {tf1 tf2 1 0}
test fCmd-9.6 {file rename: comprehensive: dir to self} -setup {
cleanup
} -constraints {unix notRoot testchmod} -body {
} -constraints {unix notRoot testchmod notWsl} -body {
file mkdir td1
file mkdir td2
testchmod 0o555 td2
@@ -1001,7 +1046,7 @@ test fCmd-10.2 {file copy: comprehensive: file to new name} -setup {
} -result {{tf1 tf2 tf3 tf4} tf1 tf2 1 0}
test fCmd-10.3 {file copy: comprehensive: dir to new name} -setup {
cleanup
} -constraints {unix notRoot testchmod} -body {
} -constraints {unix notRoot testchmod notWsl} -body {
file mkdir [file join td1 tdx]
file mkdir [file join td2 tdy]
testchmod 0o555 td2
@@ -1020,6 +1065,7 @@ test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup {
file mkdir [file join td1 tdx]
file mkdir [file join td2 tdy]
testchmod 0o555 td2
testchmod 0o555 td2/tdy; # Above line removes inherited perms. So restore.
file copy td1 td3
file copy td2 td4
list [lsort [glob td*]] [glob -directory td3 t*] \
@@ -1041,10 +1087,19 @@ test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup {
createfile tfd2
createfile tfd3
createfile tfd4
testchmod 0o444 tfs3
testchmod 0o444 tfs4
testchmod 0o444 tfd2
testchmod 0o444 tfd4
if {$::tcl_platform(platform) eq "windows"} {
# On Windows testchmode will attach an ACL which file copy cannot handle
# so use good old attributes which file copy does understand
file attribute tfs3 -readonly 1
file attribute tfs4 -readonly 1
file attribute tfd2 -readonly 1
file attribute tfd4 -readonly 1
} else {
testchmod 0o444 tfs3
testchmod 0o444 tfs4
testchmod 0o444 tfd2
testchmod 0o444 tfd4
}
set msg [list [catch {file copy tf1 tf2} msg] $msg]
file copy -force tfs1 tfd1
file copy -force tfs2 tfd2
@@ -1078,7 +1133,7 @@ test fCmd-10.5 {file copy: comprehensive: dir to empty dir} -setup {
} -result [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} -setup {
cleanup
} -constraints {notRoot unixOrWin testchmod} -body {
} -constraints {notRoot unixOrWin testchmod notWsl} -body {
file mkdir tds1
file mkdir tds2
file mkdir [file join tdd1 tds1 xxx]
@@ -1102,7 +1157,7 @@ test fCmd-10.7 {file rename: comprehensive: file to new name and dir} -setup {
} -result [subst {{tf1 tf2} {[file join td1 tf3] [file join td1 tf4]} 1 0}]
test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} -setup {
cleanup
} -constraints {unix notRoot testchmod} -body {
} -constraints {unix notRoot testchmod notWsl} -body {
file mkdir td1
file mkdir td2
file mkdir td3
@@ -1194,7 +1249,7 @@ test fCmd-11.5 {TclFileRenameCmd: > 1 source & target is not a dir} -setup {
catch {file rename tfa1 tfa2 tfa3}
} -cleanup {
file delete tfa1 tfa2 tfa3
} -result {1}
} -result 1
test fCmd-11.6 {TclFileRenameCmd: : single file into directory} -setup {
catch {file delete -force -- tfa1 tfad}
} -constraints {notRoot} -body {
@@ -1239,7 +1294,7 @@ test fCmd-12.1 {renamefile: source filename translation failing} -setup {
catch {file rename ~/tfa1 tfa2}
} -cleanup {
set ::env(HOME) $temp
} -result {1}
} -result 1
test fCmd-12.2 {renamefile: src filename translation failing} -setup {
set temp $::env(HOME)
} -constraints {notRoot} -body {
@@ -1251,7 +1306,7 @@ test fCmd-12.2 {renamefile: src filename translation failing} -setup {
} -cleanup {
set ::env(HOME) $temp
file delete -force tfad
} -result {1}
} -result 1
test fCmd-12.3 {renamefile: stat failing on source} -setup {
catch {file delete -force -- tfa1 tfa2}
} -constraints {notRoot} -body {
@@ -1296,10 +1351,10 @@ test fCmd-12.7 {renamefile: renaming directory into offspring} -setup {
catch {file rename tfad tfad/dir}
} -cleanup {
file delete -force tfad
} -result {1}
} -result 1
test fCmd-12.8 {renamefile: generic error} -setup {
catch {file delete -force -- tfa}
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir tfa
file mkdir tfa/dir
file attributes tfa -permissions 0o555
@@ -1307,7 +1362,7 @@ test fCmd-12.8 {renamefile: generic error} -setup {
} -cleanup {
catch {file attributes tfa -permissions 0o777}
file delete -force tfa
} -result {1}
} -result 1
test fCmd-12.9 {renamefile: moving a file across volumes} -setup {
cleanup $tmpspace
} -constraints {unix notRoot} -body {
@@ -1369,7 +1424,7 @@ test fCmd-13.5 {TclCopyFilesCmd: target filename translation failing} -setup {
catch { file copy tfa ~/foobar }
} -cleanup {
set ::env(HOME) $temp
} -result {1}
} -result 1
test fCmd-13.6 {TclCopyFilesCmd: > 1 source & target is not a dir} -setup {
catch {file delete -force -- tfa1 tfa2 tfa3}
} -constraints {notRoot} -body {
@@ -1379,7 +1434,7 @@ test fCmd-13.6 {TclCopyFilesCmd: > 1 source & target is not a dir} -setup {
catch {file copy tfa1 tfa2 tfa3}
} -cleanup {
file delete tfa1 tfa2 tfa3
} -result {1}
} -result 1
test fCmd-13.7 {TclCopyFilesCmd: single file into directory} -setup {
catch {file delete -force -- tfa1 tfad}
} -constraints {notRoot} -body {
@@ -1425,7 +1480,7 @@ test fCmd-14.1 {copyfile: source filename translation failing} -setup {
catch {file copy ~/tfa1 tfa2}
} -cleanup {
set ::env(HOME) $temp
} -result {1}
} -result 1
test fCmd-14.2 {copyfile: dst filename translation failing} -setup {
set temp $::env(HOME)
} -constraints {notRoot} -body {
@@ -1486,14 +1541,14 @@ test fCmd-14.7 {copyfile: copy directory succeeding} -setup {
} -result {1 1}
test fCmd-14.8 {copyfile: copy directory failing} -setup {
catch {file delete -force -- tfa}
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir tfa/dir/a/b/c
file attributes tfa/dir -permissions 0
catch {file copy tfa tfa2}
} -cleanup {
file attributes tfa/dir -permissions 0o777
file delete -force tfa tfa2
} -result {1}
} -result 1
#
# Coverage tests for TclMkdirCmd()
@@ -1506,7 +1561,7 @@ test fCmd-15.1 {TclMakeDirsCmd: target filename translation failing} -setup {
catch {file mkdir ~/tfa}
} -cleanup {
set ::env(HOME) $temp
} -result {1}
} -result 1
#
# Can Tcl_SplitPath return argc == 0? If so them we need a test for that code.
#
@@ -1517,7 +1572,7 @@ test fCmd-15.2 {TclMakeDirsCmd - one directory} -setup {
file isdirectory tfa
} -cleanup {
file delete tfa
} -result {1}
} -result 1
test fCmd-15.3 {TclMakeDirsCmd: - two directories} -setup {
catch {file delete -force -- tfa1 tfa2}
} -constraints {notRoot} -body {
@@ -1536,7 +1591,7 @@ test fCmd-15.4 {TclMakeDirsCmd - stat failing} -setup {
} -cleanup {
file attributes tfa -permissions 0o777
file delete -force tfa
} -result {1}
} -result 1
test fCmd-15.5 {TclMakeDirsCmd: - making a directory several levels deep} -setup {
catch {file delete -force -- tfa}
} -constraints {notRoot} -body {
@@ -1544,7 +1599,7 @@ test fCmd-15.5 {TclMakeDirsCmd: - making a directory several levels deep} -setup
file isdir tfa/a/b/c
} -cleanup {
file delete -force tfa
} -result {1}
} -result 1
test fCmd-15.6 {TclMakeDirsCmd: - trying to overwrite a file} -setup {
catch {file delete -force -- tfa}
} -constraints {notRoot} -body {
@@ -1568,7 +1623,7 @@ test fCmd-15.8 {TclFileMakeDirsCmd: trying to create an existing dir} -body {
file isdir tfa
} -constraints {notRoot} -cleanup {
file delete tfa
} -result {1}
} -result 1
# Coverage tests for TclDeleteFilesCommand()
test fCmd-16.1 {test the -- argument} -constraints {notRoot} -setup {
@@ -1592,7 +1647,7 @@ test fCmd-16.3 {test bad option} -constraints {notRoot} -setup {
catch {file delete -dog tfa}
} -cleanup {
file delete tfa
} -result {1}
} -result 1
test fCmd-16.4 {accept zero files (TIP 323)} -body {
file delete
} -result {}
@@ -1607,7 +1662,7 @@ test fCmd-16.6 {delete: source filename translation failing} -setup {
catch {file delete ~/tfa}
} -cleanup {
set ::env(HOME) $temp
} -result {1}
} -result 1
test fCmd-16.7 {remove a non-empty directory without -force} -setup {
catch {file delete -force -- tfa}
} -constraints {notRoot} -body {
@@ -1616,7 +1671,7 @@ test fCmd-16.7 {remove a non-empty directory without -force} -setup {
catch {file delete tfa}
} -cleanup {
file delete -force tfa
} -result {1}
} -result 1
test fCmd-16.8 {remove a normal file} -constraints {notRoot} -setup {
catch {file delete -force -- tfa}
} -body {
@@ -1625,10 +1680,10 @@ test fCmd-16.8 {remove a normal file} -constraints {notRoot} -setup {
catch {file delete tfa}
} -cleanup {
file delete -force tfa
} -result {1}
} -result 1
test fCmd-16.9 {error while deleting file} -setup {
catch {file delete -force -- tfa}
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir tfa
createfile tfa/a
file attributes tfa -permissions 0o555
@@ -1641,7 +1696,7 @@ test fCmd-16.9 {error while deleting file} -setup {
} -cleanup {
file attributes tfa -permissions 0o777
file delete -force tfa
} -result {1}
} -result 1
test fCmd-16.10 {deleting multiple files} -constraints {notRoot} -setup {
catch {file delete -force -- tfa1 tfa2}
} -body {
@@ -1659,14 +1714,14 @@ test fCmd-16.11 {TclFileDeleteCmd: removing a nonexistant file} -setup {
# More coverage tests for mkpath()
test fCmd-17.1 {mkdir stat failing on target but not ENOENT} -setup {
catch {file delete -force -- tfa1}
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir tfa1
file attributes tfa1 -permissions 0o555
catch {file mkdir tfa1/tfa2}
} -cleanup {
file attributes tfa1 -permissions 0o777
file delete -force tfa1
} -result {1}
} -result 1
test fCmd-17.2 {mkdir several levels deep - relative} -setup {
catch {file delete -force -- tfa}
} -constraints {notRoot} -body {
@@ -1683,7 +1738,7 @@ test fCmd-17.3 {mkdir several levels deep - absolute} -setup {
file isdir $f
} -cleanup {
file delete $f [file join [pwd] tfa]
} -result {1}
} -result 1
#
# Functionality tests for TclFileRenameCmd()
@@ -1844,7 +1899,7 @@ test fCmd-18.15 {TclFileRenameCmd : rename a file to a symlink dir} -setup {
checkcontent tfa1/tfa2 $s
} -cleanup {
file delete -force tfa1 tfalink
} -result {1}
} -result 1
test fCmd-18.16 {TclFileRenameCmd: rename a dangling symlink} -setup {
catch {file delete -force -- tfa1 tfalink}
} -constraints {unix notRoot} -body {
@@ -1869,7 +1924,7 @@ test fCmd-19.1 {remove empty directory} -constraints {notRoot} -setup {
} -result {0}
test fCmd-19.2 {rmdir error besides EEXIST} -setup {
catch {file delete -force -- tfa}
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir tfa
file mkdir tfa/a
file attributes tfa -permissions 0o555
@@ -1877,7 +1932,7 @@ test fCmd-19.2 {rmdir error besides EEXIST} -setup {
} -cleanup {
file attributes tfa -permissions 0o777
file delete -force tfa
} -result {1}
} -result 1
test fCmd-19.3 {recursive remove} -constraints {notRoot} -setup {
catch {file delete -force -- tfa}
} -body {
@@ -1897,7 +1952,7 @@ test fCmd-19.3 {recursive remove} -constraints {notRoot} -setup {
#
test fCmd-20.1 {TraverseUnixTree : failure opening a subdirectory directory} -setup {
catch {file delete -force -- tfa}
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir tfa
file mkdir tfa/a
file attributes tfa/a -permissions 00000
@@ -1905,7 +1960,7 @@ test fCmd-20.1 {TraverseUnixTree : failure opening a subdirectory directory} -se
} -cleanup {
file attributes tfa/a -permissions 0o777
file delete -force tfa
} -result {1}
} -result 1
test fCmd-20.2 {TraverseUnixTree : recursive delete of large directory: Bug 1034337} -setup {
catch {file delete -force -- tfa}
} -constraints {unix notRoot} -body {
@@ -1958,7 +2013,7 @@ test fCmd-21.4 {copy : more than one source and target is not a directory} -setu
catch {file copy tfa1 tfa2 tfa3}
} -cleanup {
file delete tfa1 tfa2 tfa3
} -result {1}
} -result 1
test fCmd-21.5 {copy : multiple files into directory} -constraints {notRoot} -setup {
catch {file delete -force -- tfa1 tfa2 tfad}
} -body {
@@ -2083,7 +2138,7 @@ test fCmd-22.2 {TclpRenameFile: attempt to overwrite itself} -setup {
checkcontent tfa1 $s
} -cleanup {
file delete tfa1
} -result {1}
} -result 1
test fCmd-22.3 {TclpRenameFile: rename dir to existing dir} -setup {
catch {file delete -force -- d1 tfad}
} -constraints {notRoot} -body {
@@ -2543,7 +2598,7 @@ test fCmd-30.2 {file readable on 'NTUSER.DAT'} -constraints {win notWine} -body
expr {[info exists env(USERPROFILE)]
&& [file exists $env(USERPROFILE)/NTUSER.DAT]
&& [file readable $env(USERPROFILE)/NTUSER.DAT]}
} -result {1}
} -result 1
# At least one CI environment (GitHub Actions) is set up with the page file in
# an unusual location; skip the test if that is so.
test fCmd-30.3 {file readable on 'pagefile.sys'} -constraints {win notInCIenv} -body {
@@ -2599,13 +2654,20 @@ test fCmd-31.6 {file home USER} -body {
# env(HOME) even when user is current user. Assume result contains user
# name, else not sure how to check
string tolower [file home $::tcl_platform(user)]
} -match glob -result [string tolower "*$::tcl_platform(user)*"]
} -match glob -result [gethomedirglob $::tcl_platform(user)]
test fCmd-31.7 {file home UNKNOWNUSER} -body {
file home nosuchuser
} -returnCodes error -result {user "nosuchuser" doesn't exist}
test fCmd-31.8 {file home extra arg} -body {
file home $::tcl_platform(user) arg
} -returnCodes error -result {wrong # args: should be "file home ?user?"}
test fCmd-31.9 {file home USER does not follow env(HOME)} -setup {
set ::env(HOME) [file join $::env(HOME) foo]
} -cleanup {
set ::env(HOME) [file dirname $::env(HOME)]
} -body {
string tolower [file home $::tcl_platform(user)]
} -match glob -result [gethomedirglob $::tcl_platform(user)]
test fCmd-32.1 {file tildeexpand ~} -body {
file tildeexpand ~
@@ -2641,7 +2703,7 @@ test fCmd-32.5 {file tildeexpand ~USER} -body {
# env(HOME) even when user is current user. Assume result contains user
# name, else not sure how to check
string tolower [file tildeexpand ~$::tcl_platform(user)]
} -match glob -result [string tolower "*$::tcl_platform(user)*"]
} -match glob -result [gethomedirglob $::tcl_platform(user)]
test fCmd-32.6 {file tildeexpand ~UNKNOWNUSER} -body {
file tildeexpand ~nosuchuser
} -returnCodes error -result {user "nosuchuser" doesn't exist}
@@ -2656,7 +2718,7 @@ test fCmd-32.9 {file tildeexpand ~USER/bar} -body {
# env(HOME) even when user is current user. Assume result contains user
# name, else not sure how to check
string tolower [file tildeexpand ~$::tcl_platform(user)/bar]
} -match glob -result [string tolower "*$::tcl_platform(user)*/bar"]
} -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar]
test fCmd-32.10 {file tildeexpand ~UNKNOWNUSER} -body {
file tildeexpand ~nosuchuser/foo
} -returnCodes error -result {user "nosuchuser" doesn't exist}
@@ -2680,7 +2742,14 @@ test fCmd-32.16 {file tildeexpand ~USER\\bar} -body {
# env(HOME) even when user is current user. Assume result contains user
# name, else not sure how to check
string tolower [file tildeexpand ~$::tcl_platform(user)\\bar]
} -constraints win -match glob -result [string tolower "*$::tcl_platform(user)*/bar"]
} -constraints win -match glob -result [file join [gethomedirglob $::tcl_platform(user)] bar]
test fCmd-32.17 {file tildeexpand ~USER does not mirror HOME} -setup {
set ::env(HOME) [file join $::env(HOME) foo]
} -cleanup {
set ::env(HOME) [file dirname $::env(HOME)]
} -body {
string tolower [file tildeexpand ~$::tcl_platform(user)]
} -match glob -result [gethomedirglob $::tcl_platform(user)]
# cleanup
+10
View File
@@ -276,6 +276,16 @@ test filesystem-1.30.1 {normalisation of existing user} -body {
test filesystem-1.30.2 {normalisation of nonexistent user specified as user@domain} -body {
file normalize ~nonexistentuser@nonexistentdomain
} -returnCodes error -result {user "nonexistentuser@nonexistentdomain" doesn't exist}
test filesystem-1.30.3 {file normalization should distinguish between ~ and ~user} -setup {
set oldhome $::env(HOME)
set olduserhome [file normalize ~$::tcl_platform(user)]
set ::env(HOME) [file join $oldhome temp]
} -cleanup {
set env(HOME) $oldhome
} -body {
list [string equal [file normalize ~] $::env(HOME)] \
[string equal $olduserhome [file normalize ~$::tcl_platform(user)]]
} -result {1 1}
test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
testsetplatform unix
file normalize /foo/../bar
File diff suppressed because it is too large Load Diff
+142 -75
View File
@@ -48,6 +48,8 @@ testConstraint testservicemode [llength [info commands testservicemode]]
testConstraint notWinCI [expr {
$::tcl_platform(platform) ne "windows" || ![info exists ::env(CI)]}]
testConstraint notOSX [expr {$::tcl_platform(os) ne "Darwin"}]
# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]
# You need a *very* special environment to do some tests. In
# particular, many file systems do not support large-files...
@@ -272,7 +274,7 @@ test io-3.4 {WriteChars: loop over stage buffer} -body {
# stage buffer maps to more than can be queued at once.
set f [open $path(test1) w]
fconfigure $f -encoding jis0208 -buffersize 16 -nocomplainencoding 1
fconfigure $f -encoding jis0208 -buffersize 16 -profile tcl8
puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
close $f
@@ -286,7 +288,7 @@ test io-3.5 {WriteChars: saved != 0} -body {
# requested buffersize.
set f [open $path(test1) w]
fconfigure $f -encoding jis0208 -buffersize 17 -nocomplainencoding 1
fconfigure $f -encoding jis0208 -buffersize 17 -profile tcl8
puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
close $f
@@ -319,7 +321,7 @@ test io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} -body {
# of the next channel buffer.
set f [open $path(test1) w]
fconfigure $f -encoding jis0208 -buffersize 17 -nocomplainencoding 1
fconfigure $f -encoding jis0208 -buffersize 17 -profile tcl8
puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
set x [list [contents $path(test1)]]
close $f
@@ -5474,7 +5476,7 @@ test io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
# This test crashes the interp if Bug #427196 is not fixed
set chan [open [info script] r]
fconfigure $chan -buffersize 10
fconfigure $chan -buffersize 10 -encoding utf-8
set var [read $chan 2]
fconfigure $chan -buffersize 32
append var [read $chan]
@@ -5675,13 +5677,23 @@ test io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
close $f
set x
} 牦
test io-39.16 {Tcl_SetChannelOption: -encoding, errors} {
# Remove knownProfileBug constraint below post TIP656- TODO
test io-39.16 {Tcl_SetChannelOption: -encoding (shortened to "-en"), errors} -constraints {
knownProfileBug
} -body {
file delete $path(test1)
set f [open $path(test1) w]
set result [list [catch {fconfigure $f -encoding foobar} msg] $msg]
fconfigure $f -en foobar
} -cleanup {
close $f
set result
} {1 {unknown encoding "foobar"}}
} -returnCodes 1 -result {unknown encoding "foobar"}
test io-39.16a {Tcl_SetChannelOption: -encoding (invalid shortening to "-e"), errors} -body {
file delete $path(test1)
set f [open $path(test1) w]
fconfigure $f -e foobar
} -cleanup {
close $f
} -returnCodes 1 -match glob -result {bad option "-e": should be one of *}
test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} {stdio fileevent} {
set f [open "|[list [interpreter] $path(cat)]" r+]
fconfigure $f -encoding binary
@@ -5813,7 +5825,7 @@ test io-40.1 {POSIX open access modes: RDWR} {
close $f
set x
} {zzy abzzy}
test io-40.2 {POSIX open access modes: CREAT} {unix} {
test io-40.2 {POSIX open access modes: CREAT} {unix notWsl} {
file delete $path(test3)
set f [open $path(test3) {WRONLY CREAT} 0o600]
file stat $path(test3) stats
@@ -5825,7 +5837,7 @@ test io-40.2 {POSIX open access modes: CREAT} {unix} {
close $f
set x
} {0o600 {line 1}}
test io-40.3 {POSIX open access modes: CREAT} {unix umask} {
test io-40.3 {POSIX open access modes: CREAT} {unix umask notWsl} {
# This test only works if your umask is 2, like ouster's.
file delete $path(test3)
set f [open $path(test3) {WRONLY CREAT}]
@@ -7280,8 +7292,8 @@ test io-52.5 {TclCopyChannel, all} {fcopy} {
file delete $path(test1)
set f1 [open $thisScript]
set f2 [open $path(test1) w]
fconfigure $f1 -translation lf -blocking 0
fconfigure $f2 -translation lf -blocking 0
fconfigure $f1 -translation lf -encoding iso8859-1 -blocking 0
fconfigure $f2 -translation lf -encoding iso8859-1 -blocking 0
fcopy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
close $f1
@@ -7297,8 +7309,8 @@ test io-52.5a {TclCopyChannel, all, other negative value} {fcopy} {
file delete $path(test1)
set f1 [open $thisScript]
set f2 [open $path(test1) w]
fconfigure $f1 -translation lf -blocking 0
fconfigure $f2 -translation lf -blocking 0
fconfigure $f1 -translation lf -encoding iso8859-1 -blocking 0
fconfigure $f2 -translation lf -encoding iso8859-1 -blocking 0
fcopy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
close $f1
@@ -7314,8 +7326,8 @@ test io-52.5b {TclCopyChannel, all, wrap to negative value} {fcopy} {
file delete $path(test1)
set f1 [open $thisScript]
set f2 [open $path(test1) w]
fconfigure $f1 -translation lf -blocking 0
fconfigure $f2 -translation lf -blocking 0
fconfigure $f1 -translation lf -encoding iso8859-1 -blocking 0
fconfigure $f2 -translation lf -encoding iso8859-1 -blocking 0
fcopy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
close $f1
@@ -7348,8 +7360,8 @@ test io-52.7 {TclCopyChannel} {fcopy} {
file delete $path(test1)
set f1 [open $thisScript]
set f2 [open $path(test1) w]
fconfigure $f1 -translation lf -blocking 0
fconfigure $f2 -translation lf -blocking 0
fconfigure $f1 -translation lf -encoding iso8859-1 -blocking 0
fconfigure $f2 -translation lf -encoding iso8859-1 -blocking 0
fcopy $f1 $f2
set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
set s1 [file size $thisScript]
@@ -7609,6 +7621,103 @@ test io-52.19 {coverage of eofChar handling} {
close $out
file size $path(test2)
} 8
test io-52.20 {TclCopyChannel & encodings} -setup {
set out [open $path(utf8-fcopy.txt) w]
fconfigure $out -encoding utf-8 -translation lf
puts $out "Á"
close $out
} -constraints {fcopy} -body {
# binary to encoding => the input has to be
# in utf-8 to make sense to the encoder
set in [open $path(utf8-fcopy.txt) r]
set out [open $path(kyrillic.txt) w]
# Using "-encoding ascii" means reading the "Á" gives an error
fconfigure $in -encoding ascii -profile strict
fconfigure $out -encoding koi8-r -translation lf
fcopy $in $out
} -cleanup {
close $in
close $out
} -returnCodes 1 -match glob -result {error reading "file*": illegal byte sequence}
test io-52.21 {TclCopyChannel & encodings} -setup {
set out [open $path(utf8-fcopy.txt) w]
fconfigure $out -encoding utf-8 -translation lf
puts $out "Á"
close $out
} -constraints {fcopy} -body {
# binary to encoding => the input has to be
# in utf-8 to make sense to the encoder
set in [open $path(utf8-fcopy.txt) r]
set out [open $path(kyrillic.txt) w]
# Using "-encoding ascii" means writing the "Á" gives an error
fconfigure $in -encoding utf-8
fconfigure $out -encoding ascii -translation lf -profile strict
fcopy $in $out
} -cleanup {
close $in
close $out
} -returnCodes 1 -match glob -result {error writing "file*": illegal byte sequence}
test io-52.22 {TclCopyChannel & encodings} -setup {
set out [open $path(utf8-fcopy.txt) w]
fconfigure $out -encoding utf-8 -translation lf
puts $out "Á"
close $out
} -constraints {fcopy} -body {
# binary to encoding => the input has to be
# in utf-8 to make sense to the encoder
set in [open $path(utf8-fcopy.txt) r]
set out [open $path(kyrillic.txt) w]
# Using "-encoding ascii" means reading the "Á" gives an error
fconfigure $in -encoding ascii -profile strict
fconfigure $out -encoding koi8-r -translation lf
proc ::xxx args {
set ::s0 $args
}
fcopy $in $out -command ::xxx
vwait ::s0
set ::s0
} -cleanup {
close $in
close $out
unset ::s0
} -match glob -result {0 {error reading "file*": illegal byte sequence}}
test io-52.23 {TclCopyChannel & encodings} -setup {
set out [open $path(utf8-fcopy.txt) w]
fconfigure $out -encoding utf-8 -translation lf
puts $out "Á"
close $out
} -constraints {fcopy} -body {
# binary to encoding => the input has to be
# in utf-8 to make sense to the encoder
set in [open $path(utf8-fcopy.txt) r]
set out [open $path(kyrillic.txt) w]
# Using "-encoding ascii" means writing the "Á" gives an error
fconfigure $in -encoding utf-8
fconfigure $out -encoding ascii -translation lf -profile strict
proc ::xxx args {
set ::s0 $args
}
fcopy $in $out -command ::xxx
vwait ::s0
set ::s0
} -cleanup {
close $in
close $out
unset ::s0
} -match glob -result {0 {error writing "file*": illegal byte sequence}}
test io-53.1 {CopyData} {fcopy} {
file delete $path(test1)
@@ -8964,7 +9073,7 @@ test io-75.1 {multibyte encoding error read results in raw bytes} -setup {
puts -nonewline $f A\xC0\x40
flush $f
seek $f 0
fconfigure $f -encoding utf-8 -nocomplainencoding 1 -buffering none
fconfigure $f -encoding utf-8 -profile tcl8 -buffering none
} -body {
set d [read $f]
binary scan $d H* hd
@@ -8974,10 +9083,10 @@ test io-75.1 {multibyte encoding error read results in raw bytes} -setup {
removeFile io-75.1
} -result 41c040
test io-75.2 {unrepresentable character write passes and is replaced by ? (-nocomplainencoding 1)} -setup {
test io-75.2 {unrepresentable character write passes and is replaced by ? (-profile tcl8)} -setup {
set fn [makeFile {} io-75.2]
set f [open $fn w+]
fconfigure $f -encoding iso8859-1 -nocomplainencoding 1
fconfigure $f -encoding iso8859-1 -profile tcl8
} -body {
puts -nonewline $f A\u2022
flush $f
@@ -8991,14 +9100,14 @@ test io-75.2 {unrepresentable character write passes and is replaced by ? (-noco
# Incomplete sequence test.
# This error may IMHO only be detected with the close.
# But the read already returns the incomplete sequence.
test io-75.3 {incomplete multibyte encoding read is ignored (-nocomplainencoding 1)} -setup {
test io-75.3 {incomplete multibyte encoding read is ignored (-profile tcl8)} -setup {
set fn [makeFile {} io-75.3]
set f [open $fn w+]
fconfigure $f -encoding binary
puts -nonewline $f "A\xC0"
flush $f
seek $f 0
fconfigure $f -encoding utf-8 -buffering none -nocomplainencoding 1
fconfigure $f -encoding utf-8 -buffering none -profile tcl8
} -body {
set d [read $f]
close $f
@@ -9010,7 +9119,7 @@ test io-75.3 {incomplete multibyte encoding read is ignored (-nocomplainencoding
# As utf-8 has a special treatment in multi-byte decoding, also test another
# one.
test io-75.4 {shiftjis encoding error read results in raw bytes (-nocomplainencoding 1)} -setup {
test io-75.4 {shiftjis encoding error read results in raw bytes (-profile tcl8)} -setup {
set fn [makeFile {} io-75.4]
set f [open $fn w+]
fconfigure $f -encoding binary
@@ -9019,7 +9128,7 @@ test io-75.4 {shiftjis encoding error read results in raw bytes (-nocomplainenco
puts -nonewline $f A\x81\xFFA
flush $f
seek $f 0
fconfigure $f -encoding shiftjis -buffering none -eofchar "" -translation lf -nocomplainencoding 1
fconfigure $f -encoding shiftjis -buffering none -eofchar "" -translation lf -profile tcl8
} -body {
set d [read $f]
binary scan $d H* hd
@@ -9029,14 +9138,14 @@ test io-75.4 {shiftjis encoding error read results in raw bytes (-nocomplainenco
removeFile io-75.4
} -result 4181ff41
test io-75.5 {invalid utf-8 encoding read is ignored (-nocomplainencoding 1)} -setup {
test io-75.5 {invalid utf-8 encoding read is ignored (-profile tcl8)} -setup {
set fn [makeFile {} io-75.5]
set f [open $fn w+]
fconfigure $f -encoding binary
puts -nonewline $f A\x81
flush $f
seek $f 0
fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -nocomplainencoding 1
fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -profile tcl8
} -body {
set d [read $f]
close $f
@@ -9046,49 +9155,7 @@ test io-75.5 {invalid utf-8 encoding read is ignored (-nocomplainencoding 1)} -s
removeFile io-75.5
} -result 4181
test io-75.6 {invalid utf-8 encoding read is not ignored (-strictencoding 1)} -setup {
set fn [makeFile {} io-75.6]
set f [open $fn w+]
fconfigure $f -encoding binary
# \x81 is invalid in utf-8
puts -nonewline $f A\x81
flush $f
seek $f 0
fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -strictencoding 1
} -body {
set d [read $f]
binary scan $d H* hd
lappend hd [catch {read $f} msg]
close $f
lappend hd $msg
} -cleanup {
removeFile io-75.6
} -match glob -result {41 1 {error reading "*": illegal byte sequence}}
test io-75.7 {invalid utf-8 encoding eof handling (-strictencoding 1)} -setup {
set fn [makeFile {} io-75.7]
set f [open $fn w+]
fconfigure $f -encoding binary
# \xA1 is invalid in utf-8. -eofchar is not detected, because it comes later.
puts -nonewline $f A\xA1\x1A
flush $f
seek $f 0
fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A -translation lf -strictencoding 1
} -body {
set d [read $f]
binary scan $d H* hd
lappend hd [eof $f]
lappend hd [catch {read $f} msg]
lappend hd $msg
fconfigure $f -encoding iso8859-1
lappend hd [read $f];# We changed encoding, so now we can read the \xA1
close $f
set hd
} -cleanup {
removeFile io-75.7
} -match glob -result {41 0 1 {error reading "*": illegal byte sequence} ¡}
test io-75.8 {invalid utf-8 encoding eof handling (-strictencoding 1)} -setup {
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
@@ -9096,7 +9163,7 @@ test io-75.8 {invalid utf-8 encoding eof handling (-strictencoding 1)} -setup {
puts -nonewline $f A\x1A\x81
flush $f
seek $f 0
fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A -translation lf -strictencoding 1
fconfigure $f -encoding utf-8 -buffering none -eofchar \x1A -translation lf -profile strict
} -body {
set d [read $f]
binary scan $d H* hd
@@ -9111,7 +9178,7 @@ test io-75.8 {invalid utf-8 encoding eof handling (-strictencoding 1)} -setup {
test io-75.9 {unrepresentable character write passes and is replaced by ?} -setup {
set fn [makeFile {} io-75.9]
set f [open $fn w+]
fconfigure $f -encoding iso8859-1 -strictencoding 1
fconfigure $f -encoding iso8859-1 -profile strict
} -body {
catch {puts -nonewline $f "A\u2022"} msg
flush $f
@@ -9155,7 +9222,7 @@ 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 -strictencoding 1
fconfigure $f -encoding shiftjis -buffering none -eofchar "" -translation lf -profile strict
} -body {
set d [read $f]
binary scan $d H* hd
@@ -9182,7 +9249,7 @@ test io-75.12 {invalid utf-8 encoding read is ignored} -setup {
} -cleanup {
removeFile io-75.12
} -result 4181
test io-75.13 {invalid utf-8 encoding read is not ignored (-strictencoding 1)} -setup {
test io-75.13 {invalid utf-8 encoding read is not ignored (-profile strict)} -setup {
set fn [makeFile {} io-75.13]
set f [open $fn w+]
fconfigure $f -encoding binary
@@ -9190,7 +9257,7 @@ test io-75.13 {invalid utf-8 encoding read is not ignored (-strictencoding 1)} -
puts -nonewline $f "A\x81"
flush $f
seek $f 0
fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -strictencoding 1
fconfigure $f -encoding utf-8 -buffering none -eofchar "" -translation lf -profile strict
} -body {
set d [read $f]
binary scan $d H* hd
+27 -11
View File
@@ -207,7 +207,7 @@ test iocmd-7.5 {close command} -setup {
proc expectedOpts {got extra} {
set basicOpts {
-blocking -buffering -buffersize -encoding -eofchar -nocomplainencoding -strictencoding -translation
-blocking -buffering -buffersize -encoding -eofchar -profile -translation
}
set opts [list {*}$basicOpts {*}$extra]
lset opts end [string cat "or " [lindex $opts end]]
@@ -240,33 +240,33 @@ test iocmd-8.7 {fconfigure command} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
fconfigure $f1 -translation lf -eofchar {} -encoding utf-16 -nocomplainencoding 1
fconfigure $f1 -translation lf -eofchar {} -encoding utf-16 -profile tcl8
fconfigure $f1
} -cleanup {
catch {close $f1}
} -result {-blocking 1 -buffering full -buffersize 4096 -encoding utf-16 -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf}
} -result {-blocking 1 -buffering full -buffersize 4096 -encoding utf-16 -eofchar {} -profile tcl8 -translation lf}
test iocmd-8.8 {fconfigure command} -setup {
file delete $path(test1)
set x {}
} -body {
set f1 [open $path(test1) w]
fconfigure $f1 -translation lf -buffering line -buffersize 3030 \
-eofchar {} -encoding utf-16 -nocomplainencoding 1
-eofchar {} -encoding utf-16 -profile tcl8
lappend x [fconfigure $f1 -buffering]
lappend x [fconfigure $f1]
} -cleanup {
catch {close $f1}
} -result {line {-blocking 1 -buffering line -buffersize 3030 -encoding utf-16 -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf}}
} -result {line {-blocking 1 -buffering line -buffersize 3030 -encoding utf-16 -eofchar {} -profile tcl8 -translation lf}}
test iocmd-8.9 {fconfigure command} -setup {
file delete $path(test1)
} -body {
set f1 [open $path(test1) w]
fconfigure $f1 -translation binary -buffering none -buffersize 4040 \
-eofchar {} -encoding binary -nocomplainencoding 1
-eofchar {} -encoding binary -profile tcl8
fconfigure $f1
} -cleanup {
catch {close $f1}
} -result {-blocking 1 -buffering none -buffersize 4040 -encoding binary -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf}
} -result {-blocking 1 -buffering none -buffersize 4040 -encoding binary -eofchar {} -profile tcl8 -translation lf}
test iocmd-8.10 {fconfigure command} -returnCodes error -body {
fconfigure a b
} -result {can not find channel named "a"}
@@ -369,15 +369,31 @@ test iocmd-8.20 {fconfigure command / win console channel} -constraints {nonPort
# TODO: Test parsing of serial channel options (nonPortable, since requires an
# open channel to work with).
test iocmd-8.21 {fconfigure command / -nocomplainencoding 0 error} -constraints {
deprecated
deprecated obsolete
} -setup {
# I don't know how else to open the console, but this is non-portable
set console stdin
} -body {
fconfigure $console -nocomplainencoding 0
} -returnCodes error -result "bad value for -nocomplainencoding: only true allowed"
test iocmd-8.22 {fconfigure command / -nocomplainencoding 0, no error if -strictencoding already defined} -setup {
set console stdin
set oldprofile [fconfigure $console -profile]
} -constraints {
obsolete
} -body {
fconfigure $console -strictencoding 1
fconfigure $console -nocomplainencoding 0
fconfigure $console -nocomplainencoding
} -cleanup {
fconfigure $console -strictencoding $oldmode
} -result 0
test iocmd-8.21 {fconfigure -profile badprofile} -body {
fconfigure stdin -profile froboz
} -returnCodes error -result {bad profile name "froboz": must be replace, strict, or tcl8}
test iocmd-9.1 {eof command} {
list [catch {eof} msg] $msg $::errorCode
} {1 {wrong # args: should be "eof channelId"} {TCL WRONGARGS}}
@@ -1371,7 +1387,7 @@ test iocmd-25.1 {chan configure, cgetall, standard options} -match glob -body {
close $c
rename foo {}
set res
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -nocomplainencoding * -strictencoding 0 -translation {auto *}}}
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -profile * -translation {auto *}}}
test iocmd-25.2 {chan configure, cgetall, no options} -match glob -body {
set res {}
proc foo {args} {oninit cget cgetall; onfinal; track; return ""}
@@ -1380,7 +1396,7 @@ test iocmd-25.2 {chan configure, cgetall, no options} -match glob -body {
close $c
rename foo {}
set res
} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -nocomplainencoding * -strictencoding 0 -translation {auto *}}}
} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -profile * -translation {auto *}}}
test iocmd-25.3 {chan configure, cgetall, regular result} -match glob -body {
set res {}
proc foo {args} {
@@ -1392,7 +1408,7 @@ test iocmd-25.3 {chan configure, cgetall, regular result} -match glob -body {
close $c
rename foo {}
set res
} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -nocomplainencoding * -strictencoding 0 -translation {auto *} -bar foo -snarf x}}
} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -profile * -translation {auto *} -bar foo -snarf x}}
test iocmd-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
set res {}
proc foo {args} {
+88 -1
View File
@@ -634,6 +634,61 @@ test iortrans-4.9 {chan read, gets, bug 2921116} -setup {
}
}
namespace eval reflector {
proc initialize {_ chan mode} {
return {initialize finalize watch read}
}
proc finalize {_ chan} {
foreach id [after info] {
after cancel $id
}
namespace delete $_
}
proc read {_ chan count} {
namespace upvar $_ source source
set res [string range $source 0 $count-1]
set source [string range $source $count end]
return $res
}
proc watch {_ chan events} {
after 0 [list chan postevent $chan read]
return read
}
namespace ensemble create -parameters _
namespace export *
}
namespace eval inputfilter {
proc initialize {chan mode} {
return {initialize finalize read}
}
proc read {chan buffer} {
return $buffer
}
proc finalize chan {
namespace delete $chan
}
namespace ensemble create
namespace export *
}
# Channel read transform that is just the identity - pass all through
proc idxform {cmd handle args} {
switch -- $cmd {
@@ -2089,7 +2144,39 @@ test iortrans.tf-11.1 {origin thread of moved transform destroyed during access}
thread::release $tidb
} -result {Owner lost}
# ### ### ### ######### ######### #########
test iortrans-ea69b0258a9833cb {
Crash when using a channel transformation on TCP client socket
"line two" does not make it into result. This issue should probably be
addressed, but it is outside the scope of this test.
} -setup {
set res {}
set read 0
} -body {
namespace eval reflector1 {
variable source "line one\nline two"
interp alias {} [namespace current]::dispatch {} [
namespace parent]::reflector [namespace current]
}
set chan [chan create read [namespace which reflector1::dispatch]]
chan configure $chan -blocking 0
chan push $chan inputfilter
chan event $chan read [list ::apply [list chan {
variable res
variable read
set gets [gets $chan]
append res $gets
incr read
} [namespace current]] $chan]
vwait [namespace current]::read
chan pop $chan
vwait [namespace current]::read
return $res
} -cleanup {
catch {unset read}
close $chan
} -result {line one}
cleanupTests
return
+4 -4
View File
@@ -1473,7 +1473,7 @@ test safe-11.7 {testing safe encoding} -setup {
interp eval $i encoding convertfrom
} -returnCodes error -cleanup {
safe::interpDelete $i
} -result {wrong # args: should be "encoding convertfrom ?-strict? ?-failindex var? ?encoding? data" or "encoding convertfrom -nocomplain ?encoding? data"}
} -result {wrong # args: should be "encoding convertfrom ?-profile profile? ?-failindex var? encoding data" or "encoding convertfrom data"}
test safe-11.7.1 {testing safe encoding} -setup {
set i [safe::interpCreate]
} -body {
@@ -1482,7 +1482,7 @@ test safe-11.7.1 {testing safe encoding} -setup {
} -match glob -cleanup {
unset -nocomplain m o
safe::interpDelete $i
} -result {wrong # args: should be "encoding convertfrom ?-strict? ?-failindex var? ?encoding? data" or "encoding convertfrom -nocomplain ?encoding? data"
} -result {wrong # args: should be "encoding convertfrom ?-profile profile? ?-failindex var? encoding data" or "encoding convertfrom data"
while executing
"encoding convertfrom"
invoked from within
@@ -1495,7 +1495,7 @@ test safe-11.8 {testing safe encoding} -setup {
interp eval $i encoding convertto
} -returnCodes error -cleanup {
safe::interpDelete $i
} -result {wrong # args: should be "encoding convertto ?-strict? ?-failindex var? ?encoding? data" or "encoding convertto -nocomplain ?encoding? data"}
} -result {wrong # args: should be "encoding convertto ?-profile profile? ?-failindex var? encoding data" or "encoding convertto data"}
test safe-11.8.1 {testing safe encoding} -setup {
set i [safe::interpCreate]
} -body {
@@ -1504,7 +1504,7 @@ test safe-11.8.1 {testing safe encoding} -setup {
} -match glob -cleanup {
unset -nocomplain m o
safe::interpDelete $i
} -result {wrong # args: should be "encoding convertto ?-strict? ?-failindex var? ?encoding? data" or "encoding convertto -nocomplain ?encoding? data"
} -result {wrong # args: should be "encoding convertto ?-profile profile? ?-failindex var? encoding data" or "encoding convertto data"
while executing
"encoding convertto"
invoked from within
+1 -1
View File
@@ -1071,7 +1071,7 @@ test socket_$af-7.3 {testing socket specific options} -constraints [list socket
close $s
update
llength $l
} -result 22
} -result 20
test socket_$af-7.4 {testing socket specific options} -constraints [list socket supported_$af] -setup {
set timer [after 10000 "set x timed_out"]
set l ""
+3 -3
View File
@@ -69,8 +69,8 @@ test stringObj-4.2 {Tcl_SetObjLength procedure, string gets longer} {testobj dep
testobj freeallvars
teststringobj set 1 abcdef
teststringobj setlength 1 10
list [teststringobj length 1] [teststringobj length2 1]
} {10 10}
teststringobj length 1
} 10
test stringObj-4.3 {Tcl_SetObjLength procedure, string gets longer} {testobj utf32 deprecated} {
testobj freeallvars
teststringobj set 1 abcdef
@@ -78,7 +78,7 @@ test stringObj-4.3 {Tcl_SetObjLength procedure, string gets longer} {testobj utf
list [teststringobj length 1] [teststringobj length2 1] \
[teststringobj get 1]
} {10 10 abcdefxyzq}
test stringObj-4.4 {Tcl_SetObjLength procedure, "expty string", length 0} {testobj deprecated} {
test stringObj-4.4 {Tcl_SetObjLength procedure, "empty string", length 0} {testobj deprecated} {
testobj freeallvars
testobj newobj 1
teststringobj setlength 1 0
+8 -5
View File
@@ -22,6 +22,9 @@ if {"::tcltest" ni [namespace children]} {
namespace import -force ::tcltest::*
}
# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]
namespace eval ::tcltest::test {
namespace import ::tcltest::*
@@ -306,7 +309,7 @@ test tcltest-5.3 {testConstraint - constraint empty (tcltest::safeFetch)} {
#}
test tcltest-5.5 {InitConstraints: list of built-in constraints} \
-constraints {!singleTestInterp} \
-constraints {!singleTestInterp notWsl} \
-setup {tcltest::InitConstraints} \
-body { lsort [array names ::tcltest::testConstraints] } \
-result [lsort {
@@ -552,11 +555,11 @@ switch -- $::tcl_platform(platform) {
default {
# note in FAT/NTFS we won't be able to protect directory with read-only attribute...
catch {file attributes $notWriteableDir -readonly 1}
catch {testchmod 0 $notWriteableDir}
catch {testchmod 0o444 $notWriteableDir}
}
}
test tcltest-8.3 {tcltest a.tcl -tmpdir notReadableDir} {
-constraints {unix notRoot}
-constraints {unix notRoot notWsl}
-body {
child msg $a -tmpdir $notReadableDir
return $msg
@@ -572,7 +575,7 @@ testConstraint notFAT [expr {
}]
# FAT/NTFS permissions are fairly hopeless; ignore this test if that FS is used
test tcltest-8.4 {tcltest a.tcl -tmpdir notWriteableDir} {
-constraints {unixOrWin notRoot notFAT}
-constraints {unixOrWin notRoot notFAT notWsl}
-body {
child msg $a -tmpdir $notWriteableDir
return $msg
@@ -645,7 +648,7 @@ test tcltest-8.11 {tcltest a.tcl -testdir thisdirectoryisafile} {
-result {*not a directory*}
}
test tcltest-8.12 {tcltest a.tcl -testdir notReadableDir} {
-constraints {unix notRoot}
-constraints {unix notRoot notWsl}
-body {
child msg $a -testdir $notReadableDir
return $msg
+7 -5
View File
@@ -18,6 +18,8 @@ if {"::tcltest" ni [namespace children]} {
catch [list package require -exact tcl::test [info patchlevel]]
testConstraint testchmod [llength [info commands testchmod]]
# File permissions broken on wsl without some "exotic" wsl configuration
testConstraint notWsl [expr {[llength [array names ::env *WSL*]] == 0}]
# These tests really need to be run from a writable directory, which
# it is assumed [temporaryDirectory] is.
@@ -94,7 +96,7 @@ if {[testConstraint unix] && [testConstraint notRoot]} {
test unixFCmd-1.1 {TclpRenameFile: EACCES} -setup {
cleanup
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir td1/td2/td3
file attributes td1/td2 -permissions 0
file rename td1/td2/td3 td2
@@ -135,7 +137,7 @@ test unixFCmd-1.6 {TclpRenameFile: ENOTDIR} {emptyTest unix notRoot} {
} {}
test unixFCmd-1.7 {TclpRenameFile: EXDEV} -setup {
cleanup
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
file mkdir foo/bar
file attr foo -perm 0o40555
file rename foo/bar /tmp
@@ -219,7 +221,7 @@ test unixFCmd-2.4 {TclpCopyFile: src is fifo} -setup {
} -result {fifo fifo}
test unixFCmd-2.5 {TclpCopyFile: copy attributes} -setup {
cleanup
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
close [open tf1 a]
file attributes tf1 -permissions 0o472
file copy tf1 tf2
@@ -334,7 +336,7 @@ test unixFCmd-16.3 {SetOwnerAttribute - invalid owner} -setup {
test unixFCmd-17.1 {SetPermissionsAttribute} -setup {
catch {file delete -force -- foo.test}
} -constraints {unix notRoot} -body {
} -constraints {unix notRoot notWsl} -body {
close [open foo.test w]
list [file attributes foo.test -permissions 0] \
[file attributes foo.test -permissions]
@@ -366,7 +368,7 @@ test unixFCmd-17.4 {SetPermissionsAttribute} -setup {
close [open foo.test w]
set ::i 4
proc permcheck {testnum permList expected} {
test $testnum {SetPermissionsAttribute} {unix notRoot} {
test $testnum {SetPermissionsAttribute} {unix notRoot notWsl} {
set result {}
foreach permstr $permList {
file attributes foo.test -permissions $permstr
+101
View File
@@ -0,0 +1,101 @@
# This file contains a collection of tests for Tcl_UtfToExternal and
# Tcl_UtfToExternal. Sourcing this file into Tcl runs the tests and generates
# errors. No output means no errors found.
#
# Copyright (c) 2023 Ashok P. Nadkarni
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
if {"::tcltest" ni [namespace children]} {
package require tcltest 2.5
namespace import -force ::tcltest::*
}
::tcltest::loadTestedCommands
catch [list package require -exact tcl::test [info patchlevel]]
testConstraint testbytestring [llength [info commands testbytestring]]
testConstraint testencoding [llength [info commands testencoding]]
# Maps encoded bytes string to utf-8 equivalents, both in hex
# encoding utf-8 encdata
lappend utfExtMap {*}{
ascii 414243 414243
}
if {[info commands printable] eq ""} {
proc printable {s} {
set print ""
foreach c [split $s ""] {
set i [scan $c %c]
if {[string is print $c] && ($i <= 127)} {
append print $c
} elseif {$i <= 0xff} {
append print \\x[format %02X $i]
} elseif {$i <= 0xffff} {
append print \\u[format %04X $i]
} else {
append print \\U[format %08X $i]
}
}
return $print
}
}
# Simple test with basic flags
proc testbasic {direction enc hexin hexout {flags {start end}}} {
if {$direction eq "toutf"} {
set cmd Tcl_ExternalToUtf
} else {
set cmd Tcl_UtfToExternal
}
set in [binary decode hex $hexin]
set out [binary decode hex $hexout]
set dstlen 40 ;# Should be enough for all encoding tests
# The C wrapper fills entire destination buffer with FF.
# Anything beyond expected output should have FF's
set filler [string repeat \xFF $dstlen]
set result [string range "$out$filler" 0 $dstlen-1]
test $cmd-$enc-$hexin-[join $flags -] "$cmd - $enc - $hexin - $flags" -body \
[list testencoding $cmd $enc $in $flags {} $dstlen] \
-result [list ok {} $result]
foreach profile [encoding profiles] {
set flags2 [linsert $flags end profile$profile]
test $cmd-$enc-$hexin-[join $flags2 -] "$cmd - $enc - $hexin - $flags" -body \
[list testencoding $cmd $enc $in $flags2 {} $dstlen] \
-result [list ok {} $result]
}
}
#
# Basic tests
foreach {enc utfhex hex} $utfExtMap {
# Basic test - TCL_ENCODING_START|TCL_ENCODING_END
# Note by default output should be terminated with \0
testbasic toutf $enc $hex ${utfhex}00 {start end}
testbasic fromutf $enc $utfhex ${hex}00 {start end}
# Test TCL_ENCODING_NO_TERMINATE
testbasic toutf $enc $hex $utfhex {start end noterminate}
# knownBug - noterminate not obeyed by fromutf
# testbasic fromutf $enc $utfhex $hex {start end noterminate}
}
# Test for insufficient space
test xx-bufferoverflow {buffer overflow Tcl_ExternalToUtf} -body {
testencoding Tcl_UtfToExternal ucs-2 A {start end} {} 1
} -result [list nospace {} \xFF]
# Another bug - char limit not obeyed
# % set cv 2
# % testencoding Tcl_ExternalToUtf utf-8 abcdefgh {start end noterminate charlimit} {} 20 rv wv cv
# nospace {} abcÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
::tcltest::cleanupTests
return
# Local Variables:
# mode: tcl
# End:
+7 -7
View File
@@ -198,7 +198,7 @@ test console-fconfigure-get-1.0 {
Console get stdin configuration
} -constraints {win interactive} -body {
lsort [dict keys [fconfigure stdin]]
} -result {-blocking -buffering -buffersize -encoding -eofchar -inputmode -translation}
} -result {-blocking -buffering -buffersize -encoding -eofchar -inputmode -profile -translation}
set testnum 0
foreach {opt result} {
@@ -224,7 +224,7 @@ test console-fconfigure-get-1.[incr testnum] {
fconfigure -winsize
} -constraints {win interactive} -body {
fconfigure stdin -winsize
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -nocomplainencoding, -strictencoding, -translation, or -inputmode} -returnCodes error
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, -translation, or -inputmode} -returnCodes error
## fconfigure get stdout/stderr
foreach chan {stdout stderr} major {2 3} {
@@ -232,7 +232,7 @@ foreach chan {stdout stderr} major {2 3} {
win interactive
} -body {
lsort [dict keys [fconfigure $chan]]
} -result {-blocking -buffering -buffersize -encoding -eofchar -translation -winsize}
} -result {-blocking -buffering -buffersize -encoding -eofchar -profile -translation -winsize}
set testnum 0
foreach {opt result} {
-blocking 1
@@ -260,7 +260,7 @@ foreach chan {stdout stderr} major {2 3} {
fconfigure -inputmode
} -constraints {win interactive} -body {
fconfigure $chan -inputmode
} -result {bad option "-inputmode": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -nocomplainencoding, -strictencoding, -translation, or -winsize} -returnCodes error
} -result {bad option "-inputmode": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, -translation, or -winsize} -returnCodes error
}
@@ -330,7 +330,7 @@ test console-fconfigure-set-1.3 {
fconfigure stdin -winsize
} -constraints {win interactive} -body {
fconfigure stdin -winsize {10 30}
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -nocomplainencoding, -strictencoding, -translation, or -inputmode} -returnCodes error
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, -translation, or -inputmode} -returnCodes error
## fconfigure set stdout,stderr
@@ -338,13 +338,13 @@ test console-fconfigure-set-2.0 {
fconfigure stdout -winsize
} -constraints {win interactive} -body {
fconfigure stdout -winsize {10 30}
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -nocomplainencoding, -strictencoding, or -translation} -returnCodes error
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -profile, or -translation} -returnCodes error
test console-fconfigure-set-3.0 {
fconfigure stderr -winsize
} -constraints {win interactive} -body {
fconfigure stderr -winsize {10 30}
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -nocomplainencoding, -strictencoding, or -translation} -returnCodes error
} -result {bad option "-winsize": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -profile, -translation} -returnCodes error
# Multiple threads
+62 -55
View File
@@ -45,15 +45,20 @@ proc contents {file} {
set r
}
proc cleanupRecurse {args} {
# Assumes no loops via links!
# Need to change permissions BEFORE deletion
testchmod 0o777 {*}$args
foreach victim $args {
if {[file isdirectory $victim]} {
cleanupRecurse {*}[glob -nocomplain -directory $victim td* tf* Test*]
}
file delete -force $victim
}
}
proc cleanup {args} {
foreach p ". $args" {
set x ""
catch {
set x [glob -directory $p tf* td*]
}
if {$x != ""} {
catch {file delete -force -- {*}$x}
}
foreach p [list [pwd] {*}$args] {
cleanupRecurse {*}[glob -nocomplain -directory $p tf* td*]
}
}
@@ -245,8 +250,9 @@ test winFCmd-1.23 {TclpRenameFile: move dir into self} -setup {
test winFCmd-1.24 {TclpRenameFile: move a root dir} -setup {
cleanup
} -constraints {win testfile} -body {
# Error code depends on Windows version
testfile mv / c:/
} -returnCodes error -result EINVAL
} -returnCodes error -result {^(EINVAL|ENOENT)$} -match regexp
test winFCmd-1.25 {TclpRenameFile: cross file systems} -setup {
cleanup
} -constraints {win cdrom testfile} -body {
@@ -379,12 +385,12 @@ test winFCmd-1.38 {TclpRenameFile: check rename of conflicting inodes} -setup {
cleanup
} -constraints {win winNonZeroInodes knownMsvcBug notInCIenv} -body {
file mkdir td1
foreach {a b} [MakeFiles td1] break
lassign [MakeFiles td1] a b
file rename -force $a $b
file exists $a
} -cleanup {
cleanup
} -result {0}
} -result 0
test winFCmd-2.1 {TclpCopyFile: errno: EACCES} -setup {
@@ -450,11 +456,11 @@ test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} -setup {
cleanup
} -constraints {win testfile} -body {
createfile tf1 tf1
testchmod 0 tf1
file attribute tf1 -readonly 1
testfile cp tf1 tf2
list [contents tf2] [file writable tf2]
} -cleanup {
catch {testchmod 0o666 tf1}
testchmod 0o660 tf1
cleanup
} -result {tf1 0}
test winFCmd-2.13 {TclpCopyFile: CopyFile fails} -setup {
@@ -496,11 +502,10 @@ test winFCmd-2.17 {TclpCopyFile: dst is readonly} -setup {
} -constraints {win testfile testchmod} -body {
createfile tf1 tf1
createfile tf2 tf2
testchmod 0 tf2
file attribute tf2 -readonly 1
testfile cp tf1 tf2
list [file writable tf2] [contents tf2]
} -cleanup {
catch {testchmod 0o666 tf2}
cleanup
} -result {1 tf1}
@@ -578,7 +583,6 @@ test winFCmd-3.11 {TclpDeleteFile: still can't remove path} -setup {
testfile rm tf1
} -cleanup {
close $fd
catch {testchmod 0o666 tf1}
cleanup
} -returnCodes error -result EACCES
@@ -617,15 +621,18 @@ test winFCmd-5.1 {TclpCopyDirectory: calls TraverseWinTree} -setup {
test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} -setup {
cleanup
} -constraints {win testfile testchmod knownMsvcBug notInCIenv} -body {
file mkdir td1
testchmod 0 td1
testfile rmdir td1
file exists td1
} -constraints {win testfile testchmod notInCIenv} -body {
# Parent's FILE_DELETE_CHILD setting permits deletion of subdir
# even when subdir DELETE mask is clear. So we need an intermediate
# parent td0 with FILE_DELETE_CHILD turned off while allowing R/W.
file mkdir td0/td1
testchmod 0o777 td0
testchmod 0 td0/td1
testfile rmdir td0/td1
file exists td0/td1
} -returnCodes error -cleanup {
catch {testchmod 0o666 td1}
cleanup
} -result {td1 EACCES}
} -result {td0/td1 EACCES}
# This next test has a very hokey way of matching...
test winFCmd-6.2 {TclpRemoveDirectory: errno: EEXIST} -setup {
cleanup
@@ -633,7 +640,7 @@ test winFCmd-6.2 {TclpRemoveDirectory: errno: EEXIST} -setup {
file mkdir td1/td2
list [catch {testfile rmdir td1} msg] [file tail $msg]
} -result {1 {td1 EEXIST}}
test winFCmd-6.3 {TclpRemoveDirectory: errno: EACCES} {win emptyTest} {
test winFCmd-6.3 {TclpRemoveDirectory: errno: EACCES} {win emptyTest trashSystem} {
# can't test this w/o removing everything on your hard disk first!
# testfile rmdir /
} {}
@@ -669,17 +676,7 @@ test winFCmd-6.8 {TclpRemoveDirectory: RemoveDirectory fails} -setup {
createfile tf1
list [catch {testfile rmdir tf1} msg] [file tail $msg]
} -result {1 {tf1 ENOTDIR}}
test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} -setup {
cleanup
} -constraints {win testfile testchmod knownMsvcBug notInCIenv} -body {
file mkdir td1
testchmod 0 td1
testfile rmdir td1
file exists td1
} -returnCodes error -cleanup {
catch {testchmod 0o666 td1}
cleanup
} -result {td1 EACCES}
# winFCmd-6.9 removed - was exact dup of winFCmd-6.1
test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup {
cleanup
} -constraints {win testfile notInCIenv} -body {
@@ -689,15 +686,19 @@ test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup {
} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup {
cleanup
} -constraints {win testfile testchmod knownMsvcBug notInCIenv} -body {
file mkdir td1
testchmod 0 td1
testfile rmdir td1
file exists td1
} -constraints {win testfile testchmod notInCIenv} -body {
# Parent's FILE_DELETE_CHILD setting permits deletion of subdir
# even when subdir DELETE mask is clear. So we need an intermediate
# parent td0 with FILE_DELETE_CHILD turned off while allowing R/W.
file mkdir td0/td1
testchmod 0o770 td0
testchmod 0o444 td0/td1
testfile rmdir td0/td1
file exists td0/td1
} -cleanup {
catch {testchmod 0o666 td1}
testchmod 0o770 td0/td1
cleanup
} -returnCodes error -result {td1 EACCES}
} -returnCodes error -result {td0/td1 EACCES}
# This next test has a very hokey way of matching...
test winFCmd-6.15 {TclpRemoveDirectory: !recursive} -setup {
cleanup
@@ -791,11 +792,12 @@ test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} -setup {
} -constraints {win testfile testchmod} -body {
file mkdir td1
createfile td1/tf1 tf1
testchmod 0 td1
testchmod 0o770 td1/tf1; # Else tf2 will have no ACL after td1 testchmod
testchmod 0o400 td1
testfile cpdir td1 td2
list [file exists td2] [file writable td2]
} -cleanup {
catch {testchmod 0o666 td1}
testchmod 0o660 td1
cleanup
} -result {1 1}
test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} -setup {
@@ -862,11 +864,12 @@ test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} -setup {
} -constraints {win testfile testchmod} -body {
file mkdir td1
createfile td1/tf1 tf1
testchmod 0 td1
testchmod 0o770 td1/tf1; # Else tf2 will have no ACL after td1 testchmod
testchmod 0o400 td1
testfile cpdir td1 td2
list [file exists td2] [file writable td2]
} -cleanup {
catch {testchmod 0o666 td1}
testchmod 0o660 td1
cleanup
} -result {1 1}
test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} -setup {
@@ -893,11 +896,12 @@ test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} -setup {
cleanup
} -constraints {win testfile testchmod} -body {
file mkdir td1/td2
testchmod 0 td1
testchmod 0o770 td1/td2; # Else td2 will have no ACL after td1 testchmod
testchmod 0o400 td1
testfile cpdir td1 td2
list [file writable td1] [file writable td1/td2]
} -cleanup {
catch {testchmod 0o666 td1}
testchmod 0o660 td1
cleanup
} -result {0 1}
test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} -setup {
@@ -918,15 +922,19 @@ test winFCmd-9.1 {TraversalDelete: DOTREE_F} -setup {
} -result {}
test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} -setup {
cleanup
} -constraints {win testfile testchmod knownMsvcBug notInCIenv} -body {
file mkdir td1/td2
testchmod 0 td1
testfile rmdir -force td1
} -constraints {win testfile testchmod notInCIenv} -body {
# Parent's FILE_DELETE_CHILD setting permits deletion of subdir
# even when subdir DELETE mask is clear. So we need an intermediate
# parent td0 with FILE_DELETE_CHILD turned off while allowing R/W.
file mkdir td0/td1/td2
testchmod 0o770 td0
testchmod 0o400 td0/td1
testfile rmdir -force td0/td1
file exists td1
} -cleanup {
catch {testchmod 0o666 td1}
testchmod 0o770 td0/td1
cleanup
} -returnCodes error -result {td1 EACCES}
} -returnCodes error -result {td0/td1 EACCES}
test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} -setup {
cleanup
} -constraints {win testfile} -body {
@@ -1417,7 +1425,6 @@ test winFCmd-19.9 {Windows devices path names} -constraints win -body {
# }
#}
# cleanup
cleanup
::tcltest::cleanupTests
return
+1 -4
View File
@@ -19,9 +19,6 @@ if {"::tcltest" ni [namespace children]} {
catch [list package require -exact tcl::test [info patchlevel]]
testConstraint testwinclock [llength [info commands testwinclock]]
# Some things fail under all Continuous Integration systems for subtle reasons
# such as CI often running with elevated privileges in a container.
testConstraint notInCIenv [expr {![info exists ::env(CI)]}]
# The next two tests will crash on Windows if the check for negative
# clock values is not done properly.
@@ -43,7 +40,7 @@ test winTime-1.2 {TclpGetDate} {win} {
# with the Windows clock. 30 sec really isn't enough,
# but how much time does a tester have patience for?
test winTime-2.1 {Synchronization of Tcl and Windows clocks} {testwinclock notInCIenv} {
test winTime-2.1 {Synchronization of Tcl and Windows clocks} testwinclock {
# May fail due to OS/hardware discrepancies. See:
# http://support.microsoft.com/default.aspx?scid=kb;en-us;274323
set failed {}
+34 -2
View File
@@ -292,7 +292,7 @@ test zlib-8.6 {transformation and fconfigure} -setup {
} -cleanup {
catch {close $fd}
removeFile $file
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf -checksum 1 -dictionary {}} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf}}
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -profile tcl8 -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -profile tcl8 -translation lf -checksum 1 -dictionary {}} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -profile tcl8 -translation lf}}
test zlib-8.7 {transformation and fconfigure} -setup {
set file [makeFile {} test.gz]
set fd [open $file wb]
@@ -302,7 +302,7 @@ test zlib-8.7 {transformation and fconfigure} -setup {
} -cleanup {
catch {close $fd}
removeFile $file
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf -checksum 0} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -nocomplainencoding 1 -strictencoding 0 -translation lf}}
} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -profile tcl8 -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -profile tcl8 -translation lf -checksum 0} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -profile tcl8 -translation lf}}
# Input is headers from fetching SPDY draft
# Dictionary is that which is proposed _in_ SPDY draft
set spdyHeaders "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nX-Robots-Tag: noarchive\r\nLast-Modified: Tue, 05 Jun 2012 02:43:25 GMT\r\nETag: \"1338864205129|#public|0|en|||0\"\r\nExpires: Tue, 05 Jun 2012 16:17:11 GMT\r\nDate: Tue, 05 Jun 2012 16:17:06 GMT\r\nCache-Control: public, max-age=5\r\nX-Content-Type-Options: nosniff\r\nX-XSS-Protection: 1; mode=block\r\nServer: GSE\r\n"
@@ -486,6 +486,38 @@ test zlib-8.18 {Bug dd260aaf: fconfigure} -setup {
catch {close $inSide}
catch {close $outSide}
} -result {{one two} {one two}}
test zlib-8.19 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
set file [makeFile {} test.gz]
} -body {
set f [zlib push gzip [open $file w] -header [list comment [string repeat A 500]]]
} -cleanup {
catch {close $f}
removeFile $file
} -returnCodes 1 -result {Comment too large for zip}
test zlib-8.20 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
set file [makeFile {} test.gz]
} -body {
set f [zlib push gzip [open $file w] -header [list filename [string repeat A 5000]]]
} -cleanup {
catch {close $f}
removeFile $file
} -returnCodes 1 -result {Filename too large for zip}
test zlib-8.21 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
set file [makeFile {} test.gz]
} -body {
set f [zlib push gzip [open $file w] -header [list comment \u100]]
} -cleanup {
catch {close $f}
removeFile $file
} -returnCodes 1 -result {Comment contains characters > 0xFF}
test zlib-8.22 {zlib transformation, bug f9eafc3886} -constraints zlib -setup {
set file [makeFile {} test.gz]
} -body {
set f [zlib push gzip [open $file w] -header [list filename \u100]]
} -cleanup {
catch {close $f}
removeFile $file
} -returnCodes 1 -result {Filename contains characters > 0xFF}
test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
set sfile [makeFile {} testsrc.gz]
-5
View File
@@ -71,11 +71,6 @@ encodings: clean txt2enc $(EUC_ENCODINGS)
done
@echo
@echo Compiling special versions of encoding files.
@for p in ascii.txt; do \
enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
echo $$enc; \
./txt2enc -m $$p > $$enc; \
done
@for p in jis0208.txt; do \
enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
echo $$enc; \
+3 -5
View File
@@ -106,7 +106,7 @@ main(int argc, char **argv)
fputs(" -f\tfallback character (default: QUESTION MARK)\n", stderr);
fputs(" -t\toverride implicit type with single, double, or multi\n", stderr);
fputs(" -s\tsymbol+ascii encoding\n", stderr);
fputs(" -m\tdon't implicitly include range 0080 to 00FF\n", stderr);
fputs(" -m\tdon't implicitly include 007F\n", stderr);
return 1;
}
@@ -208,10 +208,8 @@ main(int argc, char **argv)
toUnicode[0][i] = i;
}
if (fixmissing) {
for (i = 0x7F; i < 0xA0; i++) {
if (toUnicode[i] == NULL && toUnicode[0][i] == 0) {
toUnicode[0][i] = i;
}
if (toUnicode[0x7F] == NULL && toUnicode[0][0x7F] == 0) {
toUnicode[0][0x7F] = 0x7F;
}
}
}
+352
View File
@@ -0,0 +1,352 @@
# ucm2tests.tcl
#
# Parses given ucm files (from ICU) to generate test data
# for encodings.
#
# tclsh ucm2tests.tcl PATH_TO_ICU_UCM_DIRECTORY ?OUTPUTPATH?
#
namespace eval ucm {
# No means to change these currently but ...
variable outputPath
variable outputChan
variable errorChan stderr
variable verbose 0
# Map Tcl encoding name to ICU UCM file name
variable encNameMap
array set encNameMap {
cp1250 glibc-CP1250-2.1.2
cp1251 glibc-CP1251-2.1.2
cp1252 glibc-CP1252-2.1.2
cp1253 glibc-CP1253-2.1.2
cp1254 glibc-CP1254-2.1.2
cp1255 glibc-CP1255-2.1.2
cp1256 glibc-CP1256-2.1.2
cp1257 glibc-CP1257-2.1.2
cp1258 glibc-CP1258-2.1.2
gb1988 glibc-GB_1988_80-2.3.3
iso8859-1 glibc-ISO_8859_1-2.1.2
iso8859-2 glibc-ISO_8859_2-2.1.2
iso8859-3 glibc-ISO_8859_3-2.1.2
iso8859-4 glibc-ISO_8859_4-2.1.2
iso8859-5 glibc-ISO_8859_5-2.1.2
iso8859-6 glibc-ISO_8859_6-2.1.2
iso8859-7 glibc-ISO_8859_7-2.3.3
iso8859-8 glibc-ISO_8859_8-2.3.3
iso8859-9 glibc-ISO_8859_9-2.1.2
iso8859-10 glibc-ISO_8859_10-2.1.2
iso8859-11 glibc-ISO_8859_11-2.1.2
iso8859-13 glibc-ISO_8859_13-2.3.3
iso8859-14 glibc-ISO_8859_14-2.1.2
iso8859-15 glibc-ISO_8859_15-2.1.2
iso8859-16 glibc-ISO_8859_16-2.3.3
}
# Array keyed by Tcl encoding name. Each element contains mapping of
# Unicode code point -> byte sequence for that encoding as a flat list
# (or dictionary). Both are stored as hex strings
variable charMap
# Array keyed by Tcl encoding name. List of invalid code sequences
# each being a hex string.
variable invalidCodeSequences
# Array keyed by Tcl encoding name. List of unicode code points that are
# not mapped, each being a hex string.
variable unmappedCodePoints
# The fallback character per encoding
variable encSubchar
}
proc ucm::abort {msg} {
variable errorChan
puts $errorChan $msg
exit 1
}
proc ucm::warn {msg} {
variable errorChan
puts $errorChan $msg
}
proc ucm::log {msg} {
variable verbose
if {$verbose} {
variable errorChan
puts $errorChan $msg
}
}
proc ucm::print {s} {
variable outputChan
puts $outputChan $s
}
proc ucm::parse_SBCS {encName fd} {
variable charMap
variable invalidCodeSequences
variable unmappedCodePoints
set result {}
while {[gets $fd line] >= 0} {
if {[string match #* $line]} {
continue
}
if {[string equal "END CHARMAP" [string trim $line]]} {
break
}
if {![regexp {^\s*<U([[:xdigit:]]{4})>\s*((\\x[[:xdigit:]]{2})+)\s*(\|(0|1|2|3|4))} $line -> unichar bytes - - precision]} {
error "Unexpected line parsing SBCS: $line"
}
set bytes [string map {\\x {}} $bytes]; # \xNN -> NN
if {$precision eq "" || $precision eq "0"} {
lappend result $unichar $bytes
} else {
# It is a fallback mapping - ignore
}
}
set charMap($encName) $result
# Find out invalid code sequences and unicode code points that are not mapped
set valid {}
set mapped {}
foreach {unich bytes} $result {
lappend mapped $unich
lappend valid $bytes
}
set invalidCodeSequences($encName) {}
for {set i 0} {$i <= 255} {incr i} {
set hex [format %.2X $i]
if {[lsearch -exact $valid $hex] < 0} {
lappend invalidCodeSequences($encName) $hex
}
}
set unmappedCodePoints($encName) {}
for {set i 0} {$i <= 65535} {incr i} {
set hex [format %.4X $i]
if {[lsearch -exact $mapped $hex] < 0} {
lappend unmappedCodePoints($encName) $hex
# Only look for (at most) one below 256 and one above 1024
if {$i < 255} {
# Found one so jump past 8 bits
set i 255
} else {
break
}
}
if {$i == 255} {
set i 1023
}
}
lappend unmappedCodePoints($encName) D800 DC00 10000 10FFFF
}
proc ucm::generate_boilerplate {} {
# Common procedures
print {
# This file is automatically generated by ucm2tests.tcl.
# Edits will be overwritten on next generation.
#
# Generates tests comparing Tcl encodings to ICU.
# The generated file is NOT standalone. It should be sourced into a test script.
proc ucmConvertfromMismatches {enc map} {
set mismatches {}
foreach {unihex hex} $map {
set unihex [string range 00000000$unihex end-7 end]; # Make 8 digits
set unich [subst "\\U$unihex"]
if {[encoding convertfrom -profile strict $enc [binary decode hex $hex]] ne $unich} {
lappend mismatches "<[printable $unich],$hex>"
}
}
return $mismatches
}
proc ucmConverttoMismatches {enc map} {
set mismatches {}
foreach {unihex hex} $map {
set unihex [string range 00000000$unihex end-7 end]; # Make 8 digits
set unich [subst "\\U$unihex"]
if {[encoding convertto -profile strict $enc $unich] ne [binary decode hex $hex]} {
lappend mismatches "<[printable $unich],$hex>"
}
}
return $mismatches
}
if {[info commands printable] eq ""} {
proc printable {s} {
set print ""
foreach c [split $s ""] {
set i [scan $c %c]
if {[string is print $c] && ($i <= 127)} {
append print $c
} elseif {$i <= 0xff} {
append print \\x[format %02X $i]
} elseif {$i <= 0xffff} {
append print \\u[format %04X $i]
} else {
append print \\U[format %08X $i]
}
}
return $print
}
}
}
} ; # generate_boilerplate
proc ucm::generate_tests {} {
variable encNameMap
variable charMap
variable invalidCodeSequences
variable unmappedCodePoints
variable outputPath
variable outputChan
variable encSubchar
if {[info exists outputPath]} {
set outputChan [open $outputPath w]
fconfigure $outputChan -translation lf
} else {
set outputChan stdout
}
array set tclNames {}
foreach encName [encoding names] {
set tclNames($encName) ""
}
generate_boilerplate
foreach encName [lsort -dictionary [array names encNameMap]] {
if {![info exists charMap($encName)]} {
warn "No character map read for $encName"
continue
}
unset tclNames($encName)
# Print the valid tests
print "\n#\n# $encName (generated from $encNameMap($encName))"
print "\ntest encoding-convertfrom-ucmCompare-$encName {Compare against ICU UCM} -body \{"
print " ucmConvertfromMismatches $encName {$charMap($encName)}"
print "\} -result {}"
print "\ntest encoding-convertto-ucmCompare-$encName {Compare against ICU UCM} -body \{"
print " ucmConverttoMismatches $encName {$charMap($encName)}"
print "\} -result {}"
if {0} {
# This will generate individual tests for every char
# and test in lead, tail, middle, solo configurations
# but takes considerable time
print "lappend encValidStrings \{*\}\{"
foreach {unich hex} $charMap($encName) {
print " $encName \\u$unich $hex {} {}"
}
print "\}; # $encName"
}
# Generate the invalidity checks
print "\n# $encName - invalid byte sequences"
print "lappend encInvalidBytes \{*\}\{"
foreach hex $invalidCodeSequences($encName) {
# Map XXXX... to \xXX\xXX...
set uhex [regsub -all .. $hex {\\x\0}]
set uhex \\U[string range 00000000$hex end-7 end]
print " $encName $hex tcl8 $uhex -1 {} {}"
print " $encName $hex replace \\uFFFD -1 {} {}"
print " $encName $hex strict {} 0 {} {}"
}
print "\}; # $encName"
print "\n# $encName - invalid byte sequences"
print "lappend encUnencodableStrings \{*\}\{"
if {[info exists encSubchar($encName)]} {
set subchar $encSubchar($encName)
} else {
set subchar "3F"; # Tcl uses ? by default
}
foreach hex $unmappedCodePoints($encName) {
set uhex \\U[string range 00000000$hex end-7 end]
print " $encName $uhex tcl8 $subchar -1 {} {}"
print " $encName $uhex replace $subchar -1 {} {}"
print " $encName $uhex strict {} 0 {} {}"
}
print "\}; # $encName"
}
if {[array size tclNames]} {
warn "Missing encoding: [lsort [array names tclNames]]"
}
if {[info exists outputPath]} {
close $outputChan
unset outputChan
}
}
proc ucm::parse_file {encName ucmPath} {
variable charMap
variable encSubchar
set fd [open $ucmPath]
try {
# Parse the metadata
unset -nocomplain state
while {[gets $fd line] >= 0} {
if {[regexp {<(code_set_name|mb_cur_max|mb_cur_min|uconv_class|subchar)>\s+(\S+)} $line -> key val]} {
set state($key) $val
} elseif {[regexp {^\s*CHARMAP\s*$} $line]} {
set state(charmap) ""
break
} else {
# Skip all else
}
}
if {![info exists state(charmap)]} {
abort "Error: $ucmPath has No CHARMAP line."
}
foreach key {code_set_name uconv_class} {
if {[info exists state($key)]} {
set state($key) [string trim $state($key) {"}]
}
}
if {[info exists charMap($encName)]} {
abort "Duplicate file for $encName ($path)"
}
if {![info exists state(uconv_class)]} {
abort "Error: $ucmPath has no uconv_class definition."
}
if {[info exists state(subchar)]} {
# \xNN\xNN.. -> NNNN..
set encSubchar($encName) [string map {\\x {}} $state(subchar)]
}
switch -exact -- $state(uconv_class) {
SBCS {
if {[catch {
parse_SBCS $encName $fd
} result]} {
abort "Could not process $ucmPath. $result"
}
}
default {
log "Skipping $ucmPath -- not SBCS encoding."
return
}
}
} finally {
close $fd
}
}
proc ucm::run {} {
variable encNameMap
variable outputPath
switch [llength $::argv] {
2 {set outputPath [lindex $::argv 1]}
1 {}
default {
abort "Usage: [info nameofexecutable] $::argv0 path/to/icu/ucm/data ?outputfile?"
}
}
foreach {encName fname} [array get encNameMap] {
ucm::parse_file $encName [file join [lindex $::argv 0] ${fname}.ucm]
}
generate_tests
}
ucm::run
+30
View File
@@ -0,0 +1,30 @@
#! /usr/bin/env tclsh
proc main {sourcetype source} {
switch $sourcetype {
file {
set chan [open $source]
try {
set data [read $chan]
} finally {
close $chan
}
}
string {
set data $source
}
default {
error [list {wrong # args}]
}
}
set found [regexp -inline -all {blocks are\
(?:(?:(?:definitely|indirectly|possibly) lost)|still reachable)} $data]
if {[llength $found]} {
puts 0
} else {
puts 1
}
flush stdout
}
main {*}$argv
+137
View File
@@ -1,3 +1,17 @@
#{
# Tcl_GetChannelOption/TcpGetOptionProc/TcphostPortList/getnameinfo/gethostbyaddr_r
# Memcheck:Leak
# match-leak-kinds: reachable
# fun:malloc
# fun:strdup
# ...
# fun:module_load
# ...
# fun:getnameinfo
# ...
# fun:Tcl_GetChannelOption
#}
{
TclCreatesocketAddress/getaddrinfo/calloc
Memcheck:Leak
@@ -8,6 +22,16 @@
fun:TclCreateSocketAddress
}
{
TclCreatesocketAddress/getaddrinfo/malloc
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
...
fun:getaddrinfo
fun:TclCreateSocketAddress
}
{
TclCreatesocketAddress/getaddrinfo/malloc
Memcheck:Leak
@@ -18,6 +42,18 @@
fun:TclCreateSocketAddress
}
{
TclpDlopen/decompose_rpath
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:decompose_rpath
...
fun:dlopen_doit
...
fun:TclpDlopen
}
{
TclpDlopen/load
Memcheck:Leak
@@ -71,6 +107,46 @@
fun:TclpGetGrNam
}
{
TclpGeHostByName/gethostbyname_r/strdup/malloc
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
fun:strdup
...
fun:dl_open_worker
...
fun:do_dlopen
...
fun:TclpGetHostByName
}
{
TclpGeHostByName/gethostbyname_r/calloc
Memcheck:Leak
match-leak-kinds: reachable
fun:calloc
...
fun:dl_open_worker
...
fun:do_dlopen
...
fun:TclpGetHostByName
}
{
TclpGeHostByName/gethostbyname_r/malloc
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
...
fun:dl_open_worker
...
fun:do_dlopen
...
fun:TclpGetHostByName
}
{
TclpGetPwNam/getpwname_r/__nss_next2/calloc
Memcheck:Leak
@@ -104,6 +180,57 @@
fun:TclpGetPwNam
}
{
TclpGetGrGid/getgrgid_r/module_load
Memcheck:Leak
match-leak-kinds: reachable
fun:calloc
...
fun:module_load
...
fun:TclpGetGrGid
}
{
TclpGetGrGid/getgrgid_r/module_load
Memcheck:Leak
match-leak-kinds: reachable
fun:malloc
...
fun:module_load
...
fun:TclpGetGrGid
}
{
TcphostPortList/getnameinfo/module_load/calloc
Memcheck:Leak
match-leak-kinds: definite,reachable
fun:calloc
...
fun:dl_open_worker_begin
...
fun:module_load
...
fun:getnameinfo
fun:TcpHostPortList
}
{
# see sourceware glibc Bug 14984 - getnameinfo() might be leaking memory
TcphostPortList/getnameinfo/module_load/mallco
Memcheck:Leak
match-leak-kinds: definite,reachable
fun:malloc
...
fun:dl_open_worker_begin
...
fun:module_load
...
fun:getnameinfo
fun:TcpHostPortList
}
{
TclpThreadExit/pthread_exit/calloc
Memcheck:Leak
@@ -124,3 +251,13 @@
fun:TclpThreadExit
}
{
TclpThreadExit/pthread_exit/malloc
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
...
fun:pthread_exit
fun:TclpThreadExit
}
+23 -2
View File
@@ -952,6 +952,27 @@ valgrind: ${TCL_EXE} ${TCLTEST_EXE}
$(TOP_DIR)/tests/all.tcl -singleproc 1 -constraints valgrind \
$(TESTFLAGS)
testresults/valgrind/%.result: ${TCL_EXE} ${TCLTEST_EXE}
@mkdir -p testresults/valgrind
$(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCLTEST_EXE} \
$(TOP_DIR)/tests/all.tcl -singleproc 1 -constraints valgrind \
-file $(basename $(notdir $@)) > $@.tmp 2>&1
@mv $@.tmp $@
.PRECIOUS: testresults/valgrind/%.result
testresults/valgrind/%.success: testresults/valgrind/%.result
@printf '%s' valgrind >&2
@printf ' %s' $(basename $(notdir $@)) >&2
@printf '\n >&2'
@status=$$(./${TCLTEST_EXE} $(TOP_DIR)/tools/valgrind_check_success \
file $(basename $@).result); \
if [ "$$status" -eq 1 ]; then touch $@; exit 0; else exit 1; fi
valgrind_each: $(addprefix testresults/valgrind/,$(addsuffix .success,$(notdir\
$(wildcard $(TOP_DIR)/tests/*.test))))
valgrindshell: ${TCL_EXE}
$(SHELL_ENV) $(VALGRIND) $(VALGRINDARGS) ./${TCL_EXE} $(SCRIPT)
@@ -1051,9 +1072,9 @@ install-libraries: libraries
@echo "Installing package msgcat 1.7.1 as a Tcl Module"
@$(INSTALL_DATA) $(TOP_DIR)/library/msgcat/msgcat.tcl \
"$(MODULE_INSTALL_DIR)/8.7/msgcat-1.7.1.tm"
@echo "Installing package tcltest 2.5.5 as a Tcl Module"
@echo "Installing package tcltest 2.5.6 as a Tcl Module"
@$(INSTALL_DATA) $(TOP_DIR)/library/tcltest/tcltest.tcl \
"$(MODULE_INSTALL_DIR)/8.5/tcltest-2.5.5.tm"
"$(MODULE_INSTALL_DIR)/8.5/tcltest-2.5.6.tm"
@echo "Installing package platform 1.0.19 as a Tcl Module"
@$(INSTALL_DATA) $(TOP_DIR)/library/platform/platform.tcl \
"$(MODULE_INSTALL_DIR)/8.4/platform-1.0.19.tm"
+12 -62
View File
@@ -6506,16 +6506,16 @@ then :
do64bit_ok=yes
fi;;
arm64|arm64e)
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch arm64e flag" >&5
printf %s "checking if compiler accepts -arch arm64e flag... " >&6; }
if test ${tcl_cv_cc_arch_arm64e+y}
arm64)
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch arm64 flag" >&5
printf %s "checking if compiler accepts -arch arm64 flag... " >&6; }
if test ${tcl_cv_cc_arch_arm64+y}
then :
printf %s "(cached) " >&6
else $as_nop
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -arch arm64e"
CFLAGS="$CFLAGS -arch arm64"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -6529,20 +6529,20 @@ main (void)
_ACEOF
if ac_fn_c_try_link "$LINENO"
then :
tcl_cv_cc_arch_arm64e=yes
tcl_cv_cc_arch_arm64=yes
else $as_nop
tcl_cv_cc_arch_arm64e=no
tcl_cv_cc_arch_arm64=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_arm64e" >&5
printf "%s\n" "$tcl_cv_cc_arch_arm64e" >&6; }
if test $tcl_cv_cc_arch_arm64e = yes
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_arm64" >&5
printf "%s\n" "$tcl_cv_cc_arch_arm64" >&6; }
if test $tcl_cv_cc_arch_arm64 = yes
then :
CFLAGS="$CFLAGS -arch arm64e"
CFLAGS="$CFLAGS -arch arm64"
do64bit_ok=yes
fi;;
@@ -6554,7 +6554,7 @@ printf "%s\n" "$as_me: WARNING: Don't know how enable 64-bit on architecture \`a
else $as_nop
# Check for combined 32-bit and 64-bit fat build
if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64e) ' \
if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \
&& echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '
then :
@@ -7631,56 +7631,6 @@ printf "%s\n" "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
fi
if test ${tcl_cv_flag__largefile_source64+y}
then :
printf %s "(cached) " >&6
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/stat.h>
int
main (void)
{
char *p = (char *)open64;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
tcl_cv_flag__largefile_source64=no
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define _LARGEFILE_SOURCE64 1
#include <sys/stat.h>
int
main (void)
{
char *p = (char *)open64;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"
then :
tcl_cv_flag__largefile_source64=yes
else $as_nop
tcl_cv_flag__largefile_source64=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
printf "%s\n" "#define _LARGEFILE_SOURCE64 1" >>confdefs.h
tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
fi
if test "x${tcl_flags}" = "x" ; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5
printf "%s\n" "none" >&6; }
+8 -11
View File
@@ -1406,16 +1406,16 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
CFLAGS="$CFLAGS -arch x86_64"
do64bit_ok=yes
]);;
arm64|arm64e)
AC_CACHE_CHECK([if compiler accepts -arch arm64e flag],
tcl_cv_cc_arch_arm64e, [
arm64)
AC_CACHE_CHECK([if compiler accepts -arch arm64 flag],
tcl_cv_cc_arch_arm64, [
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -arch arm64e"
CFLAGS="$CFLAGS -arch arm64"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
[tcl_cv_cc_arch_arm64e=yes],[tcl_cv_cc_arch_arm64e=no])
[tcl_cv_cc_arch_arm64=yes],[tcl_cv_cc_arch_arm64=no])
CFLAGS=$hold_cflags])
AS_IF([test $tcl_cv_cc_arch_arm64e = yes], [
CFLAGS="$CFLAGS -arch arm64e"
AS_IF([test $tcl_cv_cc_arch_arm64 = yes], [
CFLAGS="$CFLAGS -arch arm64"
do64bit_ok=yes
]);;
*)
@@ -1423,7 +1423,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
esac
], [
# Check for combined 32-bit and 64-bit fat build
AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64e) ' \
AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64|arm64) ' \
&& echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [
fat_32_64=yes])
])
@@ -2329,7 +2329,6 @@ AC_DEFUN([SC_TCL_LINK_LIBS], [
# Might define the following vars:
# _ISOC99_SOURCE
# _LARGEFILE64_SOURCE
# _LARGEFILE_SOURCE64
#
#--------------------------------------------------------------------
@@ -2353,8 +2352,6 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[
[char *p = (char *)strtoll; char *q = (char *)strtoull;])
SC_TCL_EARLY_FLAG(_LARGEFILE64_SOURCE,[#include <sys/stat.h>],
[struct stat64 buf; int i = stat64("/", &buf);])
SC_TCL_EARLY_FLAG(_LARGEFILE_SOURCE64,[#include <sys/stat.h>],
[char *p = (char *)open64;])
if test "x${tcl_flags}" = "x" ; then
AC_MSG_RESULT([none])
else
-3
View File
@@ -492,9 +492,6 @@
/* Add the _LARGEFILE64_SOURCE flag when building */
#undef _LARGEFILE64_SOURCE
/* Add the _LARGEFILE_SOURCE64 flag when building */
#undef _LARGEFILE_SOURCE64
/* # needed in sys/socket.h Should OS/390 do the right thing with sockets? */
#undef _OE_SOCKETS
+6 -6
View File
@@ -1033,10 +1033,10 @@ TcpGetOptionProc(
if ((len == 0) || ((len > 1) && (optionName[1] == 'k') &&
(strncmp(optionName, "-keepalive", len) == 0))) {
#if defined(SO_KEEPALIVE)
socklen_t size;
#endif
int opt = 0;
#if defined(SO_KEEPALIVE)
socklen_t size = sizeof(opt);
#endif
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-keepalive");
@@ -1053,10 +1053,10 @@ TcpGetOptionProc(
if ((len == 0) || ((len > 1) && (optionName[1] == 'n') &&
(strncmp(optionName, "-nodelay", len) == 0))) {
#if defined(SOL_TCP) && defined(TCP_NODELAY)
socklen_t size;
#endif
int opt = 0;
#if defined(SOL_TCP) && defined(TCP_NODELAY)
socklen_t size = sizeof(opt);
#endif
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-nodelay");
+2 -2
View File
@@ -889,8 +889,8 @@ install-libraries: libraries install-tzdata install-msgs
done;
@echo "Installing package msgcat 1.7.1 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/msgcat/msgcat.tcl "$(MODULE_INSTALL_DIR)/8.7/msgcat-1.7.1.tm";
@echo "Installing package tcltest 2.5.5 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl "$(MODULE_INSTALL_DIR)/8.5/tcltest-2.5.5.tm";
@echo "Installing package tcltest 2.5.6 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/tcltest/tcltest.tcl "$(MODULE_INSTALL_DIR)/8.5/tcltest-2.5.6.tm";
@echo "Installing package platform 1.0.19 as a Tcl Module";
@$(COPY) $(ROOT_DIR)/library/platform/platform.tcl "$(MODULE_INSTALL_DIR)/8.4/platform-1.0.19.tm";
@echo "Installing package platform::shell 1.1.4 as a Tcl Module";
+2 -2
View File
@@ -379,7 +379,7 @@ TclWinDriveLetterForVolMountPoint(
if (!alreadyStored) {
dlPtr2 = (MountPointMap *)ckalloc(sizeof(MountPointMap));
dlPtr2->volumeName = (WCHAR *)TclNativeDupInternalRep(Target);
dlPtr2->driveLetter = (char) drive[0];
dlPtr2->driveLetter = (WCHAR) drive[0];
dlPtr2->nextPtr = driveLetterLookup;
driveLetterLookup = dlPtr2;
}
@@ -405,7 +405,7 @@ TclWinDriveLetterForVolMountPoint(
dlPtr2 = (MountPointMap *)ckalloc(sizeof(MountPointMap));
dlPtr2->volumeName = (WCHAR *)TclNativeDupInternalRep((void *)mountPoint);
dlPtr2->driveLetter = -1;
dlPtr2->driveLetter = (WCHAR)-1;
dlPtr2->nextPtr = driveLetterLookup;
driveLetterLookup = dlPtr2;
Tcl_MutexUnlock(&mountPointMap);
+3 -3
View File
@@ -700,7 +700,7 @@ FileInputProc(
if (ReadFile(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &bytesRead,
(LPOVERLAPPED) NULL) != FALSE) {
return bytesRead;
return (int)bytesRead;
}
Tcl_WinConvertError(GetLastError());
@@ -757,7 +757,7 @@ FileOutputProc(
return -1;
}
infoPtr->dirty = 1;
return bytesWritten;
return (int)bytesWritten;
}
/*
@@ -1572,7 +1572,7 @@ NativeIsComPort(
const WCHAR *nativePath) /* Path of file to access, native encoding. */
{
const WCHAR *p = (const WCHAR *) nativePath;
int i, len = wcslen(p);
size_t i, len = wcslen(p);
/*
* 1. Look for com[1-9]:?
+31 -37
View File
@@ -1457,21 +1457,39 @@ TclpGetUserHome(
if (domain == NULL) {
const char *ptr;
/*
* No domain. Firstly check it's the current user
*/
/*
* Treat the current user as a special case because the general case
* below does not properly retrieve the path. The NetUserGetInfo
* call returns an empty path and the code defaults to the user's
* name in the profiles directory. On modern Windows systems, this
* is generally wrong as when the account is a Microsoft account,
* for example abcdefghi@outlook.com, the directory name is
* abcde and not abcdefghi.
*
* Note we could have just used env(USERPROFILE) here but
* the intent is to retrieve (as on Unix) the system's view
* of the home irrespective of environment settings of HOME
* and USERPROFILE.
*
* Fixing this for the general user needs more investigating but
* at least for the current user we can use a direct call.
*/
ptr = TclpGetUserName(&ds);
if (ptr != NULL && strcasecmp(name, ptr) == 0) {
/*
* Try safest and fastest way to get current user home
*/
ptr = TclGetEnv("HOME", &ds);
if (ptr != NULL) {
Tcl_JoinPath(1, &ptr, bufferPtr);
rc = 1;
result = Tcl_DStringValue(bufferPtr);
HANDLE hProcess;
WCHAR buf[MAX_PATH];
DWORD nChars = sizeof(buf) / sizeof(buf[0]);
/* Sadly GetCurrentProcessToken not in Win 7 so slightly longer */
hProcess = GetCurrentProcess(); /* Need not be closed */
if (hProcess) {
HANDLE hToken;
if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
if (GetUserProfileDirectoryW(hToken, buf, &nChars)) {
result = Tcl_WCharToUtfDString(buf, nChars-1, (bufferPtr));
rc = 1;
}
CloseHandle(hToken);
}
}
}
Tcl_DStringFree(&ds);
@@ -1543,30 +1561,6 @@ TclpGetUserHome(
if (wDomain != NULL) {
NetApiBufferFree((void *) wDomain);
}
if (result == NULL) {
/*
* Look in the "Password Lists" section of system.ini for the local
* user. There are also entries in that section that begin with a "*"
* character that are used by Windows for other purposes; ignore user
* names beginning with a "*".
*/
char buf[MAX_PATH];
if (name[0] != '*') {
if (GetPrivateProfileStringA("Password Lists", name, "", buf,
MAX_PATH, "system.ini") > 0) {
/*
* User exists, but there is no such thing as a home directory
* in system.ini. Return "{Windows drive}:/".
*/
GetWindowsDirectoryA(buf, MAX_PATH);
Tcl_DStringAppend(bufferPtr, buf, 3);
result = Tcl_DStringValue(bufferPtr);
}
}
}
return result;
}
+2 -2
View File
@@ -56,10 +56,10 @@ Tcl_ConsolePanic(
if (IsDebuggerPresent()) {
OutputDebugStringW(msgString);
} else if (_isatty(2)) {
WriteConsoleW(handle, msgString, wcslen(msgString), &dummy, 0);
WriteConsoleW(handle, msgString, (DWORD)wcslen(msgString), &dummy, 0);
} else {
buf[0] = '\xEF'; buf[1] = '\xBB'; buf[2] = '\xBF'; /* UTF-8 bom */
WriteFile(handle, buf, strlen(buf), &dummy, 0);
WriteFile(handle, buf, (DWORD)strlen(buf), &dummy, 0);
WriteFile(handle, "\n", 1, &dummy, 0);
FlushFileBuffers(handle);
}
+165 -151
View File
@@ -22,9 +22,8 @@
/*
* For TestplatformChmod on Windows
*/
#ifdef _WIN32
#include <aclapi.h>
#endif
#include <sddl.h>
/*
* MinGW 3.4.2 does not define this.
@@ -414,176 +413,189 @@ TestExceptionCmd(
return TCL_OK;
}
/*
* This "chmod" works sufficiently for test script purposes. Do not expect
* it to be exact emulation of Unix chmod (not sure if that's even possible)
*/
static int
TestplatformChmod(
const char *nativePath,
int pmode)
{
static const SECURITY_INFORMATION infoBits = OWNER_SECURITY_INFORMATION
| GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
/* don't reset change permissions mask (WRITE_DAC, allow test-cases restore it to cleanup) */
static const DWORD readOnlyMask = FILE_DELETE_CHILD | FILE_ADD_FILE
| FILE_ADD_SUBDIRECTORY | FILE_WRITE_EA | FILE_APPEND_DATA
| FILE_WRITE_DATA
| DELETE;
/*
* References to security functions (only available on NT and later).
* Note FILE_DELETE_CHILD missing from dirWriteMask because we do
* not want overriding of child's delete setting when testing
*/
static const DWORD dirWriteMask =
FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA |
FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY | STANDARD_RIGHTS_WRITE | DELETE |
SYNCHRONIZE;
static const DWORD dirReadMask =
FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_LIST_DIRECTORY |
STANDARD_RIGHTS_READ | SYNCHRONIZE;
/* Note - default user privileges allow ignoring TRAVERSE setting */
static const DWORD dirExecuteMask =
FILE_TRAVERSE | STANDARD_RIGHTS_READ | SYNCHRONIZE;
const BOOL set_readOnly = !(pmode & 0222);
BOOL acl_readOnly_found = FALSE, curAclPresent, curAclDefaulted;
SID_IDENTIFIER_AUTHORITY userSidAuthority = {
SECURITY_WORLD_SID_AUTHORITY
};
BYTE *secDesc = 0;
DWORD secDescLen, attr, newAclSize;
ACL_SIZE_INFORMATION ACLSize;
PACL curAcl, newAcl = 0;
WORD j;
SID *userSid = 0;
char *userDomain = 0;
static const DWORD fileWriteMask =
FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_WRITE_DATA |
FILE_APPEND_DATA | STANDARD_RIGHTS_WRITE | DELETE | SYNCHRONIZE;
static const DWORD fileReadMask =
FILE_READ_ATTRIBUTES | FILE_READ_EA | FILE_READ_DATA |
STANDARD_RIGHTS_READ | SYNCHRONIZE;
static const DWORD fileExecuteMask =
FILE_EXECUTE | STANDARD_RIGHTS_READ | SYNCHRONIZE;
DWORD attr, newAclSize;
PACL newAcl = NULL;
int res = 0;
/*
* Process the chmod request.
*/
HANDLE hToken = NULL;
int i;
int nSids = 0;
struct {
PSID pSid;
DWORD mask;
DWORD sidLen;
} aceEntry[3];
DWORD dw;
int isDir;
TOKEN_USER *pTokenUser = NULL;
res = -1; /* Assume failure */
attr = GetFileAttributesA(nativePath);
/*
* nativePath not found
*/
if (attr == 0xFFFFFFFF) {
res = -1;
goto done; /* Not found */
}
isDir = (attr & FILE_ATTRIBUTE_DIRECTORY) != 0;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
goto done;
}
/*
* If nativePath is not a directory, there is no special handling.
*/
if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
/* Get process SID */
if (!GetTokenInformation(hToken, TokenUser, NULL, 0, &dw) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto done;
}
pTokenUser = (TOKEN_USER *)ckalloc(dw);
if (!GetTokenInformation(hToken, TokenUser, pTokenUser, dw, &dw)) {
goto done;
}
aceEntry[nSids].sidLen = GetLengthSid(pTokenUser->User.Sid);
aceEntry[nSids].pSid = ckalloc(aceEntry[nSids].sidLen);
if (!CopySid(aceEntry[nSids].sidLen,
aceEntry[nSids].pSid,
pTokenUser->User.Sid)) {
ckfree(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
goto done;
}
/*
* Set the result to error, if the ACL change is successful it will be
* reset to 0.
* Always include DACL modify rights so we don't get locked out
*/
res = -1;
/*
* Read the security descriptor for the directory. Note the first call
* obtains the size of the security descriptor.
*/
if (!GetFileSecurityA(nativePath, infoBits, NULL, 0, &secDescLen)) {
DWORD secDescLen2 = 0;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto done;
aceEntry[nSids].mask = READ_CONTROL | WRITE_DAC | WRITE_OWNER | SYNCHRONIZE |
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES;
if (pmode & 0700) {
/* Owner permissions. Assumes current process is owner */
if (pmode & 0400) {
aceEntry[nSids].mask |= isDir ? dirReadMask : fileReadMask;
}
secDesc = (BYTE *)ckalloc(secDescLen);
if (!GetFileSecurityA(nativePath, infoBits,
(PSECURITY_DESCRIPTOR) secDesc, secDescLen, &secDescLen2)
|| (secDescLen < secDescLen2)) {
goto done;
if (pmode & 0200) {
aceEntry[nSids].mask |= isDir ? dirWriteMask : fileWriteMask;
}
if (pmode & 0100) {
aceEntry[nSids].mask |= isDir ? dirExecuteMask : fileExecuteMask;
}
}
++nSids;
/*
* Get the World SID.
*/
if (pmode & 0070) {
/* Group permissions. */
userSid = (SID *)ckalloc(GetSidLengthRequired((UCHAR) 1));
InitializeSid(userSid, &userSidAuthority, (BYTE) 1);
*(GetSidSubAuthority(userSid, 0)) = SECURITY_WORLD_RID;
TOKEN_PRIMARY_GROUP *pTokenGroup;
/*
* If curAclPresent == false then curAcl and curAclDefaulted not valid.
*/
/* Get primary group SID */
if (!GetTokenInformation(
hToken, TokenPrimaryGroup, NULL, 0, &dw) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto done;
}
pTokenGroup = (TOKEN_PRIMARY_GROUP *)ckalloc(dw);
if (!GetTokenInformation(hToken, TokenPrimaryGroup, pTokenGroup, dw, &dw)) {
ckfree(pTokenGroup);
goto done;
}
aceEntry[nSids].sidLen = GetLengthSid(pTokenGroup->PrimaryGroup);
aceEntry[nSids].pSid = ckalloc(aceEntry[nSids].sidLen);
if (!CopySid(aceEntry[nSids].sidLen, aceEntry[nSids].pSid, pTokenGroup->PrimaryGroup)) {
ckfree(pTokenGroup);
ckfree(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
goto done;
}
ckfree(pTokenGroup);
if (!GetSecurityDescriptorDacl((PSECURITY_DESCRIPTOR) secDesc,
&curAclPresent, &curAcl, &curAclDefaulted)) {
goto done;
}
if (!curAclPresent || !curAcl) {
ACLSize.AclBytesInUse = 0;
ACLSize.AceCount = 0;
} else if (!GetAclInformation(curAcl, &ACLSize, sizeof(ACLSize),
AclSizeInformation)) {
goto done;
/* Generate mask for group ACL */
aceEntry[nSids].mask = 0;
if (pmode & 0040) {
aceEntry[nSids].mask |= isDir ? dirReadMask : fileReadMask;
}
if (pmode & 0020) {
aceEntry[nSids].mask |= isDir ? dirWriteMask : fileWriteMask;
}
if (pmode & 0010) {
aceEntry[nSids].mask |= isDir ? dirExecuteMask : fileExecuteMask;
}
++nSids;
}
/*
* Allocate memory for the new ACL.
*/
if (pmode & 0007) {
/* World permissions */
PSID pWorldSid;
if (!ConvertStringSidToSidA("S-1-1-0", &pWorldSid)) {
goto done;
}
aceEntry[nSids].sidLen = GetLengthSid(pWorldSid);
aceEntry[nSids].pSid = ckalloc(aceEntry[nSids].sidLen);
if (!CopySid(aceEntry[nSids].sidLen, aceEntry[nSids].pSid, pWorldSid)) {
LocalFree(pWorldSid);
ckfree(aceEntry[nSids].pSid); /* Since we have not ++'ed nSids */
goto done;
}
LocalFree(pWorldSid);
newAclSize = ACLSize.AclBytesInUse + sizeof(ACCESS_DENIED_ACE)
+ GetLengthSid(userSid) - sizeof(DWORD);
newAcl = (PACL) ckalloc(newAclSize);
/* Generate mask for world ACL */
/*
* Initialize the new ACL.
*/
aceEntry[nSids].mask = 0;
if (pmode & 0004) {
aceEntry[nSids].mask |= isDir ? dirReadMask : fileReadMask;
}
if (pmode & 0002) {
aceEntry[nSids].mask |= isDir ? dirWriteMask : fileWriteMask;
}
if (pmode & 0001) {
aceEntry[nSids].mask |= isDir ? dirExecuteMask : fileExecuteMask;
}
++nSids;
}
/* Allocate memory and initialize the new ACL. */
newAclSize = sizeof(ACL);
/* Add in size required for each ACE entry in the ACL */
for (i = 0; i < nSids; ++i) {
newAclSize +=
offsetof(ACCESS_ALLOWED_ACE, SidStart) + aceEntry[i].sidLen;
}
newAcl = (PACL)ckalloc(newAclSize);
if (!InitializeAcl(newAcl, newAclSize, ACL_REVISION)) {
goto done;
}
/*
* Add denied to make readonly, this will be known as a "read-only tag".
*/
if (set_readOnly && !AddAccessDeniedAce(newAcl, ACL_REVISION,
readOnlyMask, userSid)) {
goto done;
}
acl_readOnly_found = FALSE;
for (j = 0; j < ACLSize.AceCount; j++) {
LPVOID pACE2;
ACE_HEADER *phACE2;
if (!GetAce(curAcl, j, &pACE2)) {
goto done;
}
phACE2 = (ACE_HEADER *) pACE2;
/*
* Do NOT propagate inherited ACEs.
*/
if (phACE2->AceFlags & INHERITED_ACE) {
continue;
}
/*
* Skip the "read-only tag" restriction (either added above, or it is
* being removed).
*/
if (phACE2->AceType == ACCESS_DENIED_ACE_TYPE) {
ACCESS_DENIED_ACE *pACEd = (ACCESS_DENIED_ACE *) phACE2;
if (pACEd->Mask == readOnlyMask
&& EqualSid(userSid, (PSID) &pACEd->SidStart)) {
acl_readOnly_found = TRUE;
continue;
}
}
/*
* Copy the current ACE from the old to the new ACL.
*/
if (!AddAce(newAcl, ACL_REVISION, MAXDWORD, (PACL *) pACE2,
((PACE_HEADER) pACE2)->AceSize)) {
for (i = 0; i < nSids; ++i) {
if (!AddAccessAllowedAce(newAcl, ACL_REVISION, aceEntry[i].mask, aceEntry[i].pSid)) {
goto done;
}
}
@@ -593,36 +605,38 @@ TestplatformChmod(
* to remove inherited ACL (we need to overwrite the default ACL's in this case)
*/
if (set_readOnly == acl_readOnly_found || SetNamedSecurityInfoA(
(LPSTR) nativePath, SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION /*| PROTECTED_DACL_SECURITY_INFORMATION*/,
NULL, NULL, newAcl, NULL) == ERROR_SUCCESS) {
if (SetNamedSecurityInfoA((LPSTR)nativePath,
SE_FILE_OBJECT,
DACL_SECURITY_INFORMATION |
PROTECTED_DACL_SECURITY_INFORMATION,
NULL,
NULL,
newAcl,
NULL) == ERROR_SUCCESS) {
res = 0;
}
done:
if (secDesc) {
ckfree(secDesc);
if (pTokenUser) {
ckfree(pTokenUser);
}
if (hToken) {
CloseHandle(hToken);
}
if (newAcl) {
ckfree(newAcl);
}
if (userSid) {
ckfree(userSid);
}
if (userDomain) {
ckfree(userDomain);
for (i = 0; i < nSids; ++i) {
ckfree(aceEntry[i].pSid);
}
if (res != 0) {
return res;
}
/*
* Run normal chmod command.
*/
/* Run normal chmod command */
return chmod(nativePath, pmode);
}
/*