Compare commits
324
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6134622b61 | ||
|
|
bdad96ab69 | ||
|
|
c0a02fd487 | ||
|
|
453c27a88e | ||
|
|
ac93862047 | ||
|
|
e9ccf557eb | ||
|
|
5b8c37d24f | ||
|
|
13b1529c7b | ||
|
|
1ee3af2d3d | ||
|
|
87b6456684 | ||
|
|
4f2de3dfc9 | ||
|
|
4aa63fcc25 | ||
|
|
3d439d74da | ||
|
|
9c8a1292c0 | ||
|
|
3129864cc2 | ||
|
|
5655318f50 | ||
|
|
ae0471127e | ||
|
|
1a6f1d5c40 | ||
|
|
e019e5bd1d | ||
|
|
5846b1666f | ||
|
|
a3c59e320d | ||
|
|
70cf69246f | ||
|
|
7543a1313f | ||
|
|
e0e09638fe | ||
|
|
6d3b66ad23 | ||
|
|
6bd8763c2d | ||
|
|
23a421a9c1 | ||
|
|
ba737587a8 | ||
|
|
6ded4b92be | ||
|
|
6cf4a0dea3 | ||
|
|
fdcb9621bb | ||
|
|
3aef0c58f9 | ||
|
|
87b3bcc550 | ||
|
|
b05b4cf948 | ||
|
|
18a99f2522 | ||
|
|
953a44bc6e | ||
|
|
5094fb7825 | ||
|
|
95158a2d57 | ||
|
|
d53dfb14c7 | ||
|
|
6d74232282 | ||
|
|
df8a3a6ea4 | ||
|
|
967e55306e | ||
|
|
22239fb7d2 | ||
|
|
131176ce2f | ||
|
|
77e951f2b8 | ||
|
|
8bf2e2ace2 | ||
|
|
b7f151f126 | ||
|
|
8c5fc11b5a | ||
|
|
1889ded114 | ||
|
|
6f85588bab | ||
|
|
21388fa31e | ||
|
|
0951d3f692 | ||
|
|
93bf87ed85 | ||
|
|
d06a38ae5d | ||
|
|
494b4c8127 | ||
|
|
56f5c7751c | ||
|
|
bd3a6be21b | ||
|
|
962d8aed89 | ||
|
|
5b0be62536 | ||
|
|
a1fb554585 | ||
|
|
552d2bb53f | ||
|
|
1b7f525ec7 | ||
|
|
38555b60a2 | ||
|
|
9f1cf8d5ef | ||
|
|
c3da6c8fed | ||
|
|
468e5148b3 | ||
|
|
7ed7017d94 | ||
|
|
10f4d4565d | ||
|
|
fa28b1f243 | ||
|
|
3203978c65 | ||
|
|
8dbd350305 | ||
|
|
9aea48988c | ||
|
|
0e0d74624b | ||
|
|
fffb0bdce5 | ||
|
|
82acd6a35a | ||
|
|
5cf1eed910 | ||
|
|
8c5476848a | ||
|
|
4df874dd7f | ||
|
|
906268caa7 | ||
|
|
1ae5fd8198 | ||
|
|
01d6e02666 | ||
|
|
e10915b565 | ||
|
|
03618f8c95 | ||
|
|
071917e1b2 | ||
|
|
1f6cec5ff3 | ||
|
|
fe7ee54772 | ||
|
|
f5ba8a8478 | ||
|
|
f4450abcf9 | ||
|
|
5e095a3a4d | ||
|
|
3eb68691b8 | ||
|
|
f0e415c1e1 | ||
|
|
cfa443421b | ||
|
|
296e4767ea | ||
|
|
fa795b478a | ||
|
|
40e214cd76 | ||
|
|
7ec4501d37 | ||
|
|
9e0cc9d630 | ||
|
|
9d2cc36a0e | ||
|
|
e4e1062338 | ||
|
|
0968aa6de7 | ||
|
|
f736bb9d86 | ||
|
|
6e7d72c158 | ||
|
|
1f7d2aae34 | ||
|
|
76edd58c3e | ||
|
|
923ff1e3ca | ||
|
|
33d81b98be | ||
|
|
234394e2df | ||
|
|
7b3ef36925 | ||
|
|
c862e57095 | ||
|
|
0229ba1283 | ||
|
|
4e84e02684 | ||
|
|
80b392ba8e | ||
|
|
e13edcba86 | ||
|
|
e95b015990 | ||
|
|
aebb7627f5 | ||
|
|
6285c13367 | ||
|
|
8f18e27691 | ||
|
|
7f3d1257ff | ||
|
|
e7b37f1737 | ||
|
|
18385b8363 | ||
|
|
d3aa6839f4 | ||
|
|
cb3d36ad5a | ||
|
|
1ad16ea481 | ||
|
|
b464703493 | ||
|
|
4d67456953 | ||
|
|
44fdf09f7b | ||
|
|
b2cdedcec2 | ||
|
|
1d9ebbc740 | ||
|
|
5a3e0c869e | ||
|
|
64e7f77040 | ||
|
|
cc5dd09db3 | ||
|
|
30a9b333ba | ||
|
|
261c174d97 | ||
|
|
a6b4ef3d29 | ||
|
|
74b7d6bc14 | ||
|
|
3d177bd8b5 | ||
|
|
62d9150ef5 | ||
|
|
4227ef37bb | ||
|
|
1652c942d8 | ||
|
|
5d56a5b435 | ||
|
|
7c9fe49b51 | ||
|
|
bb80189110 | ||
|
|
1eac8ab060 | ||
|
|
1923d22832 | ||
|
|
70e40dd53d | ||
|
|
7661972907 | ||
|
|
bb2f06fc73 | ||
|
|
fadb24f26a | ||
|
|
5d8ae9bf17 | ||
|
|
8e139e5cd7 | ||
|
|
da55e192ba | ||
|
|
57d266423a | ||
|
|
d29598480f | ||
|
|
7d6cf09e02 | ||
|
|
8b417f0e1e | ||
|
|
e743d3e487 | ||
|
|
a947270ff7 | ||
|
|
a1fe72fa4a | ||
|
|
85bf0db1e8 | ||
|
|
c6bb33407a | ||
|
|
e2d89615d5 | ||
|
|
ed360ca42f | ||
|
|
6b172a2131 | ||
|
|
e7b8b9d2dd | ||
|
|
152d7203ac | ||
|
|
baf9b5e9bb | ||
|
|
cbda5cb9b2 | ||
|
|
6ab1efe806 | ||
|
|
08a6b105e5 | ||
|
|
8fdf20ec2b | ||
|
|
4e6558b44a | ||
|
|
5ffda39949 | ||
|
|
79cbdf745a | ||
|
|
deec081e74 | ||
|
|
2fb6b99620 | ||
|
|
7b0b2ebd37 | ||
|
|
2a5b403768 | ||
|
|
aa2b48262b | ||
|
|
a826e66f11 | ||
|
|
8390c51fca | ||
|
|
58db3d68eb | ||
|
|
99a24e7883 | ||
|
|
76adf3151b | ||
|
|
854369a67c | ||
|
|
d5e9da898f | ||
|
|
1c3c25097b | ||
|
|
485bc2fd88 | ||
|
|
fe5707421f | ||
|
|
6caf484379 | ||
|
|
10c559acbf | ||
|
|
186cc71273 | ||
|
|
da915fdadf | ||
|
|
e469cdf190 | ||
|
|
190f9219d5 | ||
|
|
956059093c | ||
|
|
ce349b05df | ||
|
|
bf7b1adb89 | ||
|
|
d1920b380d | ||
|
|
9ae7f4dc4f | ||
|
|
1d76ffb03b | ||
|
|
7c6f71019a | ||
|
|
8f37d5c24e | ||
|
|
c3e063b0aa | ||
|
|
320eaab501 | ||
|
|
2935048126 | ||
|
|
12345dfed8 | ||
|
|
78db448fff | ||
|
|
58f1209a70 | ||
|
|
e106525498 | ||
|
|
f0284298ad | ||
|
|
03a9d6928d | ||
|
|
5219c94af5 | ||
|
|
a970bffd00 | ||
|
|
f95599f4d4 | ||
|
|
c606ae1574 | ||
|
|
9b8fa27457 | ||
|
|
42956f6f09 | ||
|
|
417f868693 | ||
|
|
4d644dfb73 | ||
|
|
3315012c95 | ||
|
|
8660fd1af2 | ||
|
|
280034d2ab | ||
|
|
fa9ac8a850 | ||
|
|
41af9f9e84 | ||
|
|
23d9ca0ec4 | ||
|
|
9f595d2fa3 | ||
|
|
41c5d1cd91 | ||
|
|
933e1c8e0c | ||
|
|
3d2dc70845 | ||
|
|
0892c6f37c | ||
|
|
c731ca1ffd | ||
|
|
fdbb12eced | ||
|
|
359092510b | ||
|
|
45796af99d | ||
|
|
6bcdbfbf84 | ||
|
|
6d674a96a1 | ||
|
|
a3f58db271 | ||
|
|
2c3252bc5c | ||
|
|
d790e81db2 | ||
|
|
684cbb8f5c | ||
|
|
0563a78902 | ||
|
|
5053891183 | ||
|
|
f06c5e7af1 | ||
|
|
96e60d29b7 | ||
|
|
7fb1760f42 | ||
|
|
4c2d834fca | ||
|
|
6aed3e7d30 | ||
|
|
fb260e8382 | ||
|
|
5040a69c28 | ||
|
|
38df355850 | ||
|
|
891d60a9ad | ||
|
|
a750ed2c24 | ||
|
|
85320f8fd0 | ||
|
|
2974b57279 | ||
|
|
0c306c8f81 | ||
|
|
05f4bc701f | ||
|
|
86d84d444c | ||
|
|
0c764d2b03 | ||
|
|
bf448a6421 | ||
|
|
b5095134df | ||
|
|
bfaa709c2e | ||
|
|
3954b7c2a3 | ||
|
|
727887b6dc | ||
|
|
c2f0e2f8da | ||
|
|
bab9170bdc | ||
|
|
e26214c287 | ||
|
|
fd83fb931e | ||
|
|
9d1ba01f11 | ||
|
|
d46a244159 | ||
|
|
b185a55c3b | ||
|
|
4294befd8b | ||
|
|
d04dfba748 | ||
|
|
615082f1fa | ||
|
|
b741dab392 | ||
|
|
e0ee29b9b6 | ||
|
|
694ae19131 | ||
|
|
f5f5ff4257 | ||
|
|
597d3b9e7b | ||
|
|
f238eb1dbc | ||
|
|
4b5b655e61 | ||
|
|
52fc9a970c | ||
|
|
100d8ce724 | ||
|
|
e31133e3b0 | ||
|
|
26e89b4b3c | ||
|
|
637e7224c9 | ||
|
|
c529405c65 | ||
|
|
de0a637d7c | ||
|
|
536651d954 | ||
|
|
b9c893dbc9 | ||
|
|
6b6d121149 | ||
|
|
3eaad4bbc9 | ||
|
|
44dd5d86bc | ||
|
|
537c8e77ba | ||
|
|
5866ef6d2a | ||
|
|
0184ebda4f | ||
|
|
078a694834 | ||
|
|
e5272c9be6 | ||
|
|
596e33bb9e | ||
|
|
081c085c0f | ||
|
|
64e3a23bfd | ||
|
|
58446472bb | ||
|
|
d3dae9eba4 | ||
|
|
8c0f76a7de | ||
|
|
4d235ca93a | ||
|
|
5b86b255d4 | ||
|
|
468b1a4346 | ||
|
|
7f87f0f8ea | ||
|
|
5d13f6b527 | ||
|
|
0318ff75d9 | ||
|
|
06de3a9ba1 | ||
|
|
d838764849 | ||
|
|
8ea5f2cfce | ||
|
|
23e46e5885 | ||
|
|
d271c9f407 | ||
|
|
97041036d3 | ||
|
|
805fa175fc | ||
|
|
985ea00b16 | ||
|
|
3919b0a0b4 | ||
|
|
63e04b3c2d | ||
|
|
a801c2d474 | ||
|
|
3b45005127 | ||
|
|
0f0fc59c9f | ||
|
|
f2cc84c99a | ||
|
|
4a8b2cf10f |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
@@ -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. */
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -9,7 +9,7 @@ S
|
||||
0040004100420043004400450046004700480049004A004B004C004D004E004F
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E0000
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -10,8 +10,8 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC0081201A0083201E2026202020210088203001602039015A0164017D0179
|
||||
009020182019201C201D202220132014009821220161203A015B0165017E017A
|
||||
20AC0000201A0000201E2026202020210000203001602039015A0164017D0179
|
||||
000020182019201C201D202220132014000021220161203A015B0165017E017A
|
||||
00A002C702D8014100A4010400A600A700A800A9015E00AB00AC00AD00AE017B
|
||||
00B000B102DB014200B400B500B600B700B80105015F00BB013D02DD013E017C
|
||||
015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
|
||||
|
||||
@@ -11,7 +11,7 @@ S
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
04020403201A0453201E20262020202120AC203004092039040A040C040B040F
|
||||
045220182019201C201D202220132014009821220459203A045A045C045B045F
|
||||
045220182019201C201D202220132014000021220459203A045A045C045B045F
|
||||
00A0040E045E040800A4049000A600A7040100A9040400AB00AC00AD00AE0407
|
||||
00B000B104060456049100B500B600B704512116045400BB0458040504550457
|
||||
0410041104120413041404150416041704180419041A041B041C041D041E041F
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC0081201A0192201E20262020202102C62030016020390152008D017D008F
|
||||
009020182019201C201D20222013201402DC21220161203A0153009D017E0178
|
||||
20AC0000201A0192201E20262020202102C620300160203901520000017D0000
|
||||
000020182019201C201D20222013201402DC21220161203A01530000017E0178
|
||||
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
|
||||
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
|
||||
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC0081201A0192201E20262020202100882030008A2039008C008D008E008F
|
||||
009020182019201C201D20222013201400982122009A203A009C009D009E009F
|
||||
20AC0000201A0192201E20262020202100002030000020390000000000000000
|
||||
000020182019201C201D202220132014000021220000203A0000000000000000
|
||||
00A00385038600A300A400A500A600A700A800A9000000AB00AC00AD00AE2015
|
||||
00B000B100B200B3038400B500B600B703880389038A00BB038C00BD038E038F
|
||||
0390039103920393039403950396039703980399039A039B039C039D039E039F
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC0081201A0192201E20262020202102C62030016020390152008D008E008F
|
||||
009020182019201C201D20222013201402DC21220161203A0153009D009E0178
|
||||
20AC0000201A0192201E20262020202102C62030016020390152000000000000
|
||||
000020182019201C201D20222013201402DC21220161203A0153000000000178
|
||||
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
|
||||
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
|
||||
00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC0081201A0192201E20262020202102C62030008A2039008C008D008E008F
|
||||
009020182019201C201D20222013201402DC2122009A203A009C009D009E009F
|
||||
20AC0000201A0192201E20262020202102C62030000020390000000000000000
|
||||
000020182019201C201D20222013201402DC21220000203A0000000000000000
|
||||
00A000A100A200A320AA00A500A600A700A800A900D700AB00AC00AD00AE00AF
|
||||
00B000B100B200B300B400B500B600B700B800B900F700BB00BC00BD00BE00BF
|
||||
05B005B105B205B305B405B505B605B705B805B9000005BB05BC05BD05BE05BF
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC0081201A0083201E20262020202100882030008A2039008C00A802C700B8
|
||||
009020182019201C201D20222013201400982122009A203A009C00AF02DB009F
|
||||
20AC0000201A0000201E2026202020210000203000002039000000A802C700B8
|
||||
000020182019201C201D202220132014000021220000203A000000AF02DB0000
|
||||
00A0000000A200A300A4000000A600A700D800A9015600AB00AC00AD00AE00C6
|
||||
00B000B100B200B300B400B500B600B700F800B9015700BB00BC00BD00BE00E6
|
||||
0104012E0100010600C400C501180112010C00C90179011601220136012A013B
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC0081201A0192201E20262020202102C62030008A20390152008D008E008F
|
||||
009020182019201C201D20222013201402DC2122009A203A0153009D009E0178
|
||||
20AC0000201A0192201E20262020202102C62030000020390152000000000000
|
||||
000020182019201C201D20222013201402DC21220000203A0153000000000178
|
||||
00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
|
||||
00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
|
||||
00C000C100C2010200C400C500C600C700C800C900CA00CB030000CD00CE00CF
|
||||
|
||||
@@ -11,7 +11,7 @@ S
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
00B000B72219221A259225002502253C2524252C251C25342510250C25142518
|
||||
03B2221E03C600B100BD00BC224800AB00BBFEF7FEF8009B009CFEFBFEFC009F
|
||||
03B2221E03C600B100BD00BC224800AB00BBFEF7FEF800000000FEFBFEFC0000
|
||||
00A000ADFE8200A300A4FE8400000000FE8EFE8FFE95FE99060CFE9DFEA1FEA5
|
||||
0660066106620663066406650666066706680669FED1061BFEB1FEB5FEB9061F
|
||||
00A2FE80FE81FE83FE85FECAFE8BFE8DFE91FE93FE97FE9BFE9FFEA3FEA7FEA9
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080008100820083008400850386008700B700AC00A620182019038820150389
|
||||
038A03AA038C00930094038E03AB00A9038F00B200B303AC00A303AD03AE03AF
|
||||
0000000000000000000000000386000000B700AC00A620182019038820150389
|
||||
038A03AA038C00000000038E03AB00A9038F00B200B303AC00A303AD03AE03AF
|
||||
03CA039003CC03CD039103920393039403950396039700BD0398039900AB00BB
|
||||
25912592259325022524039A039B039C039D256325512557255D039E039F2510
|
||||
25142534252C251C2500253C03A003A1255A25542569256625602550256C03A3
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
20AC008100820083008420260086008700880089008A008B008C008D008E008F
|
||||
009020182019201C201D20222013201400980099009A009B009C009D009E009F
|
||||
20AC000000000000000020260000000000000000000000000000000000000000
|
||||
000020182019201C201D20222013201400000000000000000000000000000000
|
||||
00A00E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
|
||||
0E100E110E120E130E140E150E160E170E180E190E1A0E1B0E1C0E1D0E1E0E1F
|
||||
0E200E210E220E230E240E250E260E270E280E290E2A0E2B0E2C0E2D0E2E0E2F
|
||||
|
||||
@@ -10,7 +10,7 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080000000000000000000850086000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
|
||||
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
|
||||
|
||||
@@ -10,7 +10,7 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -10,8 +10,8 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
2730273127322733273427352736273727382739273A273B273C273D273E273F
|
||||
2740274127422743274427452746274727482749274A274B25CF274D25A0274F
|
||||
27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000276127622763276427652766276726632666266526602460246124622463
|
||||
2464246524662467246824692776277727782779277A277B277C277D277E277F
|
||||
2780278127822783278427852786278727882789278A278B278C278D278E278F
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# Encoding file: ebcdic, single-byte
|
||||
S
|
||||
006F 0 1
|
||||
00
|
||||
|
||||
@@ -10,8 +10,8 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -10,8 +10,8 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D0000008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -10,8 +10,8 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D203E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
|
||||
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
|
||||
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D203E007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
|
||||
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
|
||||
FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
2730273127322733273427352736273727382739273A273B273C273D273E273F
|
||||
2740274127422743274427452746274727482749274A274B25CF274D25A0274F
|
||||
27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
|
||||
F8D7F8D8F8D9F8DAF8DBF8DCF8DDF8DEF8DFF8E0F8E1F8E2F8E3F8E4008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
F8D7F8D8F8D9F8DAF8DBF8DCF8DDF8DEF8DFF8E0F8E1F8E2F8E3F8E400000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000276127622763276427652766276726632666266526602460246124622463
|
||||
2464246524662467246824692776277727782779277A277B277C277D277E277F
|
||||
2780278127822783278427852786278727882789278A278B278C278D278E278F
|
||||
|
||||
@@ -10,7 +10,7 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
00A0FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
|
||||
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
|
||||
|
||||
@@ -10,7 +10,7 @@ M
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0080000000000000000000850086008700000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
|
||||
FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
|
||||
|
||||
@@ -10,8 +10,8 @@ S
|
||||
03A0039803A103A303A403A503C203A9039E03A80396005B2234005D22A5005F
|
||||
F8E503B103B203C703B403B503C603B303B703B903D503BA03BB03BC03BD03BF
|
||||
03C003B803C103C303C403C503D603C903BE03C803B6007B007C007D223C007F
|
||||
0080008100820083008400850086008700880089008A008B008C008D008E008F
|
||||
0090009100920093009400950096009700980099009A009B009C009D009E009F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
000003D2203222642044221E0192266326662665266021942190219121922193
|
||||
00B000B12033226500D7221D2202202200F72260226122482026F8E6F8E721B5
|
||||
21352111211C21182297229522052229222A2283228722842282228622082209
|
||||
|
||||
@@ -9,7 +9,7 @@ S
|
||||
0040004100420043004400450046004700480049004A004B004C004D004E004F
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E0000
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
0000000000000000000000000000000000000000000000000000000000000000
|
||||
00000E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
|
||||
|
||||
@@ -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]]
|
||||
|
||||
@@ -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]]
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 ""
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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:
|
||||
@@ -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
@@ -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
@@ -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
@@ -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]
|
||||
|
||||
@@ -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; \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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"
|
||||
|
||||
Vendored
+12
-62
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user