Compare commits
266
Commits
pyk-emptystring
...
zipfs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8729900f69 | ||
|
|
93fe453205 | ||
|
|
cb9f3f9268 | ||
|
|
6d88b01d1e | ||
|
|
77a26f5c95 | ||
|
|
9cec6bac27 | ||
|
|
2f19b0f346 | ||
|
|
265c9d416f | ||
|
|
db610f91eb | ||
|
|
afb5bf5583 | ||
|
|
9b7ce068fe | ||
|
|
820a737a2f | ||
|
|
c2d61d8dbc | ||
|
|
fb0bf9d1b9 | ||
|
|
01dd016ad8 | ||
|
|
d660b325b5 | ||
|
|
26b477b907 | ||
|
|
89ff80fbdd | ||
|
|
90afac281e | ||
|
|
aed158b518 | ||
|
|
6c78bf0adc | ||
|
|
8346cad0dd | ||
|
|
de5637f853 | ||
|
|
c1ae69114b | ||
|
|
5902889825 | ||
|
|
04c687936c | ||
|
|
2133e40e58 | ||
|
|
c7cdc550c4 | ||
|
|
7e727bed70 | ||
|
|
164a7f04c0 | ||
|
|
814c867db4 | ||
|
|
d00a212e82 | ||
|
|
7fb72851e8 | ||
|
|
4a3f32b84a | ||
|
|
a1790a1683 | ||
|
|
885a163b3c | ||
|
|
2a46a48670 | ||
|
|
51aecf205d | ||
|
|
367ce9ad48 | ||
|
|
9da2aebeae | ||
|
|
ed5ed756bc | ||
|
|
0839047d8b | ||
|
|
e2a79c2604 | ||
|
|
6cbfdcc4a3 | ||
|
|
94ec3d9431 | ||
|
|
6c1e9f2b0c | ||
|
|
563bd6e4dd | ||
|
|
b418ff1759 | ||
|
|
56ca35e8a9 | ||
|
|
107fb1eb33 | ||
|
|
c911dc937f | ||
|
|
645241afc1 | ||
|
|
03a3c09b1f | ||
|
|
3c57d80efe | ||
|
|
04004f3abc | ||
|
|
155e8a1ad5 | ||
|
|
625aca976a | ||
|
|
e9c0ec1219 | ||
|
|
8047a470ef | ||
|
|
2b739c838a | ||
|
|
983854ad7b | ||
|
|
41a6159754 | ||
|
|
df97278634 | ||
|
|
06fc5fb636 | ||
|
|
e393000b1d | ||
|
|
83d92bd747 | ||
|
|
5a05e0d782 | ||
|
|
9c8f784329 | ||
|
|
1efbaebb6a | ||
|
|
ac47e6953d | ||
|
|
400feb302b | ||
|
|
9c9b3d93f9 | ||
|
|
04d1270786 | ||
|
|
b89a3efc56 | ||
|
|
240e6b50d2 | ||
|
|
215b5dd08d | ||
|
|
a2ce3dab9b | ||
|
|
6a4d06759e | ||
|
|
6966f0a2b1 | ||
|
|
89a84af271 | ||
|
|
5e7a1545a6 | ||
|
|
f4651a5660 | ||
|
|
a0290b85c5 | ||
|
|
8145564d30 | ||
|
|
6d943ef7b5 | ||
|
|
1c13d543f4 | ||
|
|
263de53394 | ||
|
|
a410c0d8d5 | ||
|
|
ecec1703aa | ||
|
|
36a1a69178 | ||
|
|
dffe6bc7f1 | ||
|
|
423f761169 | ||
|
|
ba42e43e97 | ||
|
|
7672af7212 | ||
|
|
eae621b175 | ||
|
|
6d0cc0c589 | ||
|
|
d9bc6cbae2 | ||
|
|
ede72e80ac | ||
|
|
7bf3f83abd | ||
|
|
f7f4cbb151 | ||
|
|
f5e8751307 | ||
|
|
47e9dbdc37 | ||
|
|
8fd1568405 | ||
|
|
78ee8c697e | ||
|
|
5f0cf291f5 | ||
|
|
db133f0144 | ||
|
|
86c6a11cdb | ||
|
|
e383cd7b26 | ||
|
|
3a3fd2954f | ||
|
|
1d768f7890 | ||
|
|
80206cc113 | ||
|
|
f851263f52 | ||
|
|
3ddad4402a | ||
|
|
42259830ab | ||
|
|
8f2cdcfe32 | ||
|
|
3e94587dff | ||
|
|
8270c03fac | ||
|
|
0420e8dd91 | ||
|
|
c433e9b60a | ||
|
|
a64be34c0b | ||
|
|
310ee501e8 | ||
|
|
0104227d89 | ||
|
|
43778c199d | ||
|
|
d7023c5bf4 | ||
|
|
d1f1107ccd | ||
|
|
202ffed8ed | ||
|
|
4e74fe9243 | ||
|
|
fe6c8e39c5 | ||
|
|
39394a7c8c | ||
|
|
db323b6992 | ||
|
|
f803ae2b11 | ||
|
|
174f55c044 | ||
|
|
a270140a3e | ||
|
|
841c04fbac | ||
|
|
232349c3de | ||
|
|
fb2b7d4615 | ||
|
|
b645469c95 | ||
|
|
e295641767 | ||
|
|
c3a18ac8f4 | ||
|
|
f9dda45e97 | ||
|
|
a5c310f993 | ||
|
|
80d9aa777b | ||
|
|
c745f44e3a | ||
|
|
21d4596064 | ||
|
|
5f738db586 | ||
|
|
76bb4d1ea4 | ||
|
|
4db368d595 | ||
|
|
e9e40f5f02 | ||
|
|
c3c935369d | ||
|
|
bd1370959e | ||
|
|
9a7f1bd48c | ||
|
|
47cb19c83f | ||
|
|
f4cc5617a6 | ||
|
|
e48602d674 | ||
|
|
e9a8c42972 | ||
|
|
5bcc7fa342 | ||
|
|
b0c45c3ad0 | ||
|
|
e1e49c9dd1 | ||
|
|
18ba46bf37 | ||
|
|
5b719a2281 | ||
|
|
edbf30e23a | ||
|
|
395d0889b0 | ||
|
|
ba0d107038 | ||
|
|
763f9dff55 | ||
|
|
bbcef5b648 | ||
|
|
25d1f4aa03 | ||
|
|
22f5c55560 | ||
|
|
3cf33e9e9f | ||
|
|
a288c5e54a | ||
|
|
c3e9d3205f | ||
|
|
227fbec0fc | ||
|
|
dc21089720 | ||
|
|
f6bb864fc7 | ||
|
|
982211da16 | ||
|
|
a1740d9766 | ||
|
|
e9795fb407 | ||
|
|
299924e512 | ||
|
|
a03e74efc1 | ||
|
|
3c03a492f9 | ||
|
|
56c5833c4a | ||
|
|
63b07461da | ||
|
|
1c3288f038 | ||
|
|
8ecd6aeb5b | ||
|
|
4d00715902 | ||
|
|
95aeb2a3d6 | ||
|
|
b0a98f480d | ||
|
|
cb73551e8d | ||
|
|
4d946107e7 | ||
|
|
c795f44ea5 | ||
|
|
ecd9567624 | ||
|
|
d6fdfa4624 | ||
|
|
58ace2b1dc | ||
|
|
8f6089f225 | ||
|
|
19627fed47 | ||
|
|
83145e2bb1 | ||
|
|
621c76324a | ||
|
|
e961e1c08a | ||
|
|
e740674cb8 | ||
|
|
23ced66a6b | ||
|
|
b637222a5d | ||
|
|
9a0f7dd2c8 | ||
|
|
440e5fc7dc | ||
|
|
74ed7238b0 | ||
|
|
38d734ddcf | ||
|
|
cbeed9da92 | ||
|
|
a369d46795 | ||
|
|
4594b4f27a | ||
|
|
ff3f0131bd | ||
|
|
5b793fef99 | ||
|
|
13aa1642ac | ||
|
|
d905cc4737 | ||
|
|
d954f3c4ee | ||
|
|
c770024ce1 | ||
|
|
c1f95640c4 | ||
|
|
48ef2b50eb | ||
|
|
071aa09c6e | ||
|
|
10cd3c906d | ||
|
|
0fca37f803 | ||
|
|
9dd94f7396 | ||
|
|
ce65c7b396 | ||
|
|
a80a084de9 | ||
|
|
ddc625f2fe | ||
|
|
842b15b839 | ||
|
|
4506b4536b | ||
|
|
dbe627594e | ||
|
|
130fe11f2b | ||
|
|
3bce1ab6f2 | ||
|
|
fe773c0a46 | ||
|
|
ecc90e3787 | ||
|
|
6e0d4b6761 | ||
|
|
53ad2ab17d | ||
|
|
a2a59dfb75 | ||
|
|
829af34165 | ||
|
|
1579eae899 | ||
|
|
6fcdce9c74 | ||
|
|
ac785323be | ||
|
|
d68207f7ca | ||
|
|
ddc615491d | ||
|
|
b1031c0d07 | ||
|
|
83da0d6374 | ||
|
|
e886aae69e | ||
|
|
adceea62b6 | ||
|
|
348f13ad57 | ||
|
|
dd60d52814 | ||
|
|
428c3163c5 | ||
|
|
410178bb88 | ||
|
|
18eed1d727 | ||
|
|
ce72e40607 | ||
|
|
f038b7fc3d | ||
|
|
30dbc0a75b | ||
|
|
57d33c5027 | ||
|
|
e1c5526cb2 | ||
|
|
290c2ef84f | ||
|
|
073618d375 | ||
|
|
5ddf03d324 | ||
|
|
ac98be85ce | ||
|
|
048fae9de6 | ||
|
|
81735df1fa | ||
|
|
9c32ab0d8b | ||
|
|
861e75f503 | ||
|
|
e891120584 | ||
|
|
2045bb3c21 | ||
|
|
a498488c59 | ||
|
|
dd43ee3dbf | ||
|
|
39ad9eb8f3 | ||
|
|
b30ba5a92b |
Executable → Regular
+13
@@ -453,6 +453,19 @@ If this situation occurs, the first occurrence of the time is chosen.
|
||||
(For this reason, it is wise to have the input string contain the
|
||||
time zone when converting local times. This caveat does not apply to
|
||||
UTC times.)
|
||||
.PP
|
||||
If the interpretation of the groups yields an impossible time because
|
||||
a field is out of range, enough of that field's unit will be added to
|
||||
or subtracted from the time to bring it in range. Thus, if attempting to
|
||||
scan or format day 0 of the month, one day will be subtracted from day
|
||||
1 of the month, yielding the last day of the previous month.
|
||||
.PP
|
||||
If the interpretation of the groups yields an impossible time because
|
||||
a Daylight Saving Time change skips over that time, or an ambiguous
|
||||
time because a Daylight Saving Time change skips back so that the clock
|
||||
observes the given time twice, and no time zone specifier (\fB%z\fR
|
||||
or \fB%Z\fR) is present in the format, the time is interpreted as
|
||||
if the clock had not changed.
|
||||
.SH "FORMAT GROUPS"
|
||||
.PP
|
||||
The following format groups are recognized by the \fBclock scan\fR and
|
||||
|
||||
+17
@@ -217,6 +217,19 @@ information is instead sent to the console, if one is present, or is
|
||||
discarded.
|
||||
.RS
|
||||
.PP
|
||||
Note that the current escape resp. quoting of arguments for windows works only
|
||||
with executables using CommandLineToArgv, CRT-library or similar, as well as
|
||||
with the windows batch files (excepting the newline, see below).
|
||||
Although it is the common escape algorithm, but, in fact, the way how the
|
||||
executable parses the command-line (resp. splits it into single arguments)
|
||||
is decisive.
|
||||
.PP
|
||||
Unfortunately, there is currently no way to supply newline character within
|
||||
an argument to the batch files (\fB.cmd\fR or \fB.bat\fR) or to the command
|
||||
processor (\fBcmd.exe /c\fR), because this causes truncation of command-line
|
||||
(also the argument chain) on the first newline character.
|
||||
But it works properly with an executable (using CommandLineToArgv, etc).
|
||||
.PP
|
||||
The Tk console text widget does not provide real standard IO capabilities.
|
||||
Under Tk, when redirecting from standard input, all applications will see an
|
||||
immediate end-of-file; information redirected to standard output or standard
|
||||
@@ -409,6 +422,10 @@ that sometimes pop up:
|
||||
With the file \fIcmp.bat\fR looking something like:
|
||||
.PP
|
||||
.CS
|
||||
@gcc %*
|
||||
.CE
|
||||
or like another variant using single parameters:
|
||||
.CS
|
||||
@gcc %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
.CE
|
||||
.SS "WORKING WITH COMMAND BUILT-INS"
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2015 Jan Nijtmans <jan.nijtmans@gmail.com>
|
||||
'\" Copyright (c) 2015 Christian Werner <chw@ch-werner.de>
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH Tclzipfs 3 8.7 Tcl "Tcl Library Procedures"
|
||||
.so man.macros
|
||||
.BS
|
||||
.SH NAME
|
||||
Tclzipfs_Init, Tclzipfs_SafeInit, Tclzipfs_Mount, Tclzipfs_Unmount \- handle ZIP files as VFS
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tclZipfs.h>\fR
|
||||
.sp
|
||||
int
|
||||
\fBTclzipfs_Init\fR(\fIinterp\fR)
|
||||
.sp
|
||||
int
|
||||
\fBTclzipfs_SafeInit\fR(\fIinterp\fR)
|
||||
.sp
|
||||
int
|
||||
\fBTclzipfs_Mount\fR(\fIinterp, zipname, mntpt, passwd\fR)
|
||||
.sp
|
||||
int
|
||||
\fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR)
|
||||
.SH ARGUMENTS
|
||||
.AS Tcl_Interp **termPtr
|
||||
.AP Tcl_Interp *interp in
|
||||
Interpreter in which the zip file system is mounted. The interpreter's result is
|
||||
modified to hold the result or error message from the script.
|
||||
.AP "const char" *zipname in
|
||||
Name of a zipfile.
|
||||
.AP "const char" *mntpt in
|
||||
Name of a mount point.
|
||||
.AP "const char" *passwd in
|
||||
An (optional) password.
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
\fBTclzipfs_Init()\fR performs one-time initialization of the file system
|
||||
and registers it process wide. Additionally, a package named \fIzipfs\fR
|
||||
is provided and supplemental Tcl commands are created in the given
|
||||
interpreter \fIinterp\fR.
|
||||
.PP
|
||||
\fBTclzipfs_SafeInit()\fR is the version of \fBTclzipfs_Init()\fR for
|
||||
safe interpreters. It exposes only uncritical supplemental Tcl commands
|
||||
in the given interpreter \fIinterp\fR.
|
||||
.PP
|
||||
\fBTclzipfs_Mount()\fR mount the ZIP archive \fIzipname\fR on the mount
|
||||
point given in \fImntpt\fR using the optional ZIP password \fIpasswd\fR.
|
||||
Errors during that process are reported in the interpreter \fIinterp\fR.
|
||||
If \fIzipname\fR is a NULL pointer, information on all currently mounted
|
||||
ZIP file systems is written into \fIinterp\fR's result as a sequence of
|
||||
mount points and ZIP file names.
|
||||
.PP
|
||||
\fBTclzipfs_Unmount()\fR undoes the effect of \fBTclzipfs_Mount()\fR,
|
||||
i.e. it unmounts the mounted ZIP archive file \fIzipname\fR. Errors are
|
||||
reported in the interpreter \fIinterp\fR.
|
||||
.SH KEYWORDS
|
||||
compress, filesystem, zip
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2015 Jan Nijtmans <jan.nijtmans@gmail.com>
|
||||
'\" Copyright (c) 2015 Christian Werner <chw@ch-werner.de>
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH zipfs n 1.0 Zipfs "zipfs Commands"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
zipfs \- Mount and work with ZIP files within Tcl
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require zipfs \fR?\fB1.0\fR?
|
||||
.sp
|
||||
\fBzipfs exists\fR \fIfilename\fR
|
||||
\fBzipfs find\fR \fIdir\fR
|
||||
\fBzipfs info\fR \fIfilename\fR
|
||||
\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
|
||||
\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
|
||||
\fBzipfs mount\fR \fI?zipfile?\fR \fI?mountpoint?\fR \fI?password?\fR
|
||||
\fBzipfs unmount\fR \fIzipfile\fR
|
||||
.fi
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBzipfs\fR package provides tcl with the ability to mount
|
||||
the contents of a zip file as a virtual file system.
|
||||
.TP
|
||||
\fBzipfs exists\fR \fIfilename\fR
|
||||
.
|
||||
Return 1 if the given filename exists in the mounted zipfs and 0 if it does not.
|
||||
.TP
|
||||
\fBzipfs find\fR \fIdir\fR
|
||||
.
|
||||
Recursively lists files including and below the directory \fIdir\fR.
|
||||
The result list consists of relative path names starting from the
|
||||
given directory. This command is also used by the \fBzipfs mkzip\fR
|
||||
and \fBzipfs mkimg\fR commands.
|
||||
.TP
|
||||
\fBzipfs info\fR \fIfile\fR
|
||||
.
|
||||
Return information about the given file in the mounted zipfs. The information
|
||||
consists of (1) the name of the ZIP archive file that contains the file,
|
||||
(2) the size of the file after decompressions, (3) the compressed size of
|
||||
the file, and (4) the offset of the compressed data in the ZIP archive file.
|
||||
.RS
|
||||
.PP
|
||||
Note: querying the mount point gives the start of zip data offset in (4),
|
||||
which can be used to truncate the zip info off an executable.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
|
||||
.
|
||||
Return a list of all files in the mounted zipfs. The order of the names
|
||||
in the list is arbitrary.
|
||||
.TP
|
||||
\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
|
||||
.
|
||||
Creates an image (potentially a new executable file) similar to
|
||||
\fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified,
|
||||
this file is prepended in front of the ZIP archive, otherwise the file
|
||||
returned by \fBTcl_NameOfExecutable(3)\fR (i.e. the executable file of
|
||||
the running process) is used. If the \fIpassword\fR parameter is not empty,
|
||||
an obfuscated version of that password is placed between the image and ZIP
|
||||
chunks of the output file and the contents of the ZIP chunk are protected
|
||||
with that password.
|
||||
.RS
|
||||
.PP
|
||||
Caution: highly experimental, not usable on Android, only partially tested
|
||||
on Linux and Windows.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
.
|
||||
For the clear text \fIpassword\fR argument an obfuscated string version
|
||||
is returned with the same format used in the \fBzipfs mkimg\fR command.
|
||||
.TP
|
||||
\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
|
||||
.
|
||||
Creates a ZIP archive file named \fIoutfile\fR from the contents of the input
|
||||
directory \fIindir\fR (contained regular files only) with optional ZIP
|
||||
password \fIpassword\fR. While processing the files below \fIindir\fR the
|
||||
optional file name prefix given in \fIstrip\fR is stripped off the beginning
|
||||
of the respective file name.
|
||||
.RS
|
||||
.PP
|
||||
Caution: the choice of the \fIindir\fR parameter
|
||||
(less the optional stripped prefix) determines the later root name of the
|
||||
archive's content.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs mount ?\fIzipfile\fR? ?\fImountpoint\fR? ?\fIpassword\fR?
|
||||
.
|
||||
The \fBzipfs mount\fR command mounts a ZIP archive file as a VFS.
|
||||
After this command executes, files contained in \fIzipfile\fR
|
||||
will appear to Tcl to be regular files at the mount point.
|
||||
.RS
|
||||
.PP
|
||||
With no \fImountpoint\fR, returns the mount point for \fIzipfile\fR.
|
||||
With no \fIzipfile\fR, return all zipfile/mount point pairs.
|
||||
If \fImountpoint\fR is specified as an empty string, the mount point
|
||||
will be the current directory. If \fIpassword\fR is specified, files from
|
||||
\fIzipfile\fR are decrypted using this password when read.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs unmount \fIzipfile\fR
|
||||
.
|
||||
Unmounts a previously mounted ZIP archive file \fIzipfile\fR.
|
||||
.SH "SEE ALSO"
|
||||
tclsh(1), file(n), zlib(n)
|
||||
.SH "KEYWORDS"
|
||||
compress, filesystem, zip
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" End:
|
||||
+265
-259
@@ -137,8 +137,8 @@ static const crange alphaRangeTable[] = {
|
||||
{0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6},
|
||||
{0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374},
|
||||
{0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5},
|
||||
{0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
|
||||
{0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
|
||||
{0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x560, 0x588},
|
||||
{0x5d0, 0x5ea}, {0x5ef, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
|
||||
{0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
|
||||
{0x800, 0x815}, {0x840, 0x858}, {0x860, 0x86a}, {0x8a0, 0x8b4},
|
||||
{0x8b6, 0x8bd}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980},
|
||||
@@ -165,45 +165,42 @@ static const crange alphaRangeTable[] = {
|
||||
{0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
|
||||
{0x16f1, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731},
|
||||
{0x1740, 0x1751}, {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3},
|
||||
{0x1820, 0x1877}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5},
|
||||
{0x1820, 0x1878}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5},
|
||||
{0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
|
||||
{0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
|
||||
{0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23},
|
||||
{0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec},
|
||||
{0x1cee, 0x1cf1}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d},
|
||||
{0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d},
|
||||
{0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc},
|
||||
{0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4},
|
||||
{0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d},
|
||||
{0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149},
|
||||
{0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee},
|
||||
{0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6},
|
||||
{0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035},
|
||||
{0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff},
|
||||
{0x3105, 0x312e}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff},
|
||||
{0x3400, 0x4db5}, {0x4e00, 0x9fea}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd},
|
||||
{0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d},
|
||||
{0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae},
|
||||
{0xa7b0, 0xa7b7}, {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a},
|
||||
{0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7},
|
||||
{0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2},
|
||||
{0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28},
|
||||
{0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf},
|
||||
{0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4},
|
||||
{0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26},
|
||||
{0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2},
|
||||
{0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e},
|
||||
{0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e},
|
||||
{0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e},
|
||||
{0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e},
|
||||
{0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d},
|
||||
{0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28},
|
||||
{0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d},
|
||||
{0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74},
|
||||
{0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe},
|
||||
{0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
|
||||
#if TCL_UTF_MAX > 4
|
||||
{0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba},
|
||||
{0x1cbd, 0x1cbf}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf},
|
||||
{0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
|
||||
{0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc},
|
||||
{0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb},
|
||||
{0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c},
|
||||
{0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139},
|
||||
{0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e},
|
||||
{0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67},
|
||||
{0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6},
|
||||
{0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6},
|
||||
{0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f},
|
||||
{0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e},
|
||||
{0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef},
|
||||
{0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f},
|
||||
{0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f},
|
||||
{0xa722, 0xa788}, {0xa78b, 0xa7b9}, {0xa7f7, 0xa801}, {0xa803, 0xa805},
|
||||
{0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873}, {0xa882, 0xa8b3},
|
||||
{0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946}, {0xa960, 0xa97c},
|
||||
{0xa984, 0xa9b2}, {0xa9e0, 0xa9e4}, {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe},
|
||||
{0xaa00, 0xaa28}, {0xaa40, 0xaa42}, {0xaa44, 0xaa4b}, {0xaa60, 0xaa76},
|
||||
{0xaa7e, 0xaaaf}, {0xaab9, 0xaabd}, {0xaadb, 0xaadd}, {0xaae0, 0xaaea},
|
||||
{0xaaf2, 0xaaf4}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
|
||||
{0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab65},
|
||||
{0xab70, 0xabe2}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
|
||||
{0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
|
||||
{0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1},
|
||||
{0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb},
|
||||
{0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a},
|
||||
{0xff66, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7},
|
||||
{0xffda, 0xffdc}
|
||||
#if CHRBITS > 16
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
|
||||
{0x10300, 0x1031f}, {0x1032d, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
|
||||
@@ -212,23 +209,25 @@ static const crange alphaRangeTable[] = {
|
||||
{0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
|
||||
{0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e},
|
||||
{0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7},
|
||||
{0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c},
|
||||
{0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {0x10a60, 0x10a7c},
|
||||
{0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
|
||||
{0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af},
|
||||
{0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
|
||||
{0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
|
||||
{0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
|
||||
{0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
|
||||
{0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
|
||||
{0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
|
||||
{0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10d00, 0x10d23}, {0x10f00, 0x10f1c},
|
||||
{0x10f30, 0x10f45}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8},
|
||||
{0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
|
||||
{0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, {0x11305, 0x1130c},
|
||||
{0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361},
|
||||
{0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, {0x11580, 0x115ae},
|
||||
{0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, {0x11700, 0x1171a},
|
||||
{0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
|
||||
{0x11a86, 0x11a89}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c2e},
|
||||
{0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x12000, 0x12399},
|
||||
{0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38},
|
||||
{0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43},
|
||||
{0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
|
||||
{0x17000, 0x187ec}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
|
||||
{0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x11d60, 0x11d65},
|
||||
{0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2}, {0x12000, 0x12399}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
|
||||
{0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
|
||||
{0x16b7d, 0x16b8f}, {0x16e40, 0x16e7f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
|
||||
{0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
|
||||
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
|
||||
{0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9},
|
||||
{0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
|
||||
@@ -264,17 +263,18 @@ static const chr alphaCharTable[] = {
|
||||
0x1baf, 0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f,
|
||||
0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184,
|
||||
0x2cf2, 0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b,
|
||||
0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5,
|
||||
0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
|
||||
#if TCL_UTF_MAX > 4
|
||||
0x303c, 0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa8fe, 0xa9cf, 0xaa7a, 0xaab1,
|
||||
0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43,
|
||||
0xfb44
|
||||
#if CHRBITS > 16
|
||||
,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
|
||||
0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332,
|
||||
0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11a00,
|
||||
0x11a3a, 0x11a50, 0x11c40, 0x11d08, 0x11d09, 0x11d46, 0x16f50, 0x16fe0, 0x16fe1,
|
||||
0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22,
|
||||
0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51,
|
||||
0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62,
|
||||
0x1ee64, 0x1ee7e
|
||||
0x109bf, 0x10a00, 0x10f27, 0x11144, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f,
|
||||
0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644,
|
||||
0x118ff, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d, 0x11c40, 0x11d08, 0x11d09, 0x11d46,
|
||||
0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2,
|
||||
0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39,
|
||||
0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57,
|
||||
0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -288,7 +288,7 @@ static const crange controlRangeTable[] = {
|
||||
{0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x605}, {0x200b, 0x200f},
|
||||
{0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
|
||||
{0xfff9, 0xfffb}
|
||||
#if TCL_UTF_MAX > 4
|
||||
#if CHRBITS > 16
|
||||
,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd},
|
||||
{0x100000, 0x10fffd}
|
||||
#endif
|
||||
@@ -298,8 +298,8 @@ static const crange controlRangeTable[] = {
|
||||
|
||||
static const chr controlCharTable[] = {
|
||||
0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x110bd, 0xe0001
|
||||
#if CHRBITS > 16
|
||||
,0x110bd, 0x110cd, 0xe0001
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -320,12 +320,12 @@ static const crange digitRangeTable[] = {
|
||||
{0x1c50, 0x1c59}, {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909},
|
||||
{0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9},
|
||||
{0xff10, 0xff19}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
|
||||
{0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9},
|
||||
{0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9},
|
||||
{0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59},
|
||||
{0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
|
||||
#if CHRBITS > 16
|
||||
,{0x104a0, 0x104a9}, {0x10d30, 0x10d39}, {0x11066, 0x1106f}, {0x110f0, 0x110f9},
|
||||
{0x11136, 0x1113f}, {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459},
|
||||
{0x114d0, 0x114d9}, {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739},
|
||||
{0x118e0, 0x118e9}, {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x11da0, 0x11da9},
|
||||
{0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -348,19 +348,20 @@ static const crange punctRangeTable[] = {
|
||||
{0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7},
|
||||
{0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e},
|
||||
{0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998},
|
||||
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e49},
|
||||
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e4e},
|
||||
{0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
|
||||
{0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
|
||||
{0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
|
||||
{0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d},
|
||||
{0xff5f, 0xff65}
|
||||
#if TCL_UTF_MAX > 4
|
||||
#if CHRBITS > 16
|
||||
,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
|
||||
{0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
|
||||
{0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
|
||||
{0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
|
||||
{0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, {0x11c41, 0x11c45},
|
||||
{0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
|
||||
{0x10b99, 0x10b9c}, {0x10f55, 0x10f59}, {0x11047, 0x1104d}, {0x110be, 0x110c1},
|
||||
{0x11140, 0x11143}, {0x111c5, 0x111c8}, {0x111dd, 0x111df}, {0x11238, 0x1123d},
|
||||
{0x1144b, 0x1144f}, {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c},
|
||||
{0x1173c, 0x1173e}, {0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2},
|
||||
{0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x16e97, 0x16e9a},
|
||||
{0x1da87, 0x1da8b}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -371,18 +372,20 @@ static const chr punctCharTable[] = {
|
||||
0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
|
||||
0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
|
||||
0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970,
|
||||
0x9fd, 0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9,
|
||||
0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736,
|
||||
0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e,
|
||||
0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe,
|
||||
0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673,
|
||||
0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df,
|
||||
0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68,
|
||||
0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
|
||||
#if TCL_UTF_MAX > 4
|
||||
0x9fd, 0xa76, 0xaf0, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14,
|
||||
0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c,
|
||||
0x1735, 0x1736, 0x1944, 0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3,
|
||||
0x207d, 0x207e, 0x208d, 0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc,
|
||||
0x29fd, 0x2cfe, 0x2cff, 0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe,
|
||||
0xa4ff, 0xa673, 0xa67e, 0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f,
|
||||
0xa9de, 0xa9df, 0xaade, 0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f,
|
||||
0xfe63, 0xfe68, 0xfe6a, 0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f,
|
||||
0xff5b, 0xff5d
|
||||
#if CHRBITS > 16
|
||||
,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
|
||||
0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
|
||||
0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f
|
||||
0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x1183b,
|
||||
0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f,
|
||||
0x1e95e, 0x1e95f
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -413,25 +416,25 @@ static const crange lowerRangeTable[] = {
|
||||
{0x61, 0x7a}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x17e, 0x180},
|
||||
{0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
|
||||
{0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
|
||||
{0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd},
|
||||
{0x1c80, 0x1c88}, {0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a},
|
||||
{0x1e95, 0x1e9d}, {0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27},
|
||||
{0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67},
|
||||
{0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7},
|
||||
{0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7},
|
||||
{0x1ff2, 0x1ff4}, {0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b},
|
||||
{0x2d00, 0x2d25}, {0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795},
|
||||
{0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06},
|
||||
{0xfb13, 0xfb17}, {0xff41, 0xff5a}
|
||||
#if TCL_UTF_MAX > 4
|
||||
{0x3ef, 0x3f3}, {0x430, 0x45f}, {0x560, 0x588}, {0x10d0, 0x10fa},
|
||||
{0x10fd, 0x10ff}, {0x13f8, 0x13fd}, {0x1c80, 0x1c88}, {0x1d00, 0x1d2b},
|
||||
{0x1d6b, 0x1d77}, {0x1d79, 0x1d9a}, {0x1e95, 0x1e9d}, {0x1eff, 0x1f07},
|
||||
{0x1f10, 0x1f15}, {0x1f20, 0x1f27}, {0x1f30, 0x1f37}, {0x1f40, 0x1f45},
|
||||
{0x1f50, 0x1f57}, {0x1f60, 0x1f67}, {0x1f70, 0x1f7d}, {0x1f80, 0x1f87},
|
||||
{0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4},
|
||||
{0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4}, {0x2146, 0x2149},
|
||||
{0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25}, {0xa72f, 0xa731},
|
||||
{0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xab60, 0xab65},
|
||||
{0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
|
||||
#if CHRBITS > 16
|
||||
,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df},
|
||||
{0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b},
|
||||
{0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503},
|
||||
{0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3},
|
||||
{0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5},
|
||||
{0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b},
|
||||
{0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f},
|
||||
{0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943}
|
||||
{0x16e60, 0x16e7f}, {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467},
|
||||
{0x1d482, 0x1d49b}, {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf},
|
||||
{0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f},
|
||||
{0x1d5ba, 0x1d5d3}, {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f},
|
||||
{0x1d68a, 0x1d6a5}, {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714},
|
||||
{0x1d716, 0x1d71b}, {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788},
|
||||
{0x1d78a, 0x1d78f}, {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -501,8 +504,8 @@ static const chr lowerCharTable[] = {
|
||||
0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c,
|
||||
0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e, 0xa791, 0xa797,
|
||||
0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9,
|
||||
0xa7b5, 0xa7b7, 0xa7fa
|
||||
#if TCL_UTF_MAX > 4
|
||||
0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7fa
|
||||
#if CHRBITS > 16
|
||||
,0x1d4bb, 0x1d7cb
|
||||
#endif
|
||||
};
|
||||
@@ -518,20 +521,22 @@ static const crange upperRangeTable[] = {
|
||||
{0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8},
|
||||
{0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab},
|
||||
{0x3d2, 0x3d4}, {0x3fd, 0x42f}, {0x531, 0x556}, {0x10a0, 0x10c5},
|
||||
{0x13a0, 0x13f5}, {0x1f08, 0x1f0f}, {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f},
|
||||
{0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb},
|
||||
{0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb},
|
||||
{0x210b, 0x210d}, {0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d},
|
||||
{0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70},
|
||||
{0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
|
||||
#if TCL_UTF_MAX > 4
|
||||
{0x13a0, 0x13f5}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cbf}, {0x1f08, 0x1f0f},
|
||||
{0x1f18, 0x1f1d}, {0x1f28, 0x1f2f}, {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d},
|
||||
{0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb}, {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb},
|
||||
{0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112},
|
||||
{0x2119, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2133}, {0x2c00, 0x2c2e},
|
||||
{0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae},
|
||||
{0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
|
||||
#if CHRBITS > 16
|
||||
,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf},
|
||||
{0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac},
|
||||
{0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
|
||||
{0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550},
|
||||
{0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621},
|
||||
{0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa},
|
||||
{0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921}
|
||||
{0x16e40, 0x16e5f}, {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481},
|
||||
{0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a},
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
|
||||
{0x1d54a, 0x1d550}, {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed},
|
||||
{0x1d608, 0x1d621}, {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0},
|
||||
{0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8},
|
||||
{0x1e900, 0x1e921}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -600,8 +605,9 @@ static const chr upperCharTable[] = {
|
||||
0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766,
|
||||
0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780,
|
||||
0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798,
|
||||
0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6
|
||||
#if TCL_UTF_MAX > 4
|
||||
0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6,
|
||||
0xa7b8
|
||||
#if CHRBITS > 16
|
||||
,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
|
||||
0x1d539, 0x1d546, 0x1d7ca
|
||||
#endif
|
||||
@@ -616,85 +622,80 @@ static const chr upperCharTable[] = {
|
||||
static const crange graphRangeTable[] = {
|
||||
{0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37f},
|
||||
{0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x52f}, {0x531, 0x556},
|
||||
{0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7},
|
||||
{0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
|
||||
{0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
|
||||
{0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a},
|
||||
{0x8a0, 0x8b4}, {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983},
|
||||
{0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9},
|
||||
{0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fd},
|
||||
{0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30},
|
||||
{0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75},
|
||||
{0xa81, 0xa83}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
|
||||
{0xaaa, 0xab0}, {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9},
|
||||
{0xacb, 0xacd}, {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff},
|
||||
{0xb01, 0xb03}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
|
||||
{0xb35, 0xb39}, {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63},
|
||||
{0xb66, 0xb77}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95},
|
||||
{0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8},
|
||||
{0xbca, 0xbcd}, {0xbe6, 0xbfa}, {0xc00, 0xc03}, {0xc05, 0xc0c},
|
||||
{0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc3d, 0xc44},
|
||||
{0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc58, 0xc5a}, {0xc60, 0xc63},
|
||||
{0xc66, 0xc6f}, {0xc78, 0xc83}, {0xc85, 0xc8c}, {0xc8e, 0xc90},
|
||||
{0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbc, 0xcc4},
|
||||
{0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, {0xce6, 0xcef},
|
||||
{0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd44},
|
||||
{0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f},
|
||||
{0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6},
|
||||
{0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4},
|
||||
{0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f},
|
||||
{0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4},
|
||||
{0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47},
|
||||
{0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc},
|
||||
{0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d},
|
||||
{0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
|
||||
{0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
|
||||
{0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
|
||||
{0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd},
|
||||
{0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c},
|
||||
{0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c},
|
||||
{0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9},
|
||||
{0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa},
|
||||
{0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b},
|
||||
{0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
|
||||
{0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c},
|
||||
{0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe},
|
||||
{0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37},
|
||||
{0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf9},
|
||||
{0x1d00, 0x1df9}, {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
|
||||
{0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
|
||||
{0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef},
|
||||
{0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e},
|
||||
{0x2074, 0x208e}, {0x2090, 0x209c}, {0x20a0, 0x20bf}, {0x20d0, 0x20f0},
|
||||
{0x2100, 0x218b}, {0x2190, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
|
||||
{0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd2},
|
||||
{0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
|
||||
{0x559, 0x58a}, {0x58d, 0x58f}, {0x591, 0x5c7}, {0x5d0, 0x5ea},
|
||||
{0x5ef, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d},
|
||||
{0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, {0x7fd, 0x82d},
|
||||
{0x830, 0x83e}, {0x840, 0x85b}, {0x860, 0x86a}, {0x8a0, 0x8b4},
|
||||
{0x8b6, 0x8bd}, {0x8d3, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
|
||||
{0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
|
||||
{0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fe}, {0xa01, 0xa03},
|
||||
{0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
|
||||
{0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa76}, {0xa81, 0xa83},
|
||||
{0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
|
||||
{0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
|
||||
{0xae0, 0xae3}, {0xae6, 0xaf1}, {0xaf9, 0xaff}, {0xb01, 0xb03},
|
||||
{0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39},
|
||||
{0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77},
|
||||
{0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa},
|
||||
{0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd},
|
||||
{0xbe6, 0xbfa}, {0xc00, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
|
||||
{0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
|
||||
{0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc8c},
|
||||
{0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
|
||||
{0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3},
|
||||
{0xce6, 0xcef}, {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
|
||||
{0xd12, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63},
|
||||
{0xd66, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb},
|
||||
{0xdc0, 0xdc6}, {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef},
|
||||
{0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97},
|
||||
{0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd},
|
||||
{0xec0, 0xec4}, {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf},
|
||||
{0xf00, 0xf47}, {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc},
|
||||
{0xfbe, 0xfcc}, {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248},
|
||||
{0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288},
|
||||
{0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be},
|
||||
{0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315},
|
||||
{0x1318, 0x135a}, {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5},
|
||||
{0x13f8, 0x13fd}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8},
|
||||
{0x1700, 0x170c}, {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753},
|
||||
{0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9},
|
||||
{0x17f0, 0x17f9}, {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1878},
|
||||
{0x1880, 0x18aa}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b},
|
||||
{0x1930, 0x193b}, {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
|
||||
{0x19b0, 0x19c9}, {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e},
|
||||
{0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad},
|
||||
{0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3},
|
||||
{0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1c90, 0x1cba},
|
||||
{0x1cbd, 0x1cc7}, {0x1cd0, 0x1cf9}, {0x1d00, 0x1df9}, {0x1dfb, 0x1f15},
|
||||
{0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
|
||||
{0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3},
|
||||
{0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe},
|
||||
{0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e}, {0x2090, 0x209c},
|
||||
{0x20a0, 0x20bf}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, {0x2190, 0x2426},
|
||||
{0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bc8},
|
||||
{0x2bca, 0x2bfe}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
|
||||
{0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
|
||||
{0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e49},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e4e},
|
||||
{0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
|
||||
{0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312e},
|
||||
{0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312f},
|
||||
{0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
|
||||
{0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fea}, {0xa000, 0xa48c},
|
||||
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae},
|
||||
{0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
|
||||
{0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
|
||||
{0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe},
|
||||
{0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2},
|
||||
{0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
|
||||
{0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed},
|
||||
{0xabf0, 0xabf9}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
|
||||
{0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe},
|
||||
{0xdd00, 0xdd3e}, {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe},
|
||||
{0xde00, 0xde3e}, {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe},
|
||||
{0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe},
|
||||
{0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
|
||||
{0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f},
|
||||
{0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19},
|
||||
{0xfe20, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74},
|
||||
{0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
|
||||
{0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
|
||||
#if TCL_UTF_MAX > 4
|
||||
{0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fef}, {0xa000, 0xa48c},
|
||||
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7b9},
|
||||
{0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c5},
|
||||
{0xa8ce, 0xa8d9}, {0xa8e0, 0xa953}, {0xa95f, 0xa97c}, {0xa980, 0xa9cd},
|
||||
{0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, {0xaa00, 0xaa36}, {0xaa40, 0xaa4d},
|
||||
{0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, {0xaadb, 0xaaf6}, {0xab01, 0xab06},
|
||||
{0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
|
||||
{0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3},
|
||||
{0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
|
||||
{0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c},
|
||||
{0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7},
|
||||
{0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52}, {0xfe54, 0xfe66},
|
||||
{0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe},
|
||||
{0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc},
|
||||
{0xffe0, 0xffe6}, {0xffe8, 0xffee}
|
||||
#if CHRBITS > 16
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
|
||||
{0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
|
||||
@@ -705,80 +706,85 @@ static const crange graphRangeTable[] = {
|
||||
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
|
||||
{0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b},
|
||||
{0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03},
|
||||
{0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a},
|
||||
{0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
|
||||
{0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a35}, {0x10a38, 0x10a3a},
|
||||
{0x10a3f, 0x10a48}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
|
||||
{0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
|
||||
{0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e},
|
||||
{0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1},
|
||||
{0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143},
|
||||
{0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
|
||||
{0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
|
||||
{0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
|
||||
{0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
|
||||
{0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7},
|
||||
{0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644},
|
||||
{0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
|
||||
{0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2},
|
||||
{0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11a9c}, {0x11a9e, 0x11aa2},
|
||||
{0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45},
|
||||
{0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6},
|
||||
{0x11d00, 0x11d06}, {0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10d27}, {0x10d30, 0x10d39},
|
||||
{0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x11000, 0x1104d},
|
||||
{0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8},
|
||||
{0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146}, {0x11150, 0x11176},
|
||||
{0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, {0x11200, 0x11211},
|
||||
{0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d},
|
||||
{0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, {0x11300, 0x11303},
|
||||
{0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
|
||||
{0x1133b, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, {0x11366, 0x1136c},
|
||||
{0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, {0x114d0, 0x114d9},
|
||||
{0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, {0x11650, 0x11659},
|
||||
{0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x11700, 0x1171a},
|
||||
{0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x11800, 0x1183b}, {0x118a0, 0x118f2},
|
||||
{0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11aa2}, {0x11ac0, 0x11af8},
|
||||
{0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, {0x11c50, 0x11c6c},
|
||||
{0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, {0x11d00, 0x11d06},
|
||||
{0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, {0x11d60, 0x11d65},
|
||||
{0x11d6a, 0x11d8e}, {0x11d93, 0x11d98}, {0x11da0, 0x11da9}, {0x11ee0, 0x11ef8},
|
||||
{0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
|
||||
{0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
|
||||
{0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
|
||||
{0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec},
|
||||
{0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb}, {0x1bc00, 0x1bc6a},
|
||||
{0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f},
|
||||
{0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8},
|
||||
{0x1d200, 0x1d245}, {0x1d300, 0x1d356}, {0x1d360, 0x1d371}, {0x1d400, 0x1d454},
|
||||
{0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3},
|
||||
{0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c},
|
||||
{0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550},
|
||||
{0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb}, {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f},
|
||||
{0x1daa1, 0x1daaf}, {0x1e000, 0x1e006}, {0x1e008, 0x1e018}, {0x1e01b, 0x1e021},
|
||||
{0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a},
|
||||
{0x1e950, 0x1e959}, {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32},
|
||||
{0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72},
|
||||
{0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b},
|
||||
{0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b},
|
||||
{0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf},
|
||||
{0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b},
|
||||
{0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23b}, {0x1f240, 0x1f248},
|
||||
{0x1f260, 0x1f265}, {0x1f300, 0x1f6d4}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f8},
|
||||
{0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847},
|
||||
{0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b},
|
||||
{0x1f910, 0x1f93e}, {0x1f940, 0x1f94c}, {0x1f950, 0x1f96b}, {0x1f980, 0x1f997},
|
||||
{0x1f9d0, 0x1f9e6}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
|
||||
{0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
|
||||
{0x16e40, 0x16e9a}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f},
|
||||
{0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
|
||||
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
|
||||
{0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172},
|
||||
{0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d2e0, 0x1d2f3}, {0x1d300, 0x1d356},
|
||||
{0x1d360, 0x1d378}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
|
||||
{0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
|
||||
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
|
||||
{0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
|
||||
{0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
|
||||
{0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ec71, 0x1ecb4},
|
||||
{0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
|
||||
{0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
|
||||
{0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
|
||||
{0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093},
|
||||
{0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5},
|
||||
{0x1f100, 0x1f10c}, {0x1f110, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
|
||||
{0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4},
|
||||
{0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f9}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d8},
|
||||
{0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887},
|
||||
{0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, {0x1f910, 0x1f93e}, {0x1f940, 0x1f970},
|
||||
{0x1f973, 0x1f976}, {0x1f97c, 0x1f9a2}, {0x1f9b0, 0x1f9b9}, {0x1f9c0, 0x1f9c2},
|
||||
{0x1f9d0, 0x1f9ff}, {0x1fa60, 0x1fa6d}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
|
||||
{0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d},
|
||||
{0xe0100, 0xe01ef}
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
|
||||
|
||||
static const chr graphCharTable[] = {
|
||||
0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8,
|
||||
0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
|
||||
0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3,
|
||||
0xad0, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57,
|
||||
0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f,
|
||||
0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde,
|
||||
0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82,
|
||||
0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab,
|
||||
0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59,
|
||||
0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e,
|
||||
0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
|
||||
#if TCL_UTF_MAX > 4
|
||||
0x38c, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8, 0x9d7, 0x9dc,
|
||||
0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38, 0xa39,
|
||||
0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3, 0xad0, 0xb0f,
|
||||
0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57, 0xb5c, 0xb5d,
|
||||
0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4,
|
||||
0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6, 0xcde, 0xcf1, 0xcf2,
|
||||
0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, 0xe84, 0xe87,
|
||||
0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7,
|
||||
0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59, 0x1f5b, 0x1f5d,
|
||||
0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41,
|
||||
0xfb43, 0xfb44, 0xfffc, 0xfffd
|
||||
#if CHRBITS > 16
|
||||
,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
|
||||
0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
|
||||
0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x11d08, 0x11d09,
|
||||
0x11d3a, 0x11d3c, 0x11d3d, 0x16a6e, 0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f,
|
||||
0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f,
|
||||
0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49,
|
||||
0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f,
|
||||
0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f9c0
|
||||
0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x1145e, 0x118ff, 0x11d08,
|
||||
0x11d09, 0x11d3a, 0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e,
|
||||
0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
|
||||
0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
|
||||
0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
|
||||
0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
|
||||
0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f97a
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -2369,6 +2369,10 @@ declare 1 macosx {
|
||||
export {
|
||||
void Tcl_Main(int argc, char **argv, Tcl_AppInitProc *appInitProc)
|
||||
}
|
||||
export {
|
||||
void Tcl_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
|
||||
Tcl_Interp *interp)
|
||||
}
|
||||
export {
|
||||
const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version,
|
||||
int exact)
|
||||
|
||||
+14
-13
@@ -7606,7 +7606,19 @@ ExprEntierFunc(
|
||||
|
||||
if (type == TCL_NUMBER_DOUBLE) {
|
||||
d = *((const double *) ptr);
|
||||
if ((d >= (double)LONG_MAX) || (d <= (double)LONG_MIN)) {
|
||||
if ((d < (double)LONG_MAX) && (d > (double)LONG_MIN)) {
|
||||
long result = (long) d;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
|
||||
return TCL_OK;
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else if ((d < (double)LLONG_MAX) && (d > (double)LLONG_MIN)) {
|
||||
Tcl_WideInt result = (Tcl_WideInt) d;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
|
||||
return TCL_OK;
|
||||
#endif
|
||||
} else {
|
||||
mp_int big;
|
||||
|
||||
if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
|
||||
@@ -7615,11 +7627,6 @@ ExprEntierFunc(
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
|
||||
return TCL_OK;
|
||||
} else {
|
||||
long result = (long) d;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8402,18 +8409,12 @@ TclNRTailcallObjCmd(
|
||||
if (objc > 1) {
|
||||
Tcl_Obj *listPtr, *nsObjPtr;
|
||||
Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
|
||||
Tcl_Namespace *ns1Ptr;
|
||||
|
||||
/* The tailcall data is in a Tcl list: the first element is the
|
||||
* namespace, the rest the command to be tailcalled. */
|
||||
|
||||
listPtr = Tcl_NewListObj(objc, objv);
|
||||
|
||||
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
|
||||
if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
|
||||
|| (nsPtr != ns1Ptr)) {
|
||||
Tcl_Panic("Tailcall failed to find the proper namespace");
|
||||
}
|
||||
listPtr = Tcl_NewListObj(objc, objv);
|
||||
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
|
||||
|
||||
iPtr->varFramePtr->tailcallPtr = listPtr;
|
||||
|
||||
@@ -512,63 +512,6 @@ Tcl_ContinueObjCmd(
|
||||
return TCL_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_EncodingObjCmd --
|
||||
*
|
||||
* This command manipulates encodings.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Tcl_EncodingObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
int index;
|
||||
|
||||
static const char *const optionStrings[] = {
|
||||
"convertfrom", "convertto", "dirs", "names", "system",
|
||||
NULL
|
||||
};
|
||||
enum options {
|
||||
ENC_CONVERTFROM, ENC_CONVERTTO, ENC_DIRS, ENC_NAMES, ENC_SYSTEM
|
||||
};
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
|
||||
&index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
switch ((enum options) index) {
|
||||
case ENC_CONVERTTO:
|
||||
return EncodingConverttoObjCmd(dummy, interp, objc, objv);
|
||||
case ENC_CONVERTFROM:
|
||||
return EncodingConvertfromObjCmd(dummy, interp, objc, objv);
|
||||
case ENC_DIRS:
|
||||
return EncodingDirsObjCmd(dummy, interp, objc, objv);
|
||||
case ENC_NAMES:
|
||||
return EncodingNamesObjCmd(dummy, interp, objc, objv);
|
||||
case ENC_SYSTEM:
|
||||
return EncodingSystemObjCmd(dummy, interp, objc, objv);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+198
-167
@@ -2599,10 +2599,8 @@ StringEqualCmd(
|
||||
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
|
||||
*/
|
||||
|
||||
const char *string1, *string2;
|
||||
int length1, length2, i, match, length, nocase = 0, reqlength = -1;
|
||||
typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
|
||||
strCmpFn_t strCmpFn;
|
||||
const char *string2;
|
||||
int length2, i, match, nocase = 0, reqlength = -1;
|
||||
|
||||
if (objc < 3 || objc > 6) {
|
||||
str_cmp_args:
|
||||
@@ -2641,78 +2639,7 @@ StringEqualCmd(
|
||||
|
||||
objv += objc-2;
|
||||
|
||||
if ((reqlength == 0) || (objv[0] == objv[1])) {
|
||||
/*
|
||||
* Always match at 0 chars of if it is the same obj.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (!nocase && TclIsPureByteArray(objv[0]) &&
|
||||
TclIsPureByteArray(objv[1])) {
|
||||
/*
|
||||
* Use binary versions of comparisons since that won't cause undue
|
||||
* type conversions and it is much faster. Only do this if we're
|
||||
* case-sensitive (which is all that really makes sense with byte
|
||||
* arrays anyway, and we have no memcasecmp() for some reason... :^)
|
||||
*/
|
||||
|
||||
string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
|
||||
string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
|
||||
strCmpFn = (strCmpFn_t) memcmp;
|
||||
} else if ((objv[0]->typePtr == &tclStringType)
|
||||
&& (objv[1]->typePtr == &tclStringType)) {
|
||||
/*
|
||||
* Do a unicode-specific comparison if both of the args are of String
|
||||
* type. In benchmark testing this proved the most efficient check
|
||||
* between the unicode and string comparison operations.
|
||||
*/
|
||||
|
||||
string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
|
||||
string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
|
||||
strCmpFn = (strCmpFn_t)
|
||||
(nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
|
||||
} else {
|
||||
/*
|
||||
* As a catch-all we will work with UTF-8. We cannot use memcmp() as
|
||||
* that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
|
||||
* utf rep). We can use the more efficient TclpUtfNcmp2 if we are
|
||||
* case-sensitive and no specific length was requested.
|
||||
*/
|
||||
|
||||
string1 = (char *) TclGetStringFromObj(objv[0], &length1);
|
||||
string2 = (char *) TclGetStringFromObj(objv[1], &length2);
|
||||
if ((reqlength < 0) && !nocase) {
|
||||
strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
|
||||
} else {
|
||||
length1 = Tcl_NumUtfChars(string1, length1);
|
||||
length2 = Tcl_NumUtfChars(string2, length2);
|
||||
strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
|
||||
}
|
||||
}
|
||||
|
||||
if ((reqlength < 0) && (length1 != length2)) {
|
||||
match = 1; /* This will be reversed below. */
|
||||
} else {
|
||||
length = (length1 < length2) ? length1 : length2;
|
||||
if (reqlength > 0 && reqlength < length) {
|
||||
length = reqlength;
|
||||
} else if (reqlength < 0) {
|
||||
/*
|
||||
* The requested length is negative, so we ignore it by setting it
|
||||
* to length + 1 so we correct the match var.
|
||||
*/
|
||||
|
||||
reqlength = length + 1;
|
||||
}
|
||||
|
||||
match = strCmpFn(string1, string2, (unsigned) length);
|
||||
if ((match == 0) && (reqlength > length)) {
|
||||
match = length1 - length2;
|
||||
}
|
||||
}
|
||||
match = TclStringCmp (objv[0], objv[1], 0, nocase, reqlength);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
|
||||
return TCL_OK;
|
||||
@@ -2749,11 +2676,194 @@ StringCmpCmd(
|
||||
* the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
|
||||
*/
|
||||
|
||||
const char *string1, *string2;
|
||||
int length1, length2, i, match, length, nocase = 0, reqlength = -1;
|
||||
typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
|
||||
strCmpFn_t strCmpFn;
|
||||
int match, nocase, reqlength, status;
|
||||
|
||||
if ((status = TclStringCmpOpts(interp, objc, objv, &nocase, &reqlength))
|
||||
!= TCL_OK) {
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
objv += objc-2;
|
||||
match = TclStringCmp (objv[0], objv[1], 0, nocase, reqlength);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int TclStringCmp (
|
||||
Tcl_Obj *value1Ptr,
|
||||
Tcl_Obj *value2Ptr,
|
||||
int checkEq, /* comparison is only for equality */
|
||||
int nocase, /* comparison is not case sensitive */
|
||||
int reqlength /* requested length */
|
||||
) {
|
||||
char *s1, *s2;
|
||||
int empty, length, match, s1len, s2len;
|
||||
memCmpFn_t memCmpFn;
|
||||
|
||||
if ((reqlength == 0) || (value1Ptr == value2Ptr)) {
|
||||
/*
|
||||
* Always match at 0 chars of if it is the same obj.
|
||||
*/
|
||||
match = 0;
|
||||
} else {
|
||||
|
||||
if (!nocase && TclIsPureByteArray(value1Ptr)
|
||||
&& TclIsPureByteArray(value2Ptr)) {
|
||||
/*
|
||||
* Use binary versions of comparisons since that won't cause undue
|
||||
* type conversions and it is much faster. Only do this if we're
|
||||
* case-sensitive (which is all that really makes sense with byte
|
||||
* arrays anyway, and we have no memcasecmp() for some reason... :^)
|
||||
*/
|
||||
s1 = (char *) Tcl_GetByteArrayFromObj(value1Ptr, &s1len);
|
||||
s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
|
||||
memCmpFn = memcmp;
|
||||
} else if ((value1Ptr->typePtr == &tclStringType)
|
||||
&& (value2Ptr->typePtr == &tclStringType)) {
|
||||
/*
|
||||
* Do a unicode-specific comparison if both of the args are of
|
||||
* String type. If the char length == byte length, we can do a
|
||||
* memcmp. In benchmark testing this proved the most efficient
|
||||
* check between the unicode and string comparison operations.
|
||||
*/
|
||||
|
||||
if (nocase) {
|
||||
s1 = (char *) Tcl_GetUnicodeFromObj(value1Ptr, &s1len);
|
||||
s2 = (char *) Tcl_GetUnicodeFromObj(value2Ptr, &s2len);
|
||||
memCmpFn = (memCmpFn_t)Tcl_UniCharNcasecmp;
|
||||
} else {
|
||||
s1len = Tcl_GetCharLength(value1Ptr);
|
||||
s2len = Tcl_GetCharLength(value2Ptr);
|
||||
if ((s1len == value1Ptr->length)
|
||||
&& (value1Ptr->bytes != NULL)
|
||||
&& (s2len == value2Ptr->length)
|
||||
&& (value2Ptr->bytes != NULL)) {
|
||||
s1 = value1Ptr->bytes;
|
||||
s2 = value2Ptr->bytes;
|
||||
memCmpFn = memcmp;
|
||||
} else {
|
||||
s1 = (char *) Tcl_GetUnicode(value1Ptr);
|
||||
s2 = (char *) Tcl_GetUnicode(value2Ptr);
|
||||
if (
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
1
|
||||
#else
|
||||
checkEq
|
||||
#endif
|
||||
) {
|
||||
memCmpFn = memcmp;
|
||||
s1len *= sizeof(Tcl_UniChar);
|
||||
s2len *= sizeof(Tcl_UniChar);
|
||||
} else {
|
||||
memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((empty = TclCheckEmptyString(value1Ptr)) > 0) {
|
||||
switch (TclCheckEmptyString(value2Ptr)) {
|
||||
case -1:
|
||||
s1 = "";
|
||||
s1len = 0;
|
||||
s2 = TclGetStringFromObj(value2Ptr, &s2len);
|
||||
break;
|
||||
case 0:
|
||||
match = -1;
|
||||
goto matchdone;
|
||||
case 1:
|
||||
default: /* avoid warn: `s2` may be used uninitialized */
|
||||
match = 0;
|
||||
goto matchdone;
|
||||
}
|
||||
} else if (TclCheckEmptyString(value2Ptr) > 0) {
|
||||
switch (empty) {
|
||||
case -1:
|
||||
s2 = "";
|
||||
s2len = 0;
|
||||
s1 = TclGetStringFromObj(value1Ptr, &s1len);
|
||||
break;
|
||||
case 0:
|
||||
match = 1;
|
||||
goto matchdone;
|
||||
case 1:
|
||||
default: /* avoid warn: `s1` may be used uninitialized */
|
||||
match = 0;
|
||||
goto matchdone;
|
||||
}
|
||||
} else {
|
||||
s1 = TclGetStringFromObj(value1Ptr, &s1len);
|
||||
s2 = TclGetStringFromObj(value2Ptr, &s2len);
|
||||
}
|
||||
if (!nocase && checkEq) {
|
||||
/*
|
||||
* When we have equal-length we can check only for (in)equality.
|
||||
* We can use memcmp in all (n)eq cases because we
|
||||
* don't need to worry about lexical LE/BE variance.
|
||||
*/
|
||||
memCmpFn = memcmp;
|
||||
} else {
|
||||
|
||||
/*
|
||||
* As a catch-all we will work with UTF-8. We cannot use memcmp() as
|
||||
* that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
|
||||
* utf rep). We can use the more efficient TclpUtfNcmp2 if we are
|
||||
* case-sensitive and no specific length was requested.
|
||||
*/
|
||||
|
||||
if ((reqlength < 0) && !nocase) {
|
||||
memCmpFn = (memCmpFn_t) TclpUtfNcmp2;
|
||||
} else {
|
||||
s1len = Tcl_NumUtfChars(s1, s1len);
|
||||
s2len = Tcl_NumUtfChars(s2, s2len);
|
||||
memCmpFn = (memCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
length = (s1len < s2len) ? s1len : s2len;
|
||||
if (reqlength > 0 && reqlength < length) {
|
||||
length = reqlength;
|
||||
} else if (reqlength < 0) {
|
||||
/*
|
||||
* The requested length is negative, so we ignore it by setting it to
|
||||
* length + 1 so we correct the match var.
|
||||
*/
|
||||
|
||||
reqlength = length + 1;
|
||||
}
|
||||
|
||||
if (checkEq && (s1len != s2len)) {
|
||||
match = 1; /* This will be reversed below. */
|
||||
} else {
|
||||
/*
|
||||
* The comparison function should compare up to the minimum
|
||||
* byte length only.
|
||||
*/
|
||||
match = memCmpFn(s1, s2, (size_t) length);
|
||||
}
|
||||
if ((match == 0) && (reqlength > length)) {
|
||||
match = s1len - s2len;
|
||||
}
|
||||
match = (match > 0) ? 1 : (match < 0) ? -1 : 0;
|
||||
}
|
||||
matchdone:
|
||||
return match;
|
||||
}
|
||||
|
||||
int TclStringCmpOpts (
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[], /* Argument objects. */
|
||||
int *nocase,
|
||||
int *reqlength
|
||||
)
|
||||
{
|
||||
int i, length;
|
||||
const char *string;
|
||||
|
||||
*reqlength = -1;
|
||||
*nocase = 0;
|
||||
if (objc < 3 || objc > 6) {
|
||||
str_cmp_args:
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
@@ -2762,106 +2872,27 @@ StringCmpCmd(
|
||||
}
|
||||
|
||||
for (i = 1; i < objc-2; i++) {
|
||||
string2 = TclGetStringFromObj(objv[i], &length2);
|
||||
if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
|
||||
nocase = 1;
|
||||
} else if ((length2 > 1)
|
||||
&& !strncmp(string2, "-length", (size_t)length2)) {
|
||||
string = TclGetStringFromObj(objv[i], &length);
|
||||
if ((length > 1) && !strncmp(string, "-nocase", (size_t)length)) {
|
||||
*nocase = 1;
|
||||
} else if ((length > 1)
|
||||
&& !strncmp(string, "-length", (size_t)length)) {
|
||||
if (i+1 >= objc-2) {
|
||||
goto str_cmp_args;
|
||||
}
|
||||
i++;
|
||||
if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
|
||||
if (TclGetIntFromObj(interp, objv[i], reqlength) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\": must be -nocase or -length",
|
||||
string2));
|
||||
string));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
|
||||
string2, NULL);
|
||||
string, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* From now on, we only access the two objects at the end of the argument
|
||||
* array.
|
||||
*/
|
||||
|
||||
objv += objc-2;
|
||||
|
||||
if ((reqlength == 0) || (objv[0] == objv[1])) {
|
||||
/*
|
||||
* Always match at 0 chars of if it is the same obj.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (!nocase && TclIsPureByteArray(objv[0]) &&
|
||||
TclIsPureByteArray(objv[1])) {
|
||||
/*
|
||||
* Use binary versions of comparisons since that won't cause undue
|
||||
* type conversions and it is much faster. Only do this if we're
|
||||
* case-sensitive (which is all that really makes sense with byte
|
||||
* arrays anyway, and we have no memcasecmp() for some reason... :^)
|
||||
*/
|
||||
|
||||
string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
|
||||
string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
|
||||
strCmpFn = (strCmpFn_t) memcmp;
|
||||
} else if ((objv[0]->typePtr == &tclStringType)
|
||||
&& (objv[1]->typePtr == &tclStringType)) {
|
||||
/*
|
||||
* Do a unicode-specific comparison if both of the args are of String
|
||||
* type. In benchmark testing this proved the most efficient check
|
||||
* between the unicode and string comparison operations.
|
||||
*/
|
||||
|
||||
string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
|
||||
string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
|
||||
strCmpFn = (strCmpFn_t)
|
||||
(nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
|
||||
} else {
|
||||
/*
|
||||
* As a catch-all we will work with UTF-8. We cannot use memcmp() as
|
||||
* that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
|
||||
* utf rep). We can use the more efficient TclpUtfNcmp2 if we are
|
||||
* case-sensitive and no specific length was requested.
|
||||
*/
|
||||
|
||||
string1 = (char *) TclGetStringFromObj(objv[0], &length1);
|
||||
string2 = (char *) TclGetStringFromObj(objv[1], &length2);
|
||||
if ((reqlength < 0) && !nocase) {
|
||||
strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
|
||||
} else {
|
||||
length1 = Tcl_NumUtfChars(string1, length1);
|
||||
length2 = Tcl_NumUtfChars(string2, length2);
|
||||
strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
|
||||
}
|
||||
}
|
||||
|
||||
length = (length1 < length2) ? length1 : length2;
|
||||
if (reqlength > 0 && reqlength < length) {
|
||||
length = reqlength;
|
||||
} else if (reqlength < 0) {
|
||||
/*
|
||||
* The requested length is negative, so we ignore it by setting it to
|
||||
* length + 1 so we correct the match var.
|
||||
*/
|
||||
|
||||
reqlength = length + 1;
|
||||
}
|
||||
|
||||
match = strCmpFn(string1, string2, (unsigned) length);
|
||||
if ((match == 0) && (reqlength > length)) {
|
||||
match = length1 - length2;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewIntObj((match > 0) ? 1 : (match < 0) ? -1 : 0));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1348,7 +1348,7 @@ yyparse (info)
|
||||
int yychar;
|
||||
|
||||
/* The semantic value of the look-ahead symbol. */
|
||||
YYSTYPE yylval;
|
||||
YYSTYPE yylval = {0};
|
||||
|
||||
/* Number of syntax errors so far. */
|
||||
int yynerrs;
|
||||
|
||||
@@ -153,7 +153,7 @@ typedef struct Dict {
|
||||
* must be assignable as well as readable.
|
||||
*/
|
||||
|
||||
#define DICT(dictObj) (*((Dict **)&(dictObj)->internalRep.twoPtrValue.ptr1))
|
||||
#define DICT(dictObj) ((dictObj)->internalRep.twoPtrValue.ptr1)
|
||||
|
||||
/*
|
||||
* The structure below defines the dictionary object type by means of
|
||||
|
||||
+12
-1
@@ -723,14 +723,25 @@ TclFinalizeEnvironment(void)
|
||||
* strings. This may leak more memory that strictly necessary, since some
|
||||
* of the strings may no longer be in the environment. However,
|
||||
* determining which ones are ok to delete is n-squared, and is pretty
|
||||
* unlikely, so we don't bother.
|
||||
* unlikely, so we don't bother. However, in the case of DPURIFY, just
|
||||
* free all strings in the cache.
|
||||
*/
|
||||
|
||||
if (env.cache) {
|
||||
#ifdef PURIFY
|
||||
int i;
|
||||
for (i = 0; i < env.cacheSize; i++) {
|
||||
ckfree(env.cache[i]);
|
||||
}
|
||||
#endif
|
||||
ckfree(env.cache);
|
||||
env.cache = NULL;
|
||||
env.cacheSize = 0;
|
||||
#ifndef USE_PUTENV
|
||||
if ((env.ourEnviron != NULL)) {
|
||||
ckfree(env.ourEnviron);
|
||||
env.ourEnviron = NULL;
|
||||
}
|
||||
env.ourEnvironSize = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
+10
-80
@@ -5384,88 +5384,10 @@ TEBCresume(
|
||||
value2Ptr = OBJ_AT_TOS;
|
||||
valuePtr = OBJ_UNDER_TOS;
|
||||
|
||||
if (valuePtr == value2Ptr) {
|
||||
match = 0;
|
||||
} else {
|
||||
/*
|
||||
* We only need to check (in)equality when we have equal length
|
||||
* strings. We can use memcmp in all (n)eq cases because we
|
||||
* don't need to worry about lexical LE/BE variance.
|
||||
*/
|
||||
|
||||
typedef int (*memCmpFn_t)(const void*, const void*, size_t);
|
||||
memCmpFn_t memCmpFn;
|
||||
{
|
||||
int checkEq = ((*pc == INST_EQ) || (*pc == INST_NEQ)
|
||||
|| (*pc == INST_STR_EQ) || (*pc == INST_STR_NEQ));
|
||||
|
||||
if (TclIsPureByteArray(valuePtr)
|
||||
&& TclIsPureByteArray(value2Ptr)) {
|
||||
s1 = (char *) Tcl_GetByteArrayFromObj(valuePtr, &s1len);
|
||||
s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
|
||||
memCmpFn = memcmp;
|
||||
} else if ((valuePtr->typePtr == &tclStringType)
|
||||
&& (value2Ptr->typePtr == &tclStringType)) {
|
||||
/*
|
||||
* Do a unicode-specific comparison if both of the args are of
|
||||
* String type. If the char length == byte length, we can do a
|
||||
* memcmp. In benchmark testing this proved the most efficient
|
||||
* check between the unicode and string comparison operations.
|
||||
*/
|
||||
|
||||
s1len = Tcl_GetCharLength(valuePtr);
|
||||
s2len = Tcl_GetCharLength(value2Ptr);
|
||||
if ((s1len == valuePtr->length)
|
||||
&& (valuePtr->bytes != NULL)
|
||||
&& (s2len == value2Ptr->length)
|
||||
&& (value2Ptr->bytes != NULL)) {
|
||||
s1 = valuePtr->bytes;
|
||||
s2 = value2Ptr->bytes;
|
||||
memCmpFn = memcmp;
|
||||
} else {
|
||||
s1 = (char *) Tcl_GetUnicode(valuePtr);
|
||||
s2 = (char *) Tcl_GetUnicode(value2Ptr);
|
||||
if (
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
1
|
||||
#else
|
||||
checkEq
|
||||
#endif
|
||||
) {
|
||||
memCmpFn = memcmp;
|
||||
s1len *= sizeof(Tcl_UniChar);
|
||||
s2len *= sizeof(Tcl_UniChar);
|
||||
} else {
|
||||
memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* strcmp can't do a simple memcmp in order to handle the
|
||||
* special Tcl \xC0\x80 null encoding for utf-8.
|
||||
*/
|
||||
|
||||
s1 = TclGetStringFromObj(valuePtr, &s1len);
|
||||
s2 = TclGetStringFromObj(value2Ptr, &s2len);
|
||||
if (checkEq) {
|
||||
memCmpFn = memcmp;
|
||||
} else {
|
||||
memCmpFn = (memCmpFn_t) TclpUtfNcmp2;
|
||||
}
|
||||
}
|
||||
|
||||
if (checkEq && (s1len != s2len)) {
|
||||
match = 1;
|
||||
} else {
|
||||
/*
|
||||
* The comparison function should compare up to the minimum
|
||||
* byte length only.
|
||||
*/
|
||||
match = memCmpFn(s1, s2,
|
||||
(size_t) ((s1len < s2len) ? s1len : s2len));
|
||||
if (match == 0) {
|
||||
match = s1len - s2len;
|
||||
}
|
||||
}
|
||||
match = TclStringCmp(valuePtr, value2Ptr, checkEq, 0, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6142,6 +6064,14 @@ TEBCresume(
|
||||
value2Ptr = OBJ_AT_TOS;
|
||||
valuePtr = OBJ_UNDER_TOS;
|
||||
|
||||
/*
|
||||
Try to determine, without triggering generation of a string
|
||||
representation, whether one value is not a number.
|
||||
*/
|
||||
if (TclCheckEmptyString(valuePtr) > 0 || TclCheckEmptyString(value2Ptr) > 0) {
|
||||
goto stringCompare;
|
||||
}
|
||||
|
||||
if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK
|
||||
|| GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) {
|
||||
/*
|
||||
|
||||
+20
-14
@@ -240,9 +240,13 @@ TclFileMakeDirsCmd(
|
||||
break;
|
||||
}
|
||||
for (j = 0; j < pobjc; j++) {
|
||||
int errCount = 2;
|
||||
|
||||
target = Tcl_FSJoinPath(split, j + 1);
|
||||
Tcl_IncrRefCount(target);
|
||||
|
||||
createDir:
|
||||
|
||||
/*
|
||||
* Call Tcl_FSStat() so that if target is a symlink that points to
|
||||
* a directory we will create subdirectories in that directory.
|
||||
@@ -269,23 +273,25 @@ TclFileMakeDirsCmd(
|
||||
* subdirectory.
|
||||
*/
|
||||
|
||||
if (errno != EEXIST) {
|
||||
errfile = target;
|
||||
goto done;
|
||||
} else if ((Tcl_FSStat(target, &statBuf) == 0)
|
||||
&& S_ISDIR(statBuf.st_mode)) {
|
||||
/*
|
||||
* It is a directory that wasn't there before, so keep
|
||||
* going without error.
|
||||
*/
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
} else {
|
||||
errfile = target;
|
||||
goto done;
|
||||
if (errno == EEXIST) {
|
||||
/* Be aware other workers could delete it immediately after
|
||||
* creation, so give this worker still one chance (repeat once),
|
||||
* see [270f78ca95] for description of the race-condition.
|
||||
* Don't repeat the create always (to avoid endless loop). */
|
||||
if (--errCount > 0) {
|
||||
goto createDir;
|
||||
}
|
||||
/* Already tried, with delete in-between directly after
|
||||
* creation, so just continue (assume created successful). */
|
||||
goto nextPart;
|
||||
}
|
||||
|
||||
/* return with error */
|
||||
errfile = target;
|
||||
goto done;
|
||||
}
|
||||
|
||||
nextPart:
|
||||
/*
|
||||
* Forget about this sub-path.
|
||||
*/
|
||||
|
||||
+38
-25
@@ -139,7 +139,6 @@ Tcl_FSRenameFileProc TclpObjRenameFile;
|
||||
Tcl_FSCreateDirectoryProc TclpObjCreateDirectory;
|
||||
Tcl_FSCopyDirectoryProc TclpObjCopyDirectory;
|
||||
Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory;
|
||||
Tcl_FSUnloadFileProc TclpUnloadFile;
|
||||
Tcl_FSLinkProc TclpObjLink;
|
||||
Tcl_FSListVolumesProc TclpObjListVolumes;
|
||||
|
||||
@@ -190,6 +189,8 @@ const Tcl_Filesystem tclNativeFilesystem = {
|
||||
TclpObjChdir
|
||||
};
|
||||
|
||||
MODULE_SCOPE Tcl_Filesystem zipfsFilesystem;
|
||||
|
||||
/*
|
||||
* Define the tail of the linked list. Note that for unconventional uses of
|
||||
* Tcl without a native filesystem, we may in the future wish to modify the
|
||||
@@ -1409,6 +1410,22 @@ TclFSNormalizeToUniquePath(
|
||||
|
||||
Claim();
|
||||
for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) {
|
||||
if (fsRecPtr->fsPtr == &zipfsFilesystem) {
|
||||
ClientData clientData = NULL;
|
||||
/*
|
||||
* Allow mounted zipfs filesystem to overtake entire normalisation.
|
||||
* This is needed on unix for mounts on symlinks right below root.
|
||||
*/
|
||||
|
||||
if (fsRecPtr->fsPtr->pathInFilesystemProc != NULL) {
|
||||
if (fsRecPtr->fsPtr->pathInFilesystemProc(pathPtr,
|
||||
&clientData)!=-1) {
|
||||
TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
|
||||
continue;
|
||||
}
|
||||
@@ -1433,6 +1450,9 @@ TclFSNormalizeToUniquePath(
|
||||
if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
|
||||
continue;
|
||||
}
|
||||
if (fsRecPtr->fsPtr == &zipfsFilesystem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fsRecPtr->fsPtr->normalizePathProc != NULL) {
|
||||
startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr,
|
||||
@@ -2913,6 +2933,19 @@ Tcl_FSChdir(
|
||||
}
|
||||
|
||||
fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
|
||||
|
||||
if ((fsPtr != NULL) && (fsPtr != &tclNativeFilesystem)) {
|
||||
/*
|
||||
* Watch out for tilde substitution.
|
||||
* Only valid in native filesystem.
|
||||
*/
|
||||
char *name = Tcl_GetString(pathPtr);
|
||||
|
||||
if ((name != NULL) && (*name == '~')) {
|
||||
fsPtr = &tclNativeFilesystem;
|
||||
}
|
||||
}
|
||||
|
||||
if (fsPtr != NULL) {
|
||||
if (fsPtr->chdirProc != NULL) {
|
||||
/*
|
||||
@@ -3159,8 +3192,8 @@ Tcl_FSLoadFile(
|
||||
* present and set to true (any integer > 0) then the unlink is skipped.
|
||||
*/
|
||||
|
||||
int
|
||||
TclSkipUnlink (Tcl_Obj* shlibFile)
|
||||
static int
|
||||
skipUnlink (Tcl_Obj* shlibFile)
|
||||
{
|
||||
/* Order of testing:
|
||||
* 1. On hpux we generally want to skip unlink in general
|
||||
@@ -3414,7 +3447,7 @@ Tcl_LoadFile(
|
||||
*/
|
||||
|
||||
if (
|
||||
!TclSkipUnlink (copyToPtr) &&
|
||||
!skipUnlink (copyToPtr) &&
|
||||
(Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) {
|
||||
Tcl_DecrRefCount(copyToPtr);
|
||||
|
||||
@@ -3683,30 +3716,10 @@ Tcl_FSUnloadFile(
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclpUnloadFile(handle);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclpUnloadFile --
|
||||
*
|
||||
* Unloads a library given its handle
|
||||
*
|
||||
* This function was once filesystem-specific, but has been made portable by
|
||||
* having TclpDlopen return a structure that includes procedure pointers.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TclpUnloadFile(
|
||||
Tcl_LoadHandle handle)
|
||||
{
|
||||
if (handle->unloadFileProcPtr != NULL) {
|
||||
handle->unloadFileProcPtr(handle);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1088,7 +1088,7 @@ declare 9 win {
|
||||
}
|
||||
# new for 8.4.20+/8.5.12+ Cygwin only
|
||||
declare 10 win {
|
||||
Tcl_DirEntry *TclpReaddir(DIR *dir)
|
||||
Tcl_DirEntry *TclpReaddir(TclDIR *dir)
|
||||
}
|
||||
# Removed in 8.3.1 (for Win32s only)
|
||||
#declare 10 win {
|
||||
@@ -1226,7 +1226,7 @@ declare 9 unix {
|
||||
# Added in 8.4:
|
||||
|
||||
declare 10 unix {
|
||||
Tcl_DirEntry *TclpReaddir(DIR *dir)
|
||||
Tcl_DirEntry *TclpReaddir(TclDIR *dir)
|
||||
}
|
||||
# Slots 11 and 12 are forwarders for functions that were promoted to
|
||||
# generic Stubs
|
||||
|
||||
+17
-1
@@ -2735,6 +2735,10 @@ MODULE_SCOPE long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS];
|
||||
MODULE_SCOPE char * tclEmptyStringRep;
|
||||
MODULE_SCOPE char tclEmptyString;
|
||||
|
||||
enum CheckEmptyStringResult {
|
||||
TCL_EMPTYSTRING_UNKNOWN = -1, TCL_EMPTYSTRING_NO, TCL_EMPTYSTRING_YES
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
* Procedures shared among Tcl modules but not used by the outside world,
|
||||
@@ -2875,6 +2879,7 @@ MODULE_SCOPE int TclCheckArrayTraces(Tcl_Interp *interp, Var *varPtr,
|
||||
Var *arrayPtr, Tcl_Obj *name, int index);
|
||||
MODULE_SCOPE int TclCheckBadOctal(Tcl_Interp *interp,
|
||||
const char *value);
|
||||
MODULE_SCOPE int TclCheckEmptyString(Tcl_Obj *objPtr);
|
||||
MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp,
|
||||
Tcl_Channel chan);
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd;
|
||||
@@ -2929,7 +2934,7 @@ MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr,
|
||||
MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr);
|
||||
MODULE_SCOPE Tcl_Obj *const * TclFetchEnsembleRoot(Tcl_Interp *interp,
|
||||
Tcl_Obj *const *objv, int objc, int *objcPtr);
|
||||
Tcl_Namespace * TclEnsureNamespace(
|
||||
MODULE_SCOPE Tcl_Namespace * TclEnsureNamespace(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Namespace *namespacePtr);
|
||||
|
||||
@@ -3150,6 +3155,12 @@ MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp,
|
||||
Tcl_Obj *bad, Tcl_Obj *fix);
|
||||
MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr,
|
||||
int numBytes);
|
||||
|
||||
typedef int (*memCmpFn_t)(const void*, const void*, size_t);
|
||||
MODULE_SCOPE int TclStringCmp (Tcl_Obj *value1Ptr, Tcl_Obj *value2Ptr,
|
||||
int checkEq, int nocase, int reqlength);
|
||||
MODULE_SCOPE int TclStringCmpOpts (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
|
||||
int *nocase, int *reqlength);
|
||||
MODULE_SCOPE int TclStringMatch(const char *str, int strLen,
|
||||
const char *pattern, int ptnLen, int flags);
|
||||
MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj,
|
||||
@@ -4455,6 +4466,11 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
|
||||
#define TclIsPureByteArray(objPtr) \
|
||||
(((objPtr)->typePtr==&tclByteArrayType) && ((objPtr)->bytes==NULL))
|
||||
#define TclIsPureDict(objPtr) \
|
||||
(((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType))
|
||||
|
||||
#define TclIsPureList(objPtr) \
|
||||
(((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclListType))
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
|
||||
@@ -13,11 +13,6 @@
|
||||
#ifndef _TCLINTPLATDECLS
|
||||
#define _TCLINTPLATDECLS
|
||||
|
||||
#ifdef _WIN32
|
||||
# define Tcl_DirEntry void
|
||||
# define DIR void
|
||||
#endif
|
||||
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#ifdef BUILD_tcl
|
||||
# define TCL_STORAGE_CLASS DLLEXPORT
|
||||
@@ -72,7 +67,7 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout);
|
||||
/* 9 */
|
||||
EXTERN TclFile TclpCreateTempFile(const char *contents);
|
||||
/* 10 */
|
||||
EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir);
|
||||
EXTERN Tcl_DirEntry * TclpReaddir(TclDIR *dir);
|
||||
/* 11 */
|
||||
EXTERN struct tm * TclpLocaltime_unix(const time_t *clock);
|
||||
/* 12 */
|
||||
@@ -129,7 +124,7 @@ EXTERN int TclpGetPid(Tcl_Pid pid);
|
||||
/* 9 */
|
||||
EXTERN int TclWinGetPlatformId(void);
|
||||
/* 10 */
|
||||
EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir);
|
||||
EXTERN Tcl_DirEntry * TclpReaddir(TclDIR *dir);
|
||||
/* 11 */
|
||||
EXTERN void TclGetAndDetachPids(Tcl_Interp *interp,
|
||||
Tcl_Channel chan);
|
||||
@@ -206,7 +201,7 @@ EXTERN int TclUnixWaitForFile(int fd, int mask, int timeout);
|
||||
/* 9 */
|
||||
EXTERN TclFile TclpCreateTempFile(const char *contents);
|
||||
/* 10 */
|
||||
EXTERN Tcl_DirEntry * TclpReaddir(DIR *dir);
|
||||
EXTERN Tcl_DirEntry * TclpReaddir(TclDIR *dir);
|
||||
/* 11 */
|
||||
EXTERN struct tm * TclpLocaltime_unix(const time_t *clock);
|
||||
/* 12 */
|
||||
@@ -269,7 +264,7 @@ typedef struct TclIntPlatStubs {
|
||||
TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */
|
||||
int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */
|
||||
TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */
|
||||
Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
|
||||
Tcl_DirEntry * (*tclpReaddir) (TclDIR *dir); /* 10 */
|
||||
struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */
|
||||
struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */
|
||||
char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
|
||||
@@ -302,7 +297,7 @@ typedef struct TclIntPlatStubs {
|
||||
int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char *optval, int optlen); /* 7 */
|
||||
int (*tclpGetPid) (Tcl_Pid pid); /* 8 */
|
||||
int (*tclWinGetPlatformId) (void); /* 9 */
|
||||
Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
|
||||
Tcl_DirEntry * (*tclpReaddir) (TclDIR *dir); /* 10 */
|
||||
void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 11 */
|
||||
int (*tclpCloseFile) (TclFile file); /* 12 */
|
||||
Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 13 */
|
||||
@@ -335,7 +330,7 @@ typedef struct TclIntPlatStubs {
|
||||
TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */
|
||||
int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */
|
||||
TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */
|
||||
Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
|
||||
Tcl_DirEntry * (*tclpReaddir) (TclDIR *dir); /* 10 */
|
||||
struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */
|
||||
struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */
|
||||
char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
|
||||
|
||||
@@ -1539,69 +1539,6 @@ TclOODefineMethodObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineMixinObjCmd --
|
||||
* Implementation of the "mixin" subcommand of the "oo::define" and
|
||||
* "oo::objdefine" commands.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclOODefineMixinObjCmd(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
const int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
int isInstanceMixin = (clientData != NULL);
|
||||
Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
|
||||
Class **mixins;
|
||||
int i;
|
||||
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (!isInstanceMixin && !oPtr->classPtr) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"attempt to misuse API", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
mixins = TclStackAlloc(interp, sizeof(Class *) * (objc-1));
|
||||
|
||||
for (i=1 ; i<objc ; i++) {
|
||||
Class *clsPtr = GetClassInOuterContext(interp, objv[i],
|
||||
"may only mix in classes");
|
||||
|
||||
if (clsPtr == NULL) {
|
||||
goto freeAndError;
|
||||
}
|
||||
if (!isInstanceMixin && TclOOIsReachable(oPtr->classPtr, clsPtr)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"may not mix a class into itself", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
|
||||
goto freeAndError;
|
||||
}
|
||||
mixins[i-1] = clsPtr;
|
||||
}
|
||||
|
||||
if (isInstanceMixin) {
|
||||
TclOOObjectSetMixins(oPtr, objc-1, mixins);
|
||||
} else {
|
||||
TclOOClassSetMixins(interp, oPtr->classPtr, objc-1, mixins);
|
||||
}
|
||||
|
||||
TclStackFree(interp, mixins);
|
||||
return TCL_OK;
|
||||
|
||||
freeAndError:
|
||||
TclStackFree(interp, mixins);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+7
-1
@@ -991,7 +991,13 @@ TclParseBackslash(
|
||||
if (readPtr != NULL) {
|
||||
*readPtr = count;
|
||||
}
|
||||
return Tcl_UniCharToUtf(result, dst);
|
||||
count = Tcl_UniCharToUtf(result, dst);
|
||||
#if TCL_UTF_MAX > 3
|
||||
if (!count) {
|
||||
count = Tcl_UniCharToUtf(-1, dst);
|
||||
}
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -434,6 +434,7 @@ Tcl_GetCharLength(
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* OK, need to work with the object as a string.
|
||||
*/
|
||||
@@ -464,6 +465,50 @@ Tcl_GetCharLength(
|
||||
}
|
||||
return numChars;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCheckEmptyString --
|
||||
*
|
||||
* Determine whether the string value of an object is or would be the
|
||||
* empty string, without generating a string representation.
|
||||
*
|
||||
* Results:
|
||||
* Returns 1 if empty, 0 if not, and -1 if unknown.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
TclCheckEmptyString (
|
||||
Tcl_Obj *objPtr
|
||||
) {
|
||||
int length = -1;
|
||||
|
||||
if (objPtr->bytes == tclEmptyStringRep) {
|
||||
return TCL_EMPTYSTRING_YES;
|
||||
}
|
||||
|
||||
if (TclIsPureList(objPtr)) {
|
||||
Tcl_ListObjLength(NULL, objPtr, &length);
|
||||
return length == 0;
|
||||
}
|
||||
|
||||
if (TclIsPureDict(objPtr)) {
|
||||
Tcl_DictObjSize(NULL, objPtr, &length);
|
||||
return length == 0;
|
||||
}
|
||||
|
||||
if (objPtr->bytes == NULL) {
|
||||
return TCL_EMPTYSTRING_UNKNOWN;
|
||||
}
|
||||
return objPtr->length == 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1831,6 +1876,11 @@ Tcl_AppendFormatToObj(
|
||||
width = 0;
|
||||
if (isdigit(UCHAR(ch))) {
|
||||
width = strtoul(format, &end, 10);
|
||||
if (width < 0) {
|
||||
msg = overflow;
|
||||
errCode = "OVERFLOW";
|
||||
goto errorMsg;
|
||||
}
|
||||
format = end;
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
} else if (ch == '*') {
|
||||
@@ -1951,6 +2001,12 @@ Tcl_AppendFormatToObj(
|
||||
goto error;
|
||||
}
|
||||
length = Tcl_UniCharToUtf(code, buf);
|
||||
#if TCL_UTF_MAX > 3
|
||||
if (!length) {
|
||||
/* Special case for handling upper surrogates. */
|
||||
length = Tcl_UniCharToUtf(-1, buf);
|
||||
}
|
||||
#endif
|
||||
segment = Tcl_NewStringObj(buf, length);
|
||||
Tcl_IncrRefCount(segment);
|
||||
allocSegment = 1;
|
||||
|
||||
@@ -174,7 +174,6 @@ TclThread_Init(
|
||||
Tcl_CreateObjCommand(interp, "testthread", ThreadObjCmd, NULL, NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1158,6 +1157,14 @@ ThreadExitProc(
|
||||
|
||||
Tcl_MutexLock(&threadMutex);
|
||||
|
||||
if (self == errorThreadId) {
|
||||
if (errorProcString) { /* Extra safety */
|
||||
ckfree(errorProcString);
|
||||
errorProcString = NULL;
|
||||
}
|
||||
errorThreadId = 0;
|
||||
}
|
||||
|
||||
if (threadEvalScript) {
|
||||
ckfree(threadEvalScript);
|
||||
threadEvalScript = NULL;
|
||||
|
||||
+810
-795
File diff suppressed because it is too large
Load Diff
+17
-3
@@ -189,6 +189,13 @@ Tcl_UniCharToUtf(
|
||||
buf[0] = (char) ((ch >> 18) | 0xF0);
|
||||
return 4;
|
||||
}
|
||||
} else if (ch == -1) {
|
||||
if (((buf[0] & 0xF8) == 0xF0) && ((buf[1] & 0xC0) == 0x80)
|
||||
&& ((buf[2] & 0xCF) == 0)) {
|
||||
ch = 0xD7C0 + ((buf[0] & 0x07) << 8) + ((buf[1] & 0x3F) << 2)
|
||||
+ ((buf[2] & 0x30) >> 4);
|
||||
goto three;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -984,7 +991,11 @@ Tcl_UtfToTitle(
|
||||
}
|
||||
while (*src) {
|
||||
bytes = TclUtfToUniChar(src, &ch);
|
||||
lowChar = Tcl_UniCharToLower(ch);
|
||||
lowChar = ch;
|
||||
/* Special exception for Georgian Asomtavruli chars, no titlecase. */
|
||||
if ((unsigned)(lowChar - 0x1C90) >= 0x30) {
|
||||
lowChar = Tcl_UniCharToLower(lowChar);
|
||||
}
|
||||
|
||||
if (bytes < UtfCount(lowChar)) {
|
||||
memcpy(dst, src, (size_t) bytes);
|
||||
@@ -1256,8 +1267,9 @@ Tcl_UniCharToLower(
|
||||
int ch) /* Unicode character to convert. */
|
||||
{
|
||||
int info = GetUniCharInfo(ch);
|
||||
int mode = GetCaseType(info);
|
||||
|
||||
if (GetCaseType(info) & 0x02) {
|
||||
if ((mode & 0x02) && (mode != 0x7)) {
|
||||
ch += GetDelta(info);
|
||||
}
|
||||
return (Tcl_UniChar) ch;
|
||||
@@ -1291,7 +1303,9 @@ Tcl_UniCharToTitle(
|
||||
* Subtract or add one depending on the original case.
|
||||
*/
|
||||
|
||||
ch += ((mode & 0x4) ? -1 : 1);
|
||||
if (mode != 0x7) {
|
||||
ch += ((mode & 0x4) ? -1 : 1);
|
||||
}
|
||||
} else if (mode == 0x4) {
|
||||
ch -= GetDelta(info);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* tclZipfs.h --
|
||||
*
|
||||
* This header file describes the interface of the ZIPFS filesystem
|
||||
*
|
||||
* Copyright (c) 2013-2015 Christian Werner <chw@ch-werner.de>
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#ifndef _ZIPFS_H
|
||||
#define _ZIPFS_H
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ZIPFSAPI
|
||||
# define ZIPFSAPI extern
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_tcl
|
||||
# undef ZIPFSAPI
|
||||
# define ZIPFSAPI DLLEXPORT
|
||||
#endif
|
||||
|
||||
ZIPFSAPI int Tclzipfs_Mount(Tcl_Interp *interp, const char *zipname,
|
||||
const char *mntpt, const char *passwd);
|
||||
ZIPFSAPI int Tclzipfs_Unmount(Tcl_Interp *interp, const char *zipname);
|
||||
ZIPFSAPI int Tclzipfs_Init(Tcl_Interp *interp);
|
||||
ZIPFSAPI int Tclzipfs_SafeInit(Tcl_Interp *interp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ZIPFS_H */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
||||
@@ -0,0 +1,131 @@
|
||||
/* crypt.h -- base code for crypt/uncrypt ZIPfile
|
||||
|
||||
|
||||
Version 1.01e, February 12th, 2005
|
||||
|
||||
Copyright (C) 1998-2005 Gilles Vollant
|
||||
|
||||
This code is a modified version of crypting code in Infozip distribution
|
||||
|
||||
The encryption/decryption parts of this source code (as opposed to the
|
||||
non-echoing password parts) were originally written in Europe. The
|
||||
whole source package can be freely distributed, including from the USA.
|
||||
(Prior to January 2000, re-export from the US was a violation of US law.)
|
||||
|
||||
This encryption code is a direct transcription of the algorithm from
|
||||
Roger Schlafly, described by Phil Katz in the file appnote.txt. This
|
||||
file (appnote.txt) is distributed with the PKZIP program (even in the
|
||||
version without encryption capabilities).
|
||||
|
||||
If you don't need crypting in your application, just define symbols
|
||||
NOCRYPT and NOUNCRYPT.
|
||||
|
||||
This code support the "Traditional PKWARE Encryption".
|
||||
|
||||
The new AES encryption added on Zip format by Winzip (see the page
|
||||
http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
|
||||
Encryption is not supported.
|
||||
*/
|
||||
|
||||
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
|
||||
|
||||
/***********************************************************************
|
||||
* Return the next byte in the pseudo-random sequence
|
||||
*/
|
||||
static int decrypt_byte(unsigned long* pkeys, const unsigned int* pcrc_32_tab)
|
||||
{
|
||||
unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an
|
||||
* unpredictable manner on 16-bit systems; not a problem
|
||||
* with any known compiler so far, though */
|
||||
|
||||
temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
|
||||
return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* Update the encryption keys with the next byte of plain text
|
||||
*/
|
||||
static int update_keys(unsigned long* pkeys,const unsigned int* pcrc_32_tab,int c)
|
||||
{
|
||||
(*(pkeys+0)) = CRC32((*(pkeys+0)), c);
|
||||
(*(pkeys+1)) += (*(pkeys+0)) & 0xff;
|
||||
(*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
|
||||
{
|
||||
register int keyshift = (int)((*(pkeys+1)) >> 24);
|
||||
(*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* Initialize the encryption keys and the random header according to
|
||||
* the given password.
|
||||
*/
|
||||
static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned int* pcrc_32_tab)
|
||||
{
|
||||
*(pkeys+0) = 305419896L;
|
||||
*(pkeys+1) = 591751049L;
|
||||
*(pkeys+2) = 878082192L;
|
||||
while (*passwd != '\0') {
|
||||
update_keys(pkeys,pcrc_32_tab,(int)*passwd);
|
||||
passwd++;
|
||||
}
|
||||
}
|
||||
|
||||
#define zdecode(pkeys,pcrc_32_tab,c) \
|
||||
(update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
|
||||
|
||||
#define zencode(pkeys,pcrc_32_tab,c,t) \
|
||||
(t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
|
||||
|
||||
#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
|
||||
|
||||
#define RAND_HEAD_LEN 12
|
||||
/* "last resort" source for second part of crypt seed pattern */
|
||||
# ifndef ZCR_SEED2
|
||||
# define ZCR_SEED2 3141592654UL /* use PI as default pattern */
|
||||
# endif
|
||||
|
||||
static int crypthead(const char* passwd, /* password string */
|
||||
unsigned char* buf, /* where to write header */
|
||||
int bufSize,
|
||||
unsigned long* pkeys,
|
||||
const unsigned int* pcrc_32_tab,
|
||||
unsigned long crcForCrypting)
|
||||
{
|
||||
int n; /* index in random header */
|
||||
int t; /* temporary */
|
||||
int c; /* random byte */
|
||||
unsigned char header[RAND_HEAD_LEN-2]; /* random header */
|
||||
static unsigned calls = 0; /* ensure different random header each time */
|
||||
|
||||
if (bufSize<RAND_HEAD_LEN)
|
||||
return 0;
|
||||
|
||||
/* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
|
||||
* output of rand() to get less predictability, since rand() is
|
||||
* often poorly implemented.
|
||||
*/
|
||||
if (++calls == 1)
|
||||
{
|
||||
srand((unsigned)(time(NULL) ^ ZCR_SEED2));
|
||||
}
|
||||
init_keys(passwd, pkeys, pcrc_32_tab);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++)
|
||||
{
|
||||
c = (rand() >> 7) & 0xff;
|
||||
header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
|
||||
}
|
||||
/* Encrypt random header (last two bytes is high word of crc) */
|
||||
init_keys(passwd, pkeys, pcrc_32_tab);
|
||||
for (n = 0; n < RAND_HEAD_LEN-2; n++)
|
||||
{
|
||||
buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
|
||||
}
|
||||
buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
|
||||
buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
||||
+3437
File diff suppressed because it is too large
Load Diff
@@ -1254,6 +1254,10 @@ proc tcltest::DefineConstraintInitializers {} {
|
||||
ConstraintInitializer interactive \
|
||||
{expr {[info exists ::tcl_interactive] && $::tcl_interactive}}
|
||||
|
||||
# Skip slow tests (to enable slow tests add parameter `-constraints slowTest`)
|
||||
|
||||
ConstraintInitializer slowTest {format 0}
|
||||
|
||||
# Some tests can only be run if the installation came from a CD
|
||||
# image instead of a web image. Some tests must be skipped if you
|
||||
# are running as root on Unix. Other tests can only be run if you
|
||||
|
||||
+6
-2
@@ -13,10 +13,14 @@
|
||||
package prefer latest
|
||||
package require Tcl 8.5-
|
||||
package require tcltest 2.2
|
||||
namespace import tcltest::*
|
||||
configure {*}$argv -testdir [file dir [info script]]
|
||||
namespace import ::tcltest::*
|
||||
|
||||
configure {*}$argv -testdir [file dirname [file dirname [file normalize [
|
||||
info script]/...]]]
|
||||
|
||||
if {[singleProcess]} {
|
||||
interp debug {} -frame 1
|
||||
}
|
||||
|
||||
runAllTests
|
||||
proc exit args {}
|
||||
|
||||
+29
-11
@@ -157,17 +157,24 @@ test async-4.1 {async interrupting bytecode sequence} -constraints {
|
||||
}
|
||||
} -body {
|
||||
apply {{handle} {
|
||||
global aresult
|
||||
set aresult {Async event not delivered}
|
||||
testasync marklater $handle
|
||||
for {set i 0} {
|
||||
$i < 2500000 && $aresult eq "Async event not delivered"
|
||||
} {incr i} {
|
||||
nothing
|
||||
}
|
||||
global aresult
|
||||
set aresult {Async event not delivered}
|
||||
testasync marklater $handle
|
||||
# allow plenty of time to pass in case valgrind is running
|
||||
set start [clock seconds]
|
||||
while {
|
||||
[clock seconds] - $start < 180 && $aresult eq "Async event not delivered"
|
||||
} {
|
||||
# be less busy
|
||||
after 100
|
||||
nothing
|
||||
}
|
||||
return $aresult
|
||||
}} $hm
|
||||
} -result {test pattern} -cleanup {
|
||||
# give other threads some time to go way so that valgrind doesn't pick up
|
||||
# "still reachable" cases from early thread termination
|
||||
after 100
|
||||
testasync delete $hm
|
||||
}
|
||||
test async-4.2 {async interrupting straight bytecode sequence} -constraints {
|
||||
@@ -179,12 +186,20 @@ test async-4.2 {async interrupting straight bytecode sequence} -constraints {
|
||||
global aresult
|
||||
set aresult {Async event not delivered}
|
||||
testasync marklater $handle
|
||||
for {set i 0} {
|
||||
$i < 2500000 && $aresult eq "Async event not delivered"
|
||||
} {incr i} {}
|
||||
# allow plenty of time to pass in case valgrind is running
|
||||
set start [clock seconds]
|
||||
while {
|
||||
[clock seconds] - $start < 180 && $aresult eq "Async event not delivered"
|
||||
} {
|
||||
# be less busy
|
||||
after 100
|
||||
}
|
||||
return $aresult
|
||||
}} $hm
|
||||
} -result {test pattern} -cleanup {
|
||||
# give other threads some time to go way so that valgrind doesn't pick up
|
||||
# "still reachable" cases from early thread termination
|
||||
after 100
|
||||
testasync delete $hm
|
||||
}
|
||||
test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
|
||||
@@ -201,6 +216,9 @@ test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
|
||||
return $aresult
|
||||
}]] $hm
|
||||
} -result {test pattern} -cleanup {
|
||||
# give other threads some time to go way so that valgrind doesn't pick up
|
||||
# "still reachable" cases from early thread termination
|
||||
after 100
|
||||
testasync delete $hm
|
||||
}
|
||||
|
||||
|
||||
+4
-11
@@ -13,16 +13,11 @@
|
||||
# See the file "license.terms" for information on usage and redistribution of
|
||||
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
|
||||
# TODO: This test is likely worthless. Confirm and remove
|
||||
if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
package require tcltest 2
|
||||
namespace import -force ::tcltest::*
|
||||
}
|
||||
|
||||
::tcltest::loadTestedCommands
|
||||
catch [list package require -exact Tcltest [info patchlevel]]
|
||||
|
||||
testConstraint testbytestring [llength [info commands testbytestring]]
|
||||
|
||||
namespace eval ::tcl::test::io {
|
||||
namespace import ::tcltest::*
|
||||
|
||||
@@ -35,18 +30,16 @@ namespace eval ::tcl::test::io {
|
||||
variable msg
|
||||
variable expected
|
||||
|
||||
::tcltest::loadTestedCommands
|
||||
loadTestedCommands
|
||||
catch [list package require -exact Tcltest [info patchlevel]]
|
||||
package require tcltests
|
||||
|
||||
testConstraint testbytestring [llength [info commands testbytestring]]
|
||||
testConstraint testchannel [llength [info commands testchannel]]
|
||||
testConstraint exec [llength [info commands exec]]
|
||||
testConstraint openpipe 1
|
||||
testConstraint fileevent [llength [info commands fileevent]]
|
||||
testConstraint fcopy [llength [info commands fcopy]]
|
||||
testConstraint testfevent [llength [info commands testfevent]]
|
||||
testConstraint testchannelevent [llength [info commands testchannelevent]]
|
||||
testConstraint testmainthread [llength [info commands testmainthread]]
|
||||
testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
|
||||
|
||||
# You need a *very* special environment to do some tests. In particular,
|
||||
# many file systems do not support large-files...
|
||||
|
||||
+21
-6
@@ -1040,7 +1040,7 @@ test cmdAH-20.7.1 {
|
||||
Tcl_FileObjCmd: atime (built-in Windows names with dir path and extension)
|
||||
} -constraints {win} -body {
|
||||
file atime [file join [temporaryDirectory] CON.txt]
|
||||
} -result "could not get access time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error
|
||||
} -match regexp -result {could not (?:get access time|read)} -returnCodes error
|
||||
|
||||
if {[testConstraint unix] && [file exists /tmp]} {
|
||||
removeFile touch.me /tmp
|
||||
@@ -1281,7 +1281,7 @@ test cmdAH-24.14.1 {
|
||||
Tcl_FileObjCmd: mtime (built-in Windows names with dir path and extension)
|
||||
} -constraints {win} -body {
|
||||
file mtime [file join [temporaryDirectory] CON.txt]
|
||||
} -result "could not get modification time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error
|
||||
} -match regexp -result {could not (?:get modification time|read)} -returnCodes error
|
||||
|
||||
# owned
|
||||
test cmdAH-25.1 {Tcl_FileObjCmd: owned} -returnCodes error -body {
|
||||
@@ -1345,7 +1345,12 @@ test cmdAH-27.4 {
|
||||
test cmdAH-27.4.1 {
|
||||
Tcl_FileObjCmd: size (built-in Windows names with dir path and extension)
|
||||
} -constraints {win} -body {
|
||||
file size [file join [temporaryDirectory] con.txt]
|
||||
try {
|
||||
set res [file size [file join [temporaryDirectory] con.txt]]
|
||||
} trap {POSIX ENOENT} {} {
|
||||
set res 0
|
||||
}
|
||||
set res
|
||||
} -result 0
|
||||
|
||||
catch {testsetplatform $platform}
|
||||
@@ -1447,8 +1452,13 @@ test cmdAH-28.13 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {w
|
||||
test cmdAH-28.13.1 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {win} -setup {
|
||||
unset -nocomplain stat
|
||||
} -body {
|
||||
file stat [file join [temporaryDirectory] CON.txt] stat
|
||||
lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}
|
||||
try {
|
||||
file stat [file join [temporaryDirectory] CON.txt] stat
|
||||
set res [lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}]
|
||||
} trap {POSIX ENOENT} {} {
|
||||
set res {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
|
||||
}
|
||||
set res
|
||||
} -result {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
|
||||
unset -nocomplain stat
|
||||
|
||||
@@ -1498,7 +1508,12 @@ test cmdAH-29.6 {
|
||||
test cmdAH-29.6.1 {
|
||||
Tcl_FileObjCmd: type (built-in Windows names, with dir path and extension)
|
||||
} -constraints {win} -body {
|
||||
file type [file join [temporaryDirectory] CON.txt]
|
||||
try {
|
||||
set res [file type [file join [temporaryDirectory] CON.txt]]
|
||||
} trap {POSIX ENOENT} {} {
|
||||
set res {characterSpecial}
|
||||
}
|
||||
set res
|
||||
} -result "characterSpecial"
|
||||
|
||||
# Error conditions
|
||||
|
||||
+235
-170
@@ -16,49 +16,96 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
namespace import -force ::tcltest::*
|
||||
}
|
||||
|
||||
# Some tests require the "exec" command.
|
||||
# Skip them if exec is not defined.
|
||||
testConstraint exec [llength [info commands exec]]
|
||||
|
||||
#
|
||||
# These tests will run on any platform (and indeed crashed on the Mac). So put
|
||||
# them before you test for the existance of exec.
|
||||
#
|
||||
test env-1.1 {propagation of env values to child interpreters} -setup {
|
||||
catch {interp delete child}
|
||||
catch {unset env(test)}
|
||||
} -body {
|
||||
interp create child
|
||||
set env(test) garbage
|
||||
child eval {set env(test)}
|
||||
} -cleanup {
|
||||
interp delete child
|
||||
unset env(test)
|
||||
} -result {garbage}
|
||||
#
|
||||
# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
|
||||
# runs.
|
||||
#
|
||||
test env-1.2 {lappend to env value} -setup {
|
||||
catch {unset env(test)}
|
||||
} -body {
|
||||
set env(test) aaaaaaaaaaaaaaaa
|
||||
append env(test) bbbbbbbbbbbbbb
|
||||
unset env(test)
|
||||
}
|
||||
test env-1.3 {reflection of env by "array names"} -setup {
|
||||
catch {interp delete child}
|
||||
catch {unset env(test)}
|
||||
} -body {
|
||||
interp create child
|
||||
child eval {set env(test) garbage}
|
||||
expr {"test" in [array names env]}
|
||||
} -cleanup {
|
||||
interp delete child
|
||||
catch {unset env(test)}
|
||||
} -result {1}
|
||||
package require tcltests
|
||||
|
||||
set printenvScript [makeFile {
|
||||
# [exec] is required here to see the actual environment received by child
|
||||
# processes.
|
||||
proc getenv {} {
|
||||
global printenvScript
|
||||
catch {exec [interpreter] $printenvScript} out
|
||||
if {$out eq "child process exited abnormally"} {
|
||||
set out {}
|
||||
}
|
||||
return $out
|
||||
}
|
||||
|
||||
|
||||
proc envrestore {} {
|
||||
# Restore the environment variables at the end of the test.
|
||||
global env
|
||||
variable env2
|
||||
|
||||
foreach name [array names env] {
|
||||
unset env($name)
|
||||
}
|
||||
array set env $env2
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
proc envprep {} {
|
||||
# Save the current environment variables at the start of the test.
|
||||
global env
|
||||
variable keep
|
||||
variable env2
|
||||
|
||||
set env2 [array get env]
|
||||
foreach name [array names env] {
|
||||
# Keep some environment variables that support operation of the tcltest
|
||||
# package.
|
||||
if {[string toupper $name] ni [string toupper $keep]} {
|
||||
unset env($name)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
proc encodingrestore {} {
|
||||
variable sysenc
|
||||
encoding system $sysenc
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
proc encodingswitch encoding {
|
||||
variable sysenc
|
||||
# Need to run [getenv] in known encoding, so save the current one here...
|
||||
set sysenc [encoding system]
|
||||
encoding system $encoding
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
proc setup1 {} {
|
||||
global env
|
||||
envprep
|
||||
encodingswitch iso8859-1
|
||||
}
|
||||
|
||||
proc setup2 {} {
|
||||
global env
|
||||
setup1
|
||||
set env(NAME1) {test string}
|
||||
set env(NAME2) {new value}
|
||||
set env(XYZZY) {garbage}
|
||||
}
|
||||
|
||||
|
||||
proc cleanup1 {} {
|
||||
encodingrestore
|
||||
envrestore
|
||||
}
|
||||
|
||||
variable keep {
|
||||
TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
|
||||
SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
|
||||
DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
|
||||
__CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
|
||||
CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432
|
||||
}
|
||||
|
||||
variable printenvScript [makeFile [string map [list @keep@ [list $keep]] {
|
||||
encoding system iso8859-1
|
||||
proc lrem {listname name} {
|
||||
upvar $listname list
|
||||
@@ -70,7 +117,7 @@ set printenvScript [makeFile {
|
||||
}
|
||||
proc mangle s {
|
||||
regsub -all {\[|\\|\]} $s {\\&} s
|
||||
regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar &]} s
|
||||
regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar {&}]} s
|
||||
return [subst -novariables $s]
|
||||
}
|
||||
proc manglechar c {
|
||||
@@ -84,161 +131,154 @@ set printenvScript [makeFile {
|
||||
lrem names ComSpec
|
||||
lrem names ""
|
||||
}
|
||||
foreach name {
|
||||
TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
|
||||
SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
|
||||
DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
|
||||
__CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
|
||||
CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432
|
||||
} {
|
||||
foreach name @keep@ {
|
||||
lrem names $name
|
||||
}
|
||||
foreach p $names {
|
||||
puts "[mangle $p]=[mangle $env($p)]"
|
||||
puts [mangle $p]=[mangle $env($p)]
|
||||
}
|
||||
exit
|
||||
} printenv]
|
||||
}] printenv]
|
||||
|
||||
# [exec] is required here to see the actual environment received by child
|
||||
# processes.
|
||||
proc getenv {} {
|
||||
global printenvScript tcltest
|
||||
catch {exec [interpreter] $printenvScript} out
|
||||
if {$out eq "child process exited abnormally"} {
|
||||
set out {}
|
||||
}
|
||||
return $out
|
||||
|
||||
test env-1.1 {propagation of env values to child interpreters} -setup {
|
||||
catch {interp delete child}
|
||||
catch {unset env(test)}
|
||||
} -body {
|
||||
interp create child
|
||||
set env(test) garbage
|
||||
child eval {set env(test)}
|
||||
} -cleanup {
|
||||
interp delete child
|
||||
unset env(test)
|
||||
} -result {garbage}
|
||||
|
||||
|
||||
# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
|
||||
# runs.
|
||||
test env-1.2 {lappend to env value} -setup {
|
||||
catch {unset env(test)}
|
||||
} -body {
|
||||
set env(test) aaaaaaaaaaaaaaaa
|
||||
append env(test) bbbbbbbbbbbbbb
|
||||
unset env(test)
|
||||
}
|
||||
|
||||
# Save the current environment variables at the start of the test.
|
||||
|
||||
set env2 [array get env]
|
||||
foreach name [array names env] {
|
||||
# Keep some environment variables that support operation of the tcltest
|
||||
# package.
|
||||
if {[string toupper $name] ni {
|
||||
TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH
|
||||
SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
|
||||
DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
|
||||
SECURITYSESSIONID LANG WINDIR TERM
|
||||
CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432
|
||||
}} {
|
||||
unset env($name)
|
||||
}
|
||||
}
|
||||
|
||||
# Need to run 'getenv' in known encoding, so save the current one here...
|
||||
set sysenc [encoding system]
|
||||
|
||||
test env-2.1 {adding environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -constraints {exec} -body {
|
||||
getenv
|
||||
test env-1.3 {reflection of env by "array names"} -setup {
|
||||
catch {interp delete child}
|
||||
catch {unset env(test)}
|
||||
} -body {
|
||||
interp create child
|
||||
child eval {set env(test) garbage}
|
||||
expr {"test" in [array names env]}
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
} -result {}
|
||||
test env-2.2 {adding environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -constraints {exec} -body {
|
||||
interp delete child
|
||||
catch {unset env(test)}
|
||||
} -result 1
|
||||
|
||||
|
||||
test env-2.1 {
|
||||
adding environment variables
|
||||
} -constraints exec -setup setup1 -body {
|
||||
getenv
|
||||
} -cleanup cleanup1 -result {}
|
||||
|
||||
|
||||
test env-2.2 {
|
||||
adding environment variables
|
||||
} -constraints exec -setup setup1 -body {
|
||||
set env(NAME1) "test string"
|
||||
getenv
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
} -result {NAME1=test string}
|
||||
test env-2.3 {adding environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -cleanup cleanup1 -result {NAME1=test string}
|
||||
|
||||
|
||||
test env-2.3 {adding environment variables} -constraints exec -setup {
|
||||
setup1
|
||||
set env(NAME1) "test string"
|
||||
} -constraints {exec} -body {
|
||||
} -body {
|
||||
set env(NAME2) "more"
|
||||
getenv
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
} -result {NAME1=test string
|
||||
} -cleanup cleanup1 -result {NAME1=test string
|
||||
NAME2=more}
|
||||
test env-2.4 {adding environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
|
||||
|
||||
test env-2.4 {
|
||||
adding environment variables
|
||||
} -constraints exec -setup {
|
||||
setup1
|
||||
set env(NAME1) "test string"
|
||||
set env(NAME2) "more"
|
||||
} -constraints {exec} -body {
|
||||
} -body {
|
||||
set env(XYZZY) "garbage"
|
||||
getenv
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
} -cleanup { cleanup1
|
||||
} -result {NAME1=test string
|
||||
NAME2=more
|
||||
XYZZY=garbage}
|
||||
|
||||
set env(NAME1) "test string"
|
||||
set env(NAME2) "new value"
|
||||
set env(XYZZY) "garbage"
|
||||
test env-3.1 {changing environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -constraints {exec} -body {
|
||||
|
||||
test env-3.1 {
|
||||
changing environment variables
|
||||
} -constraints exec -setup setup2 -body {
|
||||
set result [getenv]
|
||||
unset env(NAME2)
|
||||
set result
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
cleanup1
|
||||
} -result {NAME1=test string
|
||||
NAME2=new value
|
||||
XYZZY=garbage}
|
||||
unset -nocomplain env(NAME2)
|
||||
|
||||
test env-4.1 {unsetting environment variables: default} -setup {
|
||||
encoding system iso8859-1
|
||||
} -constraints {exec} -body {
|
||||
|
||||
test env-4.1 {
|
||||
unsetting environment variables
|
||||
} -constraints exec -setup setup2 -body {
|
||||
unset -nocomplain env(NAME2)
|
||||
getenv
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
} -result {NAME1=test string
|
||||
} -cleanup cleanup1 -result {NAME1=test string
|
||||
XYZZY=garbage}
|
||||
test env-4.2 {unsetting environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -constraints {exec} -body {
|
||||
unset env(NAME1)
|
||||
getenv
|
||||
} -cleanup {
|
||||
unset env(XYZZY)
|
||||
encoding system $sysenc
|
||||
} -result {XYZZY=garbage}
|
||||
unset -nocomplain env(NAME1) env(XYZZY)
|
||||
test env-4.3 {setting international environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -constraints {exec} -body {
|
||||
|
||||
# env-4.2 is deleted
|
||||
|
||||
test env-4.3 {
|
||||
setting international environment variables
|
||||
} -constraints exec -setup setup1 -body {
|
||||
set env(\ua7) \ub6
|
||||
getenv
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
} -result {\u00a7=\u00b6}
|
||||
test env-4.4 {changing international environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -constraints {exec} -body {
|
||||
} -cleanup cleanup1 -result {\u00a7=\u00b6}
|
||||
|
||||
|
||||
test env-4.4 {
|
||||
changing international environment variables
|
||||
} -constraints exec -setup setup1 -body {
|
||||
set env(\ua7) \ua7
|
||||
getenv
|
||||
} -cleanup {
|
||||
encoding system $sysenc
|
||||
} -result {\u00a7=\u00a7}
|
||||
test env-4.5 {unsetting international environment variables} -setup {
|
||||
encoding system iso8859-1
|
||||
} -cleanup cleanup1 -result {\u00a7=\u00a7}
|
||||
|
||||
|
||||
test env-4.5 {
|
||||
unsetting international environment variables
|
||||
} -constraints exec -setup {
|
||||
setup1
|
||||
set env(\ua7) \ua7
|
||||
} -body {
|
||||
set env(\ub6) \ua7
|
||||
unset env(\ua7)
|
||||
getenv
|
||||
} -constraints {exec} -cleanup {
|
||||
unset env(\ub6)
|
||||
encoding system $sysenc
|
||||
} -result {\u00b6=\u00a7}
|
||||
} -cleanup cleanup1 -result {\u00b6=\u00a7}
|
||||
|
||||
test env-5.0 {corner cases - set a value, it should exist} -body {
|
||||
test env-5.0 {
|
||||
corner cases - set a value, it should exist
|
||||
} -setup setup1 -body {
|
||||
set env(temp) a
|
||||
set env(temp)
|
||||
} -cleanup {
|
||||
unset env(temp)
|
||||
} -result {a}
|
||||
test env-5.1 {corner cases - remove one elem at a time} -setup {
|
||||
set x [array get env]
|
||||
} -body {
|
||||
} -cleanup cleanup1 -result a
|
||||
|
||||
|
||||
test env-5.1 {
|
||||
corner cases - remove one elem at a time
|
||||
} -setup setup1 -body {
|
||||
# When no environment variables exist, the env var will contain no
|
||||
# entries. The "array names" call synchs up the C-level environ array with
|
||||
# the Tcl level env array. Make sure an empty Tcl array is created.
|
||||
@@ -246,9 +286,9 @@ test env-5.1 {corner cases - remove one elem at a time} -setup {
|
||||
unset env($e)
|
||||
}
|
||||
array size env
|
||||
} -cleanup {
|
||||
array set env $x
|
||||
} -result {0}
|
||||
} -cleanup cleanup1 -result 0
|
||||
|
||||
|
||||
test env-5.2 {corner cases - unset the env array} -setup {
|
||||
interp create i
|
||||
} -body {
|
||||
@@ -262,42 +302,54 @@ test env-5.2 {corner cases - unset the env array} -setup {
|
||||
} -cleanup {
|
||||
interp delete i
|
||||
} -result {0}
|
||||
|
||||
|
||||
test env-5.3 {corner cases: unset the env in master should unset child} -setup {
|
||||
setup1
|
||||
interp create i
|
||||
} -body {
|
||||
# Variables deleted in a master interp should be deleted in child interp
|
||||
# too.
|
||||
i eval { set env(THIS_SHOULD_EXIST) a}
|
||||
i eval {set env(THIS_SHOULD_EXIST) a}
|
||||
set result [set env(THIS_SHOULD_EXIST)]
|
||||
unset env(THIS_SHOULD_EXIST)
|
||||
lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}]
|
||||
} -cleanup {
|
||||
cleanup1
|
||||
interp delete i
|
||||
} -result {a 1}
|
||||
|
||||
|
||||
test env-5.4 {corner cases - unset the env array} -setup {
|
||||
setup1
|
||||
interp create i
|
||||
} -body {
|
||||
# The info exists command should be in synch with the env array.
|
||||
# Know Bug: 1737
|
||||
i eval { set env(THIS_SHOULD_EXIST) a}
|
||||
i eval {set env(THIS_SHOULD_EXIST) a}
|
||||
set result [info exists env(THIS_SHOULD_EXIST)]
|
||||
lappend result [set env(THIS_SHOULD_EXIST)]
|
||||
lappend result [info exists env(THIS_SHOULD_EXIST)]
|
||||
} -cleanup {
|
||||
cleanup1
|
||||
interp delete i
|
||||
} -result {1 a 1}
|
||||
test env-5.5 {corner cases - cannot have null entries on Windows} -constraints win -body {
|
||||
|
||||
|
||||
test env-5.5 {
|
||||
corner cases - cannot have null entries on Windows
|
||||
} -constraints win -body {
|
||||
set env() a
|
||||
catch {set env()}
|
||||
} -result 1
|
||||
} -cleanup cleanup1 -result 1
|
||||
|
||||
test env-6.1 {corner cases - add lots of env variables} -body {
|
||||
test env-6.1 {corner cases - add lots of env variables} -setup setup1 -body {
|
||||
set size [array size env]
|
||||
for {set i 0} {$i < 100} {incr i} {
|
||||
set env(BOGUS$i) $i
|
||||
}
|
||||
expr {[array size env] - $size}
|
||||
} -result 100
|
||||
} -cleanup cleanup1 -result 100
|
||||
|
||||
test env-7.1 {[219226]: whole env array should not be unset by read} -body {
|
||||
set n [array size env]
|
||||
@@ -310,16 +362,20 @@ test env-7.1 {[219226]: whole env array should not be unset by read} -body {
|
||||
return $n
|
||||
} -result 0
|
||||
|
||||
test env-7.2 {[219226]: links to env elements should not be removed by read} -body {
|
||||
test env-7.2 {
|
||||
[219226]: links to env elements should not be removed by read
|
||||
} -setup setup1 -body {
|
||||
apply {{} {
|
||||
set ::env(test7_2) ok
|
||||
upvar env(test7_2) elem
|
||||
set ::env(PATH)
|
||||
return $elem
|
||||
}}
|
||||
} -result ok
|
||||
} -cleanup cleanup1 -result ok
|
||||
|
||||
test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy trace} -body {
|
||||
test env-7.3 {
|
||||
[9b4702]: testing existence of env(some_thing) should not destroy trace
|
||||
} -setup setup1 -body {
|
||||
apply {{} {
|
||||
catch {unset ::env(test7_3)}
|
||||
proc foo args {
|
||||
@@ -330,16 +386,25 @@ test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy
|
||||
set ::env(not_yet_existent) "Now I'm here";
|
||||
return [info exists ::env(test7_3)]
|
||||
}}
|
||||
} -result 1
|
||||
} -cleanup cleanup1 -result 1
|
||||
|
||||
# Restore the environment variables at the end of the test.
|
||||
test env-8.0 {
|
||||
memory usage - valgrind does not report reachable memory
|
||||
} -body {
|
||||
set res [set env(__DUMMY__) {i'm with dummy}]
|
||||
unset env(__DUMMY__)
|
||||
return $res
|
||||
} -result {i'm with dummy}
|
||||
|
||||
|
||||
foreach name [array names env] {
|
||||
unset env($name)
|
||||
}
|
||||
array set env $env2
|
||||
|
||||
# cleanup
|
||||
rename getenv {}
|
||||
rename envrestore {}
|
||||
rename envprep {}
|
||||
rename encodingrestore {}
|
||||
rename encodingswitch {}
|
||||
|
||||
removeFile $printenvScript
|
||||
::tcltest::cleanupTests
|
||||
return
|
||||
|
||||
+15
-10
@@ -11,9 +11,14 @@
|
||||
# See the file "license.terms" for information on usage and redistribution of
|
||||
# this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
|
||||
# There is no point in running Valgrind on cases where [exec] forks but then
|
||||
# fails and the child process doesn't go through full cleanup.
|
||||
|
||||
package require tcltest 2
|
||||
namespace import -force ::tcltest::*
|
||||
|
||||
package require tcltests
|
||||
|
||||
# All tests require the "exec" command.
|
||||
# Skip them if exec is not defined.
|
||||
testConstraint exec [llength [info commands exec]]
|
||||
@@ -325,11 +330,11 @@ test exec-8.2 {long input and output} {exec} {
|
||||
|
||||
# Commands that return errors.
|
||||
|
||||
test exec-9.1 {commands returning errors} {exec} {
|
||||
test exec-9.1 {commands returning errors} {exec notValgrind} {
|
||||
set x [catch {exec gorp456} msg]
|
||||
list $x [string tolower $msg] [string tolower $errorCode]
|
||||
} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
|
||||
test exec-9.2 {commands returning errors} {exec} {
|
||||
test exec-9.2 {commands returning errors} {exec notValgrind} {
|
||||
string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode]
|
||||
} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
|
||||
test exec-9.3 {commands returning errors} -constraints {exec stdio} -body {
|
||||
@@ -339,7 +344,7 @@ test exec-9.4 {commands returning errors} -constraints {exec stdio} -body {
|
||||
exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar"
|
||||
} -returnCodes error -result {foo bar
|
||||
child process exited abnormally}
|
||||
test exec-9.5 {commands returning errors} -constraints {exec stdio} -body {
|
||||
test exec-9.5 {commands returning errors} -constraints {exec stdio notValgrind} -body {
|
||||
exec gorp456 | [interpreter] echo a b c
|
||||
} -returnCodes error -result {couldn't execute "gorp456": no such file or directory}
|
||||
test exec-9.6 {commands returning errors} -constraints {exec} -body {
|
||||
@@ -428,13 +433,13 @@ test exec-10.19 {errors in exec invocation} -constraints {exec} -body {
|
||||
exec cat >@ $f
|
||||
} -returnCodes error -result "channel \"$f\" wasn't opened for writing"
|
||||
close $f
|
||||
test exec-10.20 {errors in exec invocation} -constraints {exec} -body {
|
||||
test exec-10.20 {errors in exec invocation} -constraints {exec notValgrind} -body {
|
||||
exec ~non_existent_user/foo/bar
|
||||
} -returnCodes error -result {user "non_existent_user" doesn't exist}
|
||||
test exec-10.21 {errors in exec invocation} -constraints {exec} -body {
|
||||
test exec-10.21 {errors in exec invocation} -constraints {exec notValgrind} -body {
|
||||
exec [interpreter] true | ~xyzzy_bad_user/x | false
|
||||
} -returnCodes error -result {user "xyzzy_bad_user" doesn't exist}
|
||||
test exec-10.22 {errors in exec invocation} -constraints exec -body {
|
||||
test exec-10.22 {errors in exec invocation} -constraints {exec notValgrind} -body {
|
||||
exec echo test > ~non_existent_user/foo/bar
|
||||
} -returnCodes error -result {user "non_existent_user" doesn't exist}
|
||||
# Commands in background.
|
||||
@@ -510,7 +515,7 @@ test exec-13.1 {setting errorCode variable} {exec} {
|
||||
test exec-13.2 {setting errorCode variable} {exec} {
|
||||
list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode]
|
||||
} {1 {posix enoent {no such file or directory}}}
|
||||
test exec-13.3 {setting errorCode variable} {exec} {
|
||||
test exec-13.3 {setting errorCode variable} {exec notValgrind} {
|
||||
set x [catch {exec _weird_cmd_} msg]
|
||||
list $x [string tolower $msg] [lindex $errorCode 0] \
|
||||
[string tolower [lrange $errorCode 2 end]]
|
||||
@@ -548,7 +553,7 @@ test exec-14.2 {-keepnewline switch} -constraints {exec} -body {
|
||||
test exec-14.3 {unknown switch} -constraints {exec} -body {
|
||||
exec -gorp
|
||||
} -returnCodes error -result {bad option "-gorp": must be -ignorestderr, -keepnewline, or --}
|
||||
test exec-14.4 {-- switch} -constraints {exec} -body {
|
||||
test exec-14.4 {-- switch} -constraints {exec notValgrind} -body {
|
||||
exec -- -gorp
|
||||
} -returnCodes error -result {couldn't execute "-gorp": no such file or directory}
|
||||
test exec-14.5 {-ignorestderr switch} {exec} {
|
||||
@@ -662,7 +667,7 @@ test exec-18.2 {exec cat deals with weird file names} -body {
|
||||
# Note that this test cannot be adapted to work on Windows; that platform has
|
||||
# no kernel support for an analog of O_APPEND. OTOH, that means we can assume
|
||||
# that there is a POSIX shell...
|
||||
test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
|
||||
test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix notValgrind} -setup {
|
||||
set tmpfile [makeFile {0} tmpfile.exec-19.1]
|
||||
} -body {
|
||||
# Note that we have to allow for the current contents of the temporary
|
||||
@@ -675,7 +680,7 @@ test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
|
||||
{for a in a b c; do sleep 1; echo $a; done} >>$tmpfile &
|
||||
exec /bin/sh -c \
|
||||
{for a in d e f; do sleep 1; echo $a >&2; done} 2>>$tmpfile &
|
||||
# The above four shell invokations take about 3 seconds to finish, so allow
|
||||
# The above four shell invocations take about 3 seconds to finish, so allow
|
||||
# 5s (in case the machine is busy)
|
||||
after 5000
|
||||
# Check that no bytes have got lost through mixups with overlapping
|
||||
|
||||
@@ -7196,6 +7196,15 @@ test expr-51.1 {test round-to-even on input} {
|
||||
expr 6.9294956446009195e15
|
||||
} 6929495644600920.0
|
||||
|
||||
test expr-52.1 {
|
||||
comparison with empty string does not generate string representation
|
||||
} {
|
||||
set a [list one two three]
|
||||
list [expr {$a eq {}}] [expr {$a < {}}] [expr {$a > {}}] [
|
||||
string match {*no string representation*} [
|
||||
::tcl::unsupported::representation $a]]
|
||||
} {0 0 1 1}
|
||||
|
||||
|
||||
|
||||
# cleanup
|
||||
|
||||
@@ -264,6 +264,12 @@ removeDirectory dir.dir
|
||||
test filesystem-1.30 {normalisation of nonexistent user} -body {
|
||||
file normalize ~noonewiththisname
|
||||
} -returnCodes error -result {user "noonewiththisname" doesn't exist}
|
||||
test filesystem-1.30.1 {normalisation of existing user} -body {
|
||||
catch {file normalize ~$::tcl_platform(user)}
|
||||
} -result {0}
|
||||
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.31 {link normalisation: link near filesystem root} {testsetplatform} {
|
||||
testsetplatform unix
|
||||
file normalize /foo/../bar
|
||||
|
||||
@@ -585,6 +585,20 @@ test format-19.3 {Bug 2830354} {
|
||||
string length [format %340f 0]
|
||||
} 340
|
||||
|
||||
test format-19.4.1 {Bug d498578df4: width overflow should cause limit exceeded} \
|
||||
-constraints {longIs32bit} -body {
|
||||
# in case of overflow into negative, it produces width -2 (and limit exceeded),
|
||||
# in case of width will be unsigned, it will be outside limit (2GB for 32bit)...
|
||||
# and it don't throw an error in case the bug is not fixed (and probably no segfault).
|
||||
format %[expr {0xffffffff - 1}]g 0
|
||||
} -returnCodes error -result "max size for a Tcl value exceeded"
|
||||
|
||||
test format-19.4.2 {Bug d498578df4: width overflow should cause limit exceeded} -body {
|
||||
# limit should exceeds in any case,
|
||||
# and it don't throw an error in case the bug is not fixed (and probably no segfault).
|
||||
format %[expr {0xffffffffffffffff - 1}]g 0
|
||||
} -returnCodes error -result "max size for a Tcl value exceeded"
|
||||
|
||||
# Note that this test may fail in future versions
|
||||
test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body {
|
||||
set x [dict create a b c d]
|
||||
|
||||
@@ -666,6 +666,13 @@ test http11-4.3 "normal post request, check channel query length" -setup {
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
# Eliminate valgrind "still reachable" reports on outstanding "Detached"
|
||||
# structures in the detached list which stem from PipeClose2Proc not waiting
|
||||
# around for background processes to complete, meaning that previous calls to
|
||||
# Tcl_ReapDetachedProcs might not have had a chance to reap all processes.
|
||||
after 10
|
||||
exec [info nameofexecutable] << {}
|
||||
|
||||
foreach p {create_httpd httpd_read halt_httpd meta check_crc} {
|
||||
if {[llength [info proc $p]]} {rename $p {}}
|
||||
}
|
||||
|
||||
+5
-10
@@ -15,14 +15,8 @@
|
||||
|
||||
if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
package require tcltest 2
|
||||
namespace import -force ::tcltest::*
|
||||
}
|
||||
|
||||
::tcltest::loadTestedCommands
|
||||
catch [list package require -exact Tcltest [info patchlevel]]
|
||||
|
||||
testConstraint testbytestring [llength [info commands testbytestring]]
|
||||
|
||||
namespace eval ::tcl::test::io {
|
||||
namespace import ::tcltest::*
|
||||
|
||||
@@ -35,15 +29,16 @@ namespace eval ::tcl::test::io {
|
||||
variable msg
|
||||
variable expected
|
||||
|
||||
loadTestedCommands
|
||||
catch [list package require -exact Tcltest [info patchlevel]]
|
||||
package require tcltests
|
||||
|
||||
testConstraint testbytestring [llength [info commands testbytestring]]
|
||||
testConstraint testchannel [llength [info commands testchannel]]
|
||||
testConstraint exec [llength [info commands exec]]
|
||||
testConstraint openpipe 1
|
||||
testConstraint fileevent [llength [info commands fileevent]]
|
||||
testConstraint fcopy [llength [info commands fcopy]]
|
||||
testConstraint testfevent [llength [info commands testfevent]]
|
||||
testConstraint testchannelevent [llength [info commands testchannelevent]]
|
||||
testConstraint testmainthread [llength [info commands testmainthread]]
|
||||
testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
|
||||
testConstraint testobj [llength [info commands testobj]]
|
||||
|
||||
# You need a *very* special environment to do some tests. In
|
||||
|
||||
+13
-4
@@ -21,10 +21,10 @@ if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
::tcltest::loadTestedCommands
|
||||
catch [list package require -exact Tcltest [info patchlevel]]
|
||||
|
||||
package require tcltests
|
||||
|
||||
# Custom constraints used in this file
|
||||
testConstraint fcopy [llength [info commands fcopy]]
|
||||
testConstraint testchannel [llength [info commands testchannel]]
|
||||
testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
@@ -395,7 +395,7 @@ test iocmd-11.2 {I/O to command pipelines} {unixOrPc unixExecs} {
|
||||
test iocmd-11.3 {I/O to command pipelines} {unixOrPc unixExecs} {
|
||||
list [catch {open "| echo > \"$path(test5)\"" r+} msg] $msg $::errorCode
|
||||
} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
|
||||
test iocmd-11.4 {I/O to command pipelines} unixOrPc {
|
||||
test iocmd-11.4 {I/O to command pipelines} {notValgrind unixOrPc} {
|
||||
list [catch {open "| no_such_command_exists" rb} msg] $msg $::errorCode
|
||||
} {1 {couldn't execute "no_such_command_exists": no such file or directory} {POSIX ENOENT {no such file or directory}}}
|
||||
|
||||
@@ -3781,7 +3781,6 @@ test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
|
||||
# Use constraints to skip this test while valgrinding so this expected leak
|
||||
# doesn't prevent a finding of "leak-free".
|
||||
#
|
||||
testConstraint notValgrind [expr {![testConstraint valgrind]}]
|
||||
test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body {
|
||||
|
||||
#puts <<$tcltest::mainThread>>main
|
||||
@@ -3834,6 +3833,16 @@ test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -mat
|
||||
|
||||
rename track {}
|
||||
# cleanup
|
||||
|
||||
|
||||
# Eliminate valgrind "still reachable" reports on outstanding "Detached"
|
||||
# structures in the detached list which stem from PipeClose2Proc not waiting
|
||||
# around for background processes to complete, meaning that previous calls to
|
||||
# Tcl_ReapDetachedProcs might not have had a chance to reap all processes.
|
||||
after 10
|
||||
exec [info nameofexecutable] << {}
|
||||
|
||||
|
||||
foreach file [list test1 test2 test3 test4] {
|
||||
removeFile $file
|
||||
}
|
||||
|
||||
+1
-1
@@ -1240,8 +1240,8 @@ test iortrans-11.1 {origin interpreter of moved transform destroyed during acces
|
||||
set res
|
||||
}]
|
||||
} -cleanup {
|
||||
tempdone
|
||||
interp delete $idb
|
||||
tempdone
|
||||
} -result {Owner lost}
|
||||
test iortrans-11.2 {delete interp of reflected transform} -setup {
|
||||
interp create slave
|
||||
|
||||
+1
-1
@@ -608,7 +608,7 @@ test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
|
||||
variable copy 1
|
||||
}
|
||||
} -constraints {testchannel knownBug} -body {
|
||||
# This test to check the validity of aquired Tcl_Channel references is not
|
||||
# This test to check the validity of acquired Tcl_Channel references is not
|
||||
# possible because even a backgrounded fcopy will immediately start to
|
||||
# copy data, without waiting for the event loop. This is done only in case
|
||||
# of an underflow on the read size!. So stacking transforms after the
|
||||
|
||||
@@ -1210,8 +1210,6 @@ namespace eval ::tcl::test::main {
|
||||
Bug 1775878
|
||||
} -constraints {
|
||||
exec Tcltest
|
||||
} -setup {
|
||||
catch {set f [open "|[list [interpreter]]" w+]}
|
||||
} -body {
|
||||
exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result
|
||||
set f [open result]
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#! /usr/bin/env tclsh
|
||||
|
||||
package ifneeded tcltests 0.1 "
|
||||
source [list $dir/tcltests.tcl]
|
||||
package provide tcltests 0.1
|
||||
"
|
||||
+5
-1
@@ -10,6 +10,7 @@
|
||||
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
|
||||
package require tcltest 2
|
||||
package require tcltests
|
||||
|
||||
namespace eval ::tcl::test::platform {
|
||||
namespace import ::tcltest::testConstraint
|
||||
@@ -67,7 +68,10 @@ test platform-3.1 {CPU ID on Windows/UNIX} \
|
||||
# format of string it produces consists of two non-empty words separated by a
|
||||
# hyphen.
|
||||
package require platform
|
||||
test platform-4.1 {format of platform::identify result} -match regexp -body {
|
||||
test platform-4.1 {format of platform::identify result} -constraints notValgrind -match regexp -body {
|
||||
# [identify] may attempt to [exec] dpkg-architecture, which may not exist,
|
||||
# in which case fork will not be followed by exec, and valgrind will issue
|
||||
# "still reachable" reports.
|
||||
platform::identify
|
||||
} -result {^([^-]+-)+[^-]+$}
|
||||
test platform-4.2 {format of platform::generic result} -match regexp -body {
|
||||
|
||||
+4
-8
@@ -308,14 +308,10 @@ test safe-8.7 {safe source control on file} -setup {
|
||||
unset log
|
||||
safe::interpDelete $i
|
||||
} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] xxxxxxxxxxx.tcl]:no such file or directory"]]
|
||||
test safe-8.8 {safe source forbids -rsrc} -setup {
|
||||
catch {safe::interpDelete $i}
|
||||
safe::interpCreate $i
|
||||
} -body {
|
||||
$i eval {source -rsrc Init}
|
||||
} -returnCodes error -cleanup {
|
||||
safe::interpDelete $i
|
||||
} -result {wrong # args: should be "source ?-encoding E? fileName"}
|
||||
test safe-8.8 {safe source forbids -rsrc} emptyTest {
|
||||
# Disabled this test. It was only useful for long unsupported
|
||||
# Mac OS 9 systems. [Bug 860a9f1945]
|
||||
} {}
|
||||
test safe-8.9 {safe source and return} -setup {
|
||||
set returnScript [makeFile {return "ok"} return.tcl]
|
||||
catch {safe::interpDelete $i}
|
||||
|
||||
@@ -2015,6 +2015,12 @@ test string-29.4 {string cat, many args} {
|
||||
list $r1 $r2
|
||||
} {0 0}
|
||||
|
||||
test string-30.1.1 {[Bug ba921a8d98]: string cat} {
|
||||
string cat [set data [binary format a* hello]] [encoding convertto $data] [unset data]
|
||||
} hellohello
|
||||
test string-30.1.2 {[Bug ba921a8d98]: inplace cat by subst (compiled to "strcat" instruction)} {
|
||||
set x "[set data [binary format a* hello]][encoding convertto $data][unset data]"
|
||||
} hellohello
|
||||
|
||||
|
||||
# cleanup
|
||||
|
||||
@@ -688,6 +688,26 @@ if {[testConstraint testnrelevels]} {
|
||||
namespace delete testnre
|
||||
}
|
||||
|
||||
test tailcall-14.1 {in a deleted namespace} -body {
|
||||
namespace eval ns {
|
||||
proc p args {
|
||||
tailcall [namespace current] $args
|
||||
}
|
||||
namespace delete [namespace current]
|
||||
p
|
||||
}
|
||||
} -returnCodes 1 -result {namespace "::ns" not found}
|
||||
|
||||
test tailcall-14.1-bc {{in a deleted namespace} {byte compiled}} -body {
|
||||
namespace eval ns {
|
||||
proc p args {
|
||||
tailcall [namespace current] {*}$args
|
||||
}
|
||||
namespace delete [namespace current]
|
||||
p
|
||||
}
|
||||
} -returnCodes 1 -result {namespace "::ns" not found}
|
||||
|
||||
# cleanup
|
||||
::tcltest::cleanupTests
|
||||
|
||||
|
||||
+8
-1
@@ -312,7 +312,7 @@ test tcltest-5.5 {InitConstraints: list of built-in constraints} \
|
||||
-result [lsort {
|
||||
95 98 asyncPipeClose eformat emptyTest exec hasIsoLocale interactive
|
||||
knownBug mac macCrash macOnly macOrPc macOrUnix macOrWin nonBlockFiles
|
||||
nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp socket
|
||||
nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp slowTest socket
|
||||
stdio tempNotMac tempNotPc tempNotUnix tempNotWin unix unixCrash unixExecs
|
||||
unixOnly unixOrPc unixOrWin userInteraction win winCrash winOnly
|
||||
}]
|
||||
@@ -908,7 +908,9 @@ removeFile load.tcl
|
||||
|
||||
# [interpreter]
|
||||
test tcltest-13.1 {interpreter} {
|
||||
-constraints notValgrind
|
||||
-setup {
|
||||
#to do: Why is $::tcltest::tcltest being saved and restored here?
|
||||
set old $::tcltest::tcltest
|
||||
set ::tcltest::tcltest tcltest
|
||||
}
|
||||
@@ -920,6 +922,11 @@ test tcltest-13.1 {interpreter} {
|
||||
}
|
||||
-result {tcltest tclsh tclsh}
|
||||
-cleanup {
|
||||
# writing ::tcltest::tcltest triggers a trace that sets up the stdio
|
||||
# constraint, which involves a call to [exec] that might fail after
|
||||
# "fork" and before "exec", in which case the forked process will not
|
||||
# have a chance to clean itself up before exiting, which causes
|
||||
# valgrind to issue numerous "still reachable" reports.
|
||||
set ::tcltest::tcltest $old
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#! /usr/bin/env tclsh
|
||||
|
||||
package require tcltest 2.2
|
||||
namespace import ::tcltest::*
|
||||
|
||||
testConstraint exec [llength [info commands exec]]
|
||||
testConstraint fcopy [llength [info commands fcopy]]
|
||||
testConstraint fileevent [llength [info commands fileevent]]
|
||||
testConstraint thread [
|
||||
expr {0 == [catch {package require Thread 2.7-}]}]
|
||||
testConstraint notValgrind [expr {![testConstraint valgrind]}]
|
||||
+36
-31
@@ -11,25 +11,19 @@
|
||||
# See the file "license.terms" for information on usage and redistribution
|
||||
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
|
||||
if {[lsearch [namespace children] ::tcltest] == -1} {
|
||||
package require tcltest 2.2
|
||||
namespace import -force ::tcltest::*
|
||||
}
|
||||
|
||||
# when thread::release is used, -wait is passed in order allow the thread to
|
||||
# be fully finalized, which avoids valgrind "still reachable" reports.
|
||||
|
||||
package require tcltests
|
||||
|
||||
::tcltest::loadTestedCommands
|
||||
catch [list package require -exact Tcltest [info patchlevel]]
|
||||
|
||||
# Some tests require the testthread command
|
||||
|
||||
testConstraint testthread [expr {[info commands testthread] != {}}]
|
||||
testConstraint testthread [expr {[info commands testthread] ne {}}]
|
||||
|
||||
# Some tests require the Thread package
|
||||
|
||||
testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
|
||||
|
||||
# Some tests may not work under valgrind
|
||||
|
||||
testConstraint notValgrind [expr {![testConstraint valgrind]}]
|
||||
|
||||
set threadSuperKillScript {
|
||||
rename catch ""
|
||||
@@ -72,6 +66,17 @@ proc ThreadError {id info} {
|
||||
set threadSawError($id) true; # signal main thread to exit [vwait].
|
||||
}
|
||||
|
||||
proc threadSuperKill id {
|
||||
variable threadSuperKillScript
|
||||
try {
|
||||
thread::send $id $::threadSuperKillScript
|
||||
} on error {tres topts} {
|
||||
if {$tres ne {target thread died}} {
|
||||
return -options $topts $tres
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if {[testConstraint thread]} {
|
||||
thread::errorproc ThreadError
|
||||
}
|
||||
@@ -96,22 +101,22 @@ test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} {
|
||||
test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} {
|
||||
set serverthread [thread::create -preserved]
|
||||
set numthreads [llength [thread::names]]
|
||||
thread::release $serverthread
|
||||
thread::release -wait $serverthread
|
||||
set numthreads
|
||||
} {2}
|
||||
} 2
|
||||
test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
|
||||
thread::create {set x 5}
|
||||
foreach try {0 1 2 4 5 6} {
|
||||
# Try various ways to yield
|
||||
update
|
||||
after 10
|
||||
set l [llength [thread::names]]
|
||||
if {$l == 1} {
|
||||
break
|
||||
}
|
||||
# Try various ways to yield
|
||||
update
|
||||
after 10
|
||||
set l [llength [thread::names]]
|
||||
if {$l == 1} {
|
||||
break
|
||||
}
|
||||
}
|
||||
set l
|
||||
} {1}
|
||||
} 1
|
||||
test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
|
||||
thread::create {{*}{}}
|
||||
update
|
||||
@@ -121,13 +126,13 @@ test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
|
||||
test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} {
|
||||
set serverthread [thread::create -preserved]
|
||||
set five [thread::send $serverthread {set x 5}]
|
||||
thread::release $serverthread
|
||||
thread::release -wait $serverthread
|
||||
set five
|
||||
} 5
|
||||
test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} {
|
||||
set serverthread [thread::create -preserved {set z 5 ; thread::wait}]
|
||||
set five [thread::send $serverthread {set z}]
|
||||
thread::release $serverthread
|
||||
thread::release -wait $serverthread
|
||||
set five
|
||||
} 5
|
||||
|
||||
@@ -159,7 +164,7 @@ test thread-3.1 {TclThreadList} {thread} {
|
||||
set l2 [thread::names]
|
||||
set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]]
|
||||
foreach t $l1 {
|
||||
thread::release $t
|
||||
thread::release -wait $t
|
||||
}
|
||||
list $len $c
|
||||
} {1 0}
|
||||
@@ -887,7 +892,7 @@ test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainE
|
||||
# wait for other thread to signal "ready to cancel"
|
||||
vwait ::threadIdStarted; after 1000
|
||||
set res [thread::cancel $serverthread]
|
||||
thread::send $serverthread $::threadSuperKillScript
|
||||
threadSuperKill $serverthread
|
||||
vwait ::threadSawError($serverthread)
|
||||
thread::join $serverthread; drainEventQueue
|
||||
list $res [expr {[info exists ::threadIdStarted] ? \
|
||||
@@ -929,7 +934,7 @@ test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread
|
||||
# wait for other thread to signal "ready to cancel"
|
||||
vwait ::threadIdStarted; after 1000
|
||||
set res [thread::cancel $serverthread]
|
||||
thread::send $serverthread $::threadSuperKillScript
|
||||
threadSuperKill $serverthread
|
||||
vwait ::threadSawError($serverthread)
|
||||
thread::join $serverthread; drainEventQueue
|
||||
list $res [expr {[info exists ::threadIdStarted] ? \
|
||||
@@ -1029,7 +1034,7 @@ test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode lo
|
||||
# wait for other thread to signal "ready to cancel"
|
||||
vwait ::threadIdStarted; after 1000
|
||||
set res [thread::send -async $serverthread {interp cancel}]
|
||||
thread::send $serverthread $::threadSuperKillScript
|
||||
threadSuperKill $serverthread
|
||||
vwait ::threadSawError($serverthread)
|
||||
thread::join $serverthread; drainEventQueue
|
||||
list $res [expr {[info exists ::threadIdStarted] ? \
|
||||
@@ -1071,7 +1076,7 @@ test thread-7.29 {cancel: send async cancel nested catch pure inside-command loo
|
||||
# wait for other thread to signal "ready to cancel"
|
||||
vwait ::threadIdStarted; after 1000
|
||||
set res [thread::send -async $serverthread {interp cancel}]
|
||||
thread::send $serverthread $::threadSuperKillScript
|
||||
threadSuperKill $serverthread
|
||||
vwait ::threadSawError($serverthread)
|
||||
thread::join $serverthread; drainEventQueue
|
||||
list $res [expr {[info exists ::threadIdStarted] ? \
|
||||
@@ -1111,7 +1116,7 @@ test thread-7.30 {cancel: send async thread cancel nested catch inside pure byte
|
||||
# wait for other thread to signal "ready to cancel"
|
||||
vwait ::threadIdStarted; after 1000
|
||||
set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
|
||||
thread::send $serverthread $::threadSuperKillScript
|
||||
threadSuperKill $serverthread
|
||||
vwait ::threadSawError($serverthread)
|
||||
thread::join $serverthread; drainEventQueue
|
||||
list $res [expr {[info exists ::threadIdStarted] ? \
|
||||
@@ -1153,7 +1158,7 @@ test thread-7.31 {cancel: send async thread cancel nested catch pure inside-comm
|
||||
# wait for other thread to signal "ready to cancel"
|
||||
vwait ::threadIdStarted; after 1000
|
||||
set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
|
||||
thread::send $serverthread $::threadSuperKillScript
|
||||
threadSuperKill $serverthread
|
||||
vwait ::threadSawError($serverthread)
|
||||
thread::join $serverthread; drainEventQueue
|
||||
list $res [expr {[info exists ::threadIdStarted] ? \
|
||||
|
||||
+1
-1
@@ -1083,7 +1083,7 @@ test winFCmd-12.6.2 {ConvertFileNameFormat: absolute path with drive (in temp fo
|
||||
} -constraints {win} -body {
|
||||
createfile $::env(TEMP)/td1 {}
|
||||
string equal [string tolower [file attributes $::env(TEMP)/td1 -longname]] \
|
||||
[string tolower [file normalize $::env(TEMP)]/td1]]
|
||||
[string tolower [file normalize $::env(TEMP)]/td1]
|
||||
} -cleanup {
|
||||
file delete -force -- $::env(TEMP)/td1
|
||||
} -result 1
|
||||
|
||||
+220
-60
@@ -308,9 +308,54 @@ test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \
|
||||
lappend x [catch {close $f} msg] $msg
|
||||
} {writable timeout 0 {}}
|
||||
|
||||
set path(echoArgs.tcl) [makeFile {
|
||||
puts "[list $argv0 $argv]"
|
||||
} echoArgs.tcl]
|
||||
proc _testExecArgs {single args} {
|
||||
variable path
|
||||
if {![info exists path(echoArgs.tcl)] || ![file exists $path(echoArgs.tcl)]} {
|
||||
set path(echoArgs.tcl) [makeFile {
|
||||
puts "[list [file tail $argv0] {*}$argv]"
|
||||
} echoArgs.tcl]
|
||||
}
|
||||
if {![info exists path(echoArgs.bat)] || ![file exists $path(echoArgs.bat)]} {
|
||||
set path(echoArgs.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" "echoArgs.bat"]
|
||||
}
|
||||
set cmds [list [list [interpreter] $path(echoArgs.tcl)]]
|
||||
if {!($single & 2)} {
|
||||
lappend cmds [list $path(echoArgs.bat)]
|
||||
} else {
|
||||
if {![info exists path(echoArgs2.bat)] || ![file exists $path(echoArgs2.bat)]} {
|
||||
file mkdir [file join [temporaryDirectory] test(Dir)Check]
|
||||
set path(echoArgs2.bat) [makeFile "@[file native [interpreter]] $path(echoArgs.tcl) %*" \
|
||||
"test(Dir)Check/echo(Cmd)Test Args & Batch.bat"]
|
||||
}
|
||||
lappend cmds [list $path(echoArgs2.bat)]
|
||||
}
|
||||
set broken {}
|
||||
foreach args $args {
|
||||
if {$single & 1} {
|
||||
# enclose single test-arg between 1st/3rd to be sure nothing is truncated
|
||||
# (e. g. to cover unexpected trim by nts-zero case, and args don't recombined):
|
||||
set args [list "1st" $args "3rd"]
|
||||
}
|
||||
set args [list {*}$args]; # normalized canonical list
|
||||
foreach cmd $cmds {
|
||||
set e [linsert $args 0 [file tail $path(echoArgs.tcl)]]
|
||||
tcltest::DebugPuts 4 " ## test exec [file extension [lindex $cmd 0]] ($cmd) for\n ## $args"
|
||||
if {[catch {
|
||||
exec {*}$cmd {*}$args
|
||||
} r]} {
|
||||
set r "ERROR: $r"
|
||||
}
|
||||
if {$r ne $e} {
|
||||
append broken "\[ERROR\]: exec [file extension [lindex $cmd 0]] on $args\n -- result:\n$r\n -- expected:\n$e\n"
|
||||
}
|
||||
if {$single & 8} {
|
||||
# if test exe only:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return $broken
|
||||
}
|
||||
|
||||
### validate the raw output of BuildCommandLine().
|
||||
###
|
||||
@@ -369,65 +414,178 @@ test winpipe-7.18 {BuildCommandLine: special chars #5} {win exec} {
|
||||
exec $env(COMSPEC) /c echo foo \} bar
|
||||
} "foo \} bar"
|
||||
|
||||
set injectList {
|
||||
{test"whoami} {test""whoami}
|
||||
{test"""whoami} {test""""whoami}
|
||||
|
||||
"test\"whoami\\" "test\"\"whoami\\"
|
||||
"test\"\"\"whoami\\" "test\"\"\"\"whoami\\"
|
||||
|
||||
{test\\&\\test} {test"\\&\\test}
|
||||
{"test\\&\\test} {"test"\\&\\"test"}
|
||||
{test\\"&"\\test} {test"\\"&"\\test}
|
||||
{"test\\"&"\\test} {"test"\\"&"\\"test"}
|
||||
|
||||
{test\"&whoami} {test"\"&whoami}
|
||||
{test""\"&whoami} {test"""\"&whoami}
|
||||
{test\"\&whoami} {test"\"\&whoami}
|
||||
{test""\"\&whoami} {test"""\"\&whoami}
|
||||
|
||||
{test&whoami} {test|whoami}
|
||||
{"test&whoami} {"test|whoami}
|
||||
{test"&whoami} {test"|whoami}
|
||||
{"test"&whoami} {"test"|whoami}
|
||||
{""test"&whoami} {""test"|whoami}
|
||||
|
||||
{test&echo "} {test|echo "}
|
||||
{"test&echo "} {"test|echo "}
|
||||
{test"&echo "} {test"|echo "}
|
||||
{"test"&echo "} {"test"|echo "}
|
||||
{""test"&echo "} {""test"|echo "}
|
||||
|
||||
{test&echo ""} {test|echo ""}
|
||||
{"test&echo ""} {"test|echo ""}
|
||||
{test"&echo ""} {test"|echo ""}
|
||||
{"test"&echo ""} {"test"|echo ""}
|
||||
{""test"&echo ""} {""test"|echo ""}
|
||||
|
||||
{test>whoami} {test<whoami}
|
||||
{"test>whoami} {"test<whoami}
|
||||
{test">whoami} {test"<whoami}
|
||||
{"test">whoami} {"test"<whoami}
|
||||
{""test">whoami} {""test"<whoami}
|
||||
{test(whoami)} {test(whoami)}
|
||||
{test"(whoami)} {test"(whoami)}
|
||||
{test^whoami} {test^^echo ^^^}
|
||||
{test"^whoami} {test"^^echo ^^^}
|
||||
{test"^echo ^^^"} {test""^echo" ^^^"}
|
||||
|
||||
{test%USERDOMAIN%\%USERNAME%}
|
||||
{test" %USERDOMAIN%\%USERNAME%}
|
||||
{test%USERDOMAIN%\\%USERNAME%}
|
||||
{test" %USERDOMAIN%\\%USERNAME%}
|
||||
{test%USERDOMAIN%&%USERNAME%}
|
||||
{test" %USERDOMAIN%&%USERNAME%}
|
||||
{test%USERDOMAIN%\&\%USERNAME%}
|
||||
{test" %USERDOMAIN%\&\%USERNAME%}
|
||||
|
||||
{test%USERDOMAIN%\&\test}
|
||||
{test" %USERDOMAIN%\&\test}
|
||||
{test%USERDOMAIN%\\&\\test}
|
||||
{test" %USERDOMAIN%\\&\\test}
|
||||
|
||||
{test%USERDOMAIN%\&\"test}
|
||||
{test" %USERDOMAIN%\&\"test}
|
||||
{test%USERDOMAIN%\\&\\"test}
|
||||
{test" %USERDOMAIN%\\&\\"test}
|
||||
}
|
||||
|
||||
### validate the pass-thru from BuildCommandLine() to the crt's parse_cmdline().
|
||||
###
|
||||
test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo "" bar
|
||||
} [list $path(echoArgs.tcl) [list foo {} bar]]
|
||||
test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo {} bar
|
||||
} [list $path(echoArgs.tcl) [list foo {} bar]]
|
||||
test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #1} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo "\"" bar
|
||||
} [list $path(echoArgs.tcl) [list foo "\"" bar]]
|
||||
test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #2} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo {""} bar
|
||||
} [list $path(echoArgs.tcl) [list foo {""} bar]]
|
||||
test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #3} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo "\" " bar
|
||||
} [list $path(echoArgs.tcl) [list foo "\" " bar]]
|
||||
test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #4} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo {a="b"} bar
|
||||
} [list $path(echoArgs.tcl) [list foo {a="b"} bar]]
|
||||
test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #5} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo {a = "b"} bar
|
||||
} [list $path(echoArgs.tcl) [list foo {a = "b"} bar]]
|
||||
test winpipe-8.8 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #6} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}
|
||||
} [list $path(echoArgs.tcl) [list {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}]]
|
||||
test winpipe-8.9 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #1} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\ bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\ bar]]
|
||||
test winpipe-8.10 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #2} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\\\ bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\\\ bar]]
|
||||
test winpipe-8.11 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #3} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\\ \\ bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\\ \\ bar]]
|
||||
test winpipe-8.12 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #4} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\ bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\\ \\\\ bar]]
|
||||
test winpipe-8.13 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #5} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\ bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\ bar]]
|
||||
test winpipe-8.14 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #6} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\" bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\\ \\\" bar]]
|
||||
test winpipe-8.15 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #7} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\" bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\\ \\\\\" bar]]
|
||||
test winpipe-8.16 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #8} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\\" bar
|
||||
} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\\" bar]]
|
||||
test winpipe-8.17 {BuildCommandLine/parse_cmdline pass-thru: special chars #1} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \{ bar
|
||||
} [list $path(echoArgs.tcl) [list foo \{ bar]]
|
||||
test winpipe-8.18 {BuildCommandLine/parse_cmdline pass-thru: special chars #2} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo \} bar
|
||||
} [list $path(echoArgs.tcl) [list foo \} bar]]
|
||||
test winpipe-8.19 {ensure parse_cmdline isn't doing wildcard replacement} {win exec} {
|
||||
exec [interpreter] $path(echoArgs.tcl) foo * makefile.?c bar
|
||||
} [list $path(echoArgs.tcl) [list foo * makefile.?c bar]]
|
||||
test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: dumped arguments are equal original} \
|
||||
-constraints {win exec} -body {
|
||||
_testExecArgs 0 \
|
||||
[list foo "" bar] \
|
||||
[list foo {} bar] \
|
||||
[list foo "\"" bar] \
|
||||
[list foo {""} bar] \
|
||||
[list foo "\" " bar] \
|
||||
[list foo {a="b"} bar] \
|
||||
[list foo {a = "b"} bar] \
|
||||
[list {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}] \
|
||||
[list foo \\ bar] \
|
||||
[list foo \\\\ bar] \
|
||||
[list foo \\\ \\ bar] \
|
||||
[list foo \\\ \\\\ bar] \
|
||||
[list foo \\\ \\\\\\ bar] \
|
||||
[list foo \\\ \\\" bar] \
|
||||
[list foo \\\ \\\\\" bar] \
|
||||
[list foo \\\ \\\\\\\" bar] \
|
||||
[list foo \{ bar] \
|
||||
[list foo \} bar] \
|
||||
[list foo * makefile.?c bar]
|
||||
} -result {}
|
||||
|
||||
test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (particular)} \
|
||||
-constraints {win exec slowTest} -body {
|
||||
_testExecArgs 1 {*}$injectList
|
||||
} -result {}
|
||||
|
||||
test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (jointly)} \
|
||||
-constraints {win exec} -body {
|
||||
_testExecArgs 0 \
|
||||
[list START {*}$injectList END] \
|
||||
[list "START\"" {*}$injectList END] \
|
||||
[list START {*}$injectList "\"END"] \
|
||||
[list "START\"" {*}$injectList "\"END"]
|
||||
} -result {}
|
||||
|
||||
test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (command/jointly args)} \
|
||||
-constraints {win exec} -body {
|
||||
_testExecArgs 2 \
|
||||
[list START {*}$injectList END] \
|
||||
[list "START\"" {*}$injectList END] \
|
||||
[list START {*}$injectList "\"END"] \
|
||||
[list "START\"" {*}$injectList "\"END"]
|
||||
} -result {}
|
||||
|
||||
test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: check injection on special meta-chars (random mix)} \
|
||||
-constraints {win exec} -body {
|
||||
set lst {}
|
||||
set maps {
|
||||
{\&|^<>!()%}
|
||||
{\&|^<>!()% }
|
||||
{"\&|^<>!()%}
|
||||
{"\&|^<>!()% }
|
||||
{"""""\\\\\&|^<>!()%}
|
||||
{"""""\\\\\&|^<>!()% }
|
||||
}
|
||||
set i 0
|
||||
time {
|
||||
set args {[incr i].}
|
||||
time {
|
||||
set map [lindex $maps [expr {int(rand()*[llength $maps])}]]
|
||||
# be sure arg has some prefix (avoid special handling, like |& etc)
|
||||
set a {x}
|
||||
while {[string length $a] < 50} {
|
||||
append a [string index $map [expr {int(rand()*[string length $map])}]]
|
||||
}
|
||||
lappend args $a
|
||||
} 20
|
||||
lappend lst $args
|
||||
} 10
|
||||
_testExecArgs 0 {*}$lst
|
||||
} -result {} -cleanup {
|
||||
unset -nocomplain lst args a map maps
|
||||
}
|
||||
|
||||
set injectList {
|
||||
"test\"\nwhoami" "test\"\"\nwhoami"
|
||||
"test\"\"\"\nwhoami" "test\"\"\"\"\nwhoami"
|
||||
"test;\n&echo \"" "\"test;\n&echo \""
|
||||
"test\";\n&echo \"" "\"test\";\n&echo \""
|
||||
"\"\"test\";\n&echo \""
|
||||
}
|
||||
|
||||
test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: check new-line quoted in args} \
|
||||
-constraints {win exec} -body {
|
||||
# test exe only, because currently there is no proper way to escape a new-line char resp.
|
||||
# to supply a new-line to the batch-files within arguments (command line is truncated).
|
||||
_testExecArgs 8 \
|
||||
[list START {*}$injectList END] \
|
||||
[list "START\"" {*}$injectList END] \
|
||||
[list START {*}$injectList "\"END"] \
|
||||
[list "START\"" {*}$injectList "\"END"]
|
||||
} -result {}
|
||||
|
||||
test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: check new-line quoted in args (batch)} \
|
||||
-constraints {win exec knownBug} -body {
|
||||
# this will fail if executed batch-file, because currently there is no proper way to escape a new-line char.
|
||||
_testExecArgs 0 $injectList
|
||||
} -result {}
|
||||
|
||||
|
||||
rename _testExecArgs {}
|
||||
|
||||
# restore old values for env(TMP) and env(TEMP)
|
||||
|
||||
@@ -446,6 +604,8 @@ removeFile stdout
|
||||
removeFile stderr
|
||||
removeFile nothing
|
||||
removeFile echoArgs.tcl
|
||||
removeFile echoArgs.bat
|
||||
file delete -force [file join [temporaryDirectory] test(Dir)Check]
|
||||
::tcltest::cleanupTests
|
||||
return
|
||||
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
# The file tests the tclZlib.c file.
|
||||
#
|
||||
# This file contains a collection of tests for one or more of the Tcl built-in
|
||||
# commands. Sourcing this file into Tcl runs the tests and generates output
|
||||
# for errors. No output means no errors were found.
|
||||
#
|
||||
# Copyright (c) 1996-1998 by Sun Microsystems, Inc.
|
||||
# Copyright (c) 1998-1999 by Scriptics Corporation.
|
||||
#
|
||||
# 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.1
|
||||
namespace import -force ::tcltest::*
|
||||
}
|
||||
|
||||
testConstraint zipfs [expr {[llength [info commands zlib]] && [regexp tcltest [info nameofexecutable]]}]
|
||||
|
||||
test zipfs-1.1 {zipfs basics} -constraints zipfs -body {
|
||||
load {} zipfs
|
||||
} -result {}
|
||||
|
||||
test zipfs-1.2 {zipfs basics} -constraints zipfs -body {
|
||||
package require zipfs
|
||||
} -result {1.0}
|
||||
|
||||
test zipfs-1.3 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs mount a b c d e f
|
||||
} -result {wrong # args: should be "zipfs mount ?zipfile? ?mountpoint? ?password?"}
|
||||
|
||||
test zipfs-1.4 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs unmount a b c d e f
|
||||
} -result {wrong # args: should be "zipfs unmount zipfile"}
|
||||
|
||||
test zipfs-1.5 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs mkkey a b c d e f
|
||||
} -result {wrong # args: should be "zipfs mkkey password"}
|
||||
|
||||
test zipfs-1.6 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs mkimg a b c d e f
|
||||
} -result {wrong # args: should be "zipfs mkimg outfile indir ?strip? ?password? ?infile?"}
|
||||
|
||||
test zipfs-1.7 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs mkzip a b c d e f
|
||||
} -result {wrong # args: should be "zipfs mkzip outfile indir ?strip? ?password?"}
|
||||
|
||||
test zipfs-1.8 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs exists a b c d e f
|
||||
} -result {wrong # args: should be "zipfs exists filename"}
|
||||
|
||||
test zipfs-1.9 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs info a b c d e f
|
||||
} -result {wrong # args: should be "zipfs info filename"}
|
||||
|
||||
test zipfs-1.10 {zipfs basics} -constraints zipfs -returnCodes error -body {
|
||||
zipfs list a b c d e f
|
||||
} -result {wrong # args: should be "zipfs list ?(-glob|-regexp)? ?pattern?"}
|
||||
|
||||
|
||||
test zipfs-2.1 {zipfs mkzip empty archive} -constraints zipfs -returnCodes error -body {
|
||||
zipfs mkzip abc.zip [file join [file normalize $tcl_library] xxxx]
|
||||
} -result {empty archive}
|
||||
|
||||
test zipfs-2.2 {zipfs mkzip} -constraints zipfs -body {
|
||||
set pwd [pwd]
|
||||
cd [file join [file normalize $tcl_library] encoding]
|
||||
zipfs mkzip abc.zip .
|
||||
zipfs mount abc.zip /abc
|
||||
zipfs list -glob /abc/cp850.*
|
||||
} -cleanup {
|
||||
cd $pwd
|
||||
} -result {/abc/cp850.enc}
|
||||
|
||||
test zipfs-2.3 {zipfs unmount} -constraints zipfs -body {
|
||||
lrange [zipfs info /abc/cp850.enc] 0 2
|
||||
} -result [list \
|
||||
[file join [file normalize $tcl_library] encoding abc.zip] 1090 527]
|
||||
|
||||
test zipfs-2.4 {zipfs unmount} -constraints zipfs -body {
|
||||
set f [open /abc/cp850.enc]
|
||||
read $f
|
||||
} -result {# Encoding file: cp850, single-byte
|
||||
S
|
||||
003F 0 1
|
||||
00
|
||||
0000000100020003000400050006000700080009000A000B000C000D000E000F
|
||||
0010001100120013001400150016001700180019001A001B001C001D001E001F
|
||||
0020002100220023002400250026002700280029002A002B002C002D002E002F
|
||||
0030003100320033003400350036003700380039003A003B003C003D003E003F
|
||||
0040004100420043004400450046004700480049004A004B004C004D004E004F
|
||||
0050005100520053005400550056005700580059005A005B005C005D005E005F
|
||||
0060006100620063006400650066006700680069006A006B006C006D006E006F
|
||||
0070007100720073007400750076007700780079007A007B007C007D007E007F
|
||||
00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
|
||||
00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D800D70192
|
||||
00E100ED00F300FA00F100D100AA00BA00BF00AE00AC00BD00BC00A100AB00BB
|
||||
2591259225932502252400C100C200C000A9256325512557255D00A200A52510
|
||||
25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4
|
||||
00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580
|
||||
00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4
|
||||
00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0
|
||||
}
|
||||
|
||||
test zipfs-2.5 {zipfs exists} -constraints zipfs -body {
|
||||
zipfs unmount abc.zip
|
||||
zipfs exists /abc/cp850.enc
|
||||
} -cleanup {
|
||||
file delete abc.zip
|
||||
} -result 1
|
||||
|
||||
::tcltest::cleanupTests
|
||||
return
|
||||
|
||||
# Local Variables:
|
||||
# mode: tcl
|
||||
# End:
|
||||
+3
-3
@@ -20,7 +20,7 @@ proc emitRange {first last} {
|
||||
set extranges 1
|
||||
set numranges 0
|
||||
set ranges [string trimright $ranges " \n\r\t,"]
|
||||
append ranges "\n#if TCL_UTF_MAX > 4\n ,"
|
||||
append ranges "\n#if CHRBITS > 16\n ,"
|
||||
}
|
||||
append ranges [format "{0x%x, 0x%x}, " \
|
||||
$first $last]
|
||||
@@ -33,7 +33,7 @@ proc emitRange {first last} {
|
||||
set extchars 1
|
||||
set numchars 0
|
||||
set chars [string trimright $chars " \n\r\t,"]
|
||||
append chars "\n#if TCL_UTF_MAX > 4\n ,"
|
||||
append chars "\n#if CHRBITS > 16\n ,"
|
||||
}
|
||||
append chars [format "0x%x, " $first]
|
||||
incr numchars
|
||||
@@ -66,7 +66,7 @@ proc genTable {type} {
|
||||
for {set i 0} {$i <= 0x10ffff} {incr i} {
|
||||
if {$i == 0xd800} {
|
||||
# Skip surrogates
|
||||
set i 0xdc00
|
||||
set i 0xe000
|
||||
}
|
||||
if {[string is $type [format %c $i]]} {
|
||||
if {$i == ($last + 1)} {
|
||||
|
||||
+8
-3
@@ -272,6 +272,7 @@ static const unsigned char groupMap\[\] = {"
|
||||
* 100 = subtract delta for title/upper
|
||||
* 101 = sub delta for upper, sub 1 for title
|
||||
* 110 = sub delta for upper, add delta for lower
|
||||
* 111 = subtract delta for upper
|
||||
*
|
||||
* Bits 8-31 Case delta: delta for case conversions. This should be the
|
||||
* highest field so we can easily sign extend.
|
||||
@@ -309,10 +310,14 @@ static const int groups\[\] = {"
|
||||
}
|
||||
}
|
||||
} elseif {$toupper} {
|
||||
# subtract delta for upper, add delta for lower
|
||||
set case 6
|
||||
set delta $toupper
|
||||
if {$tolower != $toupper} {
|
||||
if {$tolower == $toupper} {
|
||||
# subtract delta for upper, add delta for lower
|
||||
set case 6
|
||||
} elseif {!$tolower} {
|
||||
# subtract delta for upper
|
||||
set case 7
|
||||
} else {
|
||||
error "New case conversion type needed: $toupper $tolower $totitle"
|
||||
}
|
||||
} elseif {$tolower} {
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
{
|
||||
TclCreatesocketAddress/getaddrinfo/calloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:calloc
|
||||
...
|
||||
fun:getaddrinfo
|
||||
fun:TclCreateSocketAddress
|
||||
}
|
||||
|
||||
{
|
||||
TclCreatesocketAddress/getaddrinfo/malloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
...
|
||||
fun:getaddrinfo
|
||||
fun:TclCreateSocketAddress
|
||||
}
|
||||
|
||||
{
|
||||
TclpDlopen/load
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:calloc
|
||||
...
|
||||
fun:dlopen
|
||||
fun:TclpDlopen
|
||||
}
|
||||
|
||||
{
|
||||
TclpDlopen/load
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
...
|
||||
fun:dlopen
|
||||
fun:TclpDlopen
|
||||
}
|
||||
|
||||
{
|
||||
TclpGetGrNam/__nss_next2/calloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:calloc
|
||||
...
|
||||
fun:__nss_next2
|
||||
...
|
||||
fun:TclpGetGrNam
|
||||
}
|
||||
|
||||
{
|
||||
TclpGetGrNam/__nss_next2/malloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
...
|
||||
fun:__nss_next2
|
||||
...
|
||||
fun:TclpGetGrNam
|
||||
}
|
||||
|
||||
{
|
||||
TclpGetGrNam/__nss_systemd_getfrname_r/malloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
...
|
||||
fun:_nss_systemd_getgrnam_r
|
||||
...
|
||||
fun:TclpGetGrNam
|
||||
}
|
||||
|
||||
{
|
||||
TclpGetPwNam/getpwname_r/__nss_next2/calloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:calloc
|
||||
...
|
||||
fun:__nss_next2
|
||||
...
|
||||
fun:TclpGetPwNam
|
||||
}
|
||||
|
||||
{
|
||||
TclpGetPwNam/getpwname_r/__nss_next2/malloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
...
|
||||
fun:__nss_next2
|
||||
...
|
||||
fun:TclpGetPwNam
|
||||
}
|
||||
|
||||
{
|
||||
TclpGetPwNam/getpwname_r/_nss_systemd_getpwnam_r/malloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
...
|
||||
fun:_nss_systemd_getpwnam_r
|
||||
...
|
||||
fun:TclpGetPwNam
|
||||
}
|
||||
|
||||
{
|
||||
TclpThreadExit/pthread_exit/calloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:calloc
|
||||
...
|
||||
fun:pthread_exit
|
||||
fun:TclpThreadExit
|
||||
}
|
||||
|
||||
{
|
||||
TclpThreadExit/pthread_exit/malloc
|
||||
Memcheck:Leak
|
||||
match-leak-kinds: reachable
|
||||
fun:malloc
|
||||
...
|
||||
fun:pthread_exit
|
||||
fun:TclpThreadExit
|
||||
}
|
||||
|
||||
+11
-3
@@ -262,7 +262,9 @@ GDB = gdb
|
||||
TRACE = strace
|
||||
TRACE_OPTS =
|
||||
VALGRIND = valgrind
|
||||
VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high --leak-check=yes --show-reachable=yes -v
|
||||
VALGRINDARGS = --tool=memcheck --num-callers=24 \
|
||||
--leak-resolution=high --leak-check=yes --show-reachable=yes -v \
|
||||
--suppressions=$(TOOL_DIR)/valgrind_suppress
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# The information below should be usable as is. The configure script won't
|
||||
@@ -308,7 +310,7 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \
|
||||
tclStrToD.o tclThread.o \
|
||||
tclThreadAlloc.o tclThreadJoin.o tclThreadStorage.o tclStubInit.o \
|
||||
tclTimer.o tclTrace.o tclUtf.o tclUtil.o tclVar.o tclZlib.o \
|
||||
tclTomMathInterface.o
|
||||
tclTomMathInterface.o zipfs.o
|
||||
|
||||
OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \
|
||||
tclOOMethod.o tclOOStubInit.o
|
||||
@@ -373,6 +375,7 @@ GENERIC_HDRS = \
|
||||
$(GENERIC_DIR)/tclInt.h \
|
||||
$(GENERIC_DIR)/tclIntDecls.h \
|
||||
$(GENERIC_DIR)/tclIntPlatDecls.h \
|
||||
$(GENERIC_DIR)/tclZipfs.h \
|
||||
$(GENERIC_DIR)/tclTomMath.h \
|
||||
$(GENERIC_DIR)/tclTomMathDecls.h \
|
||||
$(GENERIC_DIR)/tclOO.h \
|
||||
@@ -463,7 +466,8 @@ GENERIC_SRCS = \
|
||||
$(GENERIC_DIR)/tclUtil.c \
|
||||
$(GENERIC_DIR)/tclVar.c \
|
||||
$(GENERIC_DIR)/tclAssembly.c \
|
||||
$(GENERIC_DIR)/tclZlib.c
|
||||
$(GENERIC_DIR)/tclZlib.c \
|
||||
$(GENERIC_DIR)/zipfs.c
|
||||
|
||||
OO_SRCS = \
|
||||
$(GENERIC_DIR)/tclOO.c \
|
||||
@@ -952,6 +956,7 @@ install-headers:
|
||||
@for i in $(GENERIC_DIR)/tcl.h $(GENERIC_DIR)/tclDecls.h \
|
||||
$(GENERIC_DIR)/tclOO.h $(GENERIC_DIR)/tclOODecls.h \
|
||||
$(GENERIC_DIR)/tclPlatDecls.h \
|
||||
$(GENERIC_DIR)/tclZipfs.h \
|
||||
$(GENERIC_DIR)/tclTomMath.h \
|
||||
$(GENERIC_DIR)/tclTomMathDecls.h ; \
|
||||
do \
|
||||
@@ -1321,6 +1326,9 @@ tclVar.o: $(GENERIC_DIR)/tclVar.c
|
||||
tclZlib.o: $(GENERIC_DIR)/tclZlib.c
|
||||
$(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/tclZlib.c
|
||||
|
||||
zipfs.o: $(GENERIC_DIR)/zipfs.c
|
||||
$(CC) -c $(CC_SWITCHES) $(ZLIB_INCLUDE) $(GENERIC_DIR)/zipfs.c
|
||||
|
||||
tclTest.o: $(GENERIC_DIR)/tclTest.c $(IOHDR) $(TCLREHDRS)
|
||||
$(CC) -c $(APP_CC_SWITCHES) $(GENERIC_DIR)/tclTest.c
|
||||
|
||||
|
||||
Vendored
+64
@@ -9517,6 +9517,70 @@ _ACEOF
|
||||
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking for DIR64" >&5
|
||||
echo $ECHO_N "checking for DIR64... $ECHO_C" >&6
|
||||
if test "${tcl_cv_DIR64+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct dirent64 *p; DIR64 d = opendir64(".");
|
||||
p = readdir64(d); rewinddir64(d); closedir64(d);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext
|
||||
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
|
||||
(eval $ac_compile) 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag"
|
||||
|| test ! -s conftest.err'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest.$ac_objext'
|
||||
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
|
||||
(eval $ac_try) 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
tcl_cv_DIR64=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
tcl_cv_DIR64=no
|
||||
fi
|
||||
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
fi
|
||||
echo "$as_me:$LINENO: result: $tcl_cv_DIR64" >&5
|
||||
echo "${ECHO_T}$tcl_cv_DIR64" >&6
|
||||
if test "x${tcl_cv_DIR64}" = "xyes" ; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define HAVE_DIR64 1
|
||||
_ACEOF
|
||||
|
||||
fi
|
||||
|
||||
echo "$as_me:$LINENO: checking for struct stat64" >&5
|
||||
echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
|
||||
if test "${tcl_cv_struct_stat64+set}" = set; then
|
||||
|
||||
+16
-2
@@ -91,11 +91,13 @@ AC_DEFUN([SC_PATH_TCLCONFIG], [
|
||||
for i in `ls -d ${libdir} 2>/dev/null` \
|
||||
`ls -d ${exec_prefix}/lib 2>/dev/null` \
|
||||
`ls -d ${prefix}/lib 2>/dev/null` \
|
||||
`ls -d /usr/contrib/lib 2>/dev/null` \
|
||||
`ls -d /usr/local/lib 2>/dev/null` \
|
||||
`ls -d /usr/contrib/lib 2>/dev/null` \
|
||||
`ls -d /usr/pkg/lib 2>/dev/null` \
|
||||
`ls -d /usr/lib 2>/dev/null` \
|
||||
`ls -d /usr/lib64 2>/dev/null` \
|
||||
`ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
|
||||
`ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
|
||||
; do
|
||||
if test -f "$i/tclConfig.sh" ; then
|
||||
ac_cv_c_tclconfig="`(cd $i; pwd)`"
|
||||
@@ -224,8 +226,11 @@ AC_DEFUN([SC_PATH_TKCONFIG], [
|
||||
`ls -d ${prefix}/lib 2>/dev/null` \
|
||||
`ls -d /usr/local/lib 2>/dev/null` \
|
||||
`ls -d /usr/contrib/lib 2>/dev/null` \
|
||||
`ls -d /usr/pkg/lib 2>/dev/null` \
|
||||
`ls -d /usr/lib 2>/dev/null` \
|
||||
`ls -d /usr/lib64 2>/dev/null` \
|
||||
`ls -d /usr/local/lib/tk8.6 2>/dev/null` \
|
||||
`ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
|
||||
; do
|
||||
if test -f "$i/tkConfig.sh" ; then
|
||||
ac_cv_c_tkconfig="`(cd $i; pwd)`"
|
||||
@@ -2576,7 +2581,7 @@ AC_DEFUN([SC_TCL_EARLY_FLAGS],[
|
||||
# Might define the following vars:
|
||||
# TCL_WIDE_INT_IS_LONG
|
||||
# TCL_WIDE_INT_TYPE
|
||||
# HAVE_STRUCT_DIRENT64
|
||||
# HAVE_STRUCT_DIRENT64, HAVE_DIR64
|
||||
# HAVE_STRUCT_STAT64
|
||||
# HAVE_TYPE_OFF64_T
|
||||
#
|
||||
@@ -2612,6 +2617,15 @@ AC_DEFUN([SC_TCL_64BIT_FLAGS], [
|
||||
AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
|
||||
AC_TRY_COMPILE([#include <sys/types.h>
|
||||
#include <dirent.h>],[struct dirent64 *p; DIR64 d = opendir64(".");
|
||||
p = readdir64(d); rewinddir64(d); closedir64(d);],
|
||||
tcl_cv_DIR64=yes,tcl_cv_DIR64=no)])
|
||||
if test "x${tcl_cv_DIR64}" = "xyes" ; then
|
||||
AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
|
||||
AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
|
||||
],
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "tcl.h"
|
||||
|
||||
#ifdef TCL_TEST
|
||||
#include "tclZipfs.h"
|
||||
extern Tcl_PackageInitProc Tcltest_Init;
|
||||
extern Tcl_PackageInitProc Tcltest_SafeInit;
|
||||
#endif /* TCL_TEST */
|
||||
@@ -123,6 +124,10 @@ Tcl_AppInit(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit);
|
||||
if (Tclzipfs_Init(interp) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit);
|
||||
#endif /* TCL_TEST */
|
||||
|
||||
/*
|
||||
|
||||
@@ -196,6 +196,9 @@
|
||||
/* Is 'struct dirent64' in <sys/types.h>? */
|
||||
#undef HAVE_STRUCT_DIRENT64
|
||||
|
||||
/* Is 'DIR64' in <sys/types.h>? */
|
||||
#undef HAVE_DIR64
|
||||
|
||||
/* Define to 1 if the system has the type `struct in6_addr'. */
|
||||
#undef HAVE_STRUCT_IN6_ADDR
|
||||
|
||||
|
||||
+9
-9
@@ -369,13 +369,13 @@ DoRenameFile(
|
||||
|
||||
if (errno == EINVAL && haveRealpath) {
|
||||
char srcPath[MAXPATHLEN], dstPath[MAXPATHLEN];
|
||||
DIR *dirPtr;
|
||||
TclDIR *dirPtr;
|
||||
Tcl_DirEntry *dirEntPtr;
|
||||
|
||||
if ((Realpath((char *) src, srcPath) != NULL) /* INTL: Native. */
|
||||
&& (Realpath((char *) dst, dstPath) != NULL) /* INTL: Native */
|
||||
&& (strncmp(srcPath, dstPath, strlen(srcPath)) != 0)) {
|
||||
dirPtr = opendir(dst); /* INTL: Native. */
|
||||
dirPtr = TclOSopendir(dst); /* INTL: Native. */
|
||||
if (dirPtr != NULL) {
|
||||
while (1) {
|
||||
dirEntPtr = TclOSreaddir(dirPtr); /* INTL: Native. */
|
||||
@@ -385,11 +385,11 @@ DoRenameFile(
|
||||
if ((strcmp(dirEntPtr->d_name, ".") != 0) &&
|
||||
(strcmp(dirEntPtr->d_name, "..") != 0)) {
|
||||
errno = EEXIST;
|
||||
closedir(dirPtr);
|
||||
TclOSclosedir(dirPtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
closedir(dirPtr);
|
||||
TclOSclosedir(dirPtr);
|
||||
}
|
||||
}
|
||||
errno = EINVAL;
|
||||
@@ -965,7 +965,7 @@ TraverseUnixTree(
|
||||
#ifndef HAVE_FTS
|
||||
int numProcessed = 0;
|
||||
Tcl_DirEntry *dirEntPtr;
|
||||
DIR *dirPtr;
|
||||
TclDIR *dirPtr;
|
||||
#else
|
||||
const char *paths[2] = {NULL, NULL};
|
||||
FTS *fts = NULL;
|
||||
@@ -990,7 +990,7 @@ TraverseUnixTree(
|
||||
errorPtr);
|
||||
}
|
||||
#ifndef HAVE_FTS
|
||||
dirPtr = opendir(source); /* INTL: Native. */
|
||||
dirPtr = TclOSopendir(source); /* INTL: Native. */
|
||||
if (dirPtr == NULL) {
|
||||
/*
|
||||
* Can't read directory
|
||||
@@ -1002,7 +1002,7 @@ TraverseUnixTree(
|
||||
result = traverseProc(sourcePtr, targetPtr, &statBuf, DOTREE_PRED,
|
||||
errorPtr);
|
||||
if (result != TCL_OK) {
|
||||
closedir(dirPtr);
|
||||
TclOSclosedir(dirPtr);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1052,11 +1052,11 @@ TraverseUnixTree(
|
||||
* NULL-return that may a symptom of a buggy readdir.
|
||||
*/
|
||||
|
||||
rewinddir(dirPtr);
|
||||
TclOSrewinddir(dirPtr);
|
||||
numProcessed = 0;
|
||||
}
|
||||
}
|
||||
closedir(dirPtr);
|
||||
TclOSclosedir(dirPtr);
|
||||
|
||||
/*
|
||||
* Strip off the trailing slash we added
|
||||
|
||||
+3
-3
@@ -259,7 +259,7 @@ TclpMatchInDirectory(
|
||||
Tcl_DecrRefCount(tailPtr);
|
||||
Tcl_DecrRefCount(fileNamePtr);
|
||||
} else {
|
||||
DIR *d;
|
||||
TclDIR *d;
|
||||
Tcl_DirEntry *entryPtr;
|
||||
const char *dirName;
|
||||
int dirLength, nativeDirLen;
|
||||
@@ -309,7 +309,7 @@ TclpMatchInDirectory(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
d = opendir(native); /* INTL: Native. */
|
||||
d = TclOSopendir(native); /* INTL: Native. */
|
||||
if (d == NULL) {
|
||||
Tcl_DStringFree(&ds);
|
||||
if (interp != NULL) {
|
||||
@@ -387,7 +387,7 @@ TclpMatchInDirectory(
|
||||
}
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
TclOSclosedir(d);
|
||||
Tcl_DStringFree(&ds);
|
||||
Tcl_DStringFree(&dsOrig);
|
||||
Tcl_DecrRefCount(fileNamePtr);
|
||||
|
||||
+13
-2
@@ -57,12 +57,23 @@
|
||||
*/
|
||||
|
||||
#ifdef HAVE_STRUCT_DIRENT64
|
||||
typedef struct dirent64 Tcl_DirEntry;
|
||||
typedef struct dirent64 Tcl_DirEntry;
|
||||
# define TclOSreaddir readdir64
|
||||
#else
|
||||
typedef struct dirent Tcl_DirEntry;
|
||||
typedef struct dirent Tcl_DirEntry;
|
||||
# define TclOSreaddir readdir
|
||||
#endif
|
||||
#ifdef HAVE_DIR64
|
||||
typedef DIR64 TclDIR;
|
||||
# define TclOSopendir opendir64
|
||||
# define TclOSrewinddir rewinddir64
|
||||
# define TclOSclosedir closedir64
|
||||
#else
|
||||
typedef DIR TclDIR;
|
||||
# define TclOSopendir opendir
|
||||
# define TclOSrewinddir rewinddir
|
||||
# define TclOSclosedir closedir
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TYPE_OFF64_T
|
||||
typedef off64_t Tcl_SeekOffset;
|
||||
|
||||
+3
-3
@@ -1099,7 +1099,7 @@ TcpGetHandleProc(
|
||||
* TcpAsyncCallback --
|
||||
*
|
||||
* Called by the event handler that TcpConnect sets up internally for
|
||||
* [socket -async] to get notified when the asyncronous connection
|
||||
* [socket -async] to get notified when the asynchronous connection
|
||||
* attempt has succeeded or failed.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -1132,7 +1132,7 @@ TcpAsyncCallback(
|
||||
*
|
||||
* Remarks:
|
||||
* A single host name may resolve to more than one IP address, e.g. for
|
||||
* an IPv4/IPv6 dual stack host. For handling asyncronously connecting
|
||||
* an IPv4/IPv6 dual stack host. For handling asynchronously connecting
|
||||
* sockets in the background for such hosts, this function can act as a
|
||||
* coroutine. On the first call, it sets up the control variables for the
|
||||
* two nested loops over the local and remote addresses. Once the first
|
||||
@@ -1140,7 +1140,7 @@ TcpAsyncCallback(
|
||||
* event handler for that socket, and returns. When the callback occurs,
|
||||
* control is transferred to the "reenter" label, right after the initial
|
||||
* return and the loops resume as if they had never been interrupted.
|
||||
* For syncronously connecting sockets, the loops work the usual way.
|
||||
* For synchronously connecting sockets, the loops work the usual way.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
+4
-4
@@ -316,7 +316,7 @@ TclpInitUnlock(void)
|
||||
* in finalization; it is hidden during creation of the objects.
|
||||
*
|
||||
* This lock must be different than the initLock because the initLock is
|
||||
* held during creation of syncronization objects.
|
||||
* held during creation of synchronization objects.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -407,7 +407,7 @@ Tcl_GetAllocMutex(void)
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* May block the current thread. The mutex is aquired when this returns.
|
||||
* May block the current thread. The mutex is acquired when this returns.
|
||||
* Will allocate memory for a pthread_mutex_t and initialize this the
|
||||
* first time this Tcl_Mutex is used.
|
||||
*
|
||||
@@ -511,7 +511,7 @@ TclpFinalizeMutex(
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* May block the current thread. The mutex is aquired when this returns.
|
||||
* May block the current thread. The mutex is acquired when this returns.
|
||||
* Will allocate memory for a pthread_mutex_t and initialize this the
|
||||
* first time this Tcl_Mutex is used.
|
||||
*
|
||||
@@ -653,7 +653,7 @@ TclpFinalizeCondition(
|
||||
|
||||
Tcl_DirEntry *
|
||||
TclpReaddir(
|
||||
DIR * dir)
|
||||
TclDIR * dir)
|
||||
{
|
||||
return TclOSreaddir(dir);
|
||||
}
|
||||
|
||||
+4
-2
@@ -302,7 +302,8 @@ GENERIC_OBJS = \
|
||||
tclUtf.$(OBJEXT) \
|
||||
tclUtil.$(OBJEXT) \
|
||||
tclVar.$(OBJEXT) \
|
||||
tclZlib.$(OBJEXT)
|
||||
tclZlib.$(OBJEXT) \
|
||||
zipfs.$(OBJEXT)
|
||||
|
||||
TOMMATH_OBJS = \
|
||||
bncore.${OBJEXT} \
|
||||
@@ -635,6 +636,7 @@ install-libraries: libraries install-tzdata install-msgs
|
||||
@echo "Installing header files";
|
||||
@for i in "$(GENERIC_DIR)/tcl.h" "$(GENERIC_DIR)/tclDecls.h" \
|
||||
"$(GENERIC_DIR)/tclOO.h" "$(GENERIC_DIR)/tclOODecls.h" \
|
||||
"$(GENERIC_DIR)/tclZipfs.h" \
|
||||
"$(GENERIC_DIR)/tclPlatDecls.h" \
|
||||
"$(GENERIC_DIR)/tclTomMath.h" \
|
||||
"$(GENERIC_DIR)/tclTomMathDecls.h"; \
|
||||
@@ -749,7 +751,7 @@ clean: cleanhelp clean-packages
|
||||
|
||||
distclean: distclean-packages clean
|
||||
$(RM) Makefile config.status config.cache config.log tclConfig.sh \
|
||||
tcl.hpj config.status.lineno
|
||||
tcl.hpj config.status.lineno tclsh.exe.manifest
|
||||
|
||||
#
|
||||
# Bundled package targets
|
||||
|
||||
Vendored
+1
-1
@@ -4372,7 +4372,7 @@ if test "$tcl_ok" = "yes"; then
|
||||
|
||||
ZLIB_DLL_FILE=\${ZLIB_DLL_FILE}
|
||||
|
||||
if test "$do64bit" = "yes"; then
|
||||
if test "$do64bit" != "no"; then
|
||||
|
||||
if test "$GCC" == "yes"; then
|
||||
|
||||
|
||||
+1
-1
@@ -128,7 +128,7 @@ AS_IF([test "${enable_shared+set}" = "set"], [
|
||||
])
|
||||
AS_IF([test "$tcl_ok" = "yes"], [
|
||||
AC_SUBST(ZLIB_DLL_FILE,[\${ZLIB_DLL_FILE}])
|
||||
AS_IF([test "$do64bit" = "yes"], [
|
||||
AS_IF([test "$do64bit" != "no"], [
|
||||
AS_IF([test "$GCC" == "yes"],[
|
||||
AC_SUBST(ZLIB_LIBS,[\${ZLIB_DIR_NATIVE}/win64/libz.dll.a])
|
||||
], [
|
||||
|
||||
+6
-1
@@ -235,7 +235,8 @@ COREOBJS = \
|
||||
$(TMP_DIR)\tclUtf.obj \
|
||||
$(TMP_DIR)\tclUtil.obj \
|
||||
$(TMP_DIR)\tclVar.obj \
|
||||
$(TMP_DIR)\tclZlib.obj
|
||||
$(TMP_DIR)\tclZlib.obj \
|
||||
$(TMP_DIR)\zipfs.obj
|
||||
|
||||
ZLIBOBJS = \
|
||||
$(TMP_DIR)\adler32.obj \
|
||||
@@ -683,6 +684,9 @@ $(TMP_DIR)\tclWinTest.obj: $(WINDIR)\tclWinTest.c
|
||||
$(TMP_DIR)\tclZlib.obj: $(GENERICDIR)\tclZlib.c
|
||||
$(cc32) $(pkgcflags) -I$(COMPATDIR)\zlib -Fo$@ $?
|
||||
|
||||
$(TMP_DIR)\zipfs.obj: $(GENERICDIR)\zipfs.c
|
||||
$(cc32) $(TCL_CFLAGS) -I$(COMPATDIR)\zlib -DBUILD_tcl -Fo$@ $?
|
||||
|
||||
$(TMP_DIR)\tclPkgConfig.obj: $(GENERICDIR)\tclPkgConfig.c
|
||||
$(cc32) $(pkgcflags) \
|
||||
-DCFG_INSTALL_LIBDIR="\"$(LIB_INSTALL_DIR:\=\\)\"" \
|
||||
@@ -832,6 +836,7 @@ install-libraries: tclConfig tcl-nmake install-msgs install-tzdata
|
||||
@$(CPY) "$(GENERICDIR)\tclDecls.h" "$(INCLUDE_INSTALL_DIR)\"
|
||||
@$(CPY) "$(GENERICDIR)\tclOO.h" "$(INCLUDE_INSTALL_DIR)\"
|
||||
@$(CPY) "$(GENERICDIR)\tclOODecls.h" "$(INCLUDE_INSTALL_DIR)\"
|
||||
@$(CPY) "$(GENERICDIR)\tclZipfs.h" "$(INCLUDE_INSTALL_DIR)\"
|
||||
@$(CPY) "$(GENERICDIR)\tclPlatDecls.h" "$(INCLUDE_INSTALL_DIR)\"
|
||||
@$(CPY) "$(GENERICDIR)\tclTomMath.h" "$(INCLUDE_INSTALL_DIR)\"
|
||||
@$(CPY) "$(GENERICDIR)\tclTomMathDecls.h" "$(INCLUDE_INSTALL_DIR)\"
|
||||
|
||||
+8
-1
@@ -25,6 +25,7 @@
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef TCL_TEST
|
||||
#include "tclZipfs.h"
|
||||
extern Tcl_PackageInitProc Tcltest_Init;
|
||||
extern Tcl_PackageInitProc Tcltest_SafeInit;
|
||||
#endif /* TCL_TEST */
|
||||
@@ -35,8 +36,10 @@ extern Tcl_PackageInitProc Dde_Init;
|
||||
extern Tcl_PackageInitProc Dde_SafeInit;
|
||||
#endif
|
||||
|
||||
#ifdef TCL_BROKEN_MAINARGS
|
||||
#if defined(__GNUC__) || defined(TCL_BROKEN_MAINARGS)
|
||||
int _CRT_glob = 0;
|
||||
#endif /* __GNUC__ || TCL_BROKEN_MAINARGS */
|
||||
#ifdef TCL_BROKEN_MAINARGS
|
||||
static void setargv(int *argcPtr, TCHAR ***argvPtr);
|
||||
#endif /* TCL_BROKEN_MAINARGS */
|
||||
|
||||
@@ -174,6 +177,10 @@ Tcl_AppInit(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_StaticPackage(interp, "Tcltest", Tcltest_Init, Tcltest_SafeInit);
|
||||
if (Tclzipfs_Init(interp) == TCL_ERROR) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_StaticPackage(interp, "zipfs", Tclzipfs_Init, Tclzipfs_SafeInit);
|
||||
#endif /* TCL_TEST */
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -640,7 +640,7 @@ TclWinCPUID(
|
||||
|
||||
#if defined(HAVE_INTRIN_H) && defined(_WIN64)
|
||||
|
||||
__cpuid(regsPtr, index);
|
||||
__cpuid((int *)regsPtr, index);
|
||||
status = TCL_OK;
|
||||
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
+50
-19
@@ -1436,48 +1436,78 @@ TclpGetUserHome(
|
||||
Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
|
||||
* name of user's home directory. */
|
||||
{
|
||||
const char *result = NULL;
|
||||
USER_INFO_1 *uiPtr, **uiPtrPtr = &uiPtr;
|
||||
char *result = NULL;
|
||||
USER_INFO_1 *uiPtr;
|
||||
Tcl_DString ds;
|
||||
int nameLen = -1;
|
||||
int badDomain = 0;
|
||||
char *domain;
|
||||
WCHAR *wName, *wHomeDir, *wDomain, **wDomainPtr = &wDomain;
|
||||
int rc = 0;
|
||||
const char *domain;
|
||||
WCHAR *wName, *wHomeDir, *wDomain;
|
||||
WCHAR buf[MAX_PATH];
|
||||
|
||||
Tcl_DStringInit(bufferPtr);
|
||||
|
||||
wDomain = NULL;
|
||||
domain = strchr(name, '@');
|
||||
if (domain != NULL) {
|
||||
domain = Tcl_UtfFindFirst(name, '@');
|
||||
if (domain == NULL) {
|
||||
const char *ptr;
|
||||
|
||||
/* no domain - firstly check it's the current user */
|
||||
if ( (ptr = TclpGetUserName(&ds)) != 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);
|
||||
}
|
||||
}
|
||||
Tcl_DStringFree(&ds);
|
||||
} else {
|
||||
Tcl_DStringInit(&ds);
|
||||
wName = Tcl_UtfToUniCharDString(domain + 1, -1, &ds);
|
||||
badDomain = NetGetDCName(NULL, wName, (LPBYTE *) wDomainPtr);
|
||||
rc = NetGetDCName(NULL, wName, (LPBYTE *) &wDomain);
|
||||
Tcl_DStringFree(&ds);
|
||||
nameLen = domain - name;
|
||||
}
|
||||
if (badDomain == 0) {
|
||||
if (rc == 0) {
|
||||
Tcl_DStringInit(&ds);
|
||||
wName = Tcl_UtfToUniCharDString(name, nameLen, &ds);
|
||||
if (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) uiPtrPtr) == 0) {
|
||||
while (NetUserGetInfo(wDomain, wName, 1, (LPBYTE *) &uiPtr) != 0) {
|
||||
/*
|
||||
* user does not exists - if domain was not specified,
|
||||
* try again using current domain.
|
||||
*/
|
||||
rc = 1;
|
||||
if (domain != NULL) break;
|
||||
/* get current domain */
|
||||
rc = NetGetDCName(NULL, NULL, (LPBYTE *) &wDomain);
|
||||
if (rc != 0) break;
|
||||
domain = INT2PTR(-1); /* repeat once */
|
||||
}
|
||||
if (rc == 0) {
|
||||
DWORD i, size = MAX_PATH;
|
||||
wHomeDir = uiPtr->usri1_home_dir;
|
||||
if ((wHomeDir != NULL) && (wHomeDir[0] != L'\0')) {
|
||||
Tcl_UniCharToUtfDString(wHomeDir, lstrlenW(wHomeDir),
|
||||
bufferPtr);
|
||||
size = lstrlenW(wHomeDir);
|
||||
Tcl_UniCharToUtfDString(wHomeDir, size, bufferPtr);
|
||||
} else {
|
||||
/*
|
||||
* User exists but has no home dir. Return
|
||||
* "{GetProfilesDirectory}/<user>".
|
||||
*/
|
||||
DWORD i, size = MAX_PATH;
|
||||
GetProfilesDirectoryW(buf, &size);
|
||||
for (i = 0; i < size; ++i){
|
||||
if (buf[i] == '\\') buf[i] = '/';
|
||||
}
|
||||
Tcl_UniCharToUtfDString(buf, size-1, bufferPtr);
|
||||
Tcl_DStringAppend(bufferPtr, "/", -1);
|
||||
Tcl_DStringAppend(bufferPtr, name, -1);
|
||||
Tcl_DStringAppend(bufferPtr, "/", 1);
|
||||
Tcl_DStringAppend(bufferPtr, name, nameLen);
|
||||
}
|
||||
result = Tcl_DStringValue(bufferPtr);
|
||||
/* be sure we returns normalized path */
|
||||
for (i = 0; i < size; ++i){
|
||||
if (result[i] == '\\') result[i] = '/';
|
||||
}
|
||||
NetApiBufferFree((void *) uiPtr);
|
||||
}
|
||||
Tcl_DStringFree(&ds);
|
||||
@@ -1992,7 +2022,8 @@ NativeStat(
|
||||
*/
|
||||
|
||||
fileHandle = CreateFile(nativePath, GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
|
||||
|
||||
if (fileHandle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
+34
-19
@@ -112,7 +112,12 @@ static ProcessGlobalValue sourceLibraryDir =
|
||||
{0, 0, NULL, NULL, InitializeSourceLibraryDir, NULL, NULL};
|
||||
|
||||
static void AppendEnvironment(Tcl_Obj *listPtr, const char *lib);
|
||||
static int ToUtf(const WCHAR *wSrc, char *dst);
|
||||
|
||||
#if TCL_UTF_MAX < 4
|
||||
static void ToUtf(const WCHAR *wSrc, char *dst);
|
||||
#else
|
||||
#define ToUtf(wSrc, dst) WideCharToMultiByte(CP_UTF8, 0, wSrc, -1, dst, MAX_PATH * TCL_UTF_MAX, NULL, NULL)
|
||||
#endif
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
@@ -435,7 +440,7 @@ InitializeSourceLibraryDir(
|
||||
*
|
||||
* ToUtf --
|
||||
*
|
||||
* Convert a char string to a UTF string.
|
||||
* Convert a wchar string to a UTF string.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -446,21 +451,19 @@ InitializeSourceLibraryDir(
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
#if TCL_UTF_MAX < 4
|
||||
static void
|
||||
ToUtf(
|
||||
const WCHAR *wSrc,
|
||||
char *dst)
|
||||
{
|
||||
char *start;
|
||||
|
||||
start = dst;
|
||||
while (*wSrc != '\0') {
|
||||
dst += Tcl_UniCharToUtf(*wSrc, dst);
|
||||
wSrc++;
|
||||
}
|
||||
*dst = '\0';
|
||||
return (int) (dst - start);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
@@ -514,6 +517,27 @@ Tcl_GetEncodingNameFromEnvironment(
|
||||
return Tcl_DStringValue(bufPtr);
|
||||
}
|
||||
|
||||
const char *
|
||||
TclpGetUserName(
|
||||
Tcl_DString *bufferPtr) /* Uninitialized or free DString filled with
|
||||
* the name of user. */
|
||||
{
|
||||
Tcl_DStringInit(bufferPtr);
|
||||
|
||||
if (TclGetEnv("USERNAME", bufferPtr) == NULL) {
|
||||
TCHAR szUserName[UNLEN+1];
|
||||
DWORD cchUserNameLen = UNLEN;
|
||||
|
||||
if (!GetUserName(szUserName, &cchUserNameLen)) {
|
||||
return NULL;
|
||||
}
|
||||
cchUserNameLen--;
|
||||
cchUserNameLen *= sizeof(TCHAR);
|
||||
Tcl_WinTCharToUtf(szUserName, cchUserNameLen, bufferPtr);
|
||||
}
|
||||
return Tcl_DStringValue(bufferPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
@@ -544,8 +568,6 @@ TclpSetVariables(
|
||||
static OSVERSIONINFOW osInfo;
|
||||
static int osInfoInitialized = 0;
|
||||
Tcl_DString ds;
|
||||
TCHAR szUserName[UNLEN+1];
|
||||
DWORD cchUserNameLen = UNLEN;
|
||||
|
||||
Tcl_SetVar2Ex(interp, "tclDefaultLibrary", NULL,
|
||||
TclGetProcessGlobalValue(&defaultLibraryDir), TCL_GLOBAL_ONLY);
|
||||
@@ -623,15 +645,8 @@ TclpSetVariables(
|
||||
* Note: cchUserNameLen is number of characters including nul terminator.
|
||||
*/
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
if (TclGetEnv("USERNAME", &ds) == NULL) {
|
||||
if (GetUserName(szUserName, &cchUserNameLen) != 0) {
|
||||
int cbUserNameLen = cchUserNameLen - 1;
|
||||
cbUserNameLen *= sizeof(TCHAR);
|
||||
Tcl_WinTCharToUtf(szUserName, cbUserNameLen, &ds);
|
||||
}
|
||||
}
|
||||
Tcl_SetVar2(interp, "tcl_platform", "user", Tcl_DStringValue(&ds),
|
||||
ptr = TclpGetUserName(&ds);
|
||||
Tcl_SetVar2(interp, "tcl_platform", "user", ptr ? ptr : "",
|
||||
TCL_GLOBAL_ONLY);
|
||||
Tcl_DStringFree(&ds);
|
||||
|
||||
@@ -648,7 +663,7 @@ TclpSetVariables(
|
||||
* TclpFindVariable --
|
||||
*
|
||||
* Locate the entry in environ for a given name. On Unix this routine is
|
||||
* case sensitive, on Windows this matches mioxed case.
|
||||
* case sensitive, on Windows this matches mixed case.
|
||||
*
|
||||
* Results:
|
||||
* The return value is the index in environ of an entry with the name
|
||||
|
||||
@@ -90,6 +90,8 @@ MODULE_SCOPE void * TclpGetAllocCache(void);
|
||||
MODULE_SCOPE void TclpSetAllocCache(void *);
|
||||
#endif /* TCL_THREADS */
|
||||
|
||||
MODULE_SCOPE const char*TclpGetUserName(Tcl_DString *bufferPtr);
|
||||
|
||||
/* Needed by tclWinFile.c and tclWinFCmd.c */
|
||||
#ifndef FILE_ATTRIBUTE_REPARSE_POINT
|
||||
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
|
||||
|
||||
+176
-47
@@ -1289,7 +1289,7 @@ ApplicationType(
|
||||
|
||||
/*
|
||||
* Look for the program as an external program. First try the name as it
|
||||
* is, then try adding .com, .exe, and .bat, in that order, to the name,
|
||||
* is, then try adding .com, .exe, .bat and .cmd, in that order, to the name,
|
||||
* looking for an executable.
|
||||
*
|
||||
* Using the raw SearchPath() function doesn't do quite what is necessary.
|
||||
@@ -1408,7 +1408,7 @@ ApplicationType(
|
||||
return APPL_NONE;
|
||||
}
|
||||
|
||||
if ((applType == APPL_DOS) || (applType == APPL_WIN3X)) {
|
||||
if (applType == APPL_WIN3X) {
|
||||
/*
|
||||
* Replace long path name of executable with short path name for
|
||||
* 16-bit applications. Otherwise the application may not be able to
|
||||
@@ -1442,6 +1442,86 @@ ApplicationType(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static const char *
|
||||
BuildCmdLineBypassBS(
|
||||
const char *current,
|
||||
const char **bspos
|
||||
) {
|
||||
/* mark first backslash possition */
|
||||
if (!*bspos) {
|
||||
*bspos = current;
|
||||
}
|
||||
do {
|
||||
current++;
|
||||
} while (*current == '\\');
|
||||
return current;
|
||||
}
|
||||
|
||||
static void
|
||||
QuoteCmdLineBackslash(
|
||||
Tcl_DString *dsPtr,
|
||||
const char *start,
|
||||
const char *current,
|
||||
const char *bspos
|
||||
) {
|
||||
if (!bspos) {
|
||||
if (current > start) { /* part before current (special) */
|
||||
Tcl_DStringAppend(dsPtr, start, (int) (current - start));
|
||||
}
|
||||
} else {
|
||||
if (bspos > start) { /* part before first backslash */
|
||||
Tcl_DStringAppend(dsPtr, start, (int) (bspos - start));
|
||||
}
|
||||
while (bspos++ < current) { /* each backslash twice */
|
||||
TclDStringAppendLiteral(dsPtr, "\\\\");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char *
|
||||
QuoteCmdLinePart(
|
||||
Tcl_DString *dsPtr,
|
||||
const char *start,
|
||||
const char *special,
|
||||
const char *specMetaChars,
|
||||
const char **bspos
|
||||
) {
|
||||
if (!*bspos) {
|
||||
/* rest before special (before quote) */
|
||||
QuoteCmdLineBackslash(dsPtr, start, special, NULL);
|
||||
start = special;
|
||||
} else {
|
||||
/* rest before first backslash and backslashes into new quoted block */
|
||||
QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL);
|
||||
start = *bspos;
|
||||
}
|
||||
/*
|
||||
* escape all special chars enclosed in quotes like `"..."`, note that here we
|
||||
* don't must escape `\` (with `\`), because it's outside of the main quotes,
|
||||
* so `\` remains `\`, but important - not at end of part, because results as
|
||||
* before the quote, so `%\%\` should be escaped as `"%\%"\\`).
|
||||
*/
|
||||
TclDStringAppendLiteral(dsPtr, "\""); /* opening escape quote-char */
|
||||
do {
|
||||
*bspos = NULL;
|
||||
special++;
|
||||
if (*special == '\\') {
|
||||
/* bypass backslashes (and mark first backslash possition)*/
|
||||
special = BuildCmdLineBypassBS(special, bspos);
|
||||
if (*special == '\0') break;
|
||||
}
|
||||
} while (*special && strchr(specMetaChars, *special));
|
||||
if (!*bspos) {
|
||||
/* unescaped rest before quote */
|
||||
QuoteCmdLineBackslash(dsPtr, start, special, NULL);
|
||||
} else {
|
||||
/* unescaped rest before first backslash (rather belongs to the main block) */
|
||||
QuoteCmdLineBackslash(dsPtr, start, *bspos, NULL);
|
||||
}
|
||||
TclDStringAppendLiteral(dsPtr, "\""); /* closing escape quote-char */
|
||||
return special;
|
||||
}
|
||||
|
||||
static void
|
||||
BuildCommandLine(
|
||||
const char *executable, /* Full path of executable (including
|
||||
@@ -1451,10 +1531,22 @@ BuildCommandLine(
|
||||
Tcl_DString *linePtr) /* Initialized Tcl_DString that receives the
|
||||
* command line (TCHAR). */
|
||||
{
|
||||
const char *arg, *start, *special;
|
||||
int quote, i;
|
||||
const char *arg, *start, *special, *bspos;
|
||||
int quote = 0, i;
|
||||
Tcl_DString ds;
|
||||
|
||||
/* characters to enclose in quotes if unpaired quote flag set */
|
||||
const static char *specMetaChars = "&|^<>!()%";
|
||||
/* characters to enclose in quotes in any case (regardless unpaired-flag) */
|
||||
const static char *specMetaChars2 = "%";
|
||||
|
||||
/* Quote flags:
|
||||
* CL_ESCAPE - escape argument;
|
||||
* CL_QUOTE - enclose in quotes;
|
||||
* CL_UNPAIRED - previous arguments chain contains unpaired quote-char;
|
||||
*/
|
||||
enum {CL_ESCAPE = 1, CL_QUOTE = 2, CL_UNPAIRED = 4};
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
|
||||
/*
|
||||
@@ -1474,61 +1566,98 @@ BuildCommandLine(
|
||||
TclDStringAppendLiteral(&ds, " ");
|
||||
}
|
||||
|
||||
quote = 0;
|
||||
quote &= ~(CL_ESCAPE|CL_QUOTE); /* reset escape flags */
|
||||
bspos = NULL;
|
||||
if (arg[0] == '\0') {
|
||||
quote = 1;
|
||||
quote = CL_QUOTE;
|
||||
} else {
|
||||
int count;
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
for (start = arg; *start != '\0'; start += count) {
|
||||
count = TclUtfToUniChar(start, &ch);
|
||||
if (Tcl_UniCharIsSpace(ch)) { /* INTL: ISO space. */
|
||||
quote = 1;
|
||||
Tcl_UniChar ch;
|
||||
for (start = arg;
|
||||
*start != '\0' &&
|
||||
(quote & (CL_ESCAPE|CL_QUOTE)) != (CL_ESCAPE|CL_QUOTE);
|
||||
start += count
|
||||
) {
|
||||
count = Tcl_UtfToUniChar(start, &ch);
|
||||
if (count > 1) continue;
|
||||
if (Tcl_UniCharIsSpace(ch)) {
|
||||
quote |= CL_QUOTE; /* quote only */
|
||||
if (bspos) { /* if backslash found - escape & quote */
|
||||
quote |= CL_ESCAPE;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (strchr(specMetaChars, *start)) {
|
||||
quote |= (CL_ESCAPE|CL_QUOTE); /*escape & quote */
|
||||
break;
|
||||
}
|
||||
if (*start == '"') {
|
||||
quote |= CL_ESCAPE; /* escape only */
|
||||
continue;
|
||||
}
|
||||
if (*start == '\\') {
|
||||
bspos = start;
|
||||
if (quote & CL_QUOTE) { /* if quote - escape & quote */
|
||||
quote |= CL_ESCAPE;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
bspos = NULL;
|
||||
}
|
||||
if (quote) {
|
||||
if (quote & CL_QUOTE) {
|
||||
/* start of argument (main opening quote-char) */
|
||||
TclDStringAppendLiteral(&ds, "\"");
|
||||
}
|
||||
start = arg;
|
||||
for (special = arg; ; ) {
|
||||
if ((*special == '\\') && (special[1] == '\\' ||
|
||||
special[1] == '"' || (quote && special[1] == '\0'))) {
|
||||
Tcl_DStringAppend(&ds, start, (int) (special - start));
|
||||
start = special;
|
||||
while (1) {
|
||||
special++;
|
||||
if (*special == '"' || (quote && *special == '\0')) {
|
||||
/*
|
||||
* N backslashes followed a quote -> insert N * 2 + 1
|
||||
* backslashes then a quote.
|
||||
*/
|
||||
|
||||
Tcl_DStringAppend(&ds, start,
|
||||
(int) (special - start));
|
||||
break;
|
||||
}
|
||||
if (*special != '\\') {
|
||||
break;
|
||||
}
|
||||
if (!(quote & CL_ESCAPE)) {
|
||||
/* nothing to escape */
|
||||
Tcl_DStringAppend(&ds, arg, -1);
|
||||
} else {
|
||||
start = arg;
|
||||
for (special = arg; *special != '\0'; ) {
|
||||
/* position of `\` is important before quote or at end (equal `\"` because quoted) */
|
||||
if (*special == '\\') {
|
||||
/* bypass backslashes (and mark first backslash possition)*/
|
||||
special = BuildCmdLineBypassBS(special, &bspos);
|
||||
if (*special == '\0') break;
|
||||
}
|
||||
Tcl_DStringAppend(&ds, start, (int) (special - start));
|
||||
start = special;
|
||||
/* ["] */
|
||||
if (*special == '"') {
|
||||
quote ^= CL_UNPAIRED; /* invert unpaired flag - observe unpaired quotes */
|
||||
/* add part before (and escape backslashes before quote) */
|
||||
QuoteCmdLineBackslash(&ds, start, special, bspos);
|
||||
bspos = NULL;
|
||||
/* escape using backslash */
|
||||
TclDStringAppendLiteral(&ds, "\\\"");
|
||||
start = ++special;
|
||||
continue;
|
||||
}
|
||||
/* unpaired (escaped) quote causes special handling on meta-chars */
|
||||
if ((quote & CL_UNPAIRED) && strchr(specMetaChars, *special)) {
|
||||
special = QuoteCmdLinePart(&ds, start, special, specMetaChars, &bspos);
|
||||
/* start to current or first backslash */
|
||||
start = !bspos ? special : bspos;
|
||||
continue;
|
||||
}
|
||||
/* special case for % - should be enclosed always (paired also) */
|
||||
if (strchr(specMetaChars2, *special)) {
|
||||
special = QuoteCmdLinePart(&ds, start, special, specMetaChars2, &bspos);
|
||||
/* start to current or first backslash */
|
||||
start = !bspos ? special : bspos;
|
||||
continue;
|
||||
}
|
||||
/* other not special (and not meta) character */
|
||||
bspos = NULL; /* reset last backslash possition (not interesting) */
|
||||
special++;
|
||||
}
|
||||
if (*special == '"') {
|
||||
Tcl_DStringAppend(&ds, start, (int) (special - start));
|
||||
TclDStringAppendLiteral(&ds, "\\\"");
|
||||
start = special + 1;
|
||||
}
|
||||
if (*special == '\0') {
|
||||
break;
|
||||
}
|
||||
special++;
|
||||
/* rest of argument (and escape backslashes before closing main quote) */
|
||||
QuoteCmdLineBackslash(&ds, start, special,
|
||||
(quote & CL_QUOTE) ? bspos : NULL);
|
||||
}
|
||||
Tcl_DStringAppend(&ds, start, (int) (special - start));
|
||||
if (quote) {
|
||||
if (quote & CL_QUOTE) {
|
||||
/* end of argument (main closing quote-char) */
|
||||
TclDStringAppendLiteral(&ds, "\"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -568,4 +568,7 @@ typedef DWORD_PTR * PDWORD_PTR;
|
||||
# define LABEL_SECURITY_INFORMATION (0x00000010L)
|
||||
#endif
|
||||
|
||||
#define Tcl_DirEntry void
|
||||
#define TclDIR void
|
||||
|
||||
#endif /* _TCLWINPORT */
|
||||
|
||||
+8
-8
@@ -686,7 +686,7 @@ WaitForConnect(
|
||||
}
|
||||
|
||||
/*
|
||||
* A non blocking socket waiting for an asyncronous connect
|
||||
* A non blocking socket waiting for an asynchronous connect
|
||||
* returns directly the error EWOULDBLOCK
|
||||
*/
|
||||
|
||||
@@ -1606,9 +1606,9 @@ TcpGetHandleProc(
|
||||
*
|
||||
* This might be called in 3 circumstances:
|
||||
* - By a regular socket command
|
||||
* - By the event handler to continue an asynchroneous connect
|
||||
* - By the event handler to continue an asynchronously connect
|
||||
* - By a blocking socket function (gets/puts) to terminate the
|
||||
* connect synchroneously
|
||||
* connect synchronously
|
||||
*
|
||||
* Results:
|
||||
* TCL_OK, if the socket was successfully connected or an asynchronous
|
||||
@@ -1620,7 +1620,7 @@ TcpGetHandleProc(
|
||||
*
|
||||
* Remarks:
|
||||
* A single host name may resolve to more than one IP address, e.g. for
|
||||
* an IPv4/IPv6 dual stack host. For handling asyncronously connecting
|
||||
* an IPv4/IPv6 dual stack host. For handling asynchronously connecting
|
||||
* sockets in the background for such hosts, this function can act as a
|
||||
* coroutine. On the first call, it sets up the control variables for the
|
||||
* two nested loops over the local and remote addresses. Once the first
|
||||
@@ -1628,7 +1628,7 @@ TcpGetHandleProc(
|
||||
* event handler for that socket, and returns. When the callback occurs,
|
||||
* control is transferred to the "reenter" label, right after the initial
|
||||
* return and the loops resume as if they had never been interrupted.
|
||||
* For syncronously connecting sockets, the loops work the usual way.
|
||||
* For synchronously connecting sockets, the loops work the usual way.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1718,7 +1718,7 @@ TcpConnect(
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* For asyncroneous connect set the socket in nonblocking mode
|
||||
* For asynchroneous connect set the socket in nonblocking mode
|
||||
* and activate connect notification
|
||||
*/
|
||||
if (async_connect) {
|
||||
@@ -1806,7 +1806,7 @@ TcpConnect(
|
||||
|
||||
/*
|
||||
* Clear the tsd socket list pointer if we did not wait for
|
||||
* the FD_CONNECT asyncroneously
|
||||
* the FD_CONNECT asynchroneously
|
||||
*/
|
||||
tsdPtr->pendingTcpState = NULL;
|
||||
|
||||
@@ -1868,7 +1868,7 @@ out:
|
||||
SetEvent(tsdPtr->socketListLock);
|
||||
}
|
||||
/*
|
||||
* Error message on syncroneous connect
|
||||
* Error message on synchroneous connect
|
||||
*/
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
|
||||
+4
-4
@@ -247,7 +247,7 @@ TclpThreadCreate(
|
||||
|
||||
/*
|
||||
* The only purpose of this is to decrement the reference count so the
|
||||
* OS resources will be reaquired when the thread closes.
|
||||
* OS resources will be reacquired when the thread closes.
|
||||
*/
|
||||
|
||||
CloseHandle(tHandle);
|
||||
@@ -405,7 +405,7 @@ TclpInitUnlock(void)
|
||||
* mutexes, condition variables, and thread local storage keys.
|
||||
*
|
||||
* This lock must be different than the initLock because the initLock is
|
||||
* held during creation of syncronization objects.
|
||||
* held during creation of synchronization objects.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -555,7 +555,7 @@ static void FinalizeConditionEvent(ClientData data);
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* May block the current thread. The mutex is aquired when this returns.
|
||||
* May block the current thread. The mutex is acquired when this returns.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -655,7 +655,7 @@ TclpFinalizeMutex(
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* May block the current thread. The mutex is aquired when this returns.
|
||||
* May block the current thread. The mutex is acquired when this returns.
|
||||
* Will allocate memory for a HANDLE and initialize this the first time
|
||||
* this Tcl_Condition is used.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user