Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2c25652324 | ||
|
|
3c1b27e3cd | ||
|
|
3f7351e88d | ||
|
|
71a34fe05a | ||
|
|
a9c238476a | ||
|
|
cfafc391f2 | ||
|
|
0fbade1cf8 | ||
|
|
dd54301fb6 | ||
|
|
6352a07912 | ||
|
|
440f85800c | ||
|
|
2a11adb848 | ||
|
|
77f95f38bf | ||
|
|
2710235273 | ||
|
|
042e99227a | ||
|
|
64c9b509b0 | ||
|
|
d39c33303f | ||
|
|
45175dd264 | ||
|
|
20b4459b9d | ||
|
|
c488b70a47 | ||
|
|
73f548527a | ||
|
|
3923106cf7 | ||
|
|
17711009b6 | ||
|
|
b3bda726c1 | ||
|
|
e1b4ae0798 | ||
|
|
aca86a46ff | ||
|
|
9ddb31d522 | ||
|
|
6123ba004c | ||
|
|
bc4db4d40e | ||
|
|
0f0ca3d932 | ||
|
|
2cdd3134ab | ||
|
|
107760e1da | ||
|
|
d453cdacec | ||
|
|
ad34457a54 | ||
|
|
3f2eb64de8 | ||
|
|
4b81f6ff43 | ||
|
|
cc72d116bd | ||
|
|
94b635d569 | ||
|
|
de1c1f0f47 | ||
|
|
a4f7145579 | ||
|
|
bbcbd64e3b | ||
|
|
36d9205d97 | ||
|
|
7673d614a9 | ||
|
|
c348386388 | ||
|
|
878c874975 | ||
|
|
b796f3dee7 | ||
|
|
dd96539335 | ||
|
|
23ab25afdc | ||
|
|
192d5ccf32 | ||
|
|
9ce3a23afe | ||
|
|
c2e241f3cd | ||
|
|
9562ecd7fa | ||
|
|
fbfe81cc7b | ||
|
|
73a3dfdeea | ||
|
|
4cf238f3c3 | ||
|
|
1b667ef114 | ||
|
|
0aa0da515c | ||
|
|
5667bb5f8e | ||
|
|
b0146fbd50 | ||
|
|
615771f0b6 | ||
|
|
8d78b23f96 | ||
|
|
fab7d970af | ||
|
|
617e92d7b4 | ||
|
|
7edce7686e | ||
|
|
3d8a0152af | ||
|
|
cb68061d12 | ||
|
|
5c4bb0f4e9 | ||
|
|
8129d3e1c3 | ||
|
|
3cdd3064b5 | ||
|
|
708ca98ace | ||
|
|
f5f03750c8 | ||
|
|
901f58f13b | ||
|
|
c688e0737c | ||
|
|
21dfa74b03 | ||
|
|
3f0e8d6265 | ||
|
|
aaca962ffe | ||
|
|
fcd399d49a | ||
|
|
ca9d6593d1 | ||
|
|
4a9ae53836 | ||
|
|
60c071ed62 | ||
|
|
bbb13bf577 | ||
|
|
c05da96a35 | ||
|
|
73b3bf53ad | ||
|
|
777941e35b | ||
|
|
e06e0c8625 | ||
|
|
ece8767c5c | ||
|
|
b63d3d703e | ||
|
|
a59ccae461 | ||
|
|
18315c5b5c | ||
|
|
c922cc78a8 | ||
|
|
9220ca224b | ||
|
|
3be2fece8c | ||
|
|
e5726b4339 | ||
|
|
cf0cf6ad90 | ||
|
|
f3ea991996 | ||
|
|
14949f27a3 | ||
|
|
c571887777 | ||
|
|
f100bae746 | ||
|
|
4db003c2bf | ||
|
|
62e71e311e | ||
|
|
df664778c8 | ||
|
|
82ddcc716b | ||
|
|
34189452da | ||
|
|
8b5d3394c2 | ||
|
|
2a5ae4319f | ||
|
|
246869993a | ||
|
|
dea5aab977 | ||
|
|
8bdc794177 | ||
|
|
993aa1b338 | ||
|
|
c3077bd013 | ||
|
|
02d6d68a68 | ||
|
|
c6484de085 | ||
|
|
dcc8bd9aa8 | ||
|
|
5d20272000 | ||
|
|
0adb50f88b | ||
|
|
a6c79230c3 | ||
|
|
0ec19f6b11 | ||
|
|
d6de0fb46b | ||
|
|
6b33bdad03 | ||
|
|
5171d6b4ef | ||
|
|
39a388f035 | ||
|
|
ea1ae51d2d | ||
|
|
95d531e781 | ||
|
|
1ea7d20306 | ||
|
|
0cdf2fd457 | ||
|
|
5202a013d2 | ||
|
|
f9abf9b060 | ||
|
|
2eaa3d3c8d | ||
|
|
19b2d40089 | ||
|
|
ba8e7c4211 | ||
|
|
3fe213e031 | ||
|
|
d9b0bec7d6 | ||
|
|
a021af135e | ||
|
|
ee3d72e1e1 | ||
|
|
2752a9f58b | ||
|
|
a73818d8b6 | ||
|
|
2130fd8582 | ||
|
|
f32ecd5894 | ||
|
|
1ed15145a6 | ||
|
|
46f75926ff | ||
|
|
ca65694482 | ||
|
|
69865e4f83 | ||
|
|
71a9a4406a | ||
|
|
dd53d408e3 | ||
|
|
ce501f14c5 | ||
|
|
b96146d014 | ||
|
|
6f18f8d375 | ||
|
|
63cf0366bd | ||
|
|
fd7ea3420f | ||
|
|
52e520be10 | ||
|
|
af718696fb | ||
|
|
2c5a00c966 | ||
|
|
3d65f9905d | ||
|
|
709366bdfe | ||
|
|
910200b637 | ||
|
|
be831d7ecb | ||
|
|
44c544160a | ||
|
|
262df0197b | ||
|
|
ed853e1ffb | ||
|
|
799554b1c5 | ||
|
|
5d0864fb41 | ||
|
|
90ffbb4170 | ||
|
|
adfd841d9d | ||
|
|
237c46512c | ||
|
|
64f999ee89 | ||
|
|
198407b5ba | ||
|
|
ab5586a7a3 | ||
|
|
79426acd55 | ||
|
|
14f579844d | ||
|
|
83495af5ce | ||
|
|
dc9c72819c | ||
|
|
1200929a72 | ||
|
|
10ab52081d | ||
|
|
fecff1bcf0 | ||
|
|
513d77788d | ||
|
|
2f5a766c71 | ||
|
|
0b9703a36f | ||
|
|
2bf6ae09b3 | ||
|
|
879750b278 | ||
|
|
e3a9350e58 | ||
|
|
04086099d0 | ||
|
|
757450b24f | ||
|
|
fbbc93906e | ||
|
|
85dbf412fd | ||
|
|
1f25f80d5b | ||
|
|
99143db529 | ||
|
|
2f99ece694 | ||
|
|
251dc3a322 | ||
|
|
c1b1e9af62 | ||
|
|
bcbbf6dacf | ||
|
|
93a924d020 | ||
|
|
6f7ac0e29c | ||
|
|
bfdfb7479d | ||
|
|
56739b8036 | ||
|
|
2c5d1036db | ||
|
|
15b0a7813d | ||
|
|
490e5ace3a | ||
|
|
6be0cf66e0 | ||
|
|
ea1a2f3fbf | ||
|
|
5ba18ec98d | ||
|
|
62b2b9bf45 | ||
|
|
244e69a10a | ||
|
|
e006ff39be | ||
|
|
9faad3da69 | ||
|
|
47a749742a | ||
|
|
9d252ff7d2 | ||
|
|
9b4213bb3f | ||
|
|
0cc7fd3498 | ||
|
|
1638a98f0e | ||
|
|
85cc06f56c | ||
|
|
76054b4646 | ||
|
|
9b95c00218 | ||
|
|
b8186ff707 | ||
|
|
f5538049ef | ||
|
|
119d9ad3aa | ||
|
|
8b0910d31f | ||
|
|
cd48f2d313 | ||
|
|
26f98a5e56 | ||
|
|
bbfc7b1ea2 | ||
|
|
1e3fa455c9 | ||
|
|
d00198bd14 | ||
|
|
ff4b11441b | ||
|
|
904733362e | ||
|
|
44de3dd8da | ||
|
|
ceb75ca9ff | ||
|
|
55edd253ff | ||
|
|
2ae10f0b33 | ||
|
|
b9cc513f2f | ||
|
|
14192d21dd | ||
|
|
19719bf57f | ||
|
|
ea8cb9b7bb | ||
|
|
72ac20b7d7 | ||
|
|
7b4e946f74 | ||
|
|
85397cf893 | ||
|
|
d10ba45b4b | ||
|
|
ce7746b49e | ||
|
|
354e08673b | ||
|
|
c552943f9e | ||
|
|
810395f913 | ||
|
|
8dfdec39fd | ||
|
|
0abecbc87d | ||
|
|
efbb62b5bd | ||
|
|
24f5b98e8c | ||
|
|
dd5e309d31 | ||
|
|
0c0b1e1498 | ||
|
|
0d54bf3711 | ||
|
|
920aa8280f | ||
|
|
8a2c820213 | ||
|
|
ab08379d1c | ||
|
|
321cd769b7 | ||
|
|
802974ec84 | ||
|
|
91cb892574 | ||
|
|
4703c1399d | ||
|
|
e58e9e1fb9 | ||
|
|
5894e1b085 | ||
|
|
dc25a1a62b | ||
|
|
754b233873 | ||
|
|
5617ad7c18 | ||
|
|
909f1a1a30 | ||
|
|
f6837a8ef4 | ||
|
|
d287c6c8b0 | ||
|
|
488735e4a2 | ||
|
|
43d597b30f | ||
|
|
a3f676461c | ||
|
|
607667f89d | ||
|
|
6212b342f6 | ||
|
|
5ddb691286 | ||
|
|
6f905e1f0f | ||
|
|
4ccedfaec4 | ||
|
|
c010901ea9 | ||
|
|
c0bedd810f | ||
|
|
5d66bf5a1f | ||
|
|
d4b614d655 | ||
|
|
f55296bdf0 | ||
|
|
bed000d72e | ||
|
|
b2181df698 | ||
|
|
6469ae095f | ||
|
|
636e904b09 | ||
|
|
2c343f8ac1 | ||
|
|
30dc72c0aa | ||
|
|
279bfdeef3 | ||
|
|
da85dcc288 | ||
|
|
07050778e3 | ||
|
|
ac3cb936ee | ||
|
|
d183e03dc3 | ||
|
|
fa0de66105 | ||
|
|
aaa76b7a7d | ||
|
|
ad788184e3 | ||
|
|
aec683eef8 | ||
|
|
41646a2294 | ||
|
|
2a1688c8f5 | ||
|
|
6ba062e067 | ||
|
|
089381e2b1 | ||
|
|
ef3d739cdf | ||
|
|
0f7d84bbbf | ||
|
|
94253c0df4 | ||
|
|
30c48b68df | ||
|
|
7088b7efe3 | ||
|
|
13ccdabc07 | ||
|
|
203bbab7c9 | ||
|
|
93d3ea1393 | ||
|
|
874b8643e0 | ||
|
|
d18329a21e | ||
|
|
82296abf08 | ||
|
|
5772e32729 | ||
|
|
3ef7160d41 | ||
|
|
462ffc7927 | ||
|
|
a13289725c | ||
|
|
c8646e5c72 | ||
|
|
efa3ec6939 | ||
|
|
a638162ed4 | ||
|
|
c77bd091df | ||
|
|
2bb76d85aa | ||
|
|
8dde174dd4 | ||
|
|
ca98340c4c | ||
|
|
35539e2f98 | ||
|
|
8fb5bb0f20 | ||
|
|
6db42b86e6 | ||
|
|
8066c6a687 | ||
|
|
4671050f10 | ||
|
|
fca34fb8d0 | ||
|
|
0e31751aed | ||
|
|
d5c18c780a | ||
|
|
19e0981d35 | ||
|
|
b2a59d29b6 | ||
|
|
d917353c7e | ||
|
|
5fdbd4a749 | ||
|
|
b3800e2fed | ||
|
|
67b6b8b92c | ||
|
|
17cf9db2f7 | ||
|
|
e7e8174dba | ||
|
|
4b357897d5 | ||
|
|
68275b03de | ||
|
|
2645c0ef3a | ||
|
|
7de961e9fa | ||
|
|
c26df8ae12 | ||
|
|
d1c1cbf476 | ||
|
|
4166996b42 | ||
|
|
47692f4e99 | ||
|
|
649902f7fa | ||
|
|
e7e764dbdf | ||
|
|
b0aa1e2416 | ||
|
|
3cd704802f | ||
|
|
ea1cc886b5 | ||
|
|
3dba96d22a | ||
|
|
a0ea496ffb | ||
|
|
1ef8141062 | ||
|
|
893b999f51 | ||
|
|
1a7f4b5e4c | ||
|
|
2d2102400e | ||
|
|
4c239ca4d9 | ||
|
|
e1dcac30d8 | ||
|
|
ad6dcfad67 | ||
|
|
77481ec3e1 | ||
|
|
f03990cd12 | ||
|
|
a841205be9 | ||
|
|
df7cbb28e0 | ||
|
|
01697f2acc | ||
|
|
0a1c05fbb8 | ||
|
|
8fa2e7802e | ||
|
|
c2ee1525ef | ||
|
|
ae731e3e50 | ||
|
|
bc879a58f2 | ||
|
|
d551c0972c | ||
|
|
27fd5c0793 | ||
|
|
264cc47fd4 | ||
|
|
866efbc904 | ||
|
|
941e45f907 | ||
|
|
7a654297a0 | ||
|
|
4600d7c026 | ||
|
|
c97ddc73f6 | ||
|
|
bd20b3429a | ||
|
|
d830389b53 | ||
|
|
63c8495242 | ||
|
|
9d7b1b2b03 | ||
|
|
0f7c885e8c | ||
|
|
95b63f4c39 | ||
|
|
20ec6252d1 | ||
|
|
2ba998572c | ||
|
|
c5ff074db9 | ||
|
|
717e43f1bd | ||
|
|
e130d09c74 | ||
|
|
36d60df82c | ||
|
|
e9177a25c1 | ||
|
|
02b4c1de38 | ||
|
|
feb62aa2bd | ||
|
|
6c38124bb9 | ||
|
|
caf50ef7ea | ||
|
|
c51ce8e879 | ||
|
|
94dc5e4e43 | ||
|
|
c52322d409 | ||
|
|
a4c93085d2 | ||
|
|
18dc49dd08 | ||
|
|
c5d6cc90d9 | ||
|
|
bcb2a0a181 | ||
|
|
940c0805c0 | ||
|
|
a3c42aef3e | ||
|
|
aba1f29686 | ||
|
|
898bc97bbe | ||
|
|
5ab3eafa66 | ||
|
|
1f1f1e4dfc | ||
|
|
32b5c49ef3 | ||
|
|
21878028d5 | ||
|
|
18b31092c6 | ||
|
|
736824a259 | ||
|
|
9e52bb21b7 | ||
|
|
a3433951b0 | ||
|
|
ad284758d3 | ||
|
|
6aed9a6630 | ||
|
|
704f3a5483 | ||
|
|
2de37edd0d | ||
|
|
cc89e55f7d | ||
|
|
3703dbd940 | ||
|
|
8da19e064b | ||
|
|
666afa7352 | ||
|
|
5e02396d5e | ||
|
|
2e108cd831 | ||
|
|
27fb8875b7 | ||
|
|
cdb6b73776 | ||
|
|
fad7a0e23d | ||
|
|
da7cc28446 | ||
|
|
e6e391530f | ||
|
|
a0256cda63 | ||
|
|
85daeb5e16 |
@@ -0,0 +1,14 @@
|
||||
compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
|
||||
compat/zlib/contrib/vstudio/readme.txt
|
||||
compat/zlib/contrib/vstudio/*/zlib.rc
|
||||
compat/zlib/win32/*.txt
|
||||
compat/zlib/win64/*.txt
|
||||
tools/tcl.hpj.in
|
||||
tools/tcl.wse.in
|
||||
win/buildall.vc.bat
|
||||
win/coffbase.txt
|
||||
win/makefile.vc
|
||||
win/rules.vc
|
||||
win/tcl.dsp
|
||||
win/tcl.dsw
|
||||
win/tcl.hpj.in
|
||||
@@ -7,7 +7,6 @@ tools/tcl.hpj.in
|
||||
tools/tcl.wse.in
|
||||
win/buildall.vc.bat
|
||||
win/coffbase.txt
|
||||
win/makefile.bc
|
||||
win/makefile.vc
|
||||
win/rules.vc
|
||||
win/tcl.dsp
|
||||
|
||||
@@ -2,7 +2,6 @@ tools/tcl.hpj.in
|
||||
tools/tcl.wse.in
|
||||
win/buildall.vc.bat
|
||||
win/coffbase.txt
|
||||
win/makefile.bc
|
||||
win/makefile.vc
|
||||
win/rules.vc
|
||||
win/tcl.dsp
|
||||
|
||||
@@ -3,7 +3,7 @@ set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
|
||||
|
||||
project(zlib C)
|
||||
|
||||
set(VERSION "1.2.10")
|
||||
set(VERSION "1.2.11")
|
||||
|
||||
option(ASM686 "Enable building i686 assembly implementation")
|
||||
option(AMD64 "Enable building amd64 assembly implementation")
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
|
||||
ChangeLog file for zlib
|
||||
|
||||
Changes in 1.2.11 (15 Jan 2017)
|
||||
- Fix deflate stored bug when pulling last block from window
|
||||
- Permit immediate deflateParams changes before any deflate input
|
||||
|
||||
Changes in 1.2.10 (2 Jan 2017)
|
||||
- Avoid warnings on snprintf() return value
|
||||
- Fix bug in deflate_stored() for zero-length input
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Makefile for zlib
|
||||
# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler
|
||||
# Copyright (C) 1995-2017 Jean-loup Gailly, Mark Adler
|
||||
# For conditions of distribution and use, see copyright notice in zlib.h
|
||||
|
||||
# To compile and test, type:
|
||||
@@ -32,7 +32,7 @@ CPP=$(CC) -E
|
||||
|
||||
STATICLIB=libz.a
|
||||
SHAREDLIB=libz.so
|
||||
SHAREDLIBV=libz.so.1.2.10
|
||||
SHAREDLIBV=libz.so.1.2.11
|
||||
SHAREDLIBM=libz.so.1
|
||||
LIBS=$(STATICLIB) $(SHAREDLIBV)
|
||||
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
ZLIB DATA COMPRESSION LIBRARY
|
||||
|
||||
zlib 1.2.10 is a general purpose data compression library. All the code is
|
||||
zlib 1.2.11 is a general purpose data compression library. All the code is
|
||||
thread safe. The data format used by the zlib library is described by RFCs
|
||||
(Request for Comments) 1950 to 1952 in the files
|
||||
http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
|
||||
@@ -31,7 +31,7 @@ Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
|
||||
issue of Dr. Dobb's Journal; a copy of the article is available at
|
||||
http://marknelson.us/1997/01/01/zlib-engine/ .
|
||||
|
||||
The changes made in version 1.2.10 are documented in the file ChangeLog.
|
||||
The changes made in version 1.2.11 are documented in the file ChangeLog.
|
||||
|
||||
Unsupported third party contributions are provided in directory contrib/ .
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
|
||||
const OutBuf: Pointer; BufSize: Integer);
|
||||
|
||||
const
|
||||
zlib_version = '1.2.10';
|
||||
zlib_version = '1.2.11';
|
||||
|
||||
type
|
||||
EZlibError = class(Exception);
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace DotZLibTests
|
||||
public void Info_Version()
|
||||
{
|
||||
Info info = new Info();
|
||||
Assert.AreEqual("1.2.10", Info.Version);
|
||||
Assert.AreEqual("1.2.11", Info.Version);
|
||||
Assert.AreEqual(32, info.SizeOfUInt);
|
||||
Assert.AreEqual(32, info.SizeOfULong);
|
||||
Assert.AreEqual(32, info.SizeOfPointer);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate9_copyright[] =
|
||||
" inflate9 1.2.10 Copyright 1995-2017 Mark Adler ";
|
||||
" inflate9 1.2.11 Copyright 1995-2017 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@@ -64,7 +64,7 @@ unsigned short FAR *work;
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
|
||||
130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
|
||||
133, 133, 133, 133, 144, 192, 202};
|
||||
133, 133, 133, 133, 144, 77, 202};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
|
||||
65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([minizip], [1.2.10], [bugzilla.redhat.com])
|
||||
AC_INIT([minizip], [1.2.11], [bugzilla.redhat.com])
|
||||
AC_CONFIG_SRCDIR([minizip.c])
|
||||
AM_INIT_AUTOMAKE([foreign])
|
||||
LT_INIT
|
||||
|
||||
@@ -10,7 +10,7 @@ unit zlibpas;
|
||||
interface
|
||||
|
||||
const
|
||||
ZLIB_VERSION = '1.2.10';
|
||||
ZLIB_VERSION = '1.2.11';
|
||||
ZLIB_VERNUM = $12a0;
|
||||
|
||||
type
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Building instructions for the DLL versions of Zlib 1.2.10
|
||||
Building instructions for the DLL versions of Zlib 1.2.11
|
||||
========================================================
|
||||
|
||||
This directory contains projects that build zlib and minizip using
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#define IDR_VERSION1 1
|
||||
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
|
||||
FILEVERSION 1, 2, 10, 0
|
||||
PRODUCTVERSION 1, 2, 10, 0
|
||||
FILEVERSION 1, 2, 11, 0
|
||||
PRODUCTVERSION 1, 2, 11, 0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS 0
|
||||
FILEOS VOS_DOS_WINDOWS32
|
||||
@@ -17,7 +17,7 @@ BEGIN
|
||||
|
||||
BEGIN
|
||||
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
|
||||
VALUE "FileVersion", "1.2.10\0"
|
||||
VALUE "FileVersion", "1.2.11\0"
|
||||
VALUE "InternalName", "zlib\0"
|
||||
VALUE "OriginalFilename", "zlibwapi.dll\0"
|
||||
VALUE "ProductName", "ZLib.DLL\0"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#define IDR_VERSION1 1
|
||||
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
|
||||
FILEVERSION 1, 2, 10, 0
|
||||
PRODUCTVERSION 1, 2, 10, 0
|
||||
FILEVERSION 1, 2, 11, 0
|
||||
PRODUCTVERSION 1, 2, 11, 0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS 0
|
||||
FILEOS VOS_DOS_WINDOWS32
|
||||
@@ -17,7 +17,7 @@ BEGIN
|
||||
|
||||
BEGIN
|
||||
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
|
||||
VALUE "FileVersion", "1.2.10\0"
|
||||
VALUE "FileVersion", "1.2.11\0"
|
||||
VALUE "InternalName", "zlib\0"
|
||||
VALUE "OriginalFilename", "zlibwapi.dll\0"
|
||||
VALUE "ProductName", "ZLib.DLL\0"
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#define IDR_VERSION1 1
|
||||
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
|
||||
FILEVERSION 1, 2, 10, 0
|
||||
PRODUCTVERSION 1, 2, 10, 0
|
||||
FILEVERSION 1, 2, 11, 0
|
||||
PRODUCTVERSION 1, 2, 11, 0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS 0
|
||||
FILEOS VOS_DOS_WINDOWS32
|
||||
@@ -17,7 +17,7 @@ BEGIN
|
||||
|
||||
BEGIN
|
||||
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
|
||||
VALUE "FileVersion", "1.2.10\0"
|
||||
VALUE "FileVersion", "1.2.11\0"
|
||||
VALUE "InternalName", "zlib\0"
|
||||
VALUE "OriginalFilename", "zlibwapi.dll\0"
|
||||
VALUE "ProductName", "ZLib.DLL\0"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#define IDR_VERSION1 1
|
||||
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
|
||||
FILEVERSION 1, 2, 10, 0
|
||||
PRODUCTVERSION 1, 2, 10, 0
|
||||
FILEVERSION 1, 2, 11, 0
|
||||
PRODUCTVERSION 1, 2, 11, 0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS 0
|
||||
FILEOS VOS_DOS_WINDOWS32
|
||||
@@ -17,7 +17,7 @@ BEGIN
|
||||
|
||||
BEGIN
|
||||
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
|
||||
VALUE "FileVersion", "1.2.10\0"
|
||||
VALUE "FileVersion", "1.2.11\0"
|
||||
VALUE "InternalName", "zlib\0"
|
||||
VALUE "OriginalFilename", "zlibwapi.dll\0"
|
||||
VALUE "ProductName", "ZLib.DLL\0"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#define IDR_VERSION1 1
|
||||
IDR_VERSION1 VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
|
||||
FILEVERSION 1, 2, 10, 0
|
||||
PRODUCTVERSION 1, 2, 10, 0
|
||||
FILEVERSION 1, 2, 11, 0
|
||||
PRODUCTVERSION 1, 2, 11, 0
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS 0
|
||||
FILEOS VOS_DOS_WINDOWS32
|
||||
@@ -17,7 +17,7 @@ BEGIN
|
||||
|
||||
BEGIN
|
||||
VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
|
||||
VALUE "FileVersion", "1.2.10\0"
|
||||
VALUE "FileVersion", "1.2.11\0"
|
||||
VALUE "InternalName", "zlib\0"
|
||||
VALUE "OriginalFilename", "zlibwapi.dll\0"
|
||||
VALUE "ProductName", "ZLib.DLL\0"
|
||||
|
||||
+12
-7
@@ -52,7 +52,7 @@
|
||||
#include "deflate.h"
|
||||
|
||||
const char deflate_copyright[] =
|
||||
" deflate 1.2.10 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
|
||||
" deflate 1.2.11 Copyright 1995-2017 Jean-loup Gailly and Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@@ -586,7 +586,8 @@ int ZEXPORT deflateParams(strm, level, strategy)
|
||||
}
|
||||
func = configuration_table[s->level].func;
|
||||
|
||||
if ((strategy != s->strategy || func != configuration_table[level].func)) {
|
||||
if ((strategy != s->strategy || func != configuration_table[level].func) &&
|
||||
s->high_water) {
|
||||
/* Flush the last buffer: */
|
||||
int err = deflate(strm, Z_BLOCK);
|
||||
if (err == Z_STREAM_ERROR)
|
||||
@@ -1671,8 +1672,6 @@ local block_state deflate_stored(s, flush)
|
||||
len = left + s->strm->avail_in; /* limit len to the input */
|
||||
if (len > have)
|
||||
len = have; /* limit len to the output */
|
||||
if (left > len)
|
||||
left = len; /* limit window pull to len */
|
||||
|
||||
/* If the stored block would be less than min_block in length, or if
|
||||
* unable to copy all of the available input when flushing, then try
|
||||
@@ -1681,13 +1680,13 @@ local block_state deflate_stored(s, flush)
|
||||
*/
|
||||
if (len < min_block && ((len == 0 && flush != Z_FINISH) ||
|
||||
flush == Z_NO_FLUSH ||
|
||||
len - left != s->strm->avail_in))
|
||||
len != left + s->strm->avail_in))
|
||||
break;
|
||||
|
||||
/* Make a dummy stored block in pending to get the header bytes,
|
||||
* including any pending bits. This also updates the debugging counts.
|
||||
*/
|
||||
last = flush == Z_FINISH && len - left == s->strm->avail_in ? 1 : 0;
|
||||
last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0;
|
||||
_tr_stored_block(s, (char *)0, 0L, last);
|
||||
|
||||
/* Replace the lengths in the dummy stored block with len. */
|
||||
@@ -1699,14 +1698,16 @@ local block_state deflate_stored(s, flush)
|
||||
/* Write the stored block header bytes. */
|
||||
flush_pending(s->strm);
|
||||
|
||||
/* Update debugging counts for the data about to be copied. */
|
||||
#ifdef ZLIB_DEBUG
|
||||
/* Update debugging counts for the data about to be copied. */
|
||||
s->compressed_len += len << 3;
|
||||
s->bits_sent += len << 3;
|
||||
#endif
|
||||
|
||||
/* Copy uncompressed bytes from the window to next_out. */
|
||||
if (left) {
|
||||
if (left > len)
|
||||
left = len;
|
||||
zmemcpy(s->strm->next_out, s->window + s->block_start, left);
|
||||
s->strm->next_out += left;
|
||||
s->strm->avail_out -= left;
|
||||
@@ -1756,6 +1757,8 @@ local block_state deflate_stored(s, flush)
|
||||
s->block_start = s->strstart;
|
||||
s->insert += MIN(used, s->w_size - s->insert);
|
||||
}
|
||||
if (s->high_water < s->strstart)
|
||||
s->high_water = s->strstart;
|
||||
|
||||
/* If the last block was written to next_out, then done. */
|
||||
if (last)
|
||||
@@ -1783,6 +1786,8 @@ local block_state deflate_stored(s, flush)
|
||||
read_buf(s->strm, s->window + s->strstart, have);
|
||||
s->strstart += have;
|
||||
}
|
||||
if (s->high_water < s->strstart)
|
||||
s->high_water = s->strstart;
|
||||
|
||||
/* There was not enough avail_out to write a complete worthy or flushed
|
||||
* stored block to next_out. Write a stored block to pending instead, if we
|
||||
|
||||
@@ -1,209 +0,0 @@
|
||||
1. Compression algorithm (deflate)
|
||||
|
||||
The deflation algorithm used by gzip (also zip and zlib) is a variation of
|
||||
LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
|
||||
the input data. The second occurrence of a string is replaced by a
|
||||
pointer to the previous string, in the form of a pair (distance,
|
||||
length). Distances are limited to 32K bytes, and lengths are limited
|
||||
to 258 bytes. When a string does not occur anywhere in the previous
|
||||
32K bytes, it is emitted as a sequence of literal bytes. (In this
|
||||
description, `string' must be taken as an arbitrary sequence of bytes,
|
||||
and is not restricted to printable characters.)
|
||||
|
||||
Literals or match lengths are compressed with one Huffman tree, and
|
||||
match distances are compressed with another tree. The trees are stored
|
||||
in a compact form at the start of each block. The blocks can have any
|
||||
size (except that the compressed data for one block must fit in
|
||||
available memory). A block is terminated when deflate() determines that
|
||||
it would be useful to start another block with fresh trees. (This is
|
||||
somewhat similar to the behavior of LZW-based _compress_.)
|
||||
|
||||
Duplicated strings are found using a hash table. All input strings of
|
||||
length 3 are inserted in the hash table. A hash index is computed for
|
||||
the next 3 bytes. If the hash chain for this index is not empty, all
|
||||
strings in the chain are compared with the current input string, and
|
||||
the longest match is selected.
|
||||
|
||||
The hash chains are searched starting with the most recent strings, to
|
||||
favor small distances and thus take advantage of the Huffman encoding.
|
||||
The hash chains are singly linked. There are no deletions from the
|
||||
hash chains, the algorithm simply discards matches that are too old.
|
||||
|
||||
To avoid a worst-case situation, very long hash chains are arbitrarily
|
||||
truncated at a certain length, determined by a runtime option (level
|
||||
parameter of deflateInit). So deflate() does not always find the longest
|
||||
possible match but generally finds a match which is long enough.
|
||||
|
||||
deflate() also defers the selection of matches with a lazy evaluation
|
||||
mechanism. After a match of length N has been found, deflate() searches for
|
||||
a longer match at the next input byte. If a longer match is found, the
|
||||
previous match is truncated to a length of one (thus producing a single
|
||||
literal byte) and the process of lazy evaluation begins again. Otherwise,
|
||||
the original match is kept, and the next match search is attempted only N
|
||||
steps later.
|
||||
|
||||
The lazy match evaluation is also subject to a runtime parameter. If
|
||||
the current match is long enough, deflate() reduces the search for a longer
|
||||
match, thus speeding up the whole process. If compression ratio is more
|
||||
important than speed, deflate() attempts a complete second search even if
|
||||
the first match is already long enough.
|
||||
|
||||
The lazy match evaluation is not performed for the fastest compression
|
||||
modes (level parameter 1 to 3). For these fast modes, new strings
|
||||
are inserted in the hash table only when no match was found, or
|
||||
when the match is not too long. This degrades the compression ratio
|
||||
but saves time since there are both fewer insertions and fewer searches.
|
||||
|
||||
|
||||
2. Decompression algorithm (inflate)
|
||||
|
||||
2.1 Introduction
|
||||
|
||||
The key question is how to represent a Huffman code (or any prefix code) so
|
||||
that you can decode fast. The most important characteristic is that shorter
|
||||
codes are much more common than longer codes, so pay attention to decoding the
|
||||
short codes fast, and let the long codes take longer to decode.
|
||||
|
||||
inflate() sets up a first level table that covers some number of bits of
|
||||
input less than the length of longest code. It gets that many bits from the
|
||||
stream, and looks it up in the table. The table will tell if the next
|
||||
code is that many bits or less and how many, and if it is, it will tell
|
||||
the value, else it will point to the next level table for which inflate()
|
||||
grabs more bits and tries to decode a longer code.
|
||||
|
||||
How many bits to make the first lookup is a tradeoff between the time it
|
||||
takes to decode and the time it takes to build the table. If building the
|
||||
table took no time (and if you had infinite memory), then there would only
|
||||
be a first level table to cover all the way to the longest code. However,
|
||||
building the table ends up taking a lot longer for more bits since short
|
||||
codes are replicated many times in such a table. What inflate() does is
|
||||
simply to make the number of bits in the first table a variable, and then
|
||||
to set that variable for the maximum speed.
|
||||
|
||||
For inflate, which has 286 possible codes for the literal/length tree, the size
|
||||
of the first table is nine bits. Also the distance trees have 30 possible
|
||||
values, and the size of the first table is six bits. Note that for each of
|
||||
those cases, the table ended up one bit longer than the ``average'' code
|
||||
length, i.e. the code length of an approximately flat code which would be a
|
||||
little more than eight bits for 286 symbols and a little less than five bits
|
||||
for 30 symbols.
|
||||
|
||||
|
||||
2.2 More details on the inflate table lookup
|
||||
|
||||
Ok, you want to know what this cleverly obfuscated inflate tree actually
|
||||
looks like. You are correct that it's not a Huffman tree. It is simply a
|
||||
lookup table for the first, let's say, nine bits of a Huffman symbol. The
|
||||
symbol could be as short as one bit or as long as 15 bits. If a particular
|
||||
symbol is shorter than nine bits, then that symbol's translation is duplicated
|
||||
in all those entries that start with that symbol's bits. For example, if the
|
||||
symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
|
||||
symbol is nine bits long, it appears in the table once.
|
||||
|
||||
If the symbol is longer than nine bits, then that entry in the table points
|
||||
to another similar table for the remaining bits. Again, there are duplicated
|
||||
entries as needed. The idea is that most of the time the symbol will be short
|
||||
and there will only be one table look up. (That's whole idea behind data
|
||||
compression in the first place.) For the less frequent long symbols, there
|
||||
will be two lookups. If you had a compression method with really long
|
||||
symbols, you could have as many levels of lookups as is efficient. For
|
||||
inflate, two is enough.
|
||||
|
||||
So a table entry either points to another table (in which case nine bits in
|
||||
the above example are gobbled), or it contains the translation for the symbol
|
||||
and the number of bits to gobble. Then you start again with the next
|
||||
ungobbled bit.
|
||||
|
||||
You may wonder: why not just have one lookup table for how ever many bits the
|
||||
longest symbol is? The reason is that if you do that, you end up spending
|
||||
more time filling in duplicate symbol entries than you do actually decoding.
|
||||
At least for deflate's output that generates new trees every several 10's of
|
||||
kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
|
||||
would take too long if you're only decoding several thousand symbols. At the
|
||||
other extreme, you could make a new table for every bit in the code. In fact,
|
||||
that's essentially a Huffman tree. But then you spend too much time
|
||||
traversing the tree while decoding, even for short symbols.
|
||||
|
||||
So the number of bits for the first lookup table is a trade of the time to
|
||||
fill out the table vs. the time spent looking at the second level and above of
|
||||
the table.
|
||||
|
||||
Here is an example, scaled down:
|
||||
|
||||
The code being decoded, with 10 symbols, from 1 to 6 bits long:
|
||||
|
||||
A: 0
|
||||
B: 10
|
||||
C: 1100
|
||||
D: 11010
|
||||
E: 11011
|
||||
F: 11100
|
||||
G: 11101
|
||||
H: 11110
|
||||
I: 111110
|
||||
J: 111111
|
||||
|
||||
Let's make the first table three bits long (eight entries):
|
||||
|
||||
000: A,1
|
||||
001: A,1
|
||||
010: A,1
|
||||
011: A,1
|
||||
100: B,2
|
||||
101: B,2
|
||||
110: -> table X (gobble 3 bits)
|
||||
111: -> table Y (gobble 3 bits)
|
||||
|
||||
Each entry is what the bits decode as and how many bits that is, i.e. how
|
||||
many bits to gobble. Or the entry points to another table, with the number of
|
||||
bits to gobble implicit in the size of the table.
|
||||
|
||||
Table X is two bits long since the longest code starting with 110 is five bits
|
||||
long:
|
||||
|
||||
00: C,1
|
||||
01: C,1
|
||||
10: D,2
|
||||
11: E,2
|
||||
|
||||
Table Y is three bits long since the longest code starting with 111 is six
|
||||
bits long:
|
||||
|
||||
000: F,2
|
||||
001: F,2
|
||||
010: G,2
|
||||
011: G,2
|
||||
100: H,2
|
||||
101: H,2
|
||||
110: I,3
|
||||
111: J,3
|
||||
|
||||
So what we have here are three tables with a total of 20 entries that had to
|
||||
be constructed. That's compared to 64 entries for a single table. Or
|
||||
compared to 16 entries for a Huffman tree (six two entry tables and one four
|
||||
entry table). Assuming that the code ideally represents the probability of
|
||||
the symbols, it takes on the average 1.25 lookups per symbol. That's compared
|
||||
to one lookup for the single table, or 1.66 lookups per symbol for the
|
||||
Huffman tree.
|
||||
|
||||
There, I think that gives you a picture of what's going on. For inflate, the
|
||||
meaning of a particular symbol is often more than just a letter. It can be a
|
||||
byte (a "literal"), or it can be either a length or a distance which
|
||||
indicates a base value and a number of bits to fetch after the code that is
|
||||
added to the base value. Or it might be the special end-of-block code. The
|
||||
data structures created in inftrees.c try to encode all that information
|
||||
compactly in the tables.
|
||||
|
||||
|
||||
Jean-loup Gailly Mark Adler
|
||||
jloup@gzip.org madler@alumni.caltech.edu
|
||||
|
||||
|
||||
References:
|
||||
|
||||
[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
|
||||
Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
|
||||
pp. 337-343.
|
||||
|
||||
``DEFLATE Compressed Data Format Specification'' available in
|
||||
http://tools.ietf.org/html/rfc1951
|
||||
@@ -1,619 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group P. Deutsch
|
||||
Request for Comments: 1950 Aladdin Enterprises
|
||||
Category: Informational J-L. Gailly
|
||||
Info-ZIP
|
||||
May 1996
|
||||
|
||||
|
||||
ZLIB Compressed Data Format Specification version 3.3
|
||||
|
||||
Status of This Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
IESG Note:
|
||||
|
||||
The IESG takes no position on the validity of any Intellectual
|
||||
Property Rights statements contained in this document.
|
||||
|
||||
Notices
|
||||
|
||||
Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
|
||||
|
||||
Permission is granted to copy and distribute this document for any
|
||||
purpose and without charge, including translations into other
|
||||
languages and incorporation into compilations, provided that the
|
||||
copyright notice and this notice are preserved, and that any
|
||||
substantive changes or deletions from the original are clearly
|
||||
marked.
|
||||
|
||||
A pointer to the latest version of this and related documentation in
|
||||
HTML format can be found at the URL
|
||||
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
|
||||
|
||||
Abstract
|
||||
|
||||
This specification defines a lossless compressed data format. The
|
||||
data can be produced or consumed, even for an arbitrarily long
|
||||
sequentially presented input data stream, using only an a priori
|
||||
bounded amount of intermediate storage. The format presently uses
|
||||
the DEFLATE compression method but can be easily extended to use
|
||||
other compression methods. It can be implemented readily in a manner
|
||||
not covered by patents. This specification also defines the ADLER-32
|
||||
checksum (an extension and improvement of the Fletcher checksum),
|
||||
used for detection of data corruption, and provides an algorithm for
|
||||
computing it.
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 1]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Introduction ................................................... 2
|
||||
1.1. Purpose ................................................... 2
|
||||
1.2. Intended audience ......................................... 3
|
||||
1.3. Scope ..................................................... 3
|
||||
1.4. Compliance ................................................ 3
|
||||
1.5. Definitions of terms and conventions used ................ 3
|
||||
1.6. Changes from previous versions ............................ 3
|
||||
2. Detailed specification ......................................... 3
|
||||
2.1. Overall conventions ....................................... 3
|
||||
2.2. Data format ............................................... 4
|
||||
2.3. Compliance ................................................ 7
|
||||
3. References ..................................................... 7
|
||||
4. Source code .................................................... 8
|
||||
5. Security Considerations ........................................ 8
|
||||
6. Acknowledgements ............................................... 8
|
||||
7. Authors' Addresses ............................................. 8
|
||||
8. Appendix: Rationale ............................................ 9
|
||||
9. Appendix: Sample code ..........................................10
|
||||
|
||||
1. Introduction
|
||||
|
||||
1.1. Purpose
|
||||
|
||||
The purpose of this specification is to define a lossless
|
||||
compressed data format that:
|
||||
|
||||
* Is independent of CPU type, operating system, file system,
|
||||
and character set, and hence can be used for interchange;
|
||||
|
||||
* Can be produced or consumed, even for an arbitrarily long
|
||||
sequentially presented input data stream, using only an a
|
||||
priori bounded amount of intermediate storage, and hence can
|
||||
be used in data communications or similar structures such as
|
||||
Unix filters;
|
||||
|
||||
* Can use a number of different compression methods;
|
||||
|
||||
* Can be implemented readily in a manner not covered by
|
||||
patents, and hence can be practiced freely.
|
||||
|
||||
The data format defined by this specification does not attempt to
|
||||
allow random access to compressed data.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 2]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
1.2. Intended audience
|
||||
|
||||
This specification is intended for use by implementors of software
|
||||
to compress data into zlib format and/or decompress data from zlib
|
||||
format.
|
||||
|
||||
The text of the specification assumes a basic background in
|
||||
programming at the level of bits and other primitive data
|
||||
representations.
|
||||
|
||||
1.3. Scope
|
||||
|
||||
The specification specifies a compressed data format that can be
|
||||
used for in-memory compression of a sequence of arbitrary bytes.
|
||||
|
||||
1.4. Compliance
|
||||
|
||||
Unless otherwise indicated below, a compliant decompressor must be
|
||||
able to accept and decompress any data set that conforms to all
|
||||
the specifications presented here; a compliant compressor must
|
||||
produce data sets that conform to all the specifications presented
|
||||
here.
|
||||
|
||||
1.5. Definitions of terms and conventions used
|
||||
|
||||
byte: 8 bits stored or transmitted as a unit (same as an octet).
|
||||
(For this specification, a byte is exactly 8 bits, even on
|
||||
machines which store a character on a number of bits different
|
||||
from 8.) See below, for the numbering of bits within a byte.
|
||||
|
||||
1.6. Changes from previous versions
|
||||
|
||||
Version 3.1 was the first public release of this specification.
|
||||
In version 3.2, some terminology was changed and the Adler-32
|
||||
sample code was rewritten for clarity. In version 3.3, the
|
||||
support for a preset dictionary was introduced, and the
|
||||
specification was converted to RFC style.
|
||||
|
||||
2. Detailed specification
|
||||
|
||||
2.1. Overall conventions
|
||||
|
||||
In the diagrams below, a box like this:
|
||||
|
||||
+---+
|
||||
| | <-- the vertical bars might be missing
|
||||
+---+
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 3]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
represents one byte; a box like this:
|
||||
|
||||
+==============+
|
||||
| |
|
||||
+==============+
|
||||
|
||||
represents a variable number of bytes.
|
||||
|
||||
Bytes stored within a computer do not have a "bit order", since
|
||||
they are always treated as a unit. However, a byte considered as
|
||||
an integer between 0 and 255 does have a most- and least-
|
||||
significant bit, and since we write numbers with the most-
|
||||
significant digit on the left, we also write bytes with the most-
|
||||
significant bit on the left. In the diagrams below, we number the
|
||||
bits of a byte so that bit 0 is the least-significant bit, i.e.,
|
||||
the bits are numbered:
|
||||
|
||||
+--------+
|
||||
|76543210|
|
||||
+--------+
|
||||
|
||||
Within a computer, a number may occupy multiple bytes. All
|
||||
multi-byte numbers in the format described here are stored with
|
||||
the MOST-significant byte first (at the lower memory address).
|
||||
For example, the decimal number 520 is stored as:
|
||||
|
||||
0 1
|
||||
+--------+--------+
|
||||
|00000010|00001000|
|
||||
+--------+--------+
|
||||
^ ^
|
||||
| |
|
||||
| + less significant byte = 8
|
||||
+ more significant byte = 2 x 256
|
||||
|
||||
2.2. Data format
|
||||
|
||||
A zlib stream has the following structure:
|
||||
|
||||
0 1
|
||||
+---+---+
|
||||
|CMF|FLG| (more-->)
|
||||
+---+---+
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 4]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
(if FLG.FDICT set)
|
||||
|
||||
0 1 2 3
|
||||
+---+---+---+---+
|
||||
| DICTID | (more-->)
|
||||
+---+---+---+---+
|
||||
|
||||
+=====================+---+---+---+---+
|
||||
|...compressed data...| ADLER32 |
|
||||
+=====================+---+---+---+---+
|
||||
|
||||
Any data which may appear after ADLER32 are not part of the zlib
|
||||
stream.
|
||||
|
||||
CMF (Compression Method and flags)
|
||||
This byte is divided into a 4-bit compression method and a 4-
|
||||
bit information field depending on the compression method.
|
||||
|
||||
bits 0 to 3 CM Compression method
|
||||
bits 4 to 7 CINFO Compression info
|
||||
|
||||
CM (Compression method)
|
||||
This identifies the compression method used in the file. CM = 8
|
||||
denotes the "deflate" compression method with a window size up
|
||||
to 32K. This is the method used by gzip and PNG (see
|
||||
references [1] and [2] in Chapter 3, below, for the reference
|
||||
documents). CM = 15 is reserved. It might be used in a future
|
||||
version of this specification to indicate the presence of an
|
||||
extra field before the compressed data.
|
||||
|
||||
CINFO (Compression info)
|
||||
For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
|
||||
size, minus eight (CINFO=7 indicates a 32K window size). Values
|
||||
of CINFO above 7 are not allowed in this version of the
|
||||
specification. CINFO is not defined in this specification for
|
||||
CM not equal to 8.
|
||||
|
||||
FLG (FLaGs)
|
||||
This flag byte is divided as follows:
|
||||
|
||||
bits 0 to 4 FCHECK (check bits for CMF and FLG)
|
||||
bit 5 FDICT (preset dictionary)
|
||||
bits 6 to 7 FLEVEL (compression level)
|
||||
|
||||
The FCHECK value must be such that CMF and FLG, when viewed as
|
||||
a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
|
||||
is a multiple of 31.
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 5]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
FDICT (Preset dictionary)
|
||||
If FDICT is set, a DICT dictionary identifier is present
|
||||
immediately after the FLG byte. The dictionary is a sequence of
|
||||
bytes which are initially fed to the compressor without
|
||||
producing any compressed output. DICT is the Adler-32 checksum
|
||||
of this sequence of bytes (see the definition of ADLER32
|
||||
below). The decompressor can use this identifier to determine
|
||||
which dictionary has been used by the compressor.
|
||||
|
||||
FLEVEL (Compression level)
|
||||
These flags are available for use by specific compression
|
||||
methods. The "deflate" method (CM = 8) sets these flags as
|
||||
follows:
|
||||
|
||||
0 - compressor used fastest algorithm
|
||||
1 - compressor used fast algorithm
|
||||
2 - compressor used default algorithm
|
||||
3 - compressor used maximum compression, slowest algorithm
|
||||
|
||||
The information in FLEVEL is not needed for decompression; it
|
||||
is there to indicate if recompression might be worthwhile.
|
||||
|
||||
compressed data
|
||||
For compression method 8, the compressed data is stored in the
|
||||
deflate compressed data format as described in the document
|
||||
"DEFLATE Compressed Data Format Specification" by L. Peter
|
||||
Deutsch. (See reference [3] in Chapter 3, below)
|
||||
|
||||
Other compressed data formats are not specified in this version
|
||||
of the zlib specification.
|
||||
|
||||
ADLER32 (Adler-32 checksum)
|
||||
This contains a checksum value of the uncompressed data
|
||||
(excluding any dictionary data) computed according to Adler-32
|
||||
algorithm. This algorithm is a 32-bit extension and improvement
|
||||
of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
|
||||
standard. See references [4] and [5] in Chapter 3, below)
|
||||
|
||||
Adler-32 is composed of two sums accumulated per byte: s1 is
|
||||
the sum of all bytes, s2 is the sum of all s1 values. Both sums
|
||||
are done modulo 65521. s1 is initialized to 1, s2 to zero. The
|
||||
Adler-32 checksum is stored as s2*65536 + s1 in most-
|
||||
significant-byte first (network) order.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 6]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
2.3. Compliance
|
||||
|
||||
A compliant compressor must produce streams with correct CMF, FLG
|
||||
and ADLER32, but need not support preset dictionaries. When the
|
||||
zlib data format is used as part of another standard data format,
|
||||
the compressor may use only preset dictionaries that are specified
|
||||
by this other data format. If this other format does not use the
|
||||
preset dictionary feature, the compressor must not set the FDICT
|
||||
flag.
|
||||
|
||||
A compliant decompressor must check CMF, FLG, and ADLER32, and
|
||||
provide an error indication if any of these have incorrect values.
|
||||
A compliant decompressor must give an error indication if CM is
|
||||
not one of the values defined in this specification (only the
|
||||
value 8 is permitted in this version), since another value could
|
||||
indicate the presence of new features that would cause subsequent
|
||||
data to be interpreted incorrectly. A compliant decompressor must
|
||||
give an error indication if FDICT is set and DICTID is not the
|
||||
identifier of a known preset dictionary. A decompressor may
|
||||
ignore FLEVEL and still be compliant. When the zlib data format
|
||||
is being used as a part of another standard format, a compliant
|
||||
decompressor must support all the preset dictionaries specified by
|
||||
the other format. When the other format does not use the preset
|
||||
dictionary feature, a compliant decompressor must reject any
|
||||
stream in which the FDICT flag is set.
|
||||
|
||||
3. References
|
||||
|
||||
[1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
|
||||
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
|
||||
|
||||
[2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
|
||||
available in ftp://ftp.uu.net/graphics/png/documents/
|
||||
|
||||
[3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
|
||||
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
|
||||
|
||||
[4] Fletcher, J. G., "An Arithmetic Checksum for Serial
|
||||
Transmissions," IEEE Transactions on Communications, Vol. COM-30,
|
||||
No. 1, January 1982, pp. 247-252.
|
||||
|
||||
[5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
|
||||
November, 1993, pp. 144, 145. (Available from
|
||||
gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 7]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
4. Source code
|
||||
|
||||
Source code for a C language implementation of a "zlib" compliant
|
||||
library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
|
||||
|
||||
5. Security Considerations
|
||||
|
||||
A decoder that fails to check the ADLER32 checksum value may be
|
||||
subject to undetected data corruption.
|
||||
|
||||
6. Acknowledgements
|
||||
|
||||
Trademarks cited in this document are the property of their
|
||||
respective owners.
|
||||
|
||||
Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
|
||||
the related software described in this specification. Glenn
|
||||
Randers-Pehrson converted this document to RFC and HTML format.
|
||||
|
||||
7. Authors' Addresses
|
||||
|
||||
L. Peter Deutsch
|
||||
Aladdin Enterprises
|
||||
203 Santa Margarita Ave.
|
||||
Menlo Park, CA 94025
|
||||
|
||||
Phone: (415) 322-0103 (AM only)
|
||||
FAX: (415) 322-1734
|
||||
EMail: <ghost@aladdin.com>
|
||||
|
||||
|
||||
Jean-Loup Gailly
|
||||
|
||||
EMail: <gzip@prep.ai.mit.edu>
|
||||
|
||||
Questions about the technical content of this specification can be
|
||||
sent by email to
|
||||
|
||||
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
|
||||
Mark Adler <madler@alumni.caltech.edu>
|
||||
|
||||
Editorial comments on this specification can be sent by email to
|
||||
|
||||
L. Peter Deutsch <ghost@aladdin.com> and
|
||||
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 8]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
8. Appendix: Rationale
|
||||
|
||||
8.1. Preset dictionaries
|
||||
|
||||
A preset dictionary is specially useful to compress short input
|
||||
sequences. The compressor can take advantage of the dictionary
|
||||
context to encode the input in a more compact manner. The
|
||||
decompressor can be initialized with the appropriate context by
|
||||
virtually decompressing a compressed version of the dictionary
|
||||
without producing any output. However for certain compression
|
||||
algorithms such as the deflate algorithm this operation can be
|
||||
achieved without actually performing any decompression.
|
||||
|
||||
The compressor and the decompressor must use exactly the same
|
||||
dictionary. The dictionary may be fixed or may be chosen among a
|
||||
certain number of predefined dictionaries, according to the kind
|
||||
of input data. The decompressor can determine which dictionary has
|
||||
been chosen by the compressor by checking the dictionary
|
||||
identifier. This document does not specify the contents of
|
||||
predefined dictionaries, since the optimal dictionaries are
|
||||
application specific. Standard data formats using this feature of
|
||||
the zlib specification must precisely define the allowed
|
||||
dictionaries.
|
||||
|
||||
8.2. The Adler-32 algorithm
|
||||
|
||||
The Adler-32 algorithm is much faster than the CRC32 algorithm yet
|
||||
still provides an extremely low probability of undetected errors.
|
||||
|
||||
The modulo on unsigned long accumulators can be delayed for 5552
|
||||
bytes, so the modulo operation time is negligible. If the bytes
|
||||
are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
|
||||
and order sensitive, unlike the first sum, which is just a
|
||||
checksum. That 65521 is prime is important to avoid a possible
|
||||
large class of two-byte errors that leave the check unchanged.
|
||||
(The Fletcher checksum uses 255, which is not prime and which also
|
||||
makes the Fletcher check insensitive to single byte changes 0 <->
|
||||
255.)
|
||||
|
||||
The sum s1 is initialized to 1 instead of zero to make the length
|
||||
of the sequence part of s2, so that the length does not have to be
|
||||
checked separately. (Any sequence of zeroes has a Fletcher
|
||||
checksum of zero.)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 9]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
9. Appendix: Sample code
|
||||
|
||||
The following C code computes the Adler-32 checksum of a data buffer.
|
||||
It is written for clarity, not for speed. The sample code is in the
|
||||
ANSI C programming language. Non C users may find it easier to read
|
||||
with these hints:
|
||||
|
||||
& Bitwise AND operator.
|
||||
>> Bitwise right shift operator. When applied to an
|
||||
unsigned quantity, as here, right shift inserts zero bit(s)
|
||||
at the left.
|
||||
<< Bitwise left shift operator. Left shift inserts zero
|
||||
bit(s) at the right.
|
||||
++ "n++" increments the variable n.
|
||||
% modulo operator: a % b is the remainder of a divided by b.
|
||||
|
||||
#define BASE 65521 /* largest prime smaller than 65536 */
|
||||
|
||||
/*
|
||||
Update a running Adler-32 checksum with the bytes buf[0..len-1]
|
||||
and return the updated checksum. The Adler-32 checksum should be
|
||||
initialized to 1.
|
||||
|
||||
Usage example:
|
||||
|
||||
unsigned long adler = 1L;
|
||||
|
||||
while (read_buffer(buffer, length) != EOF) {
|
||||
adler = update_adler32(adler, buffer, length);
|
||||
}
|
||||
if (adler != original_adler) error();
|
||||
*/
|
||||
unsigned long update_adler32(unsigned long adler,
|
||||
unsigned char *buf, int len)
|
||||
{
|
||||
unsigned long s1 = adler & 0xffff;
|
||||
unsigned long s2 = (adler >> 16) & 0xffff;
|
||||
int n;
|
||||
|
||||
for (n = 0; n < len; n++) {
|
||||
s1 = (s1 + buf[n]) % BASE;
|
||||
s2 = (s2 + s1) % BASE;
|
||||
}
|
||||
return (s2 << 16) + s1;
|
||||
}
|
||||
|
||||
/* Return the adler32 of the bytes buf[0..len-1] */
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 10]
|
||||
|
||||
RFC 1950 ZLIB Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
unsigned long adler32(unsigned char *buf, int len)
|
||||
{
|
||||
return update_adler32(1L, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch & Gailly Informational [Page 11]
|
||||
|
||||
@@ -1,955 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group P. Deutsch
|
||||
Request for Comments: 1951 Aladdin Enterprises
|
||||
Category: Informational May 1996
|
||||
|
||||
|
||||
DEFLATE Compressed Data Format Specification version 1.3
|
||||
|
||||
Status of This Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
IESG Note:
|
||||
|
||||
The IESG takes no position on the validity of any Intellectual
|
||||
Property Rights statements contained in this document.
|
||||
|
||||
Notices
|
||||
|
||||
Copyright (c) 1996 L. Peter Deutsch
|
||||
|
||||
Permission is granted to copy and distribute this document for any
|
||||
purpose and without charge, including translations into other
|
||||
languages and incorporation into compilations, provided that the
|
||||
copyright notice and this notice are preserved, and that any
|
||||
substantive changes or deletions from the original are clearly
|
||||
marked.
|
||||
|
||||
A pointer to the latest version of this and related documentation in
|
||||
HTML format can be found at the URL
|
||||
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
|
||||
|
||||
Abstract
|
||||
|
||||
This specification defines a lossless compressed data format that
|
||||
compresses data using a combination of the LZ77 algorithm and Huffman
|
||||
coding, with efficiency comparable to the best currently available
|
||||
general-purpose compression methods. The data can be produced or
|
||||
consumed, even for an arbitrarily long sequentially presented input
|
||||
data stream, using only an a priori bounded amount of intermediate
|
||||
storage. The format can be implemented readily in a manner not
|
||||
covered by patents.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 1]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Introduction ................................................... 2
|
||||
1.1. Purpose ................................................... 2
|
||||
1.2. Intended audience ......................................... 3
|
||||
1.3. Scope ..................................................... 3
|
||||
1.4. Compliance ................................................ 3
|
||||
1.5. Definitions of terms and conventions used ................ 3
|
||||
1.6. Changes from previous versions ............................ 4
|
||||
2. Compressed representation overview ............................. 4
|
||||
3. Detailed specification ......................................... 5
|
||||
3.1. Overall conventions ....................................... 5
|
||||
3.1.1. Packing into bytes .................................. 5
|
||||
3.2. Compressed block format ................................... 6
|
||||
3.2.1. Synopsis of prefix and Huffman coding ............... 6
|
||||
3.2.2. Use of Huffman coding in the "deflate" format ....... 7
|
||||
3.2.3. Details of block format ............................. 9
|
||||
3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
|
||||
3.2.5. Compressed blocks (length and distance codes) ...... 11
|
||||
3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
|
||||
3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
|
||||
3.3. Compliance ............................................... 14
|
||||
4. Compression algorithm details ................................. 14
|
||||
5. References .................................................... 16
|
||||
6. Security Considerations ....................................... 16
|
||||
7. Source code ................................................... 16
|
||||
8. Acknowledgements .............................................. 16
|
||||
9. Author's Address .............................................. 17
|
||||
|
||||
1. Introduction
|
||||
|
||||
1.1. Purpose
|
||||
|
||||
The purpose of this specification is to define a lossless
|
||||
compressed data format that:
|
||||
* Is independent of CPU type, operating system, file system,
|
||||
and character set, and hence can be used for interchange;
|
||||
* Can be produced or consumed, even for an arbitrarily long
|
||||
sequentially presented input data stream, using only an a
|
||||
priori bounded amount of intermediate storage, and hence
|
||||
can be used in data communications or similar structures
|
||||
such as Unix filters;
|
||||
* Compresses data with efficiency comparable to the best
|
||||
currently available general-purpose compression methods,
|
||||
and in particular considerably better than the "compress"
|
||||
program;
|
||||
* Can be implemented readily in a manner not covered by
|
||||
patents, and hence can be practiced freely;
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 2]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
* Is compatible with the file format produced by the current
|
||||
widely used gzip utility, in that conforming decompressors
|
||||
will be able to read data produced by the existing gzip
|
||||
compressor.
|
||||
|
||||
The data format defined by this specification does not attempt to:
|
||||
|
||||
* Allow random access to compressed data;
|
||||
* Compress specialized data (e.g., raster graphics) as well
|
||||
as the best currently available specialized algorithms.
|
||||
|
||||
A simple counting argument shows that no lossless compression
|
||||
algorithm can compress every possible input data set. For the
|
||||
format defined here, the worst case expansion is 5 bytes per 32K-
|
||||
byte block, i.e., a size increase of 0.015% for large data sets.
|
||||
English text usually compresses by a factor of 2.5 to 3;
|
||||
executable files usually compress somewhat less; graphical data
|
||||
such as raster images may compress much more.
|
||||
|
||||
1.2. Intended audience
|
||||
|
||||
This specification is intended for use by implementors of software
|
||||
to compress data into "deflate" format and/or decompress data from
|
||||
"deflate" format.
|
||||
|
||||
The text of the specification assumes a basic background in
|
||||
programming at the level of bits and other primitive data
|
||||
representations. Familiarity with the technique of Huffman coding
|
||||
is helpful but not required.
|
||||
|
||||
1.3. Scope
|
||||
|
||||
The specification specifies a method for representing a sequence
|
||||
of bytes as a (usually shorter) sequence of bits, and a method for
|
||||
packing the latter bit sequence into bytes.
|
||||
|
||||
1.4. Compliance
|
||||
|
||||
Unless otherwise indicated below, a compliant decompressor must be
|
||||
able to accept and decompress any data set that conforms to all
|
||||
the specifications presented here; a compliant compressor must
|
||||
produce data sets that conform to all the specifications presented
|
||||
here.
|
||||
|
||||
1.5. Definitions of terms and conventions used
|
||||
|
||||
Byte: 8 bits stored or transmitted as a unit (same as an octet).
|
||||
For this specification, a byte is exactly 8 bits, even on machines
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 3]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
which store a character on a number of bits different from eight.
|
||||
See below, for the numbering of bits within a byte.
|
||||
|
||||
String: a sequence of arbitrary bytes.
|
||||
|
||||
1.6. Changes from previous versions
|
||||
|
||||
There have been no technical changes to the deflate format since
|
||||
version 1.1 of this specification. In version 1.2, some
|
||||
terminology was changed. Version 1.3 is a conversion of the
|
||||
specification to RFC style.
|
||||
|
||||
2. Compressed representation overview
|
||||
|
||||
A compressed data set consists of a series of blocks, corresponding
|
||||
to successive blocks of input data. The block sizes are arbitrary,
|
||||
except that non-compressible blocks are limited to 65,535 bytes.
|
||||
|
||||
Each block is compressed using a combination of the LZ77 algorithm
|
||||
and Huffman coding. The Huffman trees for each block are independent
|
||||
of those for previous or subsequent blocks; the LZ77 algorithm may
|
||||
use a reference to a duplicated string occurring in a previous block,
|
||||
up to 32K input bytes before.
|
||||
|
||||
Each block consists of two parts: a pair of Huffman code trees that
|
||||
describe the representation of the compressed data part, and a
|
||||
compressed data part. (The Huffman trees themselves are compressed
|
||||
using Huffman encoding.) The compressed data consists of a series of
|
||||
elements of two types: literal bytes (of strings that have not been
|
||||
detected as duplicated within the previous 32K input bytes), and
|
||||
pointers to duplicated strings, where a pointer is represented as a
|
||||
pair <length, backward distance>. The representation used in the
|
||||
"deflate" format limits distances to 32K bytes and lengths to 258
|
||||
bytes, but does not limit the size of a block, except for
|
||||
uncompressible blocks, which are limited as noted above.
|
||||
|
||||
Each type of value (literals, distances, and lengths) in the
|
||||
compressed data is represented using a Huffman code, using one code
|
||||
tree for literals and lengths and a separate code tree for distances.
|
||||
The code trees for each block appear in a compact form just before
|
||||
the compressed data for that block.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 4]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
3. Detailed specification
|
||||
|
||||
3.1. Overall conventions In the diagrams below, a box like this:
|
||||
|
||||
+---+
|
||||
| | <-- the vertical bars might be missing
|
||||
+---+
|
||||
|
||||
represents one byte; a box like this:
|
||||
|
||||
+==============+
|
||||
| |
|
||||
+==============+
|
||||
|
||||
represents a variable number of bytes.
|
||||
|
||||
Bytes stored within a computer do not have a "bit order", since
|
||||
they are always treated as a unit. However, a byte considered as
|
||||
an integer between 0 and 255 does have a most- and least-
|
||||
significant bit, and since we write numbers with the most-
|
||||
significant digit on the left, we also write bytes with the most-
|
||||
significant bit on the left. In the diagrams below, we number the
|
||||
bits of a byte so that bit 0 is the least-significant bit, i.e.,
|
||||
the bits are numbered:
|
||||
|
||||
+--------+
|
||||
|76543210|
|
||||
+--------+
|
||||
|
||||
Within a computer, a number may occupy multiple bytes. All
|
||||
multi-byte numbers in the format described here are stored with
|
||||
the least-significant byte first (at the lower memory address).
|
||||
For example, the decimal number 520 is stored as:
|
||||
|
||||
0 1
|
||||
+--------+--------+
|
||||
|00001000|00000010|
|
||||
+--------+--------+
|
||||
^ ^
|
||||
| |
|
||||
| + more significant byte = 2 x 256
|
||||
+ less significant byte = 8
|
||||
|
||||
3.1.1. Packing into bytes
|
||||
|
||||
This document does not address the issue of the order in which
|
||||
bits of a byte are transmitted on a bit-sequential medium,
|
||||
since the final data format described here is byte- rather than
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 5]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
bit-oriented. However, we describe the compressed block format
|
||||
in below, as a sequence of data elements of various bit
|
||||
lengths, not a sequence of bytes. We must therefore specify
|
||||
how to pack these data elements into bytes to form the final
|
||||
compressed byte sequence:
|
||||
|
||||
* Data elements are packed into bytes in order of
|
||||
increasing bit number within the byte, i.e., starting
|
||||
with the least-significant bit of the byte.
|
||||
* Data elements other than Huffman codes are packed
|
||||
starting with the least-significant bit of the data
|
||||
element.
|
||||
* Huffman codes are packed starting with the most-
|
||||
significant bit of the code.
|
||||
|
||||
In other words, if one were to print out the compressed data as
|
||||
a sequence of bytes, starting with the first byte at the
|
||||
*right* margin and proceeding to the *left*, with the most-
|
||||
significant bit of each byte on the left as usual, one would be
|
||||
able to parse the result from right to left, with fixed-width
|
||||
elements in the correct MSB-to-LSB order and Huffman codes in
|
||||
bit-reversed order (i.e., with the first bit of the code in the
|
||||
relative LSB position).
|
||||
|
||||
3.2. Compressed block format
|
||||
|
||||
3.2.1. Synopsis of prefix and Huffman coding
|
||||
|
||||
Prefix coding represents symbols from an a priori known
|
||||
alphabet by bit sequences (codes), one code for each symbol, in
|
||||
a manner such that different symbols may be represented by bit
|
||||
sequences of different lengths, but a parser can always parse
|
||||
an encoded string unambiguously symbol-by-symbol.
|
||||
|
||||
We define a prefix code in terms of a binary tree in which the
|
||||
two edges descending from each non-leaf node are labeled 0 and
|
||||
1 and in which the leaf nodes correspond one-for-one with (are
|
||||
labeled with) the symbols of the alphabet; then the code for a
|
||||
symbol is the sequence of 0's and 1's on the edges leading from
|
||||
the root to the leaf labeled with that symbol. For example:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 6]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
/\ Symbol Code
|
||||
0 1 ------ ----
|
||||
/ \ A 00
|
||||
/\ B B 1
|
||||
0 1 C 011
|
||||
/ \ D 010
|
||||
A /\
|
||||
0 1
|
||||
/ \
|
||||
D C
|
||||
|
||||
A parser can decode the next symbol from an encoded input
|
||||
stream by walking down the tree from the root, at each step
|
||||
choosing the edge corresponding to the next input bit.
|
||||
|
||||
Given an alphabet with known symbol frequencies, the Huffman
|
||||
algorithm allows the construction of an optimal prefix code
|
||||
(one which represents strings with those symbol frequencies
|
||||
using the fewest bits of any possible prefix codes for that
|
||||
alphabet). Such a code is called a Huffman code. (See
|
||||
reference [1] in Chapter 5, references for additional
|
||||
information on Huffman codes.)
|
||||
|
||||
Note that in the "deflate" format, the Huffman codes for the
|
||||
various alphabets must not exceed certain maximum code lengths.
|
||||
This constraint complicates the algorithm for computing code
|
||||
lengths from symbol frequencies. Again, see Chapter 5,
|
||||
references for details.
|
||||
|
||||
3.2.2. Use of Huffman coding in the "deflate" format
|
||||
|
||||
The Huffman codes used for each alphabet in the "deflate"
|
||||
format have two additional rules:
|
||||
|
||||
* All codes of a given bit length have lexicographically
|
||||
consecutive values, in the same order as the symbols
|
||||
they represent;
|
||||
|
||||
* Shorter codes lexicographically precede longer codes.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 7]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
We could recode the example above to follow this rule as
|
||||
follows, assuming that the order of the alphabet is ABCD:
|
||||
|
||||
Symbol Code
|
||||
------ ----
|
||||
A 10
|
||||
B 0
|
||||
C 110
|
||||
D 111
|
||||
|
||||
I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
|
||||
lexicographically consecutive.
|
||||
|
||||
Given this rule, we can define the Huffman code for an alphabet
|
||||
just by giving the bit lengths of the codes for each symbol of
|
||||
the alphabet in order; this is sufficient to determine the
|
||||
actual codes. In our example, the code is completely defined
|
||||
by the sequence of bit lengths (2, 1, 3, 3). The following
|
||||
algorithm generates the codes as integers, intended to be read
|
||||
from most- to least-significant bit. The code lengths are
|
||||
initially in tree[I].Len; the codes are produced in
|
||||
tree[I].Code.
|
||||
|
||||
1) Count the number of codes for each code length. Let
|
||||
bl_count[N] be the number of codes of length N, N >= 1.
|
||||
|
||||
2) Find the numerical value of the smallest code for each
|
||||
code length:
|
||||
|
||||
code = 0;
|
||||
bl_count[0] = 0;
|
||||
for (bits = 1; bits <= MAX_BITS; bits++) {
|
||||
code = (code + bl_count[bits-1]) << 1;
|
||||
next_code[bits] = code;
|
||||
}
|
||||
|
||||
3) Assign numerical values to all codes, using consecutive
|
||||
values for all codes of the same length with the base
|
||||
values determined at step 2. Codes that are never used
|
||||
(which have a bit length of zero) must not be assigned a
|
||||
value.
|
||||
|
||||
for (n = 0; n <= max_code; n++) {
|
||||
len = tree[n].Len;
|
||||
if (len != 0) {
|
||||
tree[n].Code = next_code[len];
|
||||
next_code[len]++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 8]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
}
|
||||
|
||||
Example:
|
||||
|
||||
Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
|
||||
3, 2, 4, 4). After step 1, we have:
|
||||
|
||||
N bl_count[N]
|
||||
- -----------
|
||||
2 1
|
||||
3 5
|
||||
4 2
|
||||
|
||||
Step 2 computes the following next_code values:
|
||||
|
||||
N next_code[N]
|
||||
- ------------
|
||||
1 0
|
||||
2 0
|
||||
3 2
|
||||
4 14
|
||||
|
||||
Step 3 produces the following code values:
|
||||
|
||||
Symbol Length Code
|
||||
------ ------ ----
|
||||
A 3 010
|
||||
B 3 011
|
||||
C 3 100
|
||||
D 3 101
|
||||
E 3 110
|
||||
F 2 00
|
||||
G 4 1110
|
||||
H 4 1111
|
||||
|
||||
3.2.3. Details of block format
|
||||
|
||||
Each block of compressed data begins with 3 header bits
|
||||
containing the following data:
|
||||
|
||||
first bit BFINAL
|
||||
next 2 bits BTYPE
|
||||
|
||||
Note that the header bits do not necessarily begin on a byte
|
||||
boundary, since a block does not necessarily occupy an integral
|
||||
number of bytes.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 9]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
BFINAL is set if and only if this is the last block of the data
|
||||
set.
|
||||
|
||||
BTYPE specifies how the data are compressed, as follows:
|
||||
|
||||
00 - no compression
|
||||
01 - compressed with fixed Huffman codes
|
||||
10 - compressed with dynamic Huffman codes
|
||||
11 - reserved (error)
|
||||
|
||||
The only difference between the two compressed cases is how the
|
||||
Huffman codes for the literal/length and distance alphabets are
|
||||
defined.
|
||||
|
||||
In all cases, the decoding algorithm for the actual data is as
|
||||
follows:
|
||||
|
||||
do
|
||||
read block header from input stream.
|
||||
if stored with no compression
|
||||
skip any remaining bits in current partially
|
||||
processed byte
|
||||
read LEN and NLEN (see next section)
|
||||
copy LEN bytes of data to output
|
||||
otherwise
|
||||
if compressed with dynamic Huffman codes
|
||||
read representation of code trees (see
|
||||
subsection below)
|
||||
loop (until end of block code recognized)
|
||||
decode literal/length value from input stream
|
||||
if value < 256
|
||||
copy value (literal byte) to output stream
|
||||
otherwise
|
||||
if value = end of block (256)
|
||||
break from loop
|
||||
otherwise (value = 257..285)
|
||||
decode distance from input stream
|
||||
|
||||
move backwards distance bytes in the output
|
||||
stream, and copy length bytes from this
|
||||
position to the output stream.
|
||||
end loop
|
||||
while not last block
|
||||
|
||||
Note that a duplicated string reference may refer to a string
|
||||
in a previous block; i.e., the backward distance may cross one
|
||||
or more block boundaries. However a distance cannot refer past
|
||||
the beginning of the output stream. (An application using a
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 10]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
preset dictionary might discard part of the output stream; a
|
||||
distance can refer to that part of the output stream anyway)
|
||||
Note also that the referenced string may overlap the current
|
||||
position; for example, if the last 2 bytes decoded have values
|
||||
X and Y, a string reference with <length = 5, distance = 2>
|
||||
adds X,Y,X,Y,X to the output stream.
|
||||
|
||||
We now specify each compression method in turn.
|
||||
|
||||
3.2.4. Non-compressed blocks (BTYPE=00)
|
||||
|
||||
Any bits of input up to the next byte boundary are ignored.
|
||||
The rest of the block consists of the following information:
|
||||
|
||||
0 1 2 3 4...
|
||||
+---+---+---+---+================================+
|
||||
| LEN | NLEN |... LEN bytes of literal data...|
|
||||
+---+---+---+---+================================+
|
||||
|
||||
LEN is the number of data bytes in the block. NLEN is the
|
||||
one's complement of LEN.
|
||||
|
||||
3.2.5. Compressed blocks (length and distance codes)
|
||||
|
||||
As noted above, encoded data blocks in the "deflate" format
|
||||
consist of sequences of symbols drawn from three conceptually
|
||||
distinct alphabets: either literal bytes, from the alphabet of
|
||||
byte values (0..255), or <length, backward distance> pairs,
|
||||
where the length is drawn from (3..258) and the distance is
|
||||
drawn from (1..32,768). In fact, the literal and length
|
||||
alphabets are merged into a single alphabet (0..285), where
|
||||
values 0..255 represent literal bytes, the value 256 indicates
|
||||
end-of-block, and values 257..285 represent length codes
|
||||
(possibly in conjunction with extra bits following the symbol
|
||||
code) as follows:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 11]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
Extra Extra Extra
|
||||
Code Bits Length(s) Code Bits Lengths Code Bits Length(s)
|
||||
---- ---- ------ ---- ---- ------- ---- ---- -------
|
||||
257 0 3 267 1 15,16 277 4 67-82
|
||||
258 0 4 268 1 17,18 278 4 83-98
|
||||
259 0 5 269 2 19-22 279 4 99-114
|
||||
260 0 6 270 2 23-26 280 4 115-130
|
||||
261 0 7 271 2 27-30 281 5 131-162
|
||||
262 0 8 272 2 31-34 282 5 163-194
|
||||
263 0 9 273 3 35-42 283 5 195-226
|
||||
264 0 10 274 3 43-50 284 5 227-257
|
||||
265 1 11,12 275 3 51-58 285 0 258
|
||||
266 1 13,14 276 3 59-66
|
||||
|
||||
The extra bits should be interpreted as a machine integer
|
||||
stored with the most-significant bit first, e.g., bits 1110
|
||||
represent the value 14.
|
||||
|
||||
Extra Extra Extra
|
||||
Code Bits Dist Code Bits Dist Code Bits Distance
|
||||
---- ---- ---- ---- ---- ------ ---- ---- --------
|
||||
0 0 1 10 4 33-48 20 9 1025-1536
|
||||
1 0 2 11 4 49-64 21 9 1537-2048
|
||||
2 0 3 12 5 65-96 22 10 2049-3072
|
||||
3 0 4 13 5 97-128 23 10 3073-4096
|
||||
4 1 5,6 14 6 129-192 24 11 4097-6144
|
||||
5 1 7,8 15 6 193-256 25 11 6145-8192
|
||||
6 2 9-12 16 7 257-384 26 12 8193-12288
|
||||
7 2 13-16 17 7 385-512 27 12 12289-16384
|
||||
8 3 17-24 18 8 513-768 28 13 16385-24576
|
||||
9 3 25-32 19 8 769-1024 29 13 24577-32768
|
||||
|
||||
3.2.6. Compression with fixed Huffman codes (BTYPE=01)
|
||||
|
||||
The Huffman codes for the two alphabets are fixed, and are not
|
||||
represented explicitly in the data. The Huffman code lengths
|
||||
for the literal/length alphabet are:
|
||||
|
||||
Lit Value Bits Codes
|
||||
--------- ---- -----
|
||||
0 - 143 8 00110000 through
|
||||
10111111
|
||||
144 - 255 9 110010000 through
|
||||
111111111
|
||||
256 - 279 7 0000000 through
|
||||
0010111
|
||||
280 - 287 8 11000000 through
|
||||
11000111
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 12]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
The code lengths are sufficient to generate the actual codes,
|
||||
as described above; we show the codes in the table for added
|
||||
clarity. Literal/length values 286-287 will never actually
|
||||
occur in the compressed data, but participate in the code
|
||||
construction.
|
||||
|
||||
Distance codes 0-31 are represented by (fixed-length) 5-bit
|
||||
codes, with possible additional bits as shown in the table
|
||||
shown in Paragraph 3.2.5, above. Note that distance codes 30-
|
||||
31 will never actually occur in the compressed data.
|
||||
|
||||
3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
|
||||
|
||||
The Huffman codes for the two alphabets appear in the block
|
||||
immediately after the header bits and before the actual
|
||||
compressed data, first the literal/length code and then the
|
||||
distance code. Each code is defined by a sequence of code
|
||||
lengths, as discussed in Paragraph 3.2.2, above. For even
|
||||
greater compactness, the code length sequences themselves are
|
||||
compressed using a Huffman code. The alphabet for code lengths
|
||||
is as follows:
|
||||
|
||||
0 - 15: Represent code lengths of 0 - 15
|
||||
16: Copy the previous code length 3 - 6 times.
|
||||
The next 2 bits indicate repeat length
|
||||
(0 = 3, ... , 3 = 6)
|
||||
Example: Codes 8, 16 (+2 bits 11),
|
||||
16 (+2 bits 10) will expand to
|
||||
12 code lengths of 8 (1 + 6 + 5)
|
||||
17: Repeat a code length of 0 for 3 - 10 times.
|
||||
(3 bits of length)
|
||||
18: Repeat a code length of 0 for 11 - 138 times
|
||||
(7 bits of length)
|
||||
|
||||
A code length of 0 indicates that the corresponding symbol in
|
||||
the literal/length or distance alphabet will not occur in the
|
||||
block, and should not participate in the Huffman code
|
||||
construction algorithm given earlier. If only one distance
|
||||
code is used, it is encoded using one bit, not zero bits; in
|
||||
this case there is a single code length of one, with one unused
|
||||
code. One distance code of zero bits means that there are no
|
||||
distance codes used at all (the data is all literals).
|
||||
|
||||
We can now define the format of the block:
|
||||
|
||||
5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
|
||||
5 Bits: HDIST, # of Distance codes - 1 (1 - 32)
|
||||
4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19)
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 13]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
(HCLEN + 4) x 3 bits: code lengths for the code length
|
||||
alphabet given just above, in the order: 16, 17, 18,
|
||||
0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
|
||||
|
||||
These code lengths are interpreted as 3-bit integers
|
||||
(0-7); as above, a code length of 0 means the
|
||||
corresponding symbol (literal/length or distance code
|
||||
length) is not used.
|
||||
|
||||
HLIT + 257 code lengths for the literal/length alphabet,
|
||||
encoded using the code length Huffman code
|
||||
|
||||
HDIST + 1 code lengths for the distance alphabet,
|
||||
encoded using the code length Huffman code
|
||||
|
||||
The actual compressed data of the block,
|
||||
encoded using the literal/length and distance Huffman
|
||||
codes
|
||||
|
||||
The literal/length symbol 256 (end of data),
|
||||
encoded using the literal/length Huffman code
|
||||
|
||||
The code length repeat codes can cross from HLIT + 257 to the
|
||||
HDIST + 1 code lengths. In other words, all code lengths form
|
||||
a single sequence of HLIT + HDIST + 258 values.
|
||||
|
||||
3.3. Compliance
|
||||
|
||||
A compressor may limit further the ranges of values specified in
|
||||
the previous section and still be compliant; for example, it may
|
||||
limit the range of backward pointers to some value smaller than
|
||||
32K. Similarly, a compressor may limit the size of blocks so that
|
||||
a compressible block fits in memory.
|
||||
|
||||
A compliant decompressor must accept the full range of possible
|
||||
values defined in the previous section, and must accept blocks of
|
||||
arbitrary size.
|
||||
|
||||
4. Compression algorithm details
|
||||
|
||||
While it is the intent of this document to define the "deflate"
|
||||
compressed data format without reference to any particular
|
||||
compression algorithm, the format is related to the compressed
|
||||
formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
|
||||
since many variations of LZ77 are patented, it is strongly
|
||||
recommended that the implementor of a compressor follow the general
|
||||
algorithm presented here, which is known not to be patented per se.
|
||||
The material in this section is not part of the definition of the
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 14]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
specification per se, and a compressor need not follow it in order to
|
||||
be compliant.
|
||||
|
||||
The compressor terminates a block when it determines that starting a
|
||||
new block with fresh trees would be useful, or when the block size
|
||||
fills up the compressor's block buffer.
|
||||
|
||||
The compressor uses a chained hash table to find duplicated strings,
|
||||
using a hash function that operates on 3-byte sequences. At any
|
||||
given point during compression, let XYZ be the next 3 input bytes to
|
||||
be examined (not necessarily all different, of course). First, the
|
||||
compressor examines the hash chain for XYZ. If the chain is empty,
|
||||
the compressor simply writes out X as a literal byte and advances one
|
||||
byte in the input. If the hash chain is not empty, indicating that
|
||||
the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
|
||||
same hash function value) has occurred recently, the compressor
|
||||
compares all strings on the XYZ hash chain with the actual input data
|
||||
sequence starting at the current point, and selects the longest
|
||||
match.
|
||||
|
||||
The compressor searches the hash chains starting with the most recent
|
||||
strings, to favor small distances and thus take advantage of the
|
||||
Huffman encoding. The hash chains are singly linked. There are no
|
||||
deletions from the hash chains; the algorithm simply discards matches
|
||||
that are too old. To avoid a worst-case situation, very long hash
|
||||
chains are arbitrarily truncated at a certain length, determined by a
|
||||
run-time parameter.
|
||||
|
||||
To improve overall compression, the compressor optionally defers the
|
||||
selection of matches ("lazy matching"): after a match of length N has
|
||||
been found, the compressor searches for a longer match starting at
|
||||
the next input byte. If it finds a longer match, it truncates the
|
||||
previous match to a length of one (thus producing a single literal
|
||||
byte) and then emits the longer match. Otherwise, it emits the
|
||||
original match, and, as described above, advances N bytes before
|
||||
continuing.
|
||||
|
||||
Run-time parameters also control this "lazy match" procedure. If
|
||||
compression ratio is most important, the compressor attempts a
|
||||
complete second search regardless of the length of the first match.
|
||||
In the normal case, if the current match is "long enough", the
|
||||
compressor reduces the search for a longer match, thus speeding up
|
||||
the process. If speed is most important, the compressor inserts new
|
||||
strings in the hash table only when no match was found, or when the
|
||||
match is not "too long". This degrades the compression ratio but
|
||||
saves time since there are both fewer insertions and fewer searches.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 15]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
5. References
|
||||
|
||||
[1] Huffman, D. A., "A Method for the Construction of Minimum
|
||||
Redundancy Codes", Proceedings of the Institute of Radio
|
||||
Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
|
||||
|
||||
[2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
|
||||
Compression", IEEE Transactions on Information Theory, Vol. 23,
|
||||
No. 3, pp. 337-343.
|
||||
|
||||
[3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
|
||||
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
|
||||
|
||||
[4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
|
||||
available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
|
||||
|
||||
[5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
|
||||
encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
|
||||
|
||||
[6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
|
||||
Comm. ACM, 33,4, April 1990, pp. 449-459.
|
||||
|
||||
6. Security Considerations
|
||||
|
||||
Any data compression method involves the reduction of redundancy in
|
||||
the data. Consequently, any corruption of the data is likely to have
|
||||
severe effects and be difficult to correct. Uncompressed text, on
|
||||
the other hand, will probably still be readable despite the presence
|
||||
of some corrupted bytes.
|
||||
|
||||
It is recommended that systems using this data format provide some
|
||||
means of validating the integrity of the compressed data. See
|
||||
reference [3], for example.
|
||||
|
||||
7. Source code
|
||||
|
||||
Source code for a C language implementation of a "deflate" compliant
|
||||
compressor and decompressor is available within the zlib package at
|
||||
ftp://ftp.uu.net/pub/archiving/zip/zlib/.
|
||||
|
||||
8. Acknowledgements
|
||||
|
||||
Trademarks cited in this document are the property of their
|
||||
respective owners.
|
||||
|
||||
Phil Katz designed the deflate format. Jean-Loup Gailly and Mark
|
||||
Adler wrote the related software described in this specification.
|
||||
Glenn Randers-Pehrson converted this document to RFC and HTML format.
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 16]
|
||||
|
||||
RFC 1951 DEFLATE Compressed Data Format Specification May 1996
|
||||
|
||||
|
||||
9. Author's Address
|
||||
|
||||
L. Peter Deutsch
|
||||
Aladdin Enterprises
|
||||
203 Santa Margarita Ave.
|
||||
Menlo Park, CA 94025
|
||||
|
||||
Phone: (415) 322-0103 (AM only)
|
||||
FAX: (415) 322-1734
|
||||
EMail: <ghost@aladdin.com>
|
||||
|
||||
Questions about the technical content of this specification can be
|
||||
sent by email to:
|
||||
|
||||
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
|
||||
Mark Adler <madler@alumni.caltech.edu>
|
||||
|
||||
Editorial comments on this specification can be sent by email to:
|
||||
|
||||
L. Peter Deutsch <ghost@aladdin.com> and
|
||||
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 17]
|
||||
|
||||
@@ -1,675 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Network Working Group P. Deutsch
|
||||
Request for Comments: 1952 Aladdin Enterprises
|
||||
Category: Informational May 1996
|
||||
|
||||
|
||||
GZIP file format specification version 4.3
|
||||
|
||||
Status of This Memo
|
||||
|
||||
This memo provides information for the Internet community. This memo
|
||||
does not specify an Internet standard of any kind. Distribution of
|
||||
this memo is unlimited.
|
||||
|
||||
IESG Note:
|
||||
|
||||
The IESG takes no position on the validity of any Intellectual
|
||||
Property Rights statements contained in this document.
|
||||
|
||||
Notices
|
||||
|
||||
Copyright (c) 1996 L. Peter Deutsch
|
||||
|
||||
Permission is granted to copy and distribute this document for any
|
||||
purpose and without charge, including translations into other
|
||||
languages and incorporation into compilations, provided that the
|
||||
copyright notice and this notice are preserved, and that any
|
||||
substantive changes or deletions from the original are clearly
|
||||
marked.
|
||||
|
||||
A pointer to the latest version of this and related documentation in
|
||||
HTML format can be found at the URL
|
||||
<ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
|
||||
|
||||
Abstract
|
||||
|
||||
This specification defines a lossless compressed data format that is
|
||||
compatible with the widely used GZIP utility. The format includes a
|
||||
cyclic redundancy check value for detecting data corruption. The
|
||||
format presently uses the DEFLATE method of compression but can be
|
||||
easily extended to use other compression methods. The format can be
|
||||
implemented readily in a manner not covered by patents.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 1]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
Table of Contents
|
||||
|
||||
1. Introduction ................................................... 2
|
||||
1.1. Purpose ................................................... 2
|
||||
1.2. Intended audience ......................................... 3
|
||||
1.3. Scope ..................................................... 3
|
||||
1.4. Compliance ................................................ 3
|
||||
1.5. Definitions of terms and conventions used ................. 3
|
||||
1.6. Changes from previous versions ............................ 3
|
||||
2. Detailed specification ......................................... 4
|
||||
2.1. Overall conventions ....................................... 4
|
||||
2.2. File format ............................................... 5
|
||||
2.3. Member format ............................................. 5
|
||||
2.3.1. Member header and trailer ........................... 6
|
||||
2.3.1.1. Extra field ................................... 8
|
||||
2.3.1.2. Compliance .................................... 9
|
||||
3. References .................................................. 9
|
||||
4. Security Considerations .................................... 10
|
||||
5. Acknowledgements ........................................... 10
|
||||
6. Author's Address ........................................... 10
|
||||
7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
|
||||
8. Appendix: Sample CRC Code .................................. 11
|
||||
|
||||
1. Introduction
|
||||
|
||||
1.1. Purpose
|
||||
|
||||
The purpose of this specification is to define a lossless
|
||||
compressed data format that:
|
||||
|
||||
* Is independent of CPU type, operating system, file system,
|
||||
and character set, and hence can be used for interchange;
|
||||
* Can compress or decompress a data stream (as opposed to a
|
||||
randomly accessible file) to produce another data stream,
|
||||
using only an a priori bounded amount of intermediate
|
||||
storage, and hence can be used in data communications or
|
||||
similar structures such as Unix filters;
|
||||
* Compresses data with efficiency comparable to the best
|
||||
currently available general-purpose compression methods,
|
||||
and in particular considerably better than the "compress"
|
||||
program;
|
||||
* Can be implemented readily in a manner not covered by
|
||||
patents, and hence can be practiced freely;
|
||||
* Is compatible with the file format produced by the current
|
||||
widely used gzip utility, in that conforming decompressors
|
||||
will be able to read data produced by the existing gzip
|
||||
compressor.
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 2]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
The data format defined by this specification does not attempt to:
|
||||
|
||||
* Provide random access to compressed data;
|
||||
* Compress specialized data (e.g., raster graphics) as well as
|
||||
the best currently available specialized algorithms.
|
||||
|
||||
1.2. Intended audience
|
||||
|
||||
This specification is intended for use by implementors of software
|
||||
to compress data into gzip format and/or decompress data from gzip
|
||||
format.
|
||||
|
||||
The text of the specification assumes a basic background in
|
||||
programming at the level of bits and other primitive data
|
||||
representations.
|
||||
|
||||
1.3. Scope
|
||||
|
||||
The specification specifies a compression method and a file format
|
||||
(the latter assuming only that a file can store a sequence of
|
||||
arbitrary bytes). It does not specify any particular interface to
|
||||
a file system or anything about character sets or encodings
|
||||
(except for file names and comments, which are optional).
|
||||
|
||||
1.4. Compliance
|
||||
|
||||
Unless otherwise indicated below, a compliant decompressor must be
|
||||
able to accept and decompress any file that conforms to all the
|
||||
specifications presented here; a compliant compressor must produce
|
||||
files that conform to all the specifications presented here. The
|
||||
material in the appendices is not part of the specification per se
|
||||
and is not relevant to compliance.
|
||||
|
||||
1.5. Definitions of terms and conventions used
|
||||
|
||||
byte: 8 bits stored or transmitted as a unit (same as an octet).
|
||||
(For this specification, a byte is exactly 8 bits, even on
|
||||
machines which store a character on a number of bits different
|
||||
from 8.) See below for the numbering of bits within a byte.
|
||||
|
||||
1.6. Changes from previous versions
|
||||
|
||||
There have been no technical changes to the gzip format since
|
||||
version 4.1 of this specification. In version 4.2, some
|
||||
terminology was changed, and the sample CRC code was rewritten for
|
||||
clarity and to eliminate the requirement for the caller to do pre-
|
||||
and post-conditioning. Version 4.3 is a conversion of the
|
||||
specification to RFC style.
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 3]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
2. Detailed specification
|
||||
|
||||
2.1. Overall conventions
|
||||
|
||||
In the diagrams below, a box like this:
|
||||
|
||||
+---+
|
||||
| | <-- the vertical bars might be missing
|
||||
+---+
|
||||
|
||||
represents one byte; a box like this:
|
||||
|
||||
+==============+
|
||||
| |
|
||||
+==============+
|
||||
|
||||
represents a variable number of bytes.
|
||||
|
||||
Bytes stored within a computer do not have a "bit order", since
|
||||
they are always treated as a unit. However, a byte considered as
|
||||
an integer between 0 and 255 does have a most- and least-
|
||||
significant bit, and since we write numbers with the most-
|
||||
significant digit on the left, we also write bytes with the most-
|
||||
significant bit on the left. In the diagrams below, we number the
|
||||
bits of a byte so that bit 0 is the least-significant bit, i.e.,
|
||||
the bits are numbered:
|
||||
|
||||
+--------+
|
||||
|76543210|
|
||||
+--------+
|
||||
|
||||
This document does not address the issue of the order in which
|
||||
bits of a byte are transmitted on a bit-sequential medium, since
|
||||
the data format described here is byte- rather than bit-oriented.
|
||||
|
||||
Within a computer, a number may occupy multiple bytes. All
|
||||
multi-byte numbers in the format described here are stored with
|
||||
the least-significant byte first (at the lower memory address).
|
||||
For example, the decimal number 520 is stored as:
|
||||
|
||||
0 1
|
||||
+--------+--------+
|
||||
|00001000|00000010|
|
||||
+--------+--------+
|
||||
^ ^
|
||||
| |
|
||||
| + more significant byte = 2 x 256
|
||||
+ less significant byte = 8
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 4]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
2.2. File format
|
||||
|
||||
A gzip file consists of a series of "members" (compressed data
|
||||
sets). The format of each member is specified in the following
|
||||
section. The members simply appear one after another in the file,
|
||||
with no additional information before, between, or after them.
|
||||
|
||||
2.3. Member format
|
||||
|
||||
Each member has the following structure:
|
||||
|
||||
+---+---+---+---+---+---+---+---+---+---+
|
||||
|ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->)
|
||||
+---+---+---+---+---+---+---+---+---+---+
|
||||
|
||||
(if FLG.FEXTRA set)
|
||||
|
||||
+---+---+=================================+
|
||||
| XLEN |...XLEN bytes of "extra field"...| (more-->)
|
||||
+---+---+=================================+
|
||||
|
||||
(if FLG.FNAME set)
|
||||
|
||||
+=========================================+
|
||||
|...original file name, zero-terminated...| (more-->)
|
||||
+=========================================+
|
||||
|
||||
(if FLG.FCOMMENT set)
|
||||
|
||||
+===================================+
|
||||
|...file comment, zero-terminated...| (more-->)
|
||||
+===================================+
|
||||
|
||||
(if FLG.FHCRC set)
|
||||
|
||||
+---+---+
|
||||
| CRC16 |
|
||||
+---+---+
|
||||
|
||||
+=======================+
|
||||
|...compressed blocks...| (more-->)
|
||||
+=======================+
|
||||
|
||||
0 1 2 3 4 5 6 7
|
||||
+---+---+---+---+---+---+---+---+
|
||||
| CRC32 | ISIZE |
|
||||
+---+---+---+---+---+---+---+---+
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 5]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
2.3.1. Member header and trailer
|
||||
|
||||
ID1 (IDentification 1)
|
||||
ID2 (IDentification 2)
|
||||
These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
|
||||
(0x8b, \213), to identify the file as being in gzip format.
|
||||
|
||||
CM (Compression Method)
|
||||
This identifies the compression method used in the file. CM
|
||||
= 0-7 are reserved. CM = 8 denotes the "deflate"
|
||||
compression method, which is the one customarily used by
|
||||
gzip and which is documented elsewhere.
|
||||
|
||||
FLG (FLaGs)
|
||||
This flag byte is divided into individual bits as follows:
|
||||
|
||||
bit 0 FTEXT
|
||||
bit 1 FHCRC
|
||||
bit 2 FEXTRA
|
||||
bit 3 FNAME
|
||||
bit 4 FCOMMENT
|
||||
bit 5 reserved
|
||||
bit 6 reserved
|
||||
bit 7 reserved
|
||||
|
||||
If FTEXT is set, the file is probably ASCII text. This is
|
||||
an optional indication, which the compressor may set by
|
||||
checking a small amount of the input data to see whether any
|
||||
non-ASCII characters are present. In case of doubt, FTEXT
|
||||
is cleared, indicating binary data. For systems which have
|
||||
different file formats for ascii text and binary data, the
|
||||
decompressor can use FTEXT to choose the appropriate format.
|
||||
We deliberately do not specify the algorithm used to set
|
||||
this bit, since a compressor always has the option of
|
||||
leaving it cleared and a decompressor always has the option
|
||||
of ignoring it and letting some other program handle issues
|
||||
of data conversion.
|
||||
|
||||
If FHCRC is set, a CRC16 for the gzip header is present,
|
||||
immediately before the compressed data. The CRC16 consists
|
||||
of the two least significant bytes of the CRC32 for all
|
||||
bytes of the gzip header up to and not including the CRC16.
|
||||
[The FHCRC bit was never set by versions of gzip up to
|
||||
1.2.4, even though it was documented with a different
|
||||
meaning in gzip 1.2.4.]
|
||||
|
||||
If FEXTRA is set, optional extra fields are present, as
|
||||
described in a following section.
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 6]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
If FNAME is set, an original file name is present,
|
||||
terminated by a zero byte. The name must consist of ISO
|
||||
8859-1 (LATIN-1) characters; on operating systems using
|
||||
EBCDIC or any other character set for file names, the name
|
||||
must be translated to the ISO LATIN-1 character set. This
|
||||
is the original name of the file being compressed, with any
|
||||
directory components removed, and, if the file being
|
||||
compressed is on a file system with case insensitive names,
|
||||
forced to lower case. There is no original file name if the
|
||||
data was compressed from a source other than a named file;
|
||||
for example, if the source was stdin on a Unix system, there
|
||||
is no file name.
|
||||
|
||||
If FCOMMENT is set, a zero-terminated file comment is
|
||||
present. This comment is not interpreted; it is only
|
||||
intended for human consumption. The comment must consist of
|
||||
ISO 8859-1 (LATIN-1) characters. Line breaks should be
|
||||
denoted by a single line feed character (10 decimal).
|
||||
|
||||
Reserved FLG bits must be zero.
|
||||
|
||||
MTIME (Modification TIME)
|
||||
This gives the most recent modification time of the original
|
||||
file being compressed. The time is in Unix format, i.e.,
|
||||
seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this
|
||||
may cause problems for MS-DOS and other systems that use
|
||||
local rather than Universal time.) If the compressed data
|
||||
did not come from a file, MTIME is set to the time at which
|
||||
compression started. MTIME = 0 means no time stamp is
|
||||
available.
|
||||
|
||||
XFL (eXtra FLags)
|
||||
These flags are available for use by specific compression
|
||||
methods. The "deflate" method (CM = 8) sets these flags as
|
||||
follows:
|
||||
|
||||
XFL = 2 - compressor used maximum compression,
|
||||
slowest algorithm
|
||||
XFL = 4 - compressor used fastest algorithm
|
||||
|
||||
OS (Operating System)
|
||||
This identifies the type of file system on which compression
|
||||
took place. This may be useful in determining end-of-line
|
||||
convention for text files. The currently defined values are
|
||||
as follows:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 7]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
|
||||
1 - Amiga
|
||||
2 - VMS (or OpenVMS)
|
||||
3 - Unix
|
||||
4 - VM/CMS
|
||||
5 - Atari TOS
|
||||
6 - HPFS filesystem (OS/2, NT)
|
||||
7 - Macintosh
|
||||
8 - Z-System
|
||||
9 - CP/M
|
||||
10 - TOPS-20
|
||||
11 - NTFS filesystem (NT)
|
||||
12 - QDOS
|
||||
13 - Acorn RISCOS
|
||||
255 - unknown
|
||||
|
||||
XLEN (eXtra LENgth)
|
||||
If FLG.FEXTRA is set, this gives the length of the optional
|
||||
extra field. See below for details.
|
||||
|
||||
CRC32 (CRC-32)
|
||||
This contains a Cyclic Redundancy Check value of the
|
||||
uncompressed data computed according to CRC-32 algorithm
|
||||
used in the ISO 3309 standard and in section 8.1.1.6.2 of
|
||||
ITU-T recommendation V.42. (See http://www.iso.ch for
|
||||
ordering ISO documents. See gopher://info.itu.ch for an
|
||||
online version of ITU-T V.42.)
|
||||
|
||||
ISIZE (Input SIZE)
|
||||
This contains the size of the original (uncompressed) input
|
||||
data modulo 2^32.
|
||||
|
||||
2.3.1.1. Extra field
|
||||
|
||||
If the FLG.FEXTRA bit is set, an "extra field" is present in
|
||||
the header, with total length XLEN bytes. It consists of a
|
||||
series of subfields, each of the form:
|
||||
|
||||
+---+---+---+---+==================================+
|
||||
|SI1|SI2| LEN |... LEN bytes of subfield data ...|
|
||||
+---+---+---+---+==================================+
|
||||
|
||||
SI1 and SI2 provide a subfield ID, typically two ASCII letters
|
||||
with some mnemonic value. Jean-Loup Gailly
|
||||
<gzip@prep.ai.mit.edu> is maintaining a registry of subfield
|
||||
IDs; please send him any subfield ID you wish to use. Subfield
|
||||
IDs with SI2 = 0 are reserved for future use. The following
|
||||
IDs are currently defined:
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 8]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
SI1 SI2 Data
|
||||
---------- ---------- ----
|
||||
0x41 ('A') 0x70 ('P') Apollo file type information
|
||||
|
||||
LEN gives the length of the subfield data, excluding the 4
|
||||
initial bytes.
|
||||
|
||||
2.3.1.2. Compliance
|
||||
|
||||
A compliant compressor must produce files with correct ID1,
|
||||
ID2, CM, CRC32, and ISIZE, but may set all the other fields in
|
||||
the fixed-length part of the header to default values (255 for
|
||||
OS, 0 for all others). The compressor must set all reserved
|
||||
bits to zero.
|
||||
|
||||
A compliant decompressor must check ID1, ID2, and CM, and
|
||||
provide an error indication if any of these have incorrect
|
||||
values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
|
||||
at least so it can skip over the optional fields if they are
|
||||
present. It need not examine any other part of the header or
|
||||
trailer; in particular, a decompressor may ignore FTEXT and OS
|
||||
and always produce binary output, and still be compliant. A
|
||||
compliant decompressor must give an error indication if any
|
||||
reserved bit is non-zero, since such a bit could indicate the
|
||||
presence of a new field that would cause subsequent data to be
|
||||
interpreted incorrectly.
|
||||
|
||||
3. References
|
||||
|
||||
[1] "Information Processing - 8-bit single-byte coded graphic
|
||||
character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
|
||||
The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
|
||||
ASCII. Files defining this character set are available as
|
||||
iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
|
||||
|
||||
[2] ISO 3309
|
||||
|
||||
[3] ITU-T recommendation V.42
|
||||
|
||||
[4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
|
||||
available in ftp://ftp.uu.net/pub/archiving/zip/doc/
|
||||
|
||||
[5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
|
||||
ftp://prep.ai.mit.edu/pub/gnu/
|
||||
|
||||
[6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
|
||||
Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 9]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
[7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
|
||||
pp.118-133.
|
||||
|
||||
[8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
|
||||
describing the CRC concept.
|
||||
|
||||
4. Security Considerations
|
||||
|
||||
Any data compression method involves the reduction of redundancy in
|
||||
the data. Consequently, any corruption of the data is likely to have
|
||||
severe effects and be difficult to correct. Uncompressed text, on
|
||||
the other hand, will probably still be readable despite the presence
|
||||
of some corrupted bytes.
|
||||
|
||||
It is recommended that systems using this data format provide some
|
||||
means of validating the integrity of the compressed data, such as by
|
||||
setting and checking the CRC-32 check value.
|
||||
|
||||
5. Acknowledgements
|
||||
|
||||
Trademarks cited in this document are the property of their
|
||||
respective owners.
|
||||
|
||||
Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
|
||||
the related software described in this specification. Glenn
|
||||
Randers-Pehrson converted this document to RFC and HTML format.
|
||||
|
||||
6. Author's Address
|
||||
|
||||
L. Peter Deutsch
|
||||
Aladdin Enterprises
|
||||
203 Santa Margarita Ave.
|
||||
Menlo Park, CA 94025
|
||||
|
||||
Phone: (415) 322-0103 (AM only)
|
||||
FAX: (415) 322-1734
|
||||
EMail: <ghost@aladdin.com>
|
||||
|
||||
Questions about the technical content of this specification can be
|
||||
sent by email to:
|
||||
|
||||
Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
|
||||
Mark Adler <madler@alumni.caltech.edu>
|
||||
|
||||
Editorial comments on this specification can be sent by email to:
|
||||
|
||||
L. Peter Deutsch <ghost@aladdin.com> and
|
||||
Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 10]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
7. Appendix: Jean-Loup Gailly's gzip utility
|
||||
|
||||
The most widely used implementation of gzip compression, and the
|
||||
original documentation on which this specification is based, were
|
||||
created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>. Since this
|
||||
implementation is a de facto standard, we mention some more of its
|
||||
features here. Again, the material in this section is not part of
|
||||
the specification per se, and implementations need not follow it to
|
||||
be compliant.
|
||||
|
||||
When compressing or decompressing a file, gzip preserves the
|
||||
protection, ownership, and modification time attributes on the local
|
||||
file system, since there is no provision for representing protection
|
||||
attributes in the gzip file format itself. Since the file format
|
||||
includes a modification time, the gzip decompressor provides a
|
||||
command line switch that assigns the modification time from the file,
|
||||
rather than the local modification time of the compressed input, to
|
||||
the decompressed output.
|
||||
|
||||
8. Appendix: Sample CRC Code
|
||||
|
||||
The following sample code represents a practical implementation of
|
||||
the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
|
||||
for a formal specification.)
|
||||
|
||||
The sample code is in the ANSI C programming language. Non C users
|
||||
may find it easier to read with these hints:
|
||||
|
||||
& Bitwise AND operator.
|
||||
^ Bitwise exclusive-OR operator.
|
||||
>> Bitwise right shift operator. When applied to an
|
||||
unsigned quantity, as here, right shift inserts zero
|
||||
bit(s) at the left.
|
||||
! Logical NOT operator.
|
||||
++ "n++" increments the variable n.
|
||||
0xNNN 0x introduces a hexadecimal (base 16) constant.
|
||||
Suffix L indicates a long value (at least 32 bits).
|
||||
|
||||
/* Table of CRCs of all 8-bit messages. */
|
||||
unsigned long crc_table[256];
|
||||
|
||||
/* Flag: has the table been computed? Initially false. */
|
||||
int crc_table_computed = 0;
|
||||
|
||||
/* Make the table for a fast CRC. */
|
||||
void make_crc_table(void)
|
||||
{
|
||||
unsigned long c;
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 11]
|
||||
|
||||
RFC 1952 GZIP File Format Specification May 1996
|
||||
|
||||
|
||||
int n, k;
|
||||
for (n = 0; n < 256; n++) {
|
||||
c = (unsigned long) n;
|
||||
for (k = 0; k < 8; k++) {
|
||||
if (c & 1) {
|
||||
c = 0xedb88320L ^ (c >> 1);
|
||||
} else {
|
||||
c = c >> 1;
|
||||
}
|
||||
}
|
||||
crc_table[n] = c;
|
||||
}
|
||||
crc_table_computed = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
Update a running crc with the bytes buf[0..len-1] and return
|
||||
the updated crc. The crc should be initialized to zero. Pre- and
|
||||
post-conditioning (one's complement) is performed within this
|
||||
function so it shouldn't be done by the caller. Usage example:
|
||||
|
||||
unsigned long crc = 0L;
|
||||
|
||||
while (read_buffer(buffer, length) != EOF) {
|
||||
crc = update_crc(crc, buffer, length);
|
||||
}
|
||||
if (crc != original_crc) error();
|
||||
*/
|
||||
unsigned long update_crc(unsigned long crc,
|
||||
unsigned char *buf, int len)
|
||||
{
|
||||
unsigned long c = crc ^ 0xffffffffL;
|
||||
int n;
|
||||
|
||||
if (!crc_table_computed)
|
||||
make_crc_table();
|
||||
for (n = 0; n < len; n++) {
|
||||
c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
return c ^ 0xffffffffL;
|
||||
}
|
||||
|
||||
/* Return the CRC of the bytes buf[0..len-1]. */
|
||||
unsigned long crc(unsigned char *buf, int len)
|
||||
{
|
||||
return update_crc(0L, buf, len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Deutsch Informational [Page 12]
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
A Fast Method for Identifying Plain Text Files
|
||||
==============================================
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
Given a file coming from an unknown source, it is sometimes desirable
|
||||
to find out whether the format of that file is plain text. Although
|
||||
this may appear like a simple task, a fully accurate detection of the
|
||||
file type requires heavy-duty semantic analysis on the file contents.
|
||||
It is, however, possible to obtain satisfactory results by employing
|
||||
various heuristics.
|
||||
|
||||
Previous versions of PKZip and other zip-compatible compression tools
|
||||
were using a crude detection scheme: if more than 80% (4/5) of the bytes
|
||||
found in a certain buffer are within the range [7..127], the file is
|
||||
labeled as plain text, otherwise it is labeled as binary. A prominent
|
||||
limitation of this scheme is the restriction to Latin-based alphabets.
|
||||
Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
|
||||
the bytes within the range [128..255], and texts using these alphabets
|
||||
are most often misidentified by this scheme; in other words, the rate
|
||||
of false negatives is sometimes too high, which means that the recall
|
||||
is low. Another weakness of this scheme is a reduced precision, due to
|
||||
the false positives that may occur when binary files containing large
|
||||
amounts of textual characters are misidentified as plain text.
|
||||
|
||||
In this article we propose a new, simple detection scheme that features
|
||||
a much increased precision and a near-100% recall. This scheme is
|
||||
designed to work on ASCII, Unicode and other ASCII-derived alphabets,
|
||||
and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
|
||||
and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings
|
||||
(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
|
||||
|
||||
|
||||
The Algorithm
|
||||
-------------
|
||||
|
||||
The algorithm works by dividing the set of bytecodes [0..255] into three
|
||||
categories:
|
||||
- The white list of textual bytecodes:
|
||||
9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
|
||||
- The gray list of tolerated bytecodes:
|
||||
7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
|
||||
- The black list of undesired, non-textual bytecodes:
|
||||
0 (NUL) to 6, 14 to 31.
|
||||
|
||||
If a file contains at least one byte that belongs to the white list and
|
||||
no byte that belongs to the black list, then the file is categorized as
|
||||
plain text; otherwise, it is categorized as binary. (The boundary case,
|
||||
when the file is empty, automatically falls into the latter category.)
|
||||
|
||||
|
||||
Rationale
|
||||
---------
|
||||
|
||||
The idea behind this algorithm relies on two observations.
|
||||
|
||||
The first observation is that, although the full range of 7-bit codes
|
||||
[0..127] is properly specified by the ASCII standard, most control
|
||||
characters in the range [0..31] are not used in practice. The only
|
||||
widely-used, almost universally-portable control codes are 9 (TAB),
|
||||
10 (LF) and 13 (CR). There are a few more control codes that are
|
||||
recognized on a reduced range of platforms and text viewers/editors:
|
||||
7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
|
||||
codes are rarely (if ever) used alone, without being accompanied by
|
||||
some printable text. Even the newer, portable text formats such as
|
||||
XML avoid using control characters outside the list mentioned here.
|
||||
|
||||
The second observation is that most of the binary files tend to contain
|
||||
control characters, especially 0 (NUL). Even though the older text
|
||||
detection schemes observe the presence of non-ASCII codes from the range
|
||||
[128..255], the precision rarely has to suffer if this upper range is
|
||||
labeled as textual, because the files that are genuinely binary tend to
|
||||
contain both control characters and codes from the upper range. On the
|
||||
other hand, the upper range needs to be labeled as textual, because it
|
||||
is used by virtually all ASCII extensions. In particular, this range is
|
||||
used for encoding non-Latin scripts.
|
||||
|
||||
Since there is no counting involved, other than simply observing the
|
||||
presence or the absence of some byte values, the algorithm produces
|
||||
consistent results, regardless what alphabet encoding is being used.
|
||||
(If counting were involved, it could be possible to obtain different
|
||||
results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
|
||||
|
||||
There is an extra category of plain text files that are "polluted" with
|
||||
one or more black-listed codes, either by mistake or by peculiar design
|
||||
considerations. In such cases, a scheme that tolerates a small fraction
|
||||
of black-listed codes would provide an increased recall (i.e. more true
|
||||
positives). This, however, incurs a reduced precision overall, since
|
||||
false positives are more likely to appear in binary files that contain
|
||||
large chunks of textual data. Furthermore, "polluted" plain text should
|
||||
be regarded as binary by general-purpose text detection schemes, because
|
||||
general-purpose text processing algorithms might not be applicable.
|
||||
Under this premise, it is safe to say that our detection method provides
|
||||
a near-100% recall.
|
||||
|
||||
Experiments have been run on many files coming from various platforms
|
||||
and applications. We tried plain text files, system logs, source code,
|
||||
formatted office documents, compiled object code, etc. The results
|
||||
confirm the optimistic assumptions about the capabilities of this
|
||||
algorithm.
|
||||
|
||||
|
||||
--
|
||||
Cosmin Truta
|
||||
Last updated: 2006-May-28
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/* gzlib.c -- zlib functions common to reading and writing gzip files
|
||||
* Copyright (C) 2004, 2010, 2011, 2012, 2013, 2016 Mark Adler
|
||||
* Copyright (C) 2004-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* gzwrite.c -- zlib functions for writing gzip files
|
||||
* Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013, 2016 Mark Adler
|
||||
* Copyright (C) 2004-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* inffast.c -- fast decoding
|
||||
* Copyright (C) 1995-2008, 2010, 2013, 2016 Mark Adler
|
||||
* Copyright (C) 1995-2017 Mark Adler
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#define MAXBITS 15
|
||||
|
||||
const char inflate_copyright[] =
|
||||
" inflate 1.2.10 Copyright 1995-2017 Mark Adler ";
|
||||
" inflate 1.2.11 Copyright 1995-2017 Mark Adler ";
|
||||
/*
|
||||
If you use the zlib library in a product, an acknowledgment is welcome
|
||||
in the documentation of your product. If for some reason you cannot
|
||||
@@ -62,7 +62,7 @@ unsigned short FAR *work;
|
||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
|
||||
static const unsigned short lext[31] = { /* Length codes 257..285 extra */
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 192, 202};
|
||||
19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202};
|
||||
static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
|
||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ZLIB version 1.2.10 for OS/400 installation instructions
|
||||
ZLIB version 1.2.11 for OS/400 installation instructions
|
||||
|
||||
1) Download and unpack the zlib tarball to some IFS directory.
|
||||
(i.e.: /path/to/the/zlib/ifs/source/directory)
|
||||
|
||||
@@ -260,7 +260,7 @@ fi
|
||||
echo '#pragma comment(user, "ZLIB version '"${VERSION}"'")' > os400.c
|
||||
echo '#pragma comment(user, __DATE__)' >> os400.c
|
||||
echo '#pragma comment(user, __TIME__)' >> os400.c
|
||||
echo '#pragma comment(copyright, "Copyright (C) 1995-2016 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c
|
||||
echo '#pragma comment(copyright, "Copyright (C) 1995-2017 Jean-Loup Gailly, Mark Adler. OS/400 version by P. Monnerat.")' >> os400.c
|
||||
make_module OS400 os400.c
|
||||
LINK= # No need to rebuild service program yet.
|
||||
MODULES=
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
* ZLIB.INC - Interface to the general purpose compression library
|
||||
*
|
||||
* ILE RPG400 version by Patrick Monnerat, DATASPHERE.
|
||||
* Version 1.2.10
|
||||
* Version 1.2.11
|
||||
*
|
||||
*
|
||||
* WARNING:
|
||||
@@ -22,12 +22,12 @@
|
||||
*
|
||||
* Versioning information.
|
||||
*
|
||||
D ZLIB_VERSION C '1.2.10'
|
||||
D ZLIB_VERSION C '1.2.11'
|
||||
D ZLIB_VERNUM C X'12a0'
|
||||
D ZLIB_VER_MAJOR C 1
|
||||
D ZLIB_VER_MINOR C 2
|
||||
D ZLIB_VER_REVISION...
|
||||
D C 10
|
||||
D C 11
|
||||
D ZLIB_VER_SUBREVISION...
|
||||
D C 0
|
||||
*
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
<QPG:Files>
|
||||
<QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
|
||||
<QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
|
||||
<QPG:Add file="../libz.so.1.2.10" install="/opt/lib/" user="root:bin" permission="644"/>
|
||||
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.10"/>
|
||||
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.10"/>
|
||||
<QPG:Add file="../libz.so.1.2.10" install="/opt/lib/" component="slib"/>
|
||||
<QPG:Add file="../libz.so.1.2.11" install="/opt/lib/" user="root:bin" permission="644"/>
|
||||
<QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.11"/>
|
||||
<QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.11"/>
|
||||
<QPG:Add file="../libz.so.1.2.11" install="/opt/lib/" component="slib"/>
|
||||
</QPG:Files>
|
||||
|
||||
<QPG:PackageFilter>
|
||||
@@ -63,7 +63,7 @@
|
||||
</QPM:ProductDescription>
|
||||
|
||||
<QPM:ReleaseDescription>
|
||||
<QPM:ReleaseVersion>1.2.10</QPM:ReleaseVersion>
|
||||
<QPM:ReleaseVersion>1.2.11</QPM:ReleaseVersion>
|
||||
<QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
|
||||
<QPM:ReleaseStability>Stable</QPM:ReleaseStability>
|
||||
<QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" ?>
|
||||
<package name="zlib" version="1.2.10">
|
||||
<library name="zlib" dlversion="1.2.10" dlname="z">
|
||||
<package name="zlib" version="1.2.11">
|
||||
<library name="zlib" dlversion="1.2.11" dlname="z">
|
||||
<property name="description"> zip compression library </property>
|
||||
<property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/* trees.c -- output deflated data using Huffman coding
|
||||
* Copyright (C) 1995-2016 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2017 Jean-loup Gailly
|
||||
* detect_data_type() function provided freely by Cosmin Truta, 2006
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
@@ -906,7 +906,7 @@ void ZLIB_INTERNAL _tr_align(s)
|
||||
|
||||
/* ===========================================================================
|
||||
* Determine the best encoding for the current block: dynamic trees, static
|
||||
* trees or store, and output the encoded block to the zip file.
|
||||
* trees or store, and write out the encoded block.
|
||||
*/
|
||||
void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
|
||||
deflate_state *s;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Makefile for zlib using Microsoft (Visual) C
|
||||
# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler
|
||||
# zlib is copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
#
|
||||
# Usage:
|
||||
# nmake -f win32/Makefile.msc (standard build)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ZLIB DATA COMPRESSION LIBRARY
|
||||
|
||||
zlib 1.2.10 is a general purpose data compression library. All the code is
|
||||
zlib 1.2.11 is a general purpose data compression library. All the code is
|
||||
thread safe. The data format used by the zlib library is described by RFCs
|
||||
(Request for Comments) 1950 to 1952 in the files
|
||||
http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
|
||||
@@ -22,7 +22,7 @@ before asking for help.
|
||||
|
||||
Manifest:
|
||||
|
||||
The package zlib-1.2.10-win32-x86.zip will contain the following files:
|
||||
The package zlib-1.2.11-win32-x86.zip will contain the following files:
|
||||
|
||||
README-WIN32.txt This document
|
||||
ChangeLog Changes since previous zlib packages
|
||||
@@ -72,7 +72,7 @@ are too numerous to cite here.
|
||||
|
||||
Copyright notice:
|
||||
|
||||
(C) 1995-2012 Jean-loup Gailly and Mark Adler
|
||||
(C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -6,7 +6,7 @@ What's here
|
||||
|
||||
Source
|
||||
======
|
||||
zlib version 1.2.10
|
||||
zlib version 1.2.11
|
||||
available at http://www.gzip.org/zlib/
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ Build info
|
||||
|
||||
Copyright notice
|
||||
================
|
||||
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
Installing ZLIB1.DLL
|
||||
====================
|
||||
Copy ZLIB1.DLL to the SYSTEM or the SYSTEM32 directory.
|
||||
|
||||
If you want to install the 32-bit dll on a 64-bit
|
||||
machine, use the SysWOW64 directory instead.
|
||||
|
||||
|
||||
Using ZLIB1.DLL with Microsoft Visual C++
|
||||
@@ -20,12 +23,17 @@ Using ZLIB1.DLL with gcc/MinGW
|
||||
1. Install the supplied header files "zlib.h" and "zconf.h"
|
||||
into the INCLUDE directory.
|
||||
|
||||
2. Copy the supplied library file "zdll.lib" to "libzdll.a":
|
||||
2. (32-bit): Copy the supplied library file "zdll.lib" to "libzdll.a":
|
||||
cp lib/zdll.lib lib/libzdll.a
|
||||
|
||||
OR
|
||||
|
||||
2' Build the import library from the supplied "zlib.def":
|
||||
2'. (64-bit): Copy the supplied library file "libz.dll.a" to "libzdll.a":
|
||||
cp lib/libz.dll.a lib/libzdll.a
|
||||
|
||||
OR
|
||||
|
||||
2'' Build the import library from the supplied "zlib.def":
|
||||
dlltool -D zlib1.dll -d lib/zlib.def -l lib/libzdll.a
|
||||
|
||||
3. Install "libzdll.a" into the LIB directory.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
|
||||
To build zlib using the Microsoft Visual C++ environment,
|
||||
use the appropriate project from the projects/ directory.
|
||||
use the appropriate project from the contrib/vstudio/ directory.
|
||||
|
||||
Regular → Executable
BIN
Binary file not shown.
Binary file not shown.
@@ -26,7 +26,7 @@ BEGIN
|
||||
VALUE "FileDescription", "zlib data compression library\0"
|
||||
VALUE "FileVersion", ZLIB_VERSION "\0"
|
||||
VALUE "InternalName", "zlib1.dll\0"
|
||||
VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
|
||||
VALUE "LegalCopyright", "(C) 1995-2017 Jean-loup Gailly & Mark Adler\0"
|
||||
VALUE "OriginalFilename", "zlib1.dll\0"
|
||||
VALUE "ProductName", "zlib\0"
|
||||
VALUE "ProductVersion", ZLIB_VERSION "\0"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
+2
-2
@@ -1,4 +1,4 @@
|
||||
.TH ZLIB 3 "2 Jan 2017"
|
||||
.TH ZLIB 3 "15 Jan 2017"
|
||||
.SH NAME
|
||||
zlib \- compression/decompression library
|
||||
.SH SYNOPSIS
|
||||
@@ -105,7 +105,7 @@ before asking for help.
|
||||
Send questions and/or comments to zlib@gzip.org,
|
||||
or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
|
||||
.SH AUTHORS AND LICENSE
|
||||
Version 1.2.10
|
||||
Version 1.2.11
|
||||
.LP
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
.LP
|
||||
|
||||
Binary file not shown.
+9
-8
@@ -1,5 +1,5 @@
|
||||
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||||
version 1.2.10, January 2nd, 2017
|
||||
version 1.2.11, January 15th, 2017
|
||||
|
||||
Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
|
||||
|
||||
@@ -37,11 +37,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ZLIB_VERSION "1.2.10"
|
||||
#define ZLIB_VERNUM 0x12a0
|
||||
#define ZLIB_VERSION "1.2.11"
|
||||
#define ZLIB_VERNUM 0x12b0
|
||||
#define ZLIB_VER_MAJOR 1
|
||||
#define ZLIB_VER_MINOR 2
|
||||
#define ZLIB_VER_REVISION 10
|
||||
#define ZLIB_VER_REVISION 11
|
||||
#define ZLIB_VER_SUBREVISION 0
|
||||
|
||||
/*
|
||||
@@ -712,10 +712,11 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
|
||||
used to switch between compression and straight copy of the input data, or
|
||||
to switch to a different kind of input data requiring a different strategy.
|
||||
If the compression approach (which is a function of the level) or the
|
||||
strategy is changed, then the input available so far is compressed with the
|
||||
old level and strategy using deflate(strm, Z_BLOCK). There are three
|
||||
approaches for the compression levels 0, 1..3, and 4..9 respectively. The
|
||||
new level and strategy will take effect at the next call of deflate().
|
||||
strategy is changed, and if any input has been consumed in a previous
|
||||
deflate() call, then the input available so far is compressed with the old
|
||||
level and strategy using deflate(strm, Z_BLOCK). There are three approaches
|
||||
for the compression levels 0, 1..3, and 4..9 respectively. The new level
|
||||
and strategy will take effect at the next call of deflate().
|
||||
|
||||
If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does
|
||||
not have enough output space to complete, then the parameter change will not
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
/* zutil.c -- target dependent utility functions for the compression library
|
||||
* Copyright (C) 1995-2005, 2010, 2011, 2012, 2016 Jean-loup Gailly
|
||||
* Copyright (C) 1995-2017 Jean-loup Gailly
|
||||
* For conditions of distribution and use, see copyright notice in zlib.h
|
||||
*/
|
||||
|
||||
|
||||
+1
-1
@@ -205,7 +205,7 @@ and sets \fIinterp\fR's result to an error message indicating that
|
||||
the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was
|
||||
invoked in an inappropriate place.
|
||||
This means that top-level applications should never see a return code
|
||||
from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.
|
||||
from \fBTcl_EvalObjEx\fR other than \fBTCL_OK\fR or \fBTCL_ERROR\fR.
|
||||
|
||||
.SH KEYWORDS
|
||||
execute, file, global, result, script, value
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ are provided by the C language standard. The \fBTcl_WideInt\fR type is a
|
||||
typedef defined to be whatever signed integral type covers at least the
|
||||
64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending
|
||||
on the platform and the C compiler, the actual type might be
|
||||
\fBlong int\fR, \fBlong long int\fR, \fBint64\fR, or something else.
|
||||
\fBlong int\fR, \fBlong long int\fR, \fB__int64\fR, or something else.
|
||||
The \fBmp_int\fR type is a multiple-precision integer type defined
|
||||
by the LibTomMath multiple-precision integer library.
|
||||
.PP
|
||||
|
||||
+36
-12
@@ -61,7 +61,9 @@ The C variable is of type \fBint\fR.
|
||||
Any value written into the Tcl variable must have a proper integer
|
||||
form acceptable to \fBTcl_GetIntFromObj\fR; attempts to write
|
||||
non-integer values into \fIvarName\fR will be rejected with
|
||||
Tcl errors.
|
||||
Tcl errors. Incomplete integer representations (like the empty
|
||||
string, '+', '-' or the hex/octal/binary prefix) are accepted
|
||||
as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_UINT\fR
|
||||
The C variable is of type \fBunsigned int\fR.
|
||||
@@ -69,14 +71,18 @@ Any value written into the Tcl variable must have a proper unsigned
|
||||
integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the
|
||||
platform's defined range for the \fBunsigned int\fR type; attempts to
|
||||
write non-integer values (or values outside the range) into
|
||||
\fIvarName\fR will be rejected with Tcl errors.
|
||||
\fIvarName\fR will be rejected with Tcl errors. Incomplete integer
|
||||
representations (like the empty string, '+', '-' or the hex/octal/binary
|
||||
prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_CHAR\fR
|
||||
The C variable is of type \fBchar\fR.
|
||||
Any value written into the Tcl variable must have a proper integer
|
||||
form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the
|
||||
\fBchar\fR datatype; attempts to write non-integer or out-of-range
|
||||
values into \fIvarName\fR will be rejected with Tcl errors.
|
||||
values into \fIvarName\fR will be rejected with Tcl errors. Incomplete
|
||||
integer representations (like the empty string, '+', '-' or the
|
||||
hex/octal/binary prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_UCHAR\fR
|
||||
The C variable is of type \fBunsigned char\fR.
|
||||
@@ -84,14 +90,18 @@ Any value written into the Tcl variable must have a proper unsigned
|
||||
integer form acceptable to \fBTcl_GetIntFromObj\fR and in the
|
||||
platform's defined range for the \fBunsigned char\fR type; attempts to
|
||||
write non-integer values (or values outside the range) into
|
||||
\fIvarName\fR will be rejected with Tcl errors.
|
||||
\fIvarName\fR will be rejected with Tcl errors. Incomplete integer
|
||||
representations (like the empty string, '+', '-' or the hex/octal/binary
|
||||
prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_SHORT\fR
|
||||
The C variable is of type \fBshort\fR.
|
||||
Any value written into the Tcl variable must have a proper integer
|
||||
form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the
|
||||
\fBshort\fR datatype; attempts to write non-integer or out-of-range
|
||||
values into \fIvarName\fR will be rejected with Tcl errors.
|
||||
values into \fIvarName\fR will be rejected with Tcl errors. Incomplete
|
||||
integer representations (like the empty string, '+', '-' or the
|
||||
hex/octal/binary prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_USHORT\fR
|
||||
The C variable is of type \fBunsigned short\fR.
|
||||
@@ -99,14 +109,18 @@ Any value written into the Tcl variable must have a proper unsigned
|
||||
integer form acceptable to \fBTcl_GetIntFromObj\fR and in the
|
||||
platform's defined range for the \fBunsigned short\fR type; attempts to
|
||||
write non-integer values (or values outside the range) into
|
||||
\fIvarName\fR will be rejected with Tcl errors.
|
||||
\fIvarName\fR will be rejected with Tcl errors. Incomplete integer
|
||||
representations (like the empty string, '+', '-' or the hex/octal/binary
|
||||
prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_LONG\fR
|
||||
The C variable is of type \fBlong\fR.
|
||||
Any value written into the Tcl variable must have a proper integer
|
||||
form acceptable to \fBTcl_GetLongFromObj\fR; attempts to write
|
||||
non-integer or out-of-range
|
||||
values into \fIvarName\fR will be rejected with Tcl errors.
|
||||
values into \fIvarName\fR will be rejected with Tcl errors. Incomplete
|
||||
integer representations (like the empty string, '+', '-' or the
|
||||
hex/octal/binary prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_ULONG\fR
|
||||
The C variable is of type \fBunsigned long\fR.
|
||||
@@ -114,14 +128,18 @@ Any value written into the Tcl variable must have a proper unsigned
|
||||
integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the
|
||||
platform's defined range for the \fBunsigned long\fR type; attempts to
|
||||
write non-integer values (or values outside the range) into
|
||||
\fIvarName\fR will be rejected with Tcl errors.
|
||||
\fIvarName\fR will be rejected with Tcl errors. Incomplete integer
|
||||
representations (like the empty string, '+', '-' or the hex/octal/binary
|
||||
prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_DOUBLE\fR
|
||||
The C variable is of type \fBdouble\fR.
|
||||
Any value written into the Tcl variable must have a proper real
|
||||
form acceptable to \fBTcl_GetDoubleFromObj\fR; attempts to write
|
||||
non-real values into \fIvarName\fR will be rejected with
|
||||
Tcl errors.
|
||||
Tcl errors. Incomplete integer or real representations (like the
|
||||
empty string, '.', '+', '-' or the hex/octal/binary prefix) are
|
||||
accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_FLOAT\fR
|
||||
The C variable is of type \fBfloat\fR.
|
||||
@@ -129,7 +147,9 @@ Any value written into the Tcl variable must have a proper real
|
||||
form acceptable to \fBTcl_GetDoubleFromObj\fR and must be within the
|
||||
range acceptable for a \fBfloat\fR; attempts to
|
||||
write non-real values (or values outside the range) into
|
||||
\fIvarName\fR will be rejected with Tcl errors.
|
||||
\fIvarName\fR will be rejected with Tcl errors. Incomplete integer
|
||||
or real representations (like the empty string, '.', '+', '-' or
|
||||
the hex/octal/binary prefix) are accepted as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_WIDE_INT\fR
|
||||
The C variable is of type \fBTcl_WideInt\fR (which is an integer type
|
||||
@@ -137,7 +157,9 @@ at least 64-bits wide on all platforms that can support it.)
|
||||
Any value written into the Tcl variable must have a proper integer
|
||||
form acceptable to \fBTcl_GetWideIntFromObj\fR; attempts to write
|
||||
non-integer values into \fIvarName\fR will be rejected with
|
||||
Tcl errors.
|
||||
Tcl errors. Incomplete integer representations (like the empty
|
||||
string, '+', '-' or the hex/octal/binary prefix) are accepted
|
||||
as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_WIDE_UINT\fR
|
||||
The C variable is of type \fBTcl_WideUInt\fR (which is an unsigned
|
||||
@@ -148,7 +170,9 @@ integer form acceptable to \fBTcl_GetWideIntFromObj\fR (it will be
|
||||
cast to unsigned);
|
||||
.\" FIXME! Use bignums instead.
|
||||
attempts to write non-integer values into \fIvarName\fR will be
|
||||
rejected with Tcl errors.
|
||||
rejected with Tcl errors. Incomplete integer representations (like
|
||||
the empty string, '+', '-' or the hex/octal/binary prefix) are accepted
|
||||
as if they are valid too.
|
||||
.TP
|
||||
\fBTCL_LINK_BOOLEAN\fR
|
||||
The C variable is of type \fBint\fR.
|
||||
|
||||
@@ -32,8 +32,6 @@ the command at global level instead of the current stack level.
|
||||
.PP
|
||||
\fBTcl_RecordAndEvalObj\fR is invoked to record a command as an event
|
||||
on the history list and then execute it using \fBTcl_EvalObjEx\fR
|
||||
(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set
|
||||
in \fIflags\fR).
|
||||
It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
|
||||
as well as a result value containing additional information
|
||||
(a result value or error message)
|
||||
|
||||
+16
-6
@@ -14,7 +14,7 @@ oo::copy \- create copies of objects and classes
|
||||
.nf
|
||||
package require TclOO
|
||||
|
||||
\fBoo::copy\fI sourceObject \fR?\fItargetObject\fR?
|
||||
\fBoo::copy\fI sourceObject \fR?\fItargetObject\fR? ?\fItargetNamespace\fR?
|
||||
.fi
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
@@ -22,11 +22,21 @@ package require TclOO
|
||||
The \fBoo::copy\fR command creates a copy of an object or class. It takes the
|
||||
name of the object or class to be copied, \fIsourceObject\fR, and optionally
|
||||
the name of the object or class to create, \fItargetObject\fR, which will be
|
||||
resolved relative to the current namespace if not an absolute qualified name.
|
||||
If \fItargetObject\fR is omitted, a new name is chosen. The copied object will
|
||||
be of the same class as the source object, and will have all its per-object
|
||||
methods copied. If it is a class, it will also have all the class methods in
|
||||
the class copied, but it will not have any of its instances copied.
|
||||
resolved relative to the current namespace if not an absolute qualified name
|
||||
and
|
||||
.VS TIP473
|
||||
\fItargetNamespace\fR which is the name of the namespace that will hold the
|
||||
internal state of the object (\fBmy\fR command, etc.); it \fImust not\fR
|
||||
refer to an existing namespace.
|
||||
If either \fItargetObject\fR or \fItargetNamespace\fR is omitted or is given
|
||||
as the empty string, a new name is chosen. Names, unless specified, are
|
||||
chosen with the same algorithm used by the \fBnew\fR method of
|
||||
\fBoo::class\fR.
|
||||
.VE TIP473
|
||||
The copied object will be of the same class as the source object, and will have
|
||||
all its per-object methods copied. If it is a class, it will also have all the
|
||||
class methods in the class copied, but it will not have any of its instances
|
||||
copied.
|
||||
.PP
|
||||
.VS
|
||||
After the \fItargetObject\fR has been created and all definitions of its
|
||||
|
||||
@@ -142,6 +142,8 @@ be afterwards.
|
||||
\fBself\fI subcommand arg ...\fR
|
||||
.TP
|
||||
\fBself\fI script\fR
|
||||
.TP
|
||||
\fBself\fR
|
||||
.
|
||||
This command is equivalent to calling \fBoo::objdefine\fR on the class being
|
||||
defined (see \fBCONFIGURING OBJECTS\fR below for a description of the
|
||||
@@ -151,6 +153,13 @@ and
|
||||
.QW "\fBoo::define \fIcls \fBself \fIsubcommand ...\fR"
|
||||
operates identically to
|
||||
.QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
|
||||
.RS
|
||||
.PP
|
||||
.VS TIP470
|
||||
If no arguments at all are used, this gives the name of the class currently
|
||||
being configured.
|
||||
.VE TIP470
|
||||
.RE
|
||||
.TP
|
||||
\fBsuperclass\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
|
||||
.VS
|
||||
@@ -265,6 +274,12 @@ not previously refer to a method in that object. Does not affect the classes
|
||||
that the object is an instance of. Does not change the export status of the
|
||||
method; if it was exported before, it will be afterwards.
|
||||
.TP
|
||||
\fBself \fR
|
||||
.
|
||||
.VS TIP470
|
||||
This gives the name of the object currently being configured.
|
||||
.VE TIP470
|
||||
.TP
|
||||
\fBunexport\fI name \fR?\fIname ...\fR?
|
||||
.
|
||||
This arranges for each of the named methods, \fIname\fR, to be not exported
|
||||
|
||||
+1
-1
@@ -437,7 +437,7 @@ puts $foo
|
||||
# prints: \fIa b foo {a b} bar 2 baz 3\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
append(n), array(n), foreach(n), mapeach(n), incr(n), list(n), lappend(n), set(n)
|
||||
append(n), array(n), foreach(n), incr(n), list(n), lappend(n), lmap(n), set(n)
|
||||
.SH KEYWORDS
|
||||
dictionary, create, update, lookup, iterate, filter, map
|
||||
'\" Local Variables:
|
||||
|
||||
+1
-1
@@ -297,7 +297,7 @@ scripts are stored.
|
||||
This is actually the value of the \fBtcl_library\fR
|
||||
variable and may be changed by setting \fBtcl_library\fR.
|
||||
.TP
|
||||
\fBinfo loaded \fR?\fIinterp\fR? \fR?\fIpackage\fR?
|
||||
\fBinfo loaded \fR?\fIinterp\fR? ?\fIpackage\fR?
|
||||
.
|
||||
Returns the filename loaded as part of \fIpackage\fR. If \fIpackage\fR
|
||||
is not specified, returns a list describing all of the packages
|
||||
|
||||
+2
-1
@@ -40,7 +40,8 @@ except (a) case is ignored except as a tie-breaker and (b) if two
|
||||
strings contain embedded numbers, the numbers compare as integers,
|
||||
not characters. For example, in \fB\-dictionary\fR mode, \fBbigBoy\fR
|
||||
sorts between \fBbigbang\fR and \fBbigboy\fR, and \fBx10y\fR
|
||||
sorts between \fBx9y\fR and \fBx11y\fR.
|
||||
sorts between \fBx9y\fR and \fBx11y\fR. Overrides the \fB\-nocase\fR
|
||||
option.
|
||||
.TP
|
||||
\fB\-integer\fR
|
||||
.
|
||||
|
||||
+3
-3
@@ -293,12 +293,12 @@ treatment is as if the enclosing delimiters were
|
||||
.QW \fB[.\fR \&
|
||||
and
|
||||
.QW \fB.]\fR .)
|
||||
For example, if \fBo\fR and \fB\*(qo\fR are the members of an
|
||||
For example, if \fBo\fR and \fB\[^o]\fR are the members of an
|
||||
equivalence class, then
|
||||
.QW \fB[[=o=]]\fR ,
|
||||
.QW \fB[[=\*(qo=]]\fR ,
|
||||
.QW \fB[[=\[^o]=]]\fR ,
|
||||
and
|
||||
.QW \fB[o\*(qo]\fR \&
|
||||
.QW \fB[o\[^o]]\fR \&
|
||||
are all synonymous. An equivalence class may not be an endpoint of a range.
|
||||
.RS
|
||||
.PP
|
||||
|
||||
@@ -68,6 +68,31 @@ and
|
||||
sequences are handled for each substitution using the information
|
||||
from the corresponding match.
|
||||
.TP
|
||||
\fB\-command\fR
|
||||
.VS 8.7
|
||||
Changes the handling of the substitution string so that it no longer treats
|
||||
.QW &
|
||||
and
|
||||
.QW \e
|
||||
as special characters, but instead uses them as a non-empty list of words.
|
||||
Each time a substitution is processed, another complete Tcl word is appended
|
||||
to that list for each substitution value (the first such argument represents
|
||||
the overall matched substring, the subsequent arguments will be one per
|
||||
capturing sub-RE, much as are returned from \fBregexp\fR \fB\-inline\fR) and
|
||||
the overall list is then evaluated as a Tcl command call. If the command
|
||||
finishes successfully, the result of command call is substituted into the
|
||||
resulting string.
|
||||
.RS
|
||||
.PP
|
||||
If \fB\-all\fR is not also given, the command callback will be invoked at most
|
||||
once (exactly when the regular expression matches). If \fB\-all\fR is given,
|
||||
the command callback will be invoked for each matched location, in sequence.
|
||||
The exact location indices that matched are not made available to the script.
|
||||
.PP
|
||||
See \fBEXAMPLES\fR below for illustrative cases.
|
||||
.RE
|
||||
.VE 8.7
|
||||
.TP
|
||||
\fB\-expanded\fR
|
||||
.
|
||||
Enables use of the expanded regular expression syntax where
|
||||
@@ -183,6 +208,53 @@ set substitution {[format \e\e\e\eu%04x [scan "\e\e&" %c]]}
|
||||
set quoted [subst [string map {\en {\e\eu000a}} \e
|
||||
[\fBregsub\fR -all $RE $string $substitution]]]
|
||||
.CE
|
||||
.PP
|
||||
.VS 8.7
|
||||
The above operation can be done using \fBregsub \-command\fR instead, which is
|
||||
often faster. (A full pre-computed \fBstring map\fR would be faster still, but
|
||||
the cost of computing the map for a transformation as complex as this can be
|
||||
quite large.)
|
||||
.PP
|
||||
.CS
|
||||
# This RE is just a character class for everything "bad"
|
||||
set RE {[][{};#\e\e\e$\es\eu0080-\euffff]}
|
||||
|
||||
# This encodes what the RE described above matches
|
||||
proc encodeChar {ch} {
|
||||
# newline is handled specially since backslash-newline is a
|
||||
# special sequence.
|
||||
if {$ch eq "\en"} {
|
||||
return "\e\eu000a"
|
||||
}
|
||||
# No point in writing this as a one-liner
|
||||
scan $ch %c charNumber
|
||||
format "\e\eu%04x" $charNumber
|
||||
}
|
||||
|
||||
set quoted [\fBregsub\fR -all -command $RE $string encodeChar]
|
||||
.CE
|
||||
.PP
|
||||
Decoding a URL-encoded string using \fBregsub \-command\fR, a lambda term and
|
||||
the \fBapply\fR command.
|
||||
.PP
|
||||
.CS
|
||||
# Match one of the sequences in a URL-encoded string that needs
|
||||
# fixing, converting + to space and %XX to the right character
|
||||
# (e.g., %7e becomes ~)
|
||||
set RE {(\e+)|%([0-9A-Fa-f]{2})}
|
||||
|
||||
# Note that -command uses a command prefix, not a command name
|
||||
set decoded [\fBregsub\fR -all -command $RE $string {apply {{- p h} {
|
||||
# + is a special case; handle directly
|
||||
if {$p eq "+"} {
|
||||
return " "
|
||||
}
|
||||
# convert hex to a char
|
||||
scan $h %x charNumber
|
||||
format %c $charNumber
|
||||
}}}]
|
||||
.CE
|
||||
.VE 8.7
|
||||
.SH "SEE ALSO"
|
||||
regexp(n), re_syntax(n), subst(n), string(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+209
-202
@@ -140,73 +140,73 @@ static const crange alphaRangeTable[] = {
|
||||
{0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
|
||||
{0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
|
||||
{0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
|
||||
{0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x8b6, 0x8bd},
|
||||
{0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c},
|
||||
{0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1},
|
||||
{0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c},
|
||||
{0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
|
||||
{0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28},
|
||||
{0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a},
|
||||
{0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
|
||||
{0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39},
|
||||
{0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8},
|
||||
{0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
|
||||
{0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61}, {0xd7a, 0xd7f},
|
||||
{0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6},
|
||||
{0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f},
|
||||
{0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf},
|
||||
{0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a},
|
||||
{0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081},
|
||||
{0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 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},
|
||||
{0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {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}, {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, 0x312d},
|
||||
{0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5},
|
||||
{0x4e00, 0x9fd5}, {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}
|
||||
{0x800, 0x815}, {0x840, 0x858}, {0x860, 0x86a}, {0x8a0, 0x8b4},
|
||||
{0x8b6, 0x8bd}, {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980},
|
||||
{0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9},
|
||||
{0x9df, 0x9e1}, {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30},
|
||||
{0xa59, 0xa5c}, {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91},
|
||||
{0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c},
|
||||
{0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61},
|
||||
{0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa},
|
||||
{0xbae, 0xbb9}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
|
||||
{0xc2a, 0xc39}, {0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90},
|
||||
{0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c},
|
||||
{0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61},
|
||||
{0xd7a, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb},
|
||||
{0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97},
|
||||
{0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4},
|
||||
{0xedc, 0xedf}, {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c},
|
||||
{0x1000, 0x102a}, {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070},
|
||||
{0x1075, 0x1081}, {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 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}, {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd},
|
||||
{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},
|
||||
{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
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
|
||||
{0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
|
||||
{0x10300, 0x1031f}, {0x1032d, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
|
||||
{0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d},
|
||||
{0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563},
|
||||
{0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
|
||||
@@ -222,24 +222,26 @@ static const crange alphaRangeTable[] = {
|
||||
{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}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08},
|
||||
{0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {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}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
|
||||
{0x1bc90, 0x1bc99}, {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, 0x1d6c0},
|
||||
{0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734},
|
||||
{0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8},
|
||||
{0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943},
|
||||
{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}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
|
||||
{0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}
|
||||
{0x11700, 0x11719}, {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},
|
||||
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
|
||||
{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, 0x1d6c0}, {0x1d6c2, 0x1d6da},
|
||||
{0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734}, {0x1d736, 0x1d74e},
|
||||
{0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8}, {0x1d7aa, 0x1d7c2},
|
||||
{0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943}, {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}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
|
||||
{0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -250,28 +252,29 @@ static const chr alphaCharTable[] = {
|
||||
0x38c, 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef,
|
||||
0x6ff, 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828,
|
||||
0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd,
|
||||
0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38,
|
||||
0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xaf9,
|
||||
0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83,
|
||||
0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d,
|
||||
0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2,
|
||||
0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87,
|
||||
0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3,
|
||||
0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7,
|
||||
0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 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
|
||||
0x9f0, 0x9f1, 0x9fc, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
|
||||
0xa38, 0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1,
|
||||
0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71,
|
||||
0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0,
|
||||
0xc3d, 0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1,
|
||||
0xcf2, 0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84,
|
||||
0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2,
|
||||
0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e,
|
||||
0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae,
|
||||
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
|
||||
,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, 0x11c40,
|
||||
0x16f50, 0x16fe0, 0x1b000, 0x1b001, 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
|
||||
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
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -321,8 +324,8 @@ static const crange digitRangeTable[] = {
|
||||
,{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}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff},
|
||||
{0x1e950, 0x1e959}
|
||||
{0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59},
|
||||
{0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -345,7 +348,7 @@ 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, 0x2e44},
|
||||
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e49},
|
||||
{0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
|
||||
{0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
|
||||
{0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
|
||||
@@ -356,7 +359,8 @@ static const crange punctRangeTable[] = {
|
||||
{0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
|
||||
{0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
|
||||
{0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
|
||||
{0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
|
||||
{0x11a3f, 0x11a46}, {0x11a9a, 0x11a9c}, {0x11a9e, 0x11aa2}, {0x11c41, 0x11c45},
|
||||
{0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -367,14 +371,14 @@ 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,
|
||||
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
|
||||
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
|
||||
,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
|
||||
0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
|
||||
@@ -615,63 +619,63 @@ static const crange graphRangeTable[] = {
|
||||
{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}, {0x8a0, 0x8b4},
|
||||
{0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
|
||||
{0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
|
||||
{0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {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}, {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}, {0xd01, 0xd03}, {0xd05, 0xd0c},
|
||||
{0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd3d, 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, 0x1cf6}, {0x1d00, 0x1df5},
|
||||
{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, 0x20be}, {0x20d0, 0x20f0}, {0x2100, 0x218b},
|
||||
{0x2190, 0x23fe}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
|
||||
{0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1},
|
||||
{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},
|
||||
{0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
|
||||
{0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e44},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e49},
|
||||
{0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
|
||||
{0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312d},
|
||||
{0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312e},
|
||||
{0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
|
||||
{0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fd5}, {0xa000, 0xa48c},
|
||||
{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},
|
||||
@@ -694,7 +698,7 @@ static const crange graphRangeTable[] = {
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
|
||||
{0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
|
||||
{0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a},
|
||||
{0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x1032d, 0x1034a},
|
||||
{0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5},
|
||||
{0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb},
|
||||
{0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
|
||||
@@ -717,35 +721,38 @@ static const crange graphRangeTable[] = {
|
||||
{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},
|
||||
{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}, {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}, {0x1f300, 0x1f6d2}, {0x1f6e0, 0x1f6ec},
|
||||
{0x1f6f0, 0x1f6f6}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b},
|
||||
{0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad},
|
||||
{0x1f910, 0x1f91e}, {0x1f920, 0x1f927}, {0x1f933, 0x1f93e}, {0x1f940, 0x1f94b},
|
||||
{0x1f950, 0x1f95e}, {0x1f980, 0x1f991}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
|
||||
{0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
|
||||
{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}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -755,23 +762,23 @@ 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, 0xaf9, 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,
|
||||
0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d,
|
||||
0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
|
||||
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
|
||||
,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, 0x16a6e, 0x16a6f,
|
||||
0x16fe0, 0x1b000, 0x1b001, 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, 0x1f930, 0x1f9c0
|
||||
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
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -1059,7 +1059,7 @@ declare 293 {
|
||||
int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
|
||||
}
|
||||
declare 294 {
|
||||
void Tcl_ExitThread(int status)
|
||||
TCL_NORETURN void Tcl_ExitThread(int status)
|
||||
}
|
||||
declare 295 {
|
||||
int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding,
|
||||
|
||||
+25
-23
@@ -41,7 +41,6 @@ extern "C" {
|
||||
* unix/configure.ac (2 LOC Major, 2 LOC minor, 1 LOC patch)
|
||||
* win/configure.ac (as above)
|
||||
* win/tcl.m4 (not patchlevel)
|
||||
* win/makefile.bc (not patchlevel) 2 LOC
|
||||
* README (sections 0 and 2, with and without separator)
|
||||
* macosx/Tcl.pbproj/project.pbxproj (not patchlevel) 1 LOC
|
||||
* macosx/Tcl.pbproj/default.pbxuser (not patchlevel) 1 LOC
|
||||
@@ -61,6 +60,7 @@ extern "C" {
|
||||
#define TCL_VERSION "8.7"
|
||||
#define TCL_PATCH_LEVEL "8.7a0"
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) || defined(RC_INVOKED)
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* The following definitions set up the proper options for Windows compilers.
|
||||
@@ -89,6 +89,7 @@ extern "C" {
|
||||
# define JOIN(a,b) JOIN1(a,b)
|
||||
# define JOIN1(a,b) a##b
|
||||
#endif
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
* A special definition used to allow this header file to be included from
|
||||
@@ -140,7 +141,7 @@ extern "C" {
|
||||
# define TCL_VARARGS(type, name) (type name, ...)
|
||||
# define TCL_VARARGS_DEF(type, name) (type name, ...)
|
||||
# define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
|
||||
#endif
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||
# define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b)))
|
||||
# define TCL_NORETURN __attribute__ ((noreturn))
|
||||
@@ -256,7 +257,7 @@ extern "C" {
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
# undef _ANSI_ARGS_
|
||||
# define _ANSI_ARGS_(x) x
|
||||
#endif
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
* Definitions that allow this header file to be used either with or without
|
||||
@@ -376,8 +377,8 @@ typedef long LONG;
|
||||
* we have one, we can have the other.)
|
||||
*
|
||||
* Also defines the following macros:
|
||||
* TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a real
|
||||
* 64-bit system.)
|
||||
* TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a
|
||||
* LP64 system such as modern Solaris or Linux ... not including Win64)
|
||||
* Tcl_WideAsLong - forgetful converter from wideInt to long.
|
||||
* Tcl_LongAsWide - sign-extending converter from long to wideInt.
|
||||
* Tcl_WideAsDouble - converter from wideInt to double.
|
||||
@@ -394,11 +395,7 @@ typedef long LONG;
|
||||
#if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
|
||||
# if defined(_WIN32)
|
||||
# define TCL_WIDE_INT_TYPE __int64
|
||||
# ifdef __BORLANDC__
|
||||
# define TCL_LL_MODIFIER "L"
|
||||
# else /* __BORLANDC__ */
|
||||
# define TCL_LL_MODIFIER "I64"
|
||||
# endif /* __BORLANDC__ */
|
||||
# define TCL_LL_MODIFIER "I64"
|
||||
# elif defined(__GNUC__)
|
||||
# define TCL_WIDE_INT_TYPE long long
|
||||
# define TCL_LL_MODIFIER "ll"
|
||||
@@ -424,10 +421,6 @@ typedef TCL_WIDE_INT_TYPE Tcl_WideInt;
|
||||
typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
|
||||
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
# define Tcl_WideAsLong(val) ((long)(val))
|
||||
# define Tcl_LongAsWide(val) ((long)(val))
|
||||
# define Tcl_WideAsDouble(val) ((double)((long)(val)))
|
||||
# define Tcl_DoubleAsWide(val) ((long)((double)(val)))
|
||||
# ifndef TCL_LL_MODIFIER
|
||||
# define TCL_LL_MODIFIER "l"
|
||||
# endif /* !TCL_LL_MODIFIER */
|
||||
@@ -439,12 +432,13 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
|
||||
# ifndef TCL_LL_MODIFIER
|
||||
# define TCL_LL_MODIFIER "ll"
|
||||
# endif /* !TCL_LL_MODIFIER */
|
||||
# define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
|
||||
# define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val)))
|
||||
# define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val)))
|
||||
# define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val)))
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
#define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
|
||||
#define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val)))
|
||||
#define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val)))
|
||||
#define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val)))
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifdef __BORLANDC__
|
||||
typedef struct stati64 Tcl_StatBuf;
|
||||
@@ -529,7 +523,7 @@ typedef struct Tcl_Interp
|
||||
int errorLineDontUse; /* Don't use in extensions! */
|
||||
#endif
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
Tcl_Interp;
|
||||
|
||||
typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
|
||||
@@ -1003,7 +997,9 @@ typedef struct Tcl_DString {
|
||||
|
||||
#define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
|
||||
#define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
|
||||
#define Tcl_DStringTrunc Tcl_DStringSetLength
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
# define Tcl_DStringTrunc Tcl_DStringSetLength
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
* Definitions for the maximum number of digits of precision that may be
|
||||
@@ -1131,7 +1127,7 @@ typedef struct Tcl_DString {
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
# define TCL_PARSE_PART1 0x400
|
||||
#endif
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
* Types for linked variables:
|
||||
@@ -1147,8 +1143,13 @@ typedef struct Tcl_DString {
|
||||
#define TCL_LINK_SHORT 8
|
||||
#define TCL_LINK_USHORT 9
|
||||
#define TCL_LINK_UINT 10
|
||||
#if defined(TCL_WIDE_INT_IS_LONG) || defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define TCL_LINK_LONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_INT : TCL_LINK_INT)
|
||||
#define TCL_LINK_ULONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_UINT : TCL_LINK_UINT)
|
||||
#else
|
||||
#define TCL_LINK_LONG 11
|
||||
#define TCL_LINK_ULONG 12
|
||||
#endif
|
||||
#define TCL_LINK_FLOAT 13
|
||||
#define TCL_LINK_WIDE_UINT 14
|
||||
#define TCL_LINK_READ_ONLY 0x80
|
||||
@@ -2534,7 +2535,7 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
Tcl_DbNewBignumObj(val, __FILE__, __LINE__)
|
||||
# undef Tcl_NewBooleanObj
|
||||
# define Tcl_NewBooleanObj(val) \
|
||||
Tcl_DbNewBooleanObj(val, __FILE__, __LINE__)
|
||||
Tcl_DbNewLongObj((val)!=0, __FILE__, __LINE__)
|
||||
# undef Tcl_NewByteArrayObj
|
||||
# define Tcl_NewByteArrayObj(bytes, len) \
|
||||
Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
|
||||
@@ -2627,7 +2628,6 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
# define panic Tcl_Panic
|
||||
#endif
|
||||
# define panicVA Tcl_PanicVA
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -2638,6 +2638,8 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
|
||||
extern Tcl_AppInitProc Tcl_AppInit;
|
||||
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
#endif /* RC_INVOKED */
|
||||
|
||||
/*
|
||||
|
||||
+21
-1
@@ -137,6 +137,8 @@ typedef enum TalInstType {
|
||||
* ranges */
|
||||
ASSEM_BOOL, /* One Boolean operand */
|
||||
ASSEM_BOOL_LVT4, /* One Boolean, one 4-byte LVT ref. */
|
||||
ASSEM_CLOCK_READ, /* 1-byte unsigned-integer case number, in the
|
||||
* range 0-3 */
|
||||
ASSEM_CONCAT1, /* 1-byte unsigned-integer operand count, must
|
||||
* be strictly positive, consumes N, produces
|
||||
* 1 */
|
||||
@@ -350,6 +352,7 @@ static const TalInstDesc TalInstructionTable[] = {
|
||||
{"bitnot", ASSEM_1BYTE, INST_BITNOT, 1, 1},
|
||||
{"bitor", ASSEM_1BYTE, INST_BITOR, 2, 1},
|
||||
{"bitxor", ASSEM_1BYTE, INST_BITXOR, 2, 1},
|
||||
{"clockRead", ASSEM_CLOCK_READ, INST_CLOCK_READ, 0, 1},
|
||||
{"concat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1},
|
||||
{"concatStk", ASSEM_LIST, INST_CONCAT_STK, INT_MIN,1},
|
||||
{"coroName", ASSEM_1BYTE, INST_COROUTINE_NAME, 0, 1},
|
||||
@@ -1361,6 +1364,23 @@ AssembleOneLine(
|
||||
TclEmitInt4(localVar, envPtr);
|
||||
break;
|
||||
|
||||
case ASSEM_CLOCK_READ:
|
||||
if (parsePtr->numWords != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8");
|
||||
goto cleanup;
|
||||
}
|
||||
if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
if (opnd < 0 || opnd > 3) {
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewStringObj("operand must be [0..3]", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND<0,>3", NULL);
|
||||
goto cleanup;
|
||||
}
|
||||
BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, opnd);
|
||||
break;
|
||||
|
||||
case ASSEM_CONCAT1:
|
||||
if (parsePtr->numWords != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8");
|
||||
@@ -4246,7 +4266,7 @@ AddBasicBlockRangeToErrorInfo(
|
||||
Tcl_AppendObjToErrorInfo(interp, lineNo);
|
||||
Tcl_AddErrorInfo(interp, " and ");
|
||||
if (bbPtr->successor1 != NULL) {
|
||||
Tcl_SetIntObj(lineNo, bbPtr->successor1->startLine);
|
||||
TclSetLongObj(lineNo, bbPtr->successor1->startLine);
|
||||
Tcl_AppendObjToErrorInfo(interp, lineNo);
|
||||
} else {
|
||||
Tcl_AddErrorInfo(interp, "end of assembly code");
|
||||
|
||||
+62
-15
@@ -203,7 +203,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"append", Tcl_AppendObjCmd, TclCompileAppendCmd, NULL, CMD_IS_SAFE},
|
||||
{"apply", Tcl_ApplyObjCmd, NULL, TclNRApplyObjCmd, CMD_IS_SAFE},
|
||||
{"break", Tcl_BreakObjCmd, TclCompileBreakCmd, NULL, CMD_IS_SAFE},
|
||||
#ifndef EXCLUDE_OBSOLETE_COMMANDS
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
{"case", Tcl_CaseObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
#endif
|
||||
{"catch", Tcl_CatchObjCmd, TclCompileCatchCmd, TclNRCatchObjCmd, CMD_IS_SAFE},
|
||||
@@ -265,7 +265,6 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"cd", Tcl_CdObjCmd, NULL, NULL, 0},
|
||||
{"close", Tcl_CloseObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"eof", Tcl_EofObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"encoding", Tcl_EncodingObjCmd, NULL, NULL, 0},
|
||||
{"exec", Tcl_ExecObjCmd, NULL, NULL, 0},
|
||||
{"exit", Tcl_ExitObjCmd, NULL, NULL, 0},
|
||||
{"fblocked", Tcl_FblockedObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
@@ -511,7 +510,11 @@ Tcl_CreateInterp(void)
|
||||
iPtr = ckalloc(sizeof(Interp));
|
||||
interp = (Tcl_Interp *) iPtr;
|
||||
|
||||
#ifdef TCL_NO_DEPRECATED
|
||||
iPtr->result = &tclEmptyString;
|
||||
#else
|
||||
iPtr->result = iPtr->resultSpace;
|
||||
#endif
|
||||
iPtr->freeProc = NULL;
|
||||
iPtr->errorLine = 0;
|
||||
iPtr->objResultPtr = Tcl_NewObj();
|
||||
@@ -571,9 +574,11 @@ Tcl_CreateInterp(void)
|
||||
iPtr->rootFramePtr = NULL; /* Initialise as soon as :: is available */
|
||||
iPtr->lookupNsPtr = NULL;
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
iPtr->appendResult = NULL;
|
||||
iPtr->appendAvl = 0;
|
||||
iPtr->appendUsed = 0;
|
||||
#endif
|
||||
|
||||
Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
|
||||
iPtr->packageUnknown = NULL;
|
||||
@@ -603,7 +608,9 @@ Tcl_CreateInterp(void)
|
||||
iPtr->emptyObjPtr = Tcl_NewObj();
|
||||
/* Another empty object. */
|
||||
Tcl_IncrRefCount(iPtr->emptyObjPtr);
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
iPtr->resultSpace[0] = 0;
|
||||
#endif
|
||||
iPtr->threadId = Tcl_GetCurrentThread();
|
||||
|
||||
/* TIP #378 */
|
||||
@@ -790,16 +797,17 @@ Tcl_CreateInterp(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the "array", "binary", "chan", "dict", "file", "info",
|
||||
* "namespace" and "string" ensembles. Note that all these commands (and
|
||||
* their subcommands that are not present in the global namespace) are
|
||||
* wholly safe *except* for "file".
|
||||
* Create the "array", "binary", "chan", "clock", "dict", "encoding",
|
||||
* "file", "info", "namespace" and "string" ensembles. Note that all these
|
||||
* commands (and their subcommands that are not present in the global
|
||||
* namespace) are wholly safe *except* for "clock", "encoding" and "file".
|
||||
*/
|
||||
|
||||
TclInitArrayCmd(interp);
|
||||
TclInitBinaryCmd(interp);
|
||||
TclInitChanCmd(interp);
|
||||
TclInitDictCmd(interp);
|
||||
TclInitEncodingCmd(interp);
|
||||
TclInitFileCmd(interp);
|
||||
TclInitInfoCmd(interp);
|
||||
TclInitNamespaceCmd(interp);
|
||||
@@ -1027,6 +1035,7 @@ TclHideUnsafeCommands(
|
||||
Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
|
||||
}
|
||||
}
|
||||
TclMakeEncodingCommandSafe(interp); /* Ugh! */
|
||||
TclMakeFileCommandSafe(interp); /* Ugh! */
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1062,7 +1071,7 @@ Tcl_CallWhenDeleted(
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
static Tcl_ThreadDataKey assocDataCounterKey;
|
||||
int *assocDataCounterPtr =
|
||||
Tcl_GetThreadData(&assocDataCounterKey, (int)sizeof(int));
|
||||
Tcl_GetThreadData(&assocDataCounterKey, sizeof(int));
|
||||
int isNew;
|
||||
char buffer[32 + TCL_INTEGER_SPACE];
|
||||
AssocData *dPtr = ckalloc(sizeof(AssocData));
|
||||
@@ -1534,10 +1543,12 @@ DeleteInterpProc(
|
||||
if (iPtr->returnOpts) {
|
||||
Tcl_DecrRefCount(iPtr->returnOpts);
|
||||
}
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
if (iPtr->appendResult != NULL) {
|
||||
ckfree(iPtr->appendResult);
|
||||
iPtr->appendResult = NULL;
|
||||
}
|
||||
#endif
|
||||
TclFreePackageInfo(iPtr);
|
||||
while (iPtr->tracePtr != NULL) {
|
||||
Tcl_DeleteTrace((Tcl_Interp *) iPtr, (Tcl_Trace) iPtr->tracePtr);
|
||||
@@ -3550,7 +3561,7 @@ OldMathFuncProc(
|
||||
args[k].type = TCL_INT;
|
||||
break;
|
||||
}
|
||||
if (Tcl_GetWideIntFromObj(interp, valuePtr, &args[k].wideValue)
|
||||
if (TclGetWideIntFromObj(interp, valuePtr, &args[k].wideValue)
|
||||
== TCL_OK) {
|
||||
args[k].type = TCL_WIDE_INT;
|
||||
break;
|
||||
@@ -3576,7 +3587,7 @@ OldMathFuncProc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
valuePtr = Tcl_GetObjResult(interp);
|
||||
Tcl_GetWideIntFromObj(NULL, valuePtr, &args[k].wideValue);
|
||||
TclGetWideIntFromObj(NULL, valuePtr, &args[k].wideValue);
|
||||
Tcl_ResetResult(interp);
|
||||
break;
|
||||
}
|
||||
@@ -4705,7 +4716,7 @@ TEOV_RunEnterTraces(
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Command *cmdPtr = *cmdPtrPtr;
|
||||
int newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
|
||||
size_t newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
|
||||
int length, traceCode = TCL_OK;
|
||||
const char *command = TclGetStringFromObj(commandPtr, &length);
|
||||
|
||||
@@ -5850,6 +5861,7 @@ TclArgumentGet(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_Eval
|
||||
int
|
||||
Tcl_Eval(
|
||||
@@ -5902,6 +5914,7 @@ Tcl_GlobalEvalObj(
|
||||
{
|
||||
return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -6055,7 +6068,7 @@ TclNREvalObjEx(
|
||||
TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
|
||||
objPtr, NULL);
|
||||
|
||||
ListObjGetElements(listPtr, objc, objv);
|
||||
TclListObjGetElements(NULL, listPtr, &objc, &objv);
|
||||
return TclNREvalObjv(interp, objc, objv, flags, NULL);
|
||||
}
|
||||
|
||||
@@ -6728,6 +6741,7 @@ Tcl_AppendObjToErrorInfo(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_AddErrorInfo
|
||||
void
|
||||
Tcl_AddErrorInfo(
|
||||
@@ -6737,6 +6751,7 @@ Tcl_AddErrorInfo(
|
||||
{
|
||||
Tcl_AddObjErrorInfo(interp, message, -1);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -6909,6 +6924,7 @@ Tcl_VarEval(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_GlobalEval
|
||||
int
|
||||
Tcl_GlobalEval(
|
||||
@@ -6926,6 +6942,7 @@ Tcl_GlobalEval(
|
||||
iPtr->varFramePtr = savedVarFramePtr;
|
||||
return result;
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -7179,7 +7196,7 @@ ExprIsqrtFunc(
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (Tcl_GetWideIntFromObj(interp, objv[1], &w) != TCL_OK) {
|
||||
if (TclGetWideIntFromObj(interp, objv[1], &w) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (w < 0) {
|
||||
@@ -7622,7 +7639,7 @@ ExprWideFunc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objPtr = Tcl_GetObjResult(interp);
|
||||
if (Tcl_GetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) {
|
||||
if (TclGetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) {
|
||||
/*
|
||||
* Truncate the bignum; keep only bits in wide int range.
|
||||
*/
|
||||
@@ -7633,7 +7650,7 @@ ExprWideFunc(
|
||||
mp_mod_2d(&big, (int) CHAR_BIT * sizeof(Tcl_WideInt), &big);
|
||||
objPtr = Tcl_NewBignumObj(&big);
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
Tcl_GetWideIntFromObj(NULL, objPtr, &wResult);
|
||||
TclGetWideIntFromObj(NULL, objPtr, &wResult);
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult));
|
||||
@@ -8750,6 +8767,35 @@ TclNRCoroutineActivateCallback(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclNREvalList --
|
||||
*
|
||||
* Callback to invoke command as list, used in order to delayed
|
||||
* processing of canonical list command in sane environment.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
TclNREvalList(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
int objc;
|
||||
Tcl_Obj **objv;
|
||||
Tcl_Obj *listPtr = data[0];
|
||||
|
||||
Tcl_IncrRefCount(listPtr);
|
||||
|
||||
TclMarkTailcall(interp);
|
||||
TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL);
|
||||
TclListObjGetElements(NULL, listPtr, &objc, &objv);
|
||||
return TclNREvalObjv(interp, objc, objv, 0, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -8804,7 +8850,8 @@ NRCoroInjectObjCmd(
|
||||
*/
|
||||
|
||||
iPtr->execEnvPtr = corPtr->eePtr;
|
||||
TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN);
|
||||
TclNRAddCallback(interp, TclNREvalList, Tcl_NewListObj(objc-2, objv+2),
|
||||
NULL, NULL, NULL);
|
||||
iPtr->execEnvPtr = savedEEPtr;
|
||||
|
||||
return TCL_OK;
|
||||
|
||||
+12
-4
@@ -551,7 +551,7 @@ SetByteArrayFromAny(
|
||||
|
||||
byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
|
||||
for (dst = byteArrayPtr->bytes; src < srcEnd; ) {
|
||||
src += Tcl_UtfToUniChar(src, &ch);
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
improper = improper || (ch > 255);
|
||||
*dst++ = UCHAR(ch);
|
||||
}
|
||||
@@ -1303,7 +1303,7 @@ BinaryFormatCmd(
|
||||
Tcl_UniChar ch;
|
||||
char buf[TCL_UTF_MAX + 1];
|
||||
|
||||
Tcl_UtfToUniChar(errorString, &ch);
|
||||
TclUtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad field specifier \"%s\"", buf));
|
||||
@@ -1673,7 +1673,7 @@ BinaryScanCmd(
|
||||
Tcl_UniChar ch;
|
||||
char buf[TCL_UTF_MAX + 1];
|
||||
|
||||
Tcl_UtfToUniChar(errorString, &ch);
|
||||
TclUtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad field specifier \"%s\"", buf));
|
||||
@@ -1743,7 +1743,15 @@ GetFormatSpec(
|
||||
(*formatPtr)++;
|
||||
*countPtr = BINARY_ALL;
|
||||
} else if (isdigit(UCHAR(**formatPtr))) { /* INTL: digit */
|
||||
*countPtr = strtoul(*formatPtr, (char **) formatPtr, 10);
|
||||
unsigned long int count;
|
||||
|
||||
errno = 0;
|
||||
count = strtoul(*formatPtr, (char **) formatPtr, 10);
|
||||
if (errno || (count > (unsigned long) INT_MAX)) {
|
||||
*countPtr = INT_MAX;
|
||||
} else {
|
||||
*countPtr = (int) count;
|
||||
}
|
||||
} else {
|
||||
*countPtr = BINARY_NOCOUNT;
|
||||
}
|
||||
|
||||
+27
-24
@@ -89,14 +89,14 @@ static struct mem_header *allocHead = NULL; /* List of allocated structures */
|
||||
#define BODY_OFFSET \
|
||||
((size_t) (&((struct mem_header *) 0)->body))
|
||||
|
||||
static int total_mallocs = 0;
|
||||
static int total_frees = 0;
|
||||
static unsigned int total_mallocs = 0;
|
||||
static unsigned int total_frees = 0;
|
||||
static size_t current_bytes_malloced = 0;
|
||||
static size_t maximum_bytes_malloced = 0;
|
||||
static int current_malloc_packets = 0;
|
||||
static int maximum_malloc_packets = 0;
|
||||
static int break_on_malloc = 0;
|
||||
static int trace_on_at_malloc = 0;
|
||||
static unsigned int current_malloc_packets = 0;
|
||||
static unsigned int maximum_malloc_packets = 0;
|
||||
static unsigned int break_on_malloc = 0;
|
||||
static unsigned int trace_on_at_malloc = 0;
|
||||
static int alloc_tracing = FALSE;
|
||||
static int init_malloced_bodies = TRUE;
|
||||
#ifdef MEM_VALIDATE
|
||||
@@ -184,18 +184,18 @@ TclDumpMemoryInfo(
|
||||
return 0;
|
||||
}
|
||||
sprintf(buf,
|
||||
"total mallocs %10d\n"
|
||||
"total frees %10d\n"
|
||||
"current packets allocated %10d\n"
|
||||
"current bytes allocated %10lu\n"
|
||||
"maximum packets allocated %10d\n"
|
||||
"maximum bytes allocated %10lu\n",
|
||||
"total mallocs %10u\n"
|
||||
"total frees %10u\n"
|
||||
"current packets allocated %10u\n"
|
||||
"current bytes allocated %10" TCL_LL_MODIFIER "u\n"
|
||||
"maximum packets allocated %10u\n"
|
||||
"maximum bytes allocated %10" TCL_LL_MODIFIER "u\n",
|
||||
total_mallocs,
|
||||
total_frees,
|
||||
current_malloc_packets,
|
||||
(unsigned long)current_bytes_malloced,
|
||||
(Tcl_WideInt)current_bytes_malloced,
|
||||
maximum_malloc_packets,
|
||||
(unsigned long)maximum_bytes_malloced);
|
||||
(Tcl_WideInt)maximum_bytes_malloced);
|
||||
if (flags == 0) {
|
||||
fprintf((FILE *)clientData, "%s", buf);
|
||||
} else {
|
||||
@@ -359,9 +359,8 @@ Tcl_DumpActiveMemory(
|
||||
Tcl_MutexLock(ckallocMutexPtr);
|
||||
for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
|
||||
address = &memScanP->body[0];
|
||||
fprintf(fileP, "%8" TCL_LL_MODIFIER "x - %8" TCL_LL_MODIFIER "x %7" TCL_LL_MODIFIER "d @ %s %d %s",
|
||||
(Tcl_WideInt)(size_t)address,
|
||||
(Tcl_WideInt)((size_t)address + memScanP->length - 1),
|
||||
fprintf(fileP, "%p - %p %" TCL_LL_MODIFIER "d @ %s %d %s",
|
||||
address, address + memScanP->length - 1,
|
||||
(Tcl_WideInt)memScanP->length, memScanP->file, memScanP->line,
|
||||
(memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
|
||||
(void) fputc('\n', fileP);
|
||||
@@ -450,7 +449,7 @@ Tcl_DbCkalloc(
|
||||
total_mallocs++;
|
||||
if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
|
||||
(void) fflush(stdout);
|
||||
fprintf(stderr, "reached malloc trace enable point (%d)\n",
|
||||
fprintf(stderr, "reached malloc trace enable point (%u)\n",
|
||||
total_mallocs);
|
||||
fflush(stderr);
|
||||
alloc_tracing = TRUE;
|
||||
@@ -465,7 +464,7 @@ Tcl_DbCkalloc(
|
||||
if (break_on_malloc && (total_mallocs >= break_on_malloc)) {
|
||||
break_on_malloc = 0;
|
||||
(void) fflush(stdout);
|
||||
Tcl_Panic("reached malloc break limit (%d)", total_mallocs);
|
||||
Tcl_Panic("reached malloc break limit (%u)", total_mallocs);
|
||||
}
|
||||
|
||||
current_malloc_packets++;
|
||||
@@ -848,22 +847,24 @@ MemoryCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (strcmp(argv[1],"break_on_malloc") == 0) {
|
||||
int value;
|
||||
if (argc != 3) {
|
||||
goto argError;
|
||||
}
|
||||
if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK) {
|
||||
if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
break_on_malloc = (unsigned int) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (strcmp(argv[1],"info") == 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10lu\n%-25s %10d\n%-25s %10lu\n",
|
||||
"%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER"d\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER "d\n",
|
||||
"total mallocs", total_mallocs, "total frees", total_frees,
|
||||
"current packets allocated", current_malloc_packets,
|
||||
"current bytes allocated", (unsigned long)current_bytes_malloced,
|
||||
"current bytes allocated", (Tcl_WideInt)current_bytes_malloced,
|
||||
"maximum packets allocated", maximum_malloc_packets,
|
||||
"maximum bytes allocated", (unsigned long)maximum_bytes_malloced));
|
||||
"maximum bytes allocated", (Tcl_WideInt)maximum_bytes_malloced));
|
||||
return TCL_OK;
|
||||
}
|
||||
if (strcmp(argv[1], "init") == 0) {
|
||||
@@ -934,12 +935,14 @@ MemoryCmd(
|
||||
}
|
||||
|
||||
if (strcmp(argv[1],"trace_on_at_malloc") == 0) {
|
||||
int value;
|
||||
if (argc != 3) {
|
||||
goto argError;
|
||||
}
|
||||
if (Tcl_GetInt(interp, argv[2], &trace_on_at_malloc) != TCL_OK) {
|
||||
if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
trace_on_at_malloc = value;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (strcmp(argv[1],"validate") == 0) {
|
||||
|
||||
+29
-17
@@ -91,7 +91,7 @@ static const char *const literals[] = {
|
||||
* Structure containing the client data for [clock]
|
||||
*/
|
||||
|
||||
typedef struct ClockClientData {
|
||||
typedef struct {
|
||||
size_t refCount; /* Number of live references. */
|
||||
Tcl_Obj **literals; /* Pool of object literals. */
|
||||
} ClockClientData;
|
||||
@@ -208,11 +208,7 @@ struct ClockCommand {
|
||||
};
|
||||
|
||||
static const struct ClockCommand clockCommands[] = {
|
||||
{ "clicks", ClockClicksObjCmd },
|
||||
{ "getenv", ClockGetenvObjCmd },
|
||||
{ "microseconds", ClockMicrosecondsObjCmd },
|
||||
{ "milliseconds", ClockMillisecondsObjCmd },
|
||||
{ "seconds", ClockSecondsObjCmd },
|
||||
{ "Oldscan", TclClockOldscanObjCmd },
|
||||
{ "ConvertLocalToUTC", ClockConvertlocaltoutcObjCmd },
|
||||
{ "GetDateFields", ClockGetdatefieldsObjCmd },
|
||||
@@ -253,6 +249,19 @@ TclClockInit(
|
||||
ClockClientData *data;
|
||||
int i;
|
||||
|
||||
/* Structure of the 'clock' ensemble */
|
||||
|
||||
static const EnsembleImplMap clockImplMap[] = {
|
||||
{"add", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
|
||||
{"clicks", ClockClicksObjCmd, TclCompileClockClicksCmd, NULL, NULL, 0},
|
||||
{"format", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
|
||||
{"microseconds", ClockMicrosecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(1), 0},
|
||||
{"milliseconds", ClockMillisecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(2), 0},
|
||||
{"scan", NULL, TclCompileBasicMin1ArgCmd, NULL, NULL , 0},
|
||||
{"seconds", ClockSecondsObjCmd, TclCompileClockReadingCmd, NULL, INT2PTR(3), 0},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Safe interps get [::clock] as alias to a master, so do not need their
|
||||
* own copies of the support routines.
|
||||
@@ -276,6 +285,7 @@ TclClockInit(
|
||||
|
||||
/*
|
||||
* Install the commands.
|
||||
* TODO - Let Tcl_MakeEnsemble do this?
|
||||
*/
|
||||
|
||||
#define TCL_CLOCK_PREFIX_LEN 14 /* == strlen("::tcl::clock::") */
|
||||
@@ -286,6 +296,10 @@ TclClockInit(
|
||||
Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, data,
|
||||
ClockDeleteCmdProc);
|
||||
}
|
||||
|
||||
/* Make the clock ensemble */
|
||||
|
||||
TclMakeEnsemble(interp, "clock", clockImplMap);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -349,7 +363,7 @@ ClockConvertlocaltoutcObjCmd(
|
||||
"found in dictionary", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((Tcl_GetWideIntFromObj(interp, secondsObj,
|
||||
if ((TclGetWideIntFromObj(interp, secondsObj,
|
||||
&fields.localSeconds) != TCL_OK)
|
||||
|| (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK)
|
||||
|| ConvertLocalToUTC(interp, &fields, objv[2], changeover)) {
|
||||
@@ -428,7 +442,7 @@ ClockGetdatefieldsObjCmd(
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "seconds tzdata changeover");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_GetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK
|
||||
if (TclGetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1134,7 +1148,7 @@ LookupLastTransition(
|
||||
*/
|
||||
|
||||
if (Tcl_ListObjIndex(interp, rowv[0], 0, &compObj) != TCL_OK
|
||||
|| Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
|
||||
|| TclGetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1157,7 +1171,7 @@ LookupLastTransition(
|
||||
int m = (l + u + 1) / 2;
|
||||
|
||||
if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK ||
|
||||
Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
|
||||
TclGetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
if (tick >= compVal) {
|
||||
@@ -1507,9 +1521,9 @@ GetJulianDayFromEraYearMonthDay(
|
||||
* See above bug for details. The casts are necessary.
|
||||
*/
|
||||
if (ym1 >= 0)
|
||||
ym1o4 = ym1 / 4;
|
||||
ym1o4 = ym1 / 4;
|
||||
else {
|
||||
ym1o4 = - (int) (((unsigned int) -ym1) / 4);
|
||||
ym1o4 = - (int) (((unsigned int) -ym1) / 4);
|
||||
}
|
||||
#endif
|
||||
if (ym1 % 4 < 0) {
|
||||
@@ -1564,12 +1578,10 @@ static int
|
||||
IsGregorianLeapYear(
|
||||
TclDateFields *fields) /* Date to test */
|
||||
{
|
||||
int year;
|
||||
int year = fields->year;
|
||||
|
||||
if (fields->era == BCE) {
|
||||
year = 1 - fields->year;
|
||||
} else {
|
||||
year = fields->year;
|
||||
year = 1 - year;
|
||||
}
|
||||
if (year%4 != 0) {
|
||||
return 0;
|
||||
@@ -1680,7 +1692,7 @@ ThreadSafeLocalTime(
|
||||
* Get a thread-local buffer to hold the returned time.
|
||||
*/
|
||||
|
||||
struct tm *tmPtr = Tcl_GetThreadData(&tmKey, (int) sizeof(struct tm));
|
||||
struct tm *tmPtr = Tcl_GetThreadData(&tmKey, sizeof(struct tm));
|
||||
#ifdef HAVE_LOCALTIME_R
|
||||
localtime_r(timePtr, tmPtr);
|
||||
#else
|
||||
@@ -1936,7 +1948,7 @@ ClockParseformatargsObjCmd(
|
||||
* Check options.
|
||||
*/
|
||||
|
||||
if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) {
|
||||
if (TclGetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((saw & (1 << CLOCK_FORMAT_GMT))
|
||||
|
||||
+351
-72
@@ -46,9 +46,24 @@ struct ForeachState {
|
||||
|
||||
static int CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr,
|
||||
int mode);
|
||||
static int BadEncodingSubcommand(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int EncodingConvertfromObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int EncodingConverttoObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int EncodingDirsObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int EncodingNamesObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int EncodingSystemObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static inline int ForeachAssignments(Tcl_Interp *interp,
|
||||
struct ForeachState *statePtr);
|
||||
static inline void ForeachCleanup(Tcl_Interp *interp,
|
||||
@@ -149,7 +164,7 @@ Tcl_BreakObjCmd(
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
/* ARGSUSED */
|
||||
int
|
||||
Tcl_CaseObjCmd(
|
||||
@@ -267,6 +282,7 @@ Tcl_CaseObjCmd(
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -541,81 +557,282 @@ Tcl_EncodingObjCmd(
|
||||
|
||||
switch ((enum options) index) {
|
||||
case ENC_CONVERTTO:
|
||||
case ENC_CONVERTFROM: {
|
||||
Tcl_Obj *data;
|
||||
Tcl_DString ds;
|
||||
Tcl_Encoding encoding;
|
||||
int length;
|
||||
const char *stringPtr;
|
||||
|
||||
if (objc == 3) {
|
||||
encoding = Tcl_GetEncoding(interp, NULL);
|
||||
data = objv[2];
|
||||
} else if (objc == 4) {
|
||||
if (Tcl_GetEncodingFromObj(interp, objv[2], &encoding) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
data = objv[3];
|
||||
} else {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?encoding? data");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if ((enum options) index == ENC_CONVERTFROM) {
|
||||
/*
|
||||
* Treat the string as binary data.
|
||||
*/
|
||||
|
||||
stringPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
|
||||
Tcl_ExternalToUtfDString(encoding, stringPtr, length, &ds);
|
||||
|
||||
/*
|
||||
* Note that we cannot use Tcl_DStringResult here because it will
|
||||
* truncate the string at the first null byte.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, TclDStringToObj(&ds));
|
||||
} else {
|
||||
/*
|
||||
* Store the result as binary data.
|
||||
*/
|
||||
|
||||
stringPtr = TclGetStringFromObj(data, &length);
|
||||
Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds);
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(
|
||||
(unsigned char *) Tcl_DStringValue(&ds),
|
||||
Tcl_DStringLength(&ds)));
|
||||
Tcl_DStringFree(&ds);
|
||||
}
|
||||
|
||||
Tcl_FreeEncoding(encoding);
|
||||
break;
|
||||
}
|
||||
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:
|
||||
if (objc > 2) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_GetEncodingNames(interp);
|
||||
break;
|
||||
return EncodingNamesObjCmd(dummy, interp, objc, objv);
|
||||
case ENC_SYSTEM:
|
||||
if (objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?encoding?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objc == 2) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
Tcl_GetEncodingName(NULL), -1));
|
||||
} else {
|
||||
return Tcl_SetSystemEncoding(interp, TclGetString(objv[2]));
|
||||
}
|
||||
break;
|
||||
return EncodingSystemObjCmd(dummy, interp, objc, objv);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* TclInitEncodingCmd --
|
||||
*
|
||||
* This function creates the 'encoding' ensemble.
|
||||
*
|
||||
* Results:
|
||||
* Returns the Tcl_Command so created.
|
||||
*
|
||||
* Side effects:
|
||||
* The ensemble is initialized.
|
||||
*
|
||||
* This command is hidden in a safe interpreter.
|
||||
*/
|
||||
|
||||
Tcl_Command
|
||||
TclInitEncodingCmd(
|
||||
Tcl_Interp* interp) /* Tcl interpreter */
|
||||
{
|
||||
static const EnsembleImplMap encodingImplMap[] = {
|
||||
{"convertfrom", EncodingConvertfromObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"convertto", EncodingConverttoObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"names", EncodingNamesObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
return TclMakeEnsemble(interp, "encoding", encodingImplMap);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* TclMakeEncodingCommandSafe --
|
||||
*
|
||||
* This function hides the unsafe 'dirs' and 'system' subcommands of
|
||||
* the "encoding" Tcl command ensemble. It must be called only from
|
||||
* TclHideUnsafeCommands.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result
|
||||
*
|
||||
* Side effects:
|
||||
* Adds commands to the table of hidden commands.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclMakeEncodingCommandSafe(
|
||||
Tcl_Interp* interp) /* Tcl interpreter */
|
||||
{
|
||||
static const struct {
|
||||
const char *cmdName;
|
||||
int unsafe;
|
||||
} unsafeInfo[] = {
|
||||
{"convertfrom", 0},
|
||||
{"convertto", 0},
|
||||
{"dirs", 1},
|
||||
{"names", 0},
|
||||
{"system", 0},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
int i;
|
||||
Tcl_DString oldBuf, newBuf;
|
||||
|
||||
Tcl_DStringInit(&oldBuf);
|
||||
TclDStringAppendLiteral(&oldBuf, "::tcl::encoding::");
|
||||
Tcl_DStringInit(&newBuf);
|
||||
TclDStringAppendLiteral(&newBuf, "tcl:encoding:");
|
||||
for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
|
||||
if (unsafeInfo[i].unsafe) {
|
||||
const char *oldName, *newName;
|
||||
|
||||
Tcl_DStringSetLength(&oldBuf, 17);
|
||||
oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1);
|
||||
Tcl_DStringSetLength(&newBuf, 13);
|
||||
newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1);
|
||||
if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK
|
||||
|| Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) {
|
||||
Tcl_Panic("problem making 'encoding %s' safe: %s",
|
||||
unsafeInfo[i].cmdName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
Tcl_CreateObjCommand(interp, oldName, BadEncodingSubcommand,
|
||||
(ClientData) unsafeInfo[i].cmdName, NULL);
|
||||
}
|
||||
}
|
||||
Tcl_DStringFree(&oldBuf);
|
||||
Tcl_DStringFree(&newBuf);
|
||||
|
||||
/*
|
||||
* Ugh. The [encoding] command is now actually safe, but it is assumed by
|
||||
* scripts that it is not, which messes up security policies.
|
||||
*/
|
||||
|
||||
if (Tcl_HideCommand(interp, "encoding", "encoding") != TCL_OK) {
|
||||
Tcl_Panic("problem making 'encoding' safe: %s",
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* BadEncodingSubcommand --
|
||||
*
|
||||
* Command used to act as a backstop implementation when subcommands of
|
||||
* "encoding" are unsafe (the real implementations of the subcommands are
|
||||
* hidden). The clientData is always the full official subcommand name.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result (always a TCL_ERROR).
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
BadEncodingSubcommand(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
const char *subcommandName = (const char *) clientData;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"not allowed to invoke subcommand %s of encoding", subcommandName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* EncodingConvertfromObjCmd --
|
||||
*
|
||||
* This command converts a byte array in an external encoding into a
|
||||
* Tcl string
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
EncodingConvertfromObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_Obj *data; /* Byte array to convert */
|
||||
Tcl_DString ds; /* Buffer to hold the string */
|
||||
Tcl_Encoding encoding; /* Encoding to use */
|
||||
int length; /* Length of the byte array being converted */
|
||||
const char *bytesPtr; /* Pointer to the first byte of the array */
|
||||
|
||||
if (objc == 2) {
|
||||
encoding = Tcl_GetEncoding(interp, NULL);
|
||||
data = objv[1];
|
||||
} else if (objc == 3) {
|
||||
if (Tcl_GetEncodingFromObj(interp, objv[1], &encoding) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
data = objv[2];
|
||||
} else {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?encoding? data");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the string into a byte array in 'ds'
|
||||
*/
|
||||
bytesPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
|
||||
Tcl_ExternalToUtfDString(encoding, bytesPtr, length, &ds);
|
||||
|
||||
/*
|
||||
* Note that we cannot use Tcl_DStringResult here because it will
|
||||
* truncate the string at the first null byte.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, TclDStringToObj(&ds));
|
||||
|
||||
/*
|
||||
* We're done with the encoding
|
||||
*/
|
||||
|
||||
Tcl_FreeEncoding(encoding);
|
||||
return TCL_OK;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* EncodingConverttoObjCmd --
|
||||
*
|
||||
* This command converts a Tcl string into a byte array that
|
||||
* encodes the string according to some encoding.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
EncodingConverttoObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_Obj *data; /* String to convert */
|
||||
Tcl_DString ds; /* Buffer to hold the byte array */
|
||||
Tcl_Encoding encoding; /* Encoding to use */
|
||||
int length; /* Length of the string being converted */
|
||||
const char *stringPtr; /* Pointer to the first byte of the string */
|
||||
|
||||
/* TODO - ADJUST OBJ INDICES WHEN ENSEMBLIFYING THIS */
|
||||
|
||||
if (objc == 2) {
|
||||
encoding = Tcl_GetEncoding(interp, NULL);
|
||||
data = objv[1];
|
||||
} else if (objc == 3) {
|
||||
if (Tcl_GetEncodingFromObj(interp, objv[1], &encoding) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
data = objv[2];
|
||||
} else {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?encoding? data");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the string to a byte array in 'ds'
|
||||
*/
|
||||
|
||||
stringPtr = TclGetStringFromObj(data, &length);
|
||||
Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds);
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewByteArrayObj((unsigned char*) Tcl_DStringValue(&ds),
|
||||
Tcl_DStringLength(&ds)));
|
||||
Tcl_DStringFree(&ds);
|
||||
|
||||
/*
|
||||
* We're done with the encoding
|
||||
*/
|
||||
|
||||
Tcl_FreeEncoding(encoding);
|
||||
return TCL_OK;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -641,16 +858,16 @@ EncodingDirsObjCmd(
|
||||
{
|
||||
Tcl_Obj *dirListObj;
|
||||
|
||||
if (objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?dirList?");
|
||||
if (objc > 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?dirList?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objc == 2) {
|
||||
if (objc == 1) {
|
||||
Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath());
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
dirListObj = objv[2];
|
||||
dirListObj = objv[1];
|
||||
if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected directory list but got \"%s\"",
|
||||
@@ -663,6 +880,68 @@ EncodingDirsObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* EncodingNamesObjCmd --
|
||||
*
|
||||
* This command returns a list of the available encoding names
|
||||
*
|
||||
* Results:
|
||||
* Returns a standard Tcl result
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
EncodingNamesObjCmd(ClientData dummy, /* Unused */
|
||||
Tcl_Interp* interp, /* Tcl interpreter */
|
||||
int objc, /* Number of command line args */
|
||||
Tcl_Obj* const objv[]) /* Vector of command line args */
|
||||
{
|
||||
if (objc > 1) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_GetEncodingNames(interp);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* EncodingSystemObjCmd --
|
||||
*
|
||||
* This command retrieves or changes the system encoding
|
||||
*
|
||||
* Results:
|
||||
* Returns a standard Tcl result
|
||||
*
|
||||
* Side effects:
|
||||
* May change the system encoding.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
EncodingSystemObjCmd(ClientData dummy, /* Unused */
|
||||
Tcl_Interp* interp, /* Tcl interpreter */
|
||||
int objc, /* Number of command line args */
|
||||
Tcl_Obj* const objv[]) /* Vector of command line args */
|
||||
{
|
||||
if (objc > 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?encoding?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objc == 1) {
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewStringObj(Tcl_GetEncodingName(NULL), -1));
|
||||
} else {
|
||||
return Tcl_SetSystemEncoding(interp, TclGetString(objv[1]));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+20
-21
@@ -3682,7 +3682,7 @@ Tcl_LsortObjCmd(
|
||||
int sortMode = SORTMODE_ASCII;
|
||||
int group, groupSize, groupOffset, idx, allocatedIndexVector = 0;
|
||||
Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr;
|
||||
SortElement *elementArray, *elementPtr;
|
||||
SortElement *elementArray = NULL, *elementPtr;
|
||||
SortInfo sortInfo; /* Information about this sort that needs to
|
||||
* be passed to the comparison function. */
|
||||
# define NUM_LISTS 30
|
||||
@@ -3728,7 +3728,7 @@ Tcl_LsortObjCmd(
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0,
|
||||
&index) != TCL_OK) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
switch ((enum Lsort_Switches) index) {
|
||||
case LSORT_ASCII:
|
||||
@@ -3741,7 +3741,7 @@ Tcl_LsortObjCmd(
|
||||
"by comparison command", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
sortInfo.sortMode = SORTMODE_COMMAND;
|
||||
cmdPtr = objv[i+1];
|
||||
@@ -3766,12 +3766,12 @@ Tcl_LsortObjCmd(
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
if (TclListObjGetElements(interp, objv[i+1], &indexc,
|
||||
&indexv) != TCL_OK) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3788,7 +3788,7 @@ Tcl_LsortObjCmd(
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (-index option item number %d)", j));
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
indexPtr = objv[i+1];
|
||||
@@ -3817,11 +3817,11 @@ Tcl_LsortObjCmd(
|
||||
"followed by stride length", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
if (groupSize < 2) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
@@ -3829,7 +3829,7 @@ Tcl_LsortObjCmd(
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
|
||||
"BADSTRIDE", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
group = 1;
|
||||
i++;
|
||||
@@ -3884,7 +3884,7 @@ Tcl_LsortObjCmd(
|
||||
listObj = TclListObjCopy(interp, listObj);
|
||||
if (listObj == NULL) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3902,7 +3902,7 @@ Tcl_LsortObjCmd(
|
||||
Tcl_IncrRefCount(newObjPtr);
|
||||
TclDecrRefCount(newObjPtr);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
goto done;
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
|
||||
sortInfo.compareCmdPtr = newCommandPtr;
|
||||
@@ -3995,7 +3995,7 @@ Tcl_LsortObjCmd(
|
||||
* begins sorting it into the sublists as it appears.
|
||||
*/
|
||||
|
||||
elementArray = TclStackAlloc(interp, length * sizeof(SortElement));
|
||||
elementArray = ckalloc(length * sizeof(SortElement));
|
||||
|
||||
for (i=0; i < length; i++){
|
||||
idx = groupSize * i + groupOffset;
|
||||
@@ -4005,7 +4005,7 @@ Tcl_LsortObjCmd(
|
||||
*/
|
||||
indexPtr = SelectObjFromSublist(listObjPtrs[idx], &sortInfo);
|
||||
if (sortInfo.resultCode != TCL_OK) {
|
||||
goto done1;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
indexPtr = listObjPtrs[idx];
|
||||
@@ -4022,7 +4022,7 @@ Tcl_LsortObjCmd(
|
||||
|
||||
if (TclGetWideIntFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done1;
|
||||
goto done;
|
||||
}
|
||||
elementArray[i].collationKey.wideValue = a;
|
||||
} else if (sortMode == SORTMODE_REAL) {
|
||||
@@ -4031,7 +4031,7 @@ Tcl_LsortObjCmd(
|
||||
if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr,
|
||||
&a) != TCL_OK) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done1;
|
||||
goto done;
|
||||
}
|
||||
elementArray[i].collationKey.doubleValue = a;
|
||||
} else {
|
||||
@@ -4118,19 +4118,18 @@ Tcl_LsortObjCmd(
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
}
|
||||
|
||||
done1:
|
||||
TclStackFree(interp, elementArray);
|
||||
|
||||
done:
|
||||
if (sortMode == SORTMODE_COMMAND) {
|
||||
TclDecrRefCount(sortInfo.compareCmdPtr);
|
||||
TclDecrRefCount(listObj);
|
||||
sortInfo.compareCmdPtr = NULL;
|
||||
}
|
||||
done2:
|
||||
if (allocatedIndexVector) {
|
||||
TclStackFree(interp, sortInfo.indexv);
|
||||
}
|
||||
if (elementArray) {
|
||||
ckfree(elementArray);
|
||||
}
|
||||
return sortInfo.resultCode;
|
||||
}
|
||||
|
||||
@@ -4440,8 +4439,8 @@ DictionaryCompare(
|
||||
*/
|
||||
|
||||
if ((*left != '\0') && (*right != '\0')) {
|
||||
left += Tcl_UtfToUniChar(left, &uniLeft);
|
||||
right += Tcl_UtfToUniChar(right, &uniRight);
|
||||
left += TclUtfToUniChar(left, &uniLeft);
|
||||
right += TclUtfToUniChar(right, &uniRight);
|
||||
|
||||
/*
|
||||
* Convert both chars to lower for the comparison, because
|
||||
|
||||
+149
-11
@@ -487,26 +487,28 @@ Tcl_RegsubObjCmd(
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
int idx, result, cflags, all, wlen, wsublen, numMatches, offset;
|
||||
int start, end, subStart, subEnd, match;
|
||||
int start, end, subStart, subEnd, match, command, numParts, numArgs;
|
||||
Tcl_RegExp regExpr;
|
||||
Tcl_RegExpInfo info;
|
||||
Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
|
||||
Tcl_Obj **args = NULL, **parts;
|
||||
Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
|
||||
|
||||
static const char *const options[] = {
|
||||
"-all", "-nocase", "-expanded",
|
||||
"-line", "-linestop", "-lineanchor", "-start",
|
||||
"-all", "-command", "-expanded", "-line",
|
||||
"-linestop", "-lineanchor", "-nocase", "-start",
|
||||
"--", NULL
|
||||
};
|
||||
enum options {
|
||||
REGSUB_ALL, REGSUB_NOCASE, REGSUB_EXPANDED,
|
||||
REGSUB_LINE, REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_START,
|
||||
REGSUB_ALL, REGSUB_COMMAND, REGSUB_EXPANDED, REGSUB_LINE,
|
||||
REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_NOCASE, REGSUB_START,
|
||||
REGSUB_LAST
|
||||
};
|
||||
|
||||
cflags = TCL_REG_ADVANCED;
|
||||
all = 0;
|
||||
offset = 0;
|
||||
command = 0;
|
||||
resultPtr = NULL;
|
||||
|
||||
for (idx = 1; idx < objc; idx++) {
|
||||
@@ -528,6 +530,9 @@ Tcl_RegsubObjCmd(
|
||||
case REGSUB_NOCASE:
|
||||
cflags |= TCL_REG_NOCASE;
|
||||
break;
|
||||
case REGSUB_COMMAND:
|
||||
command = 1;
|
||||
break;
|
||||
case REGSUB_EXPANDED:
|
||||
cflags |= TCL_REG_EXPANDED;
|
||||
break;
|
||||
@@ -585,7 +590,7 @@ Tcl_RegsubObjCmd(
|
||||
}
|
||||
}
|
||||
|
||||
if (all && (offset == 0)
|
||||
if (all && (offset == 0) && (command == 0)
|
||||
&& (strpbrk(TclGetString(objv[2]), "&\\") == NULL)
|
||||
&& (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) {
|
||||
/*
|
||||
@@ -661,6 +666,28 @@ Tcl_RegsubObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (command) {
|
||||
/*
|
||||
* In command-prefix mode, we require that the third non-option
|
||||
* argument be a list, so we enforce that here. Afterwards, we fetch
|
||||
* the RE compilation again in case objv[0] and objv[2] are the same
|
||||
* object. (If they aren't, that's cheap to do.)
|
||||
*/
|
||||
|
||||
if (Tcl_ListObjLength(interp, objv[2], &numParts) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (numParts < 1) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"command prefix must be a list of at least one element",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "REGSUB",
|
||||
"CMDEMPTY", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure to avoid problems where the objects are shared. This can
|
||||
* cause RegExpObj <> UnicodeObj shimmering that causes data corruption.
|
||||
@@ -678,7 +705,9 @@ Tcl_RegsubObjCmd(
|
||||
} else {
|
||||
subPtr = objv[2];
|
||||
}
|
||||
wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen);
|
||||
if (!command) {
|
||||
wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen);
|
||||
}
|
||||
|
||||
result = TCL_OK;
|
||||
|
||||
@@ -736,6 +765,88 @@ Tcl_RegsubObjCmd(
|
||||
end = info.matches[0].end;
|
||||
Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, start);
|
||||
|
||||
/*
|
||||
* In command-prefix mode, the substitutions are added as quoted
|
||||
* arguments to the subSpec to form a command, that is then executed
|
||||
* and the result used as the string to substitute in. Actually,
|
||||
* everything is passed through Tcl_EvalObjv, as that's much faster.
|
||||
*/
|
||||
|
||||
if (command) {
|
||||
if (args == NULL) {
|
||||
Tcl_ListObjGetElements(interp, subPtr, &numParts, &parts);
|
||||
numArgs = numParts + info.nsubs + 1;
|
||||
args = ckalloc(sizeof(Tcl_Obj*) * numArgs);
|
||||
memcpy(args, parts, sizeof(Tcl_Obj*) * numParts);
|
||||
}
|
||||
|
||||
for (idx = 0 ; idx <= info.nsubs ; idx++) {
|
||||
subStart = info.matches[idx].start;
|
||||
subEnd = info.matches[idx].end;
|
||||
if ((subStart >= 0) && (subEnd >= 0)) {
|
||||
args[idx + numParts] = Tcl_NewUnicodeObj(
|
||||
wstring + offset + subStart, subEnd - subStart);
|
||||
} else {
|
||||
args[idx + numParts] = Tcl_NewObj();
|
||||
}
|
||||
Tcl_IncrRefCount(args[idx + numParts]);
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, we're locally holding the references to the
|
||||
* argument words we added for this time round the loop, and the
|
||||
* subPtr is holding the references to the words that the user
|
||||
* supplied directly. None are zero-refcount, which is important
|
||||
* because Tcl_EvalObjv is "hairy monster" in terms of refcount
|
||||
* handling, being able to optionally add references to any of its
|
||||
* argument words. We'll drop the local refs immediately
|
||||
* afterwarsds; subPtr is handled in the main exit stanza.
|
||||
*/
|
||||
|
||||
result = Tcl_EvalObjv(interp, numArgs, args, 0);
|
||||
for (idx = 0 ; idx <= info.nsubs ; idx++) {
|
||||
TclDecrRefCount(args[idx + numParts]);
|
||||
}
|
||||
if (result != TCL_OK) {
|
||||
if (result == TCL_ERROR) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (%s substitution computation script)",
|
||||
options[REGSUB_COMMAND]));
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
Tcl_AppendObjToObj(resultPtr, Tcl_GetObjResult(interp));
|
||||
Tcl_ResetResult(interp);
|
||||
|
||||
/*
|
||||
* Refetch the unicode, in case the representation was smashed by
|
||||
* the user code.
|
||||
*/
|
||||
|
||||
wstring = Tcl_GetUnicodeFromObj(objPtr, &wlen);
|
||||
|
||||
offset += end;
|
||||
if (end == 0 || start == end) {
|
||||
/*
|
||||
* Always consume at least one character of the input string
|
||||
* in order to prevent infinite loops, even when we
|
||||
* technically matched the empty string; we must not match
|
||||
* again at the same spot.
|
||||
*/
|
||||
|
||||
if (offset < wlen) {
|
||||
Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
if (all) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Append the subSpec argument to the variable, making appropriate
|
||||
* substitutions. This code is a bit hairy because of the backslash
|
||||
@@ -864,6 +975,9 @@ Tcl_RegsubObjCmd(
|
||||
if (subPtr && (objv[2] == objv[0])) {
|
||||
Tcl_DecrRefCount(subPtr);
|
||||
}
|
||||
if (args) {
|
||||
ckfree(args);
|
||||
}
|
||||
if (resultPtr) {
|
||||
Tcl_DecrRefCount(resultPtr);
|
||||
}
|
||||
@@ -989,8 +1103,11 @@ TclNRSourceObjCmd(
|
||||
{
|
||||
const char *encodingName = NULL;
|
||||
Tcl_Obj *fileName;
|
||||
int result;
|
||||
void **pkgFiles = NULL;
|
||||
void *names = NULL;
|
||||
|
||||
if (objc != 2 && objc !=4) {
|
||||
if (objc < 2 || objc > 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?-encoding name? fileName");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1008,9 +1125,30 @@ TclNRSourceObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
encodingName = TclGetString(objv[2]);
|
||||
}
|
||||
} else if (objc == 3) {
|
||||
/* Handle undocumented -nopkg option. This should only be
|
||||
* used by the internal ::tcl::Pkg::source utility function. */
|
||||
static const char *const nopkgoptions[] = {
|
||||
"-nopkg", NULL
|
||||
};
|
||||
int index;
|
||||
|
||||
return TclNREvalFile(interp, fileName, encodingName);
|
||||
if (TCL_ERROR == Tcl_GetIndexFromObj(interp, objv[1], nopkgoptions,
|
||||
"option", TCL_EXACT, &index)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL);
|
||||
/* Make sure that during the following TclNREvalFile no filenames
|
||||
* are recorded for inclusion in the "package files" command */
|
||||
names = *pkgFiles;
|
||||
*pkgFiles = NULL;
|
||||
}
|
||||
result = TclNREvalFile(interp, fileName, encodingName);
|
||||
if (pkgFiles) {
|
||||
/* restore "tclPkgFiles" assocdata to how it was. */
|
||||
*pkgFiles = names;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1541,7 +1679,7 @@ StringIsCmd(
|
||||
}
|
||||
break;
|
||||
case STR_IS_WIDE:
|
||||
if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {
|
||||
if (TCL_OK == TclGetWideIntFromObj(NULL, objPtr, &w)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -734,6 +734,105 @@ TclCompileCatchCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileClockClicksCmd --
|
||||
*
|
||||
* Procedure called to compile the "tcl::clock::clicks" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to run time.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "clock clicks"
|
||||
* command at runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileClockClicksCmd(
|
||||
Tcl_Interp* interp, /* Tcl interpreter */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token* tokenPtr;
|
||||
|
||||
switch (parsePtr->numWords) {
|
||||
case 1:
|
||||
/*
|
||||
* No args
|
||||
*/
|
||||
TclEmitInstInt1(INST_CLOCK_READ, 0, envPtr);
|
||||
break;
|
||||
case 2:
|
||||
/*
|
||||
* -milliseconds or -microseconds
|
||||
*/
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD
|
||||
|| tokenPtr[1].size < 4
|
||||
|| tokenPtr[1].size > 13) {
|
||||
return TCL_ERROR;
|
||||
} else if (!strncmp(tokenPtr[1].start, "-microseconds",
|
||||
tokenPtr[1].size)) {
|
||||
TclEmitInstInt1(INST_CLOCK_READ, 1, envPtr);
|
||||
break;
|
||||
} else if (!strncmp(tokenPtr[1].start, "-milliseconds",
|
||||
tokenPtr[1].size)) {
|
||||
TclEmitInstInt1(INST_CLOCK_READ, 2, envPtr);
|
||||
break;
|
||||
} else {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
default:
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileClockReadingCmd --
|
||||
*
|
||||
* Procedure called to compile the "tcl::clock::microseconds",
|
||||
* "tcl::clock::milliseconds" and "tcl::clock::seconds" commands.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to run time.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "clock clicks"
|
||||
* command at runtime.
|
||||
*
|
||||
* Client data is 1 for microseconds, 2 for milliseconds, 3 for seconds.
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileClockReadingCmd(
|
||||
Tcl_Interp* interp, /* Tcl interpreter */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
if (parsePtr->numWords != 1) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclEmitInstInt1(INST_CLOCK_READ, PTR2INT(cmdPtr->objClientData), envPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
@@ -2064,13 +2064,13 @@ ParseLexeme(
|
||||
|
||||
if (!TclIsBareword(*start) || *start == '_') {
|
||||
if (Tcl_UtfCharComplete(start, numBytes)) {
|
||||
scanned = Tcl_UtfToUniChar(start, &ch);
|
||||
scanned = TclUtfToUniChar(start, &ch);
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
|
||||
memcpy(utfBytes, start, (size_t) numBytes);
|
||||
utfBytes[numBytes] = '\0';
|
||||
scanned = Tcl_UtfToUniChar(utfBytes, &ch);
|
||||
scanned = TclUtfToUniChar(utfBytes, &ch);
|
||||
}
|
||||
*lexemePtr = INVALID;
|
||||
Tcl_DecrRefCount(literal);
|
||||
|
||||
@@ -654,6 +654,11 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
/* Lappend list to general variable.
|
||||
* Stack: ... varName list => ... listVarContents */
|
||||
|
||||
{"clockRead", 2, +1, 1, {OPERAND_UINT1}},
|
||||
/* Read clock out to the stack. Operand is which clock to read
|
||||
* 0=clicks, 1=microseconds, 2=milliseconds, 3=seconds.
|
||||
* Stack: ... => ... time */
|
||||
|
||||
{NULL, 0, 0, 0, {OPERAND_NONE}}
|
||||
};
|
||||
|
||||
|
||||
+16
-14
@@ -425,7 +425,7 @@ typedef struct ByteCode {
|
||||
* compiled. If the code is executed if a
|
||||
* different namespace, it must be
|
||||
* recompiled. */
|
||||
int nsEpoch; /* Value of nsPtr->resolverEpoch when this
|
||||
size_t nsEpoch; /* Value of nsPtr->resolverEpoch when this
|
||||
* ByteCode was compiled. Used to invalidate
|
||||
* code when new namespace resolution rules
|
||||
* are put into effect. */
|
||||
@@ -821,8 +821,10 @@ typedef struct ByteCode {
|
||||
#define INST_LAPPEND_LIST_ARRAY_STK 187
|
||||
#define INST_LAPPEND_LIST_STK 188
|
||||
|
||||
#define INST_CLOCK_READ 189
|
||||
|
||||
/* The last opcode */
|
||||
#define LAST_INST_OPCODE 188
|
||||
#define LAST_INST_OPCODE 189
|
||||
|
||||
/*
|
||||
* Table describing the Tcl bytecode instructions: their name (for displaying
|
||||
@@ -1238,10 +1240,10 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
|
||||
#define TclCheckStackDepth(depth, envPtr) \
|
||||
do { \
|
||||
int dd = (depth); \
|
||||
if (dd != (envPtr)->currStackDepth) { \
|
||||
int _dd = (depth); \
|
||||
if (_dd != (envPtr)->currStackDepth) { \
|
||||
Tcl_Panic("bad stack depth computations: is %i, should be %i", \
|
||||
(envPtr)->currStackDepth, dd); \
|
||||
(envPtr)->currStackDepth, _dd); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -1257,12 +1259,12 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
|
||||
#define TclUpdateStackReqs(op, i, envPtr) \
|
||||
do { \
|
||||
int delta = tclInstructionTable[(op)].stackEffect; \
|
||||
if (delta) { \
|
||||
if (delta == INT_MIN) { \
|
||||
delta = 1 - (i); \
|
||||
int _delta = tclInstructionTable[(op)].stackEffect; \
|
||||
if (_delta) { \
|
||||
if (_delta == INT_MIN) { \
|
||||
_delta = 1 - (i); \
|
||||
} \
|
||||
TclAdjustStackDepth(delta, envPtr); \
|
||||
TclAdjustStackDepth(_delta, envPtr); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
@@ -1376,11 +1378,11 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
|
||||
#define TclEmitPush(objIndex, envPtr) \
|
||||
do { \
|
||||
register int objIndexCopy = (objIndex); \
|
||||
if (objIndexCopy <= 255) { \
|
||||
TclEmitInstInt1(INST_PUSH1, objIndexCopy, (envPtr)); \
|
||||
register int _objIndexCopy = (objIndex); \
|
||||
if (_objIndexCopy <= 255) { \
|
||||
TclEmitInstInt1(INST_PUSH1, _objIndexCopy, (envPtr)); \
|
||||
} else { \
|
||||
TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \
|
||||
TclEmitInstInt4(INST_PUSH4, _objIndexCopy, (envPtr)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
+47
-8
@@ -878,7 +878,7 @@ EXTERN int Tcl_EvalObjv(Tcl_Interp *interp, int objc,
|
||||
EXTERN int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
int flags);
|
||||
/* 294 */
|
||||
EXTERN void Tcl_ExitThread(int status);
|
||||
EXTERN TCL_NORETURN void Tcl_ExitThread(int status);
|
||||
/* 295 */
|
||||
EXTERN int Tcl_ExternalToUtf(Tcl_Interp *interp,
|
||||
Tcl_Encoding encoding, const char *src,
|
||||
@@ -2151,7 +2151,7 @@ typedef struct TclStubs {
|
||||
int (*tcl_EvalEx) (Tcl_Interp *interp, const char *script, int numBytes, int flags); /* 291 */
|
||||
int (*tcl_EvalObjv) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags); /* 292 */
|
||||
int (*tcl_EvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 293 */
|
||||
void (*tcl_ExitThread) (int status); /* 294 */
|
||||
TCL_NORETURN1 void (*tcl_ExitThread) (int status); /* 294 */
|
||||
int (*tcl_ExternalToUtf) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 295 */
|
||||
char * (*tcl_ExternalToUtfDString) (Tcl_Encoding encoding, const char *src, int srcLen, Tcl_DString *dsPtr); /* 296 */
|
||||
void (*tcl_FinalizeThread) (void); /* 297 */
|
||||
@@ -3835,13 +3835,13 @@ extern const TclStubs *tclStubsPtr;
|
||||
sizeof(char *), msg, flags, indexPtr)
|
||||
#undef Tcl_NewBooleanObj
|
||||
#define Tcl_NewBooleanObj(boolValue) \
|
||||
Tcl_NewIntObj((boolValue)!=0)
|
||||
Tcl_NewLongObj((boolValue)!=0)
|
||||
#undef Tcl_DbNewBooleanObj
|
||||
#define Tcl_DbNewBooleanObj(boolValue, file, line) \
|
||||
Tcl_DbNewLongObj((boolValue)!=0, file, line)
|
||||
#undef Tcl_SetBooleanObj
|
||||
#define Tcl_SetBooleanObj(objPtr, boolValue) \
|
||||
Tcl_SetIntObj((objPtr), (boolValue)!=0)
|
||||
Tcl_SetLongObj(objPtr, (boolValue)!=0)
|
||||
#undef Tcl_SetVar
|
||||
#define Tcl_SetVar(interp, varName, newValue, flags) \
|
||||
Tcl_SetVar2(interp, varName, NULL, newValue, flags)
|
||||
@@ -3869,6 +3869,45 @@ extern const TclStubs *tclStubsPtr;
|
||||
#undef Tcl_AddObjErrorInfo
|
||||
#define Tcl_AddObjErrorInfo(interp, message, length) \
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_NewStringObj(message, length))
|
||||
#ifdef TCL_NO_DEPRECATED
|
||||
#undef Tcl_Eval
|
||||
#define Tcl_Eval(interp, objPtr) \
|
||||
Tcl_EvalEx(interp, objPtr, -1, 0)
|
||||
#undef Tcl_GlobalEval
|
||||
#define Tcl_GlobalEval(interp, objPtr) \
|
||||
Tcl_EvalEx(interp, objPtr, -1, TCL_EVAL_GLOBAL)
|
||||
#undef Tcl_SaveResult
|
||||
#define Tcl_SaveResult(interp, statePtr) \
|
||||
do { \
|
||||
(statePtr)->objResultPtr = Tcl_GetObjResult(interp); \
|
||||
Tcl_IncrRefCount((statePtr)->objResultPtr); \
|
||||
Tcl_SetObjResult(interp, Tcl_NewObj()); \
|
||||
} while(0)
|
||||
#undef Tcl_RestoreResult
|
||||
#define Tcl_RestoreResult(interp, statePtr) \
|
||||
do { \
|
||||
Tcl_ResetResult(interp); \
|
||||
Tcl_SetObjResult(interp, (statePtr)->objResultPtr); \
|
||||
Tcl_DecrRefCount((statePtr)->objResultPtr); \
|
||||
} while(0)
|
||||
#undef Tcl_DiscardResult
|
||||
#define Tcl_DiscardResult(statePtr) \
|
||||
Tcl_DecrRefCount((statePtr)->objResultPtr)
|
||||
#undef Tcl_SetResult
|
||||
#define Tcl_SetResult(interp, result, freeProc) \
|
||||
do { \
|
||||
char *__result = result; \
|
||||
Tcl_FreeProc *__freeProc = freeProc; \
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(__result, -1)); \
|
||||
if (__result != NULL && __freeProc != NULL && __freeProc != TCL_VOLATILE) { \
|
||||
if (__freeProc == TCL_DYNAMIC) { \
|
||||
ckfree(__result); \
|
||||
} else { \
|
||||
(*__freeProc)(__result); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)
|
||||
# if defined(__CYGWIN__) && defined(TCL_WIDE_INT_IS_LONG)
|
||||
@@ -3923,10 +3962,10 @@ extern const TclStubs *tclStubsPtr;
|
||||
*/
|
||||
|
||||
#undef Tcl_EvalObj
|
||||
#define Tcl_EvalObj(interp,objPtr) \
|
||||
Tcl_EvalObjEx((interp),(objPtr),0)
|
||||
#define Tcl_EvalObj(interp, objPtr) \
|
||||
Tcl_EvalObjEx(interp, objPtr, 0)
|
||||
#undef Tcl_GlobalEvalObj
|
||||
#define Tcl_GlobalEvalObj(interp,objPtr) \
|
||||
Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL)
|
||||
#define Tcl_GlobalEvalObj(interp, objPtr) \
|
||||
Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL)
|
||||
|
||||
#endif /* _TCLDECLS */
|
||||
|
||||
@@ -506,7 +506,7 @@ UpdateStringOfDict(
|
||||
|
||||
/* Handle empty list case first, simplifies what follows */
|
||||
if (numElems == 0) {
|
||||
dictPtr->bytes = tclEmptyStringRep;
|
||||
dictPtr->bytes = &tclEmptyString;
|
||||
dictPtr->length = 0;
|
||||
return;
|
||||
}
|
||||
@@ -3562,7 +3562,7 @@ TclDictWithFinish(
|
||||
* If the dictionary variable doesn't exist, drop everything silently.
|
||||
*/
|
||||
|
||||
dictPtr = TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
dictPtr = TclPtrGetVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
TCL_LEAVE_ERR_MSG, index);
|
||||
if (dictPtr == NULL) {
|
||||
return TCL_OK;
|
||||
@@ -3645,8 +3645,8 @@ TclDictWithFinish(
|
||||
* Write back the outermost dictionary to the variable.
|
||||
*/
|
||||
|
||||
if (TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, dictPtr,
|
||||
TCL_LEAVE_ERR_MSG, index) == NULL) {
|
||||
if (TclPtrSetVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
dictPtr, TCL_LEAVE_ERR_MSG, index) == NULL) {
|
||||
if (allocdict) {
|
||||
TclDecrRefCount(dictPtr);
|
||||
}
|
||||
|
||||
+20
-26
@@ -27,9 +27,8 @@ static Tcl_Obj * DisassembleByteCodeObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
static int FormatInstruction(ByteCode *codePtr,
|
||||
const unsigned char *pc, Tcl_Obj *bufferObj);
|
||||
static void GetLocationInformation(Tcl_Interp *interp,
|
||||
Proc *procPtr, Tcl_Obj **fileObjPtr,
|
||||
int *linePtr);
|
||||
static void GetLocationInformation(Proc *procPtr,
|
||||
Tcl_Obj **fileObjPtr, int *linePtr);
|
||||
static void PrintSourceToObj(Tcl_Obj *appendObj,
|
||||
const char *stringPtr, int maxChars);
|
||||
static void UpdateStringOfInstName(Tcl_Obj *objPtr);
|
||||
@@ -73,8 +72,6 @@ static const Tcl_ObjType tclInstNameType = {
|
||||
|
||||
static void
|
||||
GetLocationInformation(
|
||||
Tcl_Interp *interp, /* Where to look up the location
|
||||
* information. */
|
||||
Proc *procPtr, /* What to look up the information for. */
|
||||
Tcl_Obj **fileObjPtr, /* Where to write the information about what
|
||||
* file the code came from. Will be written
|
||||
@@ -88,20 +85,21 @@ GetLocationInformation(
|
||||
* either with the line number or with -1 if
|
||||
* the information is not available. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_HashEntry *hePtr;
|
||||
CmdFrame *cfPtr;
|
||||
CmdFrame *cfPtr = TclGetCmdFrameForProcedure(procPtr);
|
||||
|
||||
*fileObjPtr = NULL;
|
||||
*linePtr = -1;
|
||||
if (iPtr != NULL && procPtr != NULL) {
|
||||
hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, procPtr);
|
||||
if (hePtr != NULL && (cfPtr = Tcl_GetHashValue(hePtr)) != NULL) {
|
||||
*linePtr = cfPtr->line[0];
|
||||
if (cfPtr->type == TCL_LOCATION_SOURCE) {
|
||||
*fileObjPtr = cfPtr->data.eval.path;
|
||||
}
|
||||
}
|
||||
if (cfPtr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the source location data out of the CmdFrame.
|
||||
*/
|
||||
|
||||
*linePtr = cfPtr->line[0];
|
||||
if (cfPtr->type == TCL_LOCATION_SOURCE) {
|
||||
*fileObjPtr = cfPtr->data.eval.path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +252,6 @@ DisassembleByteCodeObj(
|
||||
int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
|
||||
Interp *iPtr = (Interp *) *codePtr->interpHandle;
|
||||
Tcl_Obj *bufferObj, *fileObj;
|
||||
char ptrBuf1[20], ptrBuf2[20];
|
||||
|
||||
TclNewObj(bufferObj);
|
||||
if (codePtr->refCount <= 0) {
|
||||
@@ -269,16 +266,14 @@ DisassembleByteCodeObj(
|
||||
* Print header lines describing the ByteCode.
|
||||
*/
|
||||
|
||||
sprintf(ptrBuf1, "%p", codePtr);
|
||||
sprintf(ptrBuf2, "%p", iPtr);
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
"ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n",
|
||||
ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2,
|
||||
"ByteCode %p, refCt %u, epoch %u, interp %p (epoch %u)\n",
|
||||
codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr,
|
||||
iPtr->compileEpoch);
|
||||
Tcl_AppendToObj(bufferObj, " Source ", -1);
|
||||
PrintSourceToObj(bufferObj, codePtr->source,
|
||||
TclMin(codePtr->numSrcBytes, 55));
|
||||
GetLocationInformation(interp, codePtr->procPtr, &fileObj, &line);
|
||||
GetLocationInformation(codePtr->procPtr, &fileObj, &line);
|
||||
if (line > -1 && fileObj != NULL) {
|
||||
Tcl_AppendPrintfToObj(bufferObj, "\n File \"%s\" Line %d",
|
||||
Tcl_GetString(fileObj), line);
|
||||
@@ -316,10 +311,9 @@ DisassembleByteCodeObj(
|
||||
Proc *procPtr = codePtr->procPtr;
|
||||
int numCompiledLocals = procPtr->numCompiledLocals;
|
||||
|
||||
sprintf(ptrBuf1, "%p", procPtr);
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
" Proc 0x%s, refCt %d, args %d, compiled locals %d\n",
|
||||
ptrBuf1, procPtr->refCount, procPtr->numArgs,
|
||||
" Proc %p, refCt %d, args %d, compiled locals %d\n",
|
||||
procPtr, procPtr->refCount, procPtr->numArgs,
|
||||
numCompiledLocals);
|
||||
if (numCompiledLocals > 0) {
|
||||
CompiledLocal *localPtr = procPtr->firstLocalPtr;
|
||||
@@ -1221,7 +1215,7 @@ DisassembleByteCodeAsDicts(
|
||||
* system if it is available.
|
||||
*/
|
||||
|
||||
GetLocationInformation(interp, codePtr->procPtr, &file, &line);
|
||||
GetLocationInformation(codePtr->procPtr, &file, &line);
|
||||
|
||||
/*
|
||||
* Build the overall result.
|
||||
|
||||
@@ -2341,7 +2341,7 @@ UtfToUtfProc(
|
||||
src += 2;
|
||||
} else if (!Tcl_UtfCharComplete(src, srcEnd - src)) {
|
||||
/*
|
||||
* Always check before using Tcl_UtfToUniChar. Not doing can so
|
||||
* Always check before using TclUtfToUniChar. Not doing can so
|
||||
* cause it run beyond the endof the buffer! If we happen such an
|
||||
* incomplete char its byts are made to represent themselves.
|
||||
*/
|
||||
@@ -2350,7 +2350,7 @@ UtfToUtfProc(
|
||||
src += 1;
|
||||
dst += Tcl_UniCharToUtf(ch, dst);
|
||||
} else {
|
||||
src += Tcl_UtfToUniChar(src, &ch);
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
dst += Tcl_UniCharToUtf(ch, dst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ static const Tcl_ObjType ensembleCmdType = {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int epoch; /* Used to confirm when the data in this
|
||||
size_t epoch; /* Used to confirm when the data in this
|
||||
* really structure matches up with the
|
||||
* ensemble. */
|
||||
Command *token; /* Reference to the command for which this
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ typedef struct BgError {
|
||||
* pending background errors for the interpreter.
|
||||
*/
|
||||
|
||||
typedef struct ErrAssocData {
|
||||
typedef struct {
|
||||
Tcl_Interp *interp; /* Interpreter in which error occurred. */
|
||||
Tcl_Obj *cmdPrefix; /* First word(s) of the handler command */
|
||||
BgError *firstBgPtr; /* First in list of all background errors
|
||||
|
||||
+68
-48
@@ -510,9 +510,8 @@ VarHashCreateVar(
|
||||
: (*(tPtr) = TCL_NUMBER_DOUBLE)), \
|
||||
*(ptrPtr) = (ClientData) \
|
||||
(&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
|
||||
((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \
|
||||
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \
|
||||
? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \
|
||||
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \
|
||||
? TCL_ERROR : \
|
||||
TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
|
||||
#else /* !TCL_WIDE_INT_IS_LONG */
|
||||
#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
|
||||
@@ -530,9 +529,8 @@ VarHashCreateVar(
|
||||
: (*(tPtr) = TCL_NUMBER_DOUBLE)), \
|
||||
*(ptrPtr) = (ClientData) \
|
||||
(&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
|
||||
((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \
|
||||
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \
|
||||
? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR : \
|
||||
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \
|
||||
? TCL_ERROR : \
|
||||
TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
@@ -910,9 +908,9 @@ TclCreateExecEnv(
|
||||
+ (size_t) (size-1) * sizeof(Tcl_Obj *));
|
||||
|
||||
eePtr->execStackPtr = esPtr;
|
||||
TclNewBooleanObj(eePtr->constants[0], 0);
|
||||
TclNewLongObj(eePtr->constants[0], 0);
|
||||
Tcl_IncrRefCount(eePtr->constants[0]);
|
||||
TclNewBooleanObj(eePtr->constants[1], 1);
|
||||
TclNewLongObj(eePtr->constants[1], 1);
|
||||
Tcl_IncrRefCount(eePtr->constants[1]);
|
||||
eePtr->interp = interp;
|
||||
eePtr->callbackPtr = NULL;
|
||||
@@ -3186,7 +3184,7 @@ TEBCresume(
|
||||
*/
|
||||
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrGetVar(interp, varPtr, arrayPtr,
|
||||
objResultPtr = TclPtrGetVarIdx(interp, varPtr, arrayPtr,
|
||||
part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (!objResultPtr) {
|
||||
@@ -3433,7 +3431,7 @@ TEBCresume(
|
||||
|
||||
doCallPtrSetVar:
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrSetVar(interp, varPtr, arrayPtr,
|
||||
objResultPtr = TclPtrSetVarIdx(interp, varPtr, arrayPtr,
|
||||
part1Ptr, part2Ptr, valuePtr, storeFlags, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (!objResultPtr) {
|
||||
@@ -3569,7 +3567,7 @@ TEBCresume(
|
||||
VarHashRefCount(arrayPtr)++;
|
||||
}
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrGetVar(interp, varPtr, arrayPtr,
|
||||
objResultPtr = TclPtrGetVarIdx(interp, varPtr, arrayPtr,
|
||||
part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (TclIsVarInHash(varPtr)) {
|
||||
@@ -3598,7 +3596,7 @@ TEBCresume(
|
||||
}
|
||||
}
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr,
|
||||
objResultPtr = TclPtrSetVarIdx(interp, varPtr, arrayPtr, part1Ptr,
|
||||
part2Ptr, objResultPtr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (!objResultPtr) {
|
||||
@@ -3862,7 +3860,7 @@ TEBCresume(
|
||||
Tcl_DecrRefCount(incrPtr);
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrIncrObjVar(interp, varPtr, arrayPtr,
|
||||
objResultPtr = TclPtrIncrObjVarIdx(interp, varPtr, arrayPtr,
|
||||
part1Ptr, part2Ptr, incrPtr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
Tcl_DecrRefCount(incrPtr);
|
||||
@@ -4017,7 +4015,7 @@ TEBCresume(
|
||||
|
||||
slowUnsetScalar:
|
||||
DECACHE_STACK_INFO();
|
||||
if (TclPtrUnsetVar(interp, varPtr, NULL, NULL, NULL, flags,
|
||||
if (TclPtrUnsetVarIdx(interp, varPtr, NULL, NULL, NULL, flags,
|
||||
opnd) != TCL_OK && flags) {
|
||||
goto errorInUnset;
|
||||
}
|
||||
@@ -4069,7 +4067,7 @@ TEBCresume(
|
||||
if (flags & TCL_LEAVE_ERR_MSG) {
|
||||
goto errorInUnset;
|
||||
}
|
||||
} else if (TclPtrUnsetVar(interp, varPtr, arrayPtr, NULL, part2Ptr,
|
||||
} else if (TclPtrUnsetVarIdx(interp, varPtr, arrayPtr, NULL, part2Ptr,
|
||||
flags, opnd) != TCL_OK && (flags & TCL_LEAVE_ERR_MSG)) {
|
||||
goto errorInUnset;
|
||||
}
|
||||
@@ -4126,7 +4124,7 @@ TEBCresume(
|
||||
varPtr->value.objPtr = NULL;
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
TclPtrUnsetVar(interp, varPtr, NULL, NULL, NULL, 0, opnd);
|
||||
TclPtrUnsetVarIdx(interp, varPtr, NULL, NULL, NULL, 0, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
}
|
||||
NEXT_INST_F(5, 0, 0);
|
||||
@@ -4342,7 +4340,7 @@ TEBCresume(
|
||||
if (TclIsVarInHash(otherPtr)) {
|
||||
VarHashRefCount(otherPtr)++;
|
||||
}
|
||||
} else if (TclPtrObjMakeUpvar(interp, otherPtr, NULL, 0,
|
||||
} else if (TclPtrObjMakeUpvarIdx(interp, otherPtr, NULL, 0,
|
||||
opnd) != TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
@@ -5950,16 +5948,17 @@ TEBCresume(
|
||||
value2Ptr = OBJ_AT_TOS;
|
||||
valuePtr = OBJ_UNDER_TOS;
|
||||
|
||||
if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) {
|
||||
if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK
|
||||
|| GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) {
|
||||
/*
|
||||
* At least one non-numeric argument - compare as strings.
|
||||
*/
|
||||
|
||||
goto stringCompare;
|
||||
}
|
||||
if (type1 == TCL_NUMBER_NAN) {
|
||||
if (type1 == TCL_NUMBER_NAN || type2 == TCL_NUMBER_NAN) {
|
||||
/*
|
||||
* NaN first arg: NaN != to everything, other compares are false.
|
||||
* NaN arg: NaN != to everything, other compares are false.
|
||||
*/
|
||||
|
||||
iResult = (*pc == INST_NEQ);
|
||||
@@ -5969,21 +5968,6 @@ TEBCresume(
|
||||
compare = MP_EQ;
|
||||
goto convertComparison;
|
||||
}
|
||||
if (GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) {
|
||||
/*
|
||||
* At least one non-numeric argument - compare as strings.
|
||||
*/
|
||||
|
||||
goto stringCompare;
|
||||
}
|
||||
if (type2 == TCL_NUMBER_NAN) {
|
||||
/*
|
||||
* NaN 2nd arg: NaN != to everything, other compares are false.
|
||||
*/
|
||||
|
||||
iResult = (*pc == INST_NEQ);
|
||||
goto foundResult;
|
||||
}
|
||||
if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
|
||||
l1 = *((const long *)ptr1);
|
||||
l2 = *((const long *)ptr2);
|
||||
@@ -6778,7 +6762,7 @@ TEBCresume(
|
||||
}
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
|
||||
if (TclPtrSetVarIdx(interp, varPtr, NULL, NULL, NULL,
|
||||
valuePtr, TCL_LEAVE_ERR_MSG, varIndex)==NULL){
|
||||
CACHE_STACK_INFO();
|
||||
TRACE_APPEND((
|
||||
@@ -6949,7 +6933,7 @@ TEBCresume(
|
||||
}
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
|
||||
if (TclPtrSetVarIdx(interp, varPtr, NULL, NULL, NULL,
|
||||
valuePtr, TCL_LEAVE_ERR_MSG, varIndex)==NULL){
|
||||
CACHE_STACK_INFO();
|
||||
TRACE_APPEND(("ERROR init. index temp %d: %.30s",
|
||||
@@ -7172,7 +7156,8 @@ TEBCresume(
|
||||
dictPtr = varPtr->value.objPtr;
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
dictPtr = TclPtrGetVar(interp, varPtr, NULL,NULL,NULL, 0, opnd2);
|
||||
dictPtr = TclPtrGetVarIdx(interp, varPtr, NULL, NULL, NULL, 0,
|
||||
opnd2);
|
||||
CACHE_STACK_INFO();
|
||||
}
|
||||
if (dictPtr == NULL) {
|
||||
@@ -7246,7 +7231,7 @@ TEBCresume(
|
||||
} else {
|
||||
Tcl_IncrRefCount(dictPtr);
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
|
||||
objResultPtr = TclPtrSetVarIdx(interp, varPtr, NULL, NULL, NULL,
|
||||
dictPtr, TCL_LEAVE_ERR_MSG, opnd2);
|
||||
CACHE_STACK_INFO();
|
||||
TclDecrRefCount(dictPtr);
|
||||
@@ -7275,7 +7260,8 @@ TEBCresume(
|
||||
dictPtr = varPtr->value.objPtr;
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
dictPtr = TclPtrGetVar(interp, varPtr, NULL, NULL, NULL, 0, opnd);
|
||||
dictPtr = TclPtrGetVarIdx(interp, varPtr, NULL, NULL, NULL, 0,
|
||||
opnd);
|
||||
CACHE_STACK_INFO();
|
||||
}
|
||||
if (dictPtr == NULL) {
|
||||
@@ -7384,7 +7370,7 @@ TEBCresume(
|
||||
} else {
|
||||
Tcl_IncrRefCount(dictPtr);
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
|
||||
objResultPtr = TclPtrSetVarIdx(interp, varPtr, NULL, NULL, NULL,
|
||||
dictPtr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
TclDecrRefCount(dictPtr);
|
||||
@@ -7478,7 +7464,7 @@ TEBCresume(
|
||||
dictPtr = varPtr->value.objPtr;
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
dictPtr = TclPtrGetVar(interp, varPtr, NULL, NULL, NULL,
|
||||
dictPtr = TclPtrGetVarIdx(interp, varPtr, NULL, NULL, NULL,
|
||||
TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (dictPtr == NULL) {
|
||||
@@ -7511,7 +7497,7 @@ TEBCresume(
|
||||
TclObjUnsetVar2(interp,
|
||||
localName(iPtr->varFramePtr, duiPtr->varIndices[i]),
|
||||
NULL, 0);
|
||||
} else if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
|
||||
} else if (TclPtrSetVarIdx(interp, varPtr, NULL, NULL, NULL,
|
||||
valuePtr, TCL_LEAVE_ERR_MSG,
|
||||
duiPtr->varIndices[i]) == NULL) {
|
||||
CACHE_STACK_INFO();
|
||||
@@ -7538,7 +7524,8 @@ TEBCresume(
|
||||
dictPtr = varPtr->value.objPtr;
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
dictPtr = TclPtrGetVar(interp, varPtr, NULL, NULL, NULL, 0, opnd);
|
||||
dictPtr = TclPtrGetVarIdx(interp, varPtr, NULL, NULL, NULL, 0,
|
||||
opnd);
|
||||
CACHE_STACK_INFO();
|
||||
}
|
||||
if (dictPtr == NULL) {
|
||||
@@ -7568,8 +7555,8 @@ TEBCresume(
|
||||
valuePtr = var2Ptr->value.objPtr;
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
valuePtr = TclPtrGetVar(interp, var2Ptr, NULL, NULL, NULL, 0,
|
||||
duiPtr->varIndices[i]);
|
||||
valuePtr = TclPtrGetVarIdx(interp, var2Ptr, NULL, NULL, NULL,
|
||||
0, duiPtr->varIndices[i]);
|
||||
CACHE_STACK_INFO();
|
||||
}
|
||||
if (valuePtr == NULL) {
|
||||
@@ -7587,7 +7574,7 @@ TEBCresume(
|
||||
varPtr->value.objPtr = dictPtr;
|
||||
} else {
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
|
||||
objResultPtr = TclPtrSetVarIdx(interp, varPtr, NULL, NULL, NULL,
|
||||
dictPtr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (objResultPtr == NULL) {
|
||||
@@ -7678,6 +7665,39 @@ TEBCresume(
|
||||
* -----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
case INST_CLOCK_READ:
|
||||
{ /* Read the wall clock */
|
||||
Tcl_WideInt wval;
|
||||
Tcl_Time now;
|
||||
switch(TclGetUInt1AtPtr(pc+1)) {
|
||||
case 0: /* clicks */
|
||||
#ifdef TCL_WIDE_CLICKS
|
||||
wval = TclpGetWideClicks();
|
||||
#else
|
||||
wval = (Tcl_WideInt) TclpGetClicks();
|
||||
#endif
|
||||
break;
|
||||
case 1: /* microseconds */
|
||||
Tcl_GetTime(&now);
|
||||
wval = (Tcl_WideInt) now.sec * 1000000 + now.usec;
|
||||
break;
|
||||
case 2: /* milliseconds */
|
||||
Tcl_GetTime(&now);
|
||||
wval = (Tcl_WideInt) now.sec * 1000 + now.usec / 1000;
|
||||
break;
|
||||
case 3: /* seconds */
|
||||
Tcl_GetTime(&now);
|
||||
wval = (Tcl_WideInt) now.sec;
|
||||
break;
|
||||
default:
|
||||
Tcl_Panic("clockRead instruction with unknown clock#");
|
||||
}
|
||||
/* TclNewWideObj(objResultPtr, wval); doesn't exist */
|
||||
objResultPtr = Tcl_NewWideIntObj(wval);
|
||||
TRACE_WITH_OBJ(("=> "), objResultPtr);
|
||||
NEXT_INST_F(2, 0, 1);
|
||||
}
|
||||
|
||||
default:
|
||||
Tcl_Panic("TclNRExecuteByteCode: unrecognized opCode %u", *pc);
|
||||
} /* end of switch on opCode */
|
||||
@@ -9213,7 +9233,7 @@ TclCompareTwoNumbers(
|
||||
Tcl_Obj *valuePtr,
|
||||
Tcl_Obj *value2Ptr)
|
||||
{
|
||||
int type1, type2, compare;
|
||||
int type1 = TCL_NUMBER_NAN, type2 = TCL_NUMBER_NAN, compare;
|
||||
ClientData ptr1, ptr2;
|
||||
mp_int big1, big2;
|
||||
double d1, d2, tmp;
|
||||
|
||||
@@ -62,15 +62,14 @@ Tcl_RecordAndEval(
|
||||
* instead of Tcl_Eval. */
|
||||
{
|
||||
register Tcl_Obj *cmdPtr;
|
||||
int length = strlen(cmd);
|
||||
int result;
|
||||
|
||||
if (length > 0) {
|
||||
if (cmd[0]) {
|
||||
/*
|
||||
* Call Tcl_RecordAndEvalObj to do the actual work.
|
||||
*/
|
||||
|
||||
cmdPtr = Tcl_NewStringObj(cmd, length);
|
||||
cmdPtr = Tcl_NewStringObj(cmd, -1);
|
||||
Tcl_IncrRefCount(cmdPtr);
|
||||
result = Tcl_RecordAndEvalObj(interp, cmdPtr, flags);
|
||||
|
||||
|
||||
+401
-373
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -214,7 +214,7 @@ typedef struct ChannelState {
|
||||
* because it happened in the background. The
|
||||
* value is the chanMg, if any. #219's
|
||||
* companion to 'unreportedError'. */
|
||||
int epoch; /* Used to test validity of stored channelname
|
||||
size_t epoch; /* Used to test validity of stored channelname
|
||||
* lookup results. */
|
||||
} ChannelState;
|
||||
|
||||
|
||||
+29
-16
@@ -25,7 +25,7 @@ typedef struct AcceptCallback {
|
||||
* It must be per-thread because of std channel limitations.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
int initialized; /* Set to 1 when the module is initialized. */
|
||||
Tcl_Obj *stdoutObjPtr; /* Cached stdout channel Tcl_Obj */
|
||||
} ThreadSpecificData;
|
||||
@@ -113,7 +113,6 @@ Tcl_PutsObjCmd(
|
||||
int newline; /* Add a newline at end? */
|
||||
int result; /* Result of puts operation. */
|
||||
int mode; /* Mode in which channel is opened. */
|
||||
ThreadSpecificData *tsdPtr;
|
||||
|
||||
switch (objc) {
|
||||
case 2: /* [puts $x] */
|
||||
@@ -160,7 +159,7 @@ Tcl_PutsObjCmd(
|
||||
}
|
||||
|
||||
if (chanObjPtr == NULL) {
|
||||
tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
if (!tsdPtr->initialized) {
|
||||
tsdPtr->initialized = 1;
|
||||
@@ -1618,19 +1617,34 @@ Tcl_SocketObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
// Set the options to their default value if the user didn't override their
|
||||
// value.
|
||||
if (reusep == -1) reusep = 0;
|
||||
if (reusea == -1) reusea = 1;
|
||||
/*
|
||||
* Set the options to their default value if the user didn't override
|
||||
* their value.
|
||||
*/
|
||||
|
||||
// Build the bitset with the flags values.
|
||||
if (reusea)
|
||||
if (reusep == -1) {
|
||||
reusep = 0;
|
||||
}
|
||||
if (reusea == -1) {
|
||||
reusea = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Build the bitset with the flags values.
|
||||
*/
|
||||
|
||||
if (reusea) {
|
||||
flags |= TCL_TCPSERVER_REUSEADDR;
|
||||
if (reusep)
|
||||
}
|
||||
if (reusep) {
|
||||
flags |= TCL_TCPSERVER_REUSEPORT;
|
||||
}
|
||||
|
||||
/*
|
||||
* All the arguments should have been parsed by now, 'a' points to the
|
||||
* last one, the port number.
|
||||
*/
|
||||
|
||||
// All the arguments should have been parsed by now, 'a' points to the last
|
||||
// one, the port number.
|
||||
if (a != objc-1) {
|
||||
goto wrongNumArgs;
|
||||
}
|
||||
@@ -1638,15 +1652,14 @@ Tcl_SocketObjCmd(
|
||||
port = TclGetString(objv[a]);
|
||||
|
||||
if (server) {
|
||||
AcceptCallback *acceptCallbackPtr =
|
||||
ckalloc(sizeof(AcceptCallback));
|
||||
AcceptCallback *acceptCallbackPtr = ckalloc(sizeof(AcceptCallback));
|
||||
|
||||
Tcl_IncrRefCount(script);
|
||||
acceptCallbackPtr->script = script;
|
||||
acceptCallbackPtr->interp = interp;
|
||||
|
||||
chan = Tcl_OpenTcpServerEx(interp, port, host, flags, AcceptCallbackProc,
|
||||
acceptCallbackPtr);
|
||||
chan = Tcl_OpenTcpServerEx(interp, port, host, flags,
|
||||
AcceptCallbackProc, acceptCallbackPtr);
|
||||
if (chan == NULL) {
|
||||
Tcl_DecrRefCount(script);
|
||||
ckfree(acceptCallbackPtr);
|
||||
|
||||
+42
-25
@@ -234,7 +234,7 @@ typedef enum {
|
||||
* sharing problems.
|
||||
*/
|
||||
|
||||
typedef struct ForwardParamBase {
|
||||
typedef struct {
|
||||
int code; /* O: Ok/Fail of the cmd handler */
|
||||
char *msgStr; /* O: Error message for handler failure */
|
||||
int mustFree; /* O: True if msgStr is allocated, false if
|
||||
@@ -309,7 +309,7 @@ typedef struct ForwardingResult ForwardingResult;
|
||||
* General event structure, with reference to operation specific data.
|
||||
*/
|
||||
|
||||
typedef struct ForwardingEvent {
|
||||
typedef struct {
|
||||
Tcl_Event event; /* Basic event data, has to be first item */
|
||||
ForwardingResult *resultPtr;
|
||||
ForwardedOperation op; /* Forwarded driver operation */
|
||||
@@ -346,7 +346,7 @@ struct ForwardingResult {
|
||||
* results. */
|
||||
};
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
/*
|
||||
* Table of all reflected channels owned by this thread. This is the
|
||||
* per-thread version of the per-interpreter map.
|
||||
@@ -723,7 +723,7 @@ TclChanCreateObjCmd(
|
||||
Tcl_DecrRefCount(rcPtr->name);
|
||||
Tcl_DecrRefCount(rcPtr->methods);
|
||||
Tcl_DecrRefCount(rcPtr->cmd);
|
||||
ckfree((char*) rcPtr);
|
||||
ckfree(rcPtr);
|
||||
return TCL_ERROR;
|
||||
|
||||
#undef MODE
|
||||
@@ -748,7 +748,7 @@ TclChanCreateObjCmd(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef struct ReflectEvent {
|
||||
typedef struct {
|
||||
Tcl_Event header;
|
||||
ReflectedChannel *rcPtr;
|
||||
int events;
|
||||
@@ -851,11 +851,12 @@ TclChanPostEventObjCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that the search above subsumes several of the older checks, namely:
|
||||
* Note that the search above subsumes several of the older checks,
|
||||
* namely:
|
||||
*
|
||||
* (1) Does the channel handle refer to a reflected channel ?
|
||||
* (1) Does the channel handle refer to a reflected channel?
|
||||
* (2) Is the post event issued from the interpreter holding the handler
|
||||
* of the reflected channel ?
|
||||
* of the reflected channel?
|
||||
*
|
||||
* A successful search answers yes to both. Because the map holds only
|
||||
* handles of reflected channels, and only of such whose handler is
|
||||
@@ -939,7 +940,8 @@ TclChanPostEventObjCmd(
|
||||
|
||||
(void) GetThreadReflectedChannelMap();
|
||||
|
||||
/* XXX Race condition !!
|
||||
/*
|
||||
* XXX Race condition !!
|
||||
* XXX The destination thread may not exist anymore already.
|
||||
* XXX (Delayed postevent executed after channel got removed).
|
||||
* XXX Can we detect this ? (check the validity of the owner threadid ?)
|
||||
@@ -1221,8 +1223,8 @@ ReflectClose(
|
||||
#endif
|
||||
tctPtr = ((Channel *)rcPtr->chan)->typePtr;
|
||||
if (tctPtr && tctPtr != &tclRChannelType) {
|
||||
ckfree(tctPtr);
|
||||
((Channel *)rcPtr->chan)->typePtr = NULL;
|
||||
ckfree(tctPtr);
|
||||
((Channel *)rcPtr->chan)->typePtr = NULL;
|
||||
}
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
return (result == TCL_OK) ? EOK : EINVAL;
|
||||
@@ -1272,7 +1274,10 @@ ReflectInput(
|
||||
|
||||
if (p.base.code != TCL_OK) {
|
||||
if (p.base.code < 0) {
|
||||
/* No error message, this is an errno signal. */
|
||||
/*
|
||||
* No error message, this is an errno signal.
|
||||
*/
|
||||
|
||||
*errorCodePtr = -p.base.code;
|
||||
} else {
|
||||
PassReceivedError(rcPtr->chan, &p);
|
||||
@@ -1375,7 +1380,10 @@ ReflectOutput(
|
||||
|
||||
if (p.base.code != TCL_OK) {
|
||||
if (p.base.code < 0) {
|
||||
/* No error message, this is an errno signal. */
|
||||
/*
|
||||
* No error message, this is an errno signal.
|
||||
*/
|
||||
|
||||
*errorCodePtr = -p.base.code;
|
||||
} else {
|
||||
PassReceivedError(rcPtr->chan, &p);
|
||||
@@ -1426,8 +1434,8 @@ ReflectOutput(
|
||||
|
||||
if ((written == 0) && (toWrite > 0)) {
|
||||
/*
|
||||
* The handler claims to have written nothing of what it was
|
||||
* given. That is bad.
|
||||
* The handler claims to have written nothing of what it was given.
|
||||
* That is bad.
|
||||
*/
|
||||
|
||||
SetChannelErrorStr(rcPtr->chan, msg_write_nothing);
|
||||
@@ -2373,8 +2381,8 @@ InvokeTclMethod(
|
||||
* None.
|
||||
*
|
||||
* Users:
|
||||
* ReflectInput/Output(), to enable the signaling of EAGAIN
|
||||
* on 0-sized short reads/writes.
|
||||
* ReflectInput/Output(), to enable the signaling of EAGAIN on 0-sized
|
||||
* short reads/writes.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -2560,7 +2568,10 @@ DeleteReflectedChannelMap(
|
||||
|
||||
evPtr = resultPtr->evPtr;
|
||||
|
||||
/* Basic crash safety until this routine can get revised [3411310] */
|
||||
/*
|
||||
* Basic crash safety until this routine can get revised [3411310]
|
||||
*/
|
||||
|
||||
if (evPtr == NULL) {
|
||||
continue;
|
||||
}
|
||||
@@ -2675,8 +2686,8 @@ DeleteThreadReflectedChannelMap(
|
||||
|
||||
/*
|
||||
* Go through the list of pending results and cancel all whose events were
|
||||
* destined for this thread. While this is in progress we block any
|
||||
* other access to the list of pending results.
|
||||
* destined for this thread. While this is in progress we block any other
|
||||
* access to the list of pending results.
|
||||
*/
|
||||
|
||||
Tcl_MutexLock(&rcForwardMutex);
|
||||
@@ -2707,7 +2718,10 @@ DeleteThreadReflectedChannelMap(
|
||||
|
||||
evPtr = resultPtr->evPtr;
|
||||
|
||||
/* Basic crash safety until this routine can get revised [3411310] */
|
||||
/*
|
||||
* Basic crash safety until this routine can get revised [3411310]
|
||||
*/
|
||||
|
||||
if (evPtr == NULL ) {
|
||||
continue;
|
||||
}
|
||||
@@ -2761,8 +2775,8 @@ ForwardOpToHandlerThread(
|
||||
const void *param) /* Arguments */
|
||||
{
|
||||
/*
|
||||
* Core of the communication from OWNER to HANDLER thread.
|
||||
* The receiver is ForwardProc() below.
|
||||
* Core of the communication from OWNER to HANDLER thread. The receiver is
|
||||
* ForwardProc() below.
|
||||
*/
|
||||
|
||||
Tcl_ThreadId dst = rcPtr->thread;
|
||||
@@ -2812,7 +2826,10 @@ ForwardOpToHandlerThread(
|
||||
*/
|
||||
|
||||
TclSpliceIn(resultPtr, forwardList);
|
||||
/* Do not unlock here. That is done by the ConditionWait */
|
||||
|
||||
/*
|
||||
* Do not unlock here. That is done by the ConditionWait.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Ensure cleanup of the event if the origin thread exits while this event
|
||||
@@ -2888,7 +2905,7 @@ ForwardProc(
|
||||
* Notes regarding access to the referenced data.
|
||||
*
|
||||
* In principle the data belongs to the originating thread (see
|
||||
* evPtr->src), however this thread is currently blocked at (*), i.e.
|
||||
* evPtr->src), however this thread is currently blocked at (*), i.e.,
|
||||
* quiescent. Because of this we can treat the data as belonging to us,
|
||||
* without fear of race conditions. I.e. we can read and write as we like.
|
||||
*
|
||||
|
||||
@@ -329,7 +329,7 @@ struct ForwardingResult {
|
||||
* results. */
|
||||
};
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
/*
|
||||
* Table of all reflected transformations owned by this thread.
|
||||
*/
|
||||
|
||||
+19
-10
@@ -12,16 +12,21 @@
|
||||
#include "tclInt.h"
|
||||
|
||||
#if defined(_WIN32) && defined(UNICODE)
|
||||
/* On Windows, we need to do proper Unicode->UTF-8 conversion. */
|
||||
/*
|
||||
* On Windows, we need to do proper Unicode->UTF-8 conversion.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
int initialized;
|
||||
Tcl_DString errorMsg; /* UTF-8 encoded error-message */
|
||||
} ThreadSpecificData;
|
||||
static Tcl_ThreadDataKey dataKey;
|
||||
|
||||
#undef gai_strerror
|
||||
static const char *gai_strerror(int code) {
|
||||
static const char *
|
||||
gai_strerror(
|
||||
int code)
|
||||
{
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
if (tsdPtr->initialized) {
|
||||
@@ -126,7 +131,7 @@ TclSockMinimumBuffers(
|
||||
}
|
||||
len = sizeof(int);
|
||||
getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF,
|
||||
(char *) ¤t, &len);
|
||||
(char *) ¤t, &len);
|
||||
if (current < size) {
|
||||
len = sizeof(int);
|
||||
setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF,
|
||||
@@ -215,7 +220,7 @@ TclCreateSocketAddress(
|
||||
* We found some problems when using AI_ADDRCONFIG, e.g. on systems that
|
||||
* have no networking besides the loopback interface and want to resolve
|
||||
* localhost. See [Bugs 3385024, 3382419, 3382431]. As the advantage of
|
||||
* using AI_ADDRCONFIG in situations where it works, is probably low,
|
||||
* using AI_ADDRCONFIG is probably low even in situations where it works,
|
||||
* we'll leave it out for now. After all, it is just an optimisation.
|
||||
*
|
||||
* Missing on: OpenBSD, NetBSD.
|
||||
@@ -300,16 +305,20 @@ TclCreateSocketAddress(
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port,
|
||||
const char *host, Tcl_TcpAcceptProc *acceptProc,
|
||||
ClientData callbackData)
|
||||
|
||||
Tcl_Channel
|
||||
Tcl_OpenTcpServer(
|
||||
Tcl_Interp *interp,
|
||||
int port,
|
||||
const char *host,
|
||||
Tcl_TcpAcceptProc *acceptProc,
|
||||
ClientData callbackData)
|
||||
{
|
||||
char portbuf[TCL_INTEGER_SPACE];
|
||||
|
||||
TclFormatInt(portbuf, port);
|
||||
|
||||
return Tcl_OpenTcpServerEx(interp, portbuf, host, TCL_TCPSERVER_REUSEADDR,
|
||||
acceptProc, callbackData);
|
||||
acceptProc, callbackData);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+30
-23
@@ -57,7 +57,7 @@ typedef struct FilesystemRecord {
|
||||
* this information each time the corresponding epoch counter changes.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
int initialized;
|
||||
size_t cwdPathEpoch;
|
||||
size_t filesystemEpoch;
|
||||
@@ -611,6 +611,7 @@ FsRecacheFilesystemList(void)
|
||||
|
||||
while (toFree) {
|
||||
FilesystemRecord *next = toFree->nextPtr;
|
||||
|
||||
toFree->fsPtr = NULL;
|
||||
ckfree(toFree);
|
||||
toFree = next;
|
||||
@@ -672,7 +673,6 @@ TclFSEpoch(void)
|
||||
|
||||
return tsdPtr->filesystemEpoch;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If non-NULL, clientData is owned by us and must be freed later.
|
||||
@@ -784,7 +784,9 @@ TclFinalizeFilesystem(void)
|
||||
while (fsRecPtr != NULL) {
|
||||
FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr;
|
||||
|
||||
/* The native filesystem is static, so we don't free it. */
|
||||
/*
|
||||
* The native filesystem is static, so we don't free it.
|
||||
*/
|
||||
|
||||
if (fsRecPtr != &nativeFilesystemRecord) {
|
||||
ckfree(fsRecPtr);
|
||||
@@ -947,7 +949,7 @@ Tcl_FSRegister(
|
||||
|
||||
int
|
||||
Tcl_FSUnregister(
|
||||
const Tcl_Filesystem *fsPtr) /* The filesystem record to remove. */
|
||||
const Tcl_Filesystem *fsPtr)/* The filesystem record to remove. */
|
||||
{
|
||||
int retVal = TCL_ERROR;
|
||||
FilesystemRecord *fsRecPtr;
|
||||
@@ -1233,7 +1235,7 @@ FsAddMountsToGlobResult(
|
||||
|
||||
len--;
|
||||
}
|
||||
len++; /* account for '/' in the mElt [Bug 1602539] */
|
||||
len++; /* account for '/' in the mElt [Bug 1602539] */
|
||||
mElt = TclNewFSPathObj(pathPtr, mount + len, mlen - len);
|
||||
Tcl_ListObjAppendElement(NULL, resultPtr, mElt);
|
||||
}
|
||||
@@ -1403,7 +1405,7 @@ TclFSNormalizeToUniquePath(
|
||||
* Call each of the "normalise path" functions in succession. This is a
|
||||
* special case, in which if we have a native filesystem handler, we call
|
||||
* it first. This is because the root of Tcl's filesystem is always a
|
||||
* native filesystem (i.e. '/' on unix is native).
|
||||
* native filesystem (i.e., '/' on unix is native).
|
||||
*/
|
||||
|
||||
firstFsRecPtr = FsGetFirstFilesystem();
|
||||
@@ -1525,7 +1527,7 @@ TclGetOpenModeEx(
|
||||
#define RW_MODES (O_RDONLY|O_WRONLY|O_RDWR)
|
||||
|
||||
/*
|
||||
* Check for the simpler fopen-like access modes (e.g. "r"). They are
|
||||
* Check for the simpler fopen-like access modes (e.g., "r"). They are
|
||||
* distinguished from the POSIX access modes by the presence of a
|
||||
* lower-case first letter.
|
||||
*/
|
||||
@@ -2671,6 +2673,7 @@ Tcl_FSGetCwd(
|
||||
fsRecPtr = fsRecPtr->nextPtr) {
|
||||
ClientData retCd;
|
||||
TclFSGetCwdProc2 *proc2;
|
||||
|
||||
if (fsRecPtr->fsPtr->getCwdProc == NULL) {
|
||||
continue;
|
||||
}
|
||||
@@ -3143,8 +3146,8 @@ Tcl_FSLoadFile(
|
||||
* Workaround for issue with modern HPUX which do allow the unlink (no ETXTBSY
|
||||
* error) yet somehow trash some internal data structures which prevents the
|
||||
* second and further shared libraries from getting properly loaded. Only the
|
||||
* first is ok. We try to get around the issue by not unlinking,
|
||||
* i.e. emulating the behaviour of the older HPUX which denied removal.
|
||||
* first is ok. We try to get around the issue by not unlinking, i.e.,
|
||||
* emulating the behaviour of the older HPUX which denied removal.
|
||||
*
|
||||
* Doing the unlink is also an issue within docker containers, whose AUFS
|
||||
* bungles this as well, see
|
||||
@@ -3162,28 +3165,30 @@ Tcl_FSLoadFile(
|
||||
*/
|
||||
|
||||
int
|
||||
TclSkipUnlink (Tcl_Obj* shlibFile)
|
||||
TclSkipUnlink(
|
||||
Tcl_Obj *shlibFile)
|
||||
{
|
||||
/* Order of testing:
|
||||
/*
|
||||
* Order of testing:
|
||||
* 1. On hpux we generally want to skip unlink in general
|
||||
*
|
||||
* Outside of hpux then:
|
||||
* 2. For a general user request (TCL_TEMPLOAD_NO_UNLINK present, non-empty, => int)
|
||||
* 2. For a general user request (TCL_TEMPLOAD_NO_UNLINK present,
|
||||
* non-empty, => int)
|
||||
* 3. For general AUFS environment (statfs, if available).
|
||||
*
|
||||
* Ad 2: This variable can disable/override the AUFS detection, i.e. for
|
||||
* testing if a newer AUFS does not have the bug any more.
|
||||
* testing if a newer AUFS does not have the bug any more.
|
||||
*
|
||||
* Ad 3: This is conditionally compiled in. Condition currently must be set manually.
|
||||
* This part needs proper tests in the configure(.in).
|
||||
* Ad 3: This is conditionally compiled in. Condition currently must be
|
||||
* set manually. This part needs proper tests in the configure(.in).
|
||||
*/
|
||||
|
||||
#ifdef hpux
|
||||
return 1;
|
||||
#else
|
||||
char* skipstr;
|
||||
char *skipstr = getenv("TCL_TEMPLOAD_NO_UNLINK");
|
||||
|
||||
skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK");
|
||||
if (skipstr && (skipstr[0] != '\0')) {
|
||||
return atoi(skipstr);
|
||||
}
|
||||
@@ -3192,7 +3197,8 @@ TclSkipUnlink (Tcl_Obj* shlibFile)
|
||||
#ifndef NO_FSTATFS
|
||||
{
|
||||
struct statfs fs;
|
||||
/* Have fstatfs. May not have the AUFS super magic ... Indeed our build
|
||||
/*
|
||||
* Have fstatfs. May not have the AUFS super magic ... Indeed our build
|
||||
* box is too old to have it directly in the headers. Define taken from
|
||||
* http://mooon.googlecode.com/svn/trunk/linux_include/linux/aufs_type.h
|
||||
* http://aufs.sourceforge.net/
|
||||
@@ -3209,8 +3215,10 @@ TclSkipUnlink (Tcl_Obj* shlibFile)
|
||||
#endif /* ... NO_FSTATFS */
|
||||
#endif /* ... TCL_TEMPLOAD_NO_UNLINK */
|
||||
|
||||
/* Fallback: !hpux, no EV override, no AUFS (detection, nor detected):
|
||||
* Don't skip */
|
||||
/*
|
||||
* Fallback: !hpux, no EV override, no AUFS (detection, nor detected):
|
||||
* Don't skip
|
||||
*/
|
||||
return 0;
|
||||
#endif /* hpux */
|
||||
}
|
||||
@@ -3415,9 +3423,8 @@ Tcl_LoadFile(
|
||||
* avoids any worries about leaving the copy laying around on exit.
|
||||
*/
|
||||
|
||||
if (
|
||||
!TclSkipUnlink (copyToPtr) &&
|
||||
(Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) {
|
||||
if (!TclSkipUnlink(copyToPtr) &&
|
||||
(Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) {
|
||||
Tcl_DecrRefCount(copyToPtr);
|
||||
|
||||
/*
|
||||
|
||||
@@ -101,6 +101,7 @@ typedef struct {
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_GetIndexFromObj
|
||||
int
|
||||
Tcl_GetIndexFromObj(
|
||||
@@ -137,6 +138,7 @@ Tcl_GetIndexFromObj(
|
||||
return Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, sizeof(char *),
|
||||
msg, flags, indexPtr);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
@@ -1011,6 +1011,32 @@ declare 251 {
|
||||
int TclRegisterLiteral(void *envPtr,
|
||||
const char *bytes, int length, int flags)
|
||||
}
|
||||
|
||||
# Exporting of the internal API to variables.
|
||||
|
||||
declare 252 {
|
||||
Tcl_Obj *TclPtrGetVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
|
||||
const int flags)
|
||||
}
|
||||
declare 253 {
|
||||
Tcl_Obj *TclPtrSetVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
|
||||
Tcl_Obj *newValuePtr, const int flags)
|
||||
}
|
||||
declare 254 {
|
||||
Tcl_Obj *TclPtrIncrObjVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
|
||||
Tcl_Obj *incrPtr, const int flags)
|
||||
}
|
||||
declare 255 {
|
||||
int TclPtrObjMakeUpvar(Tcl_Interp *interp, Tcl_Var otherPtr,
|
||||
Tcl_Obj *myNamePtr, int myFlags)
|
||||
}
|
||||
declare 256 {
|
||||
int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr,
|
||||
Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags)
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
||||
+75
-84
@@ -265,7 +265,7 @@ typedef struct Namespace {
|
||||
* strings; values have type (Namespace *). If
|
||||
* NULL, there are no children. */
|
||||
#endif
|
||||
long nsId; /* Unique id for the namespace. */
|
||||
size_t nsId; /* Unique id for the namespace. */
|
||||
Tcl_Interp *interp; /* The interpreter containing this
|
||||
* namespace. */
|
||||
int flags; /* OR-ed combination of the namespace status
|
||||
@@ -299,12 +299,12 @@ typedef struct Namespace {
|
||||
* registered using "namespace export". */
|
||||
int maxExportPatterns; /* Mumber of export patterns for which space
|
||||
* is currently allocated. */
|
||||
int cmdRefEpoch; /* Incremented if a newly added command
|
||||
size_t cmdRefEpoch; /* Incremented if a newly added command
|
||||
* shadows a command for which this namespace
|
||||
* has already cached a Command* pointer; this
|
||||
* causes all its cached Command* pointers to
|
||||
* be invalidated. */
|
||||
int resolverEpoch; /* Incremented whenever (a) the name
|
||||
size_t resolverEpoch; /* Incremented whenever (a) the name
|
||||
* resolution rules change for this namespace
|
||||
* or (b) a newly added command shadows a
|
||||
* command that is compiled to bytecodes. This
|
||||
@@ -331,7 +331,7 @@ typedef struct Namespace {
|
||||
* LookupCompiledLocal to resolve variable
|
||||
* references within the namespace at compile
|
||||
* time. */
|
||||
int exportLookupEpoch; /* Incremented whenever a command is added to
|
||||
size_t exportLookupEpoch; /* Incremented whenever a command is added to
|
||||
* a namespace, removed from a namespace or
|
||||
* the exports of a namespace are changed.
|
||||
* Allows TIP#112-driven command lists to be
|
||||
@@ -432,7 +432,7 @@ typedef struct EnsembleConfig {
|
||||
* if the command has been deleted (or never
|
||||
* existed; the global namespace never has an
|
||||
* ensemble command.) */
|
||||
int epoch; /* The epoch at which this ensemble's table of
|
||||
size_t epoch; /* The epoch at which this ensemble's table of
|
||||
* exported commands is valid. */
|
||||
char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all
|
||||
* consistent points, this will have the same
|
||||
@@ -1357,7 +1357,7 @@ MODULE_SCOPE void TclThreadDataKeySet(Tcl_ThreadDataKey *keyPtr,
|
||||
*/
|
||||
|
||||
#define TCL_TSD_INIT(keyPtr) \
|
||||
(ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData))
|
||||
Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData))
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -1639,7 +1639,7 @@ typedef struct Command {
|
||||
* representing a command's name in a ByteCode
|
||||
* instruction sequence. This structure can be
|
||||
* freed when refCount becomes zero. */
|
||||
int cmdEpoch; /* Incremented to invalidate any references
|
||||
size_t cmdEpoch; /* Incremented to invalidate any references
|
||||
* that point to this command when it is
|
||||
* renamed, deleted, hidden, or exposed. */
|
||||
CompileProc *compileProc; /* Procedure called to compile command. NULL
|
||||
@@ -1862,6 +1862,7 @@ typedef struct Interp {
|
||||
* See Tcl_AppendResult code for details.
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
char *appendResult; /* Storage space for results generated by
|
||||
* Tcl_AppendResult. Ckalloc-ed. NULL means
|
||||
* not yet allocated. */
|
||||
@@ -1869,6 +1870,11 @@ typedef struct Interp {
|
||||
* partialResult. */
|
||||
int appendUsed; /* Number of non-null bytes currently stored
|
||||
* at partialResult. */
|
||||
#else
|
||||
char *appendResultDontUse;
|
||||
int appendAvlDontUse;
|
||||
int appendUsedDontUse;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Information about packages. Used only in tclPkg.c.
|
||||
@@ -1930,8 +1936,12 @@ typedef struct Interp {
|
||||
* string. Returned by Tcl_ObjSetVar2 when
|
||||
* variable traces change a variable in a
|
||||
* gross way. */
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
char resultSpace[TCL_RESULT_SIZE+1];
|
||||
/* Static space holding small results. */
|
||||
#else
|
||||
char resultSpaceDontUse[TCL_RESULT_SIZE+1];
|
||||
#endif
|
||||
Tcl_Obj *objResultPtr; /* If the last command returned an object
|
||||
* result, this points to it. Should not be
|
||||
* accessed directly; see comment above. */
|
||||
@@ -2620,7 +2630,7 @@ typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, size_t *lengthPtr,
|
||||
*/
|
||||
|
||||
typedef struct ProcessGlobalValue {
|
||||
size_t epoch; /* Epoch counter to detect changes in the
|
||||
size_t epoch; /* Epoch counter to detect changes in the
|
||||
* master value. */
|
||||
size_t numBytes; /* Length of the master string. */
|
||||
char *value; /* The master string value. */
|
||||
@@ -2745,7 +2755,6 @@ MODULE_SCOPE long tclObjsShared[TCL_MAX_SHARED_OBJ_STATS];
|
||||
* shared by all new objects allocated by Tcl_NewObj.
|
||||
*/
|
||||
|
||||
MODULE_SCOPE char * tclEmptyStringRep;
|
||||
MODULE_SCOPE char tclEmptyString;
|
||||
|
||||
/*
|
||||
@@ -2962,7 +2971,8 @@ MODULE_SCOPE Tcl_Obj * TclGetBgErrorHandler(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr, Tcl_Channel *chanPtr,
|
||||
int *modePtr, int flags);
|
||||
MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp,
|
||||
MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr);
|
||||
MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *value, int *code);
|
||||
MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr, ClientData *clientDataPtr,
|
||||
@@ -3115,7 +3125,7 @@ MODULE_SCOPE void TclpSetVariables(Tcl_Interp *interp);
|
||||
MODULE_SCOPE void * TclThreadStorageKeyGet(Tcl_ThreadDataKey *keyPtr);
|
||||
MODULE_SCOPE void TclThreadStorageKeySet(Tcl_ThreadDataKey *keyPtr,
|
||||
void *data);
|
||||
MODULE_SCOPE void TclpThreadExit(int status);
|
||||
MODULE_SCOPE TCL_NORETURN void TclpThreadExit(int status);
|
||||
MODULE_SCOPE void TclRememberCondition(Tcl_Condition *mutex);
|
||||
MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id);
|
||||
MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex);
|
||||
@@ -3219,9 +3229,11 @@ MODULE_SCOPE Tcl_Command TclInitBinaryCmd(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int Tcl_BreakObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
MODULE_SCOPE int Tcl_CaseObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
#endif
|
||||
MODULE_SCOPE int Tcl_CatchObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -3276,10 +3288,8 @@ MODULE_SCOPE int Tcl_AssembleObjCmd(ClientData clientData,
|
||||
MODULE_SCOPE int TclNRAssembleObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
|
||||
MODULE_SCOPE int Tcl_EncodingObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE Tcl_Command TclInitEncodingCmd(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclMakeEncodingCommandSafe(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int Tcl_EofObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -3517,6 +3527,12 @@ MODULE_SCOPE int TclCompileBreakCmd(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileCatchCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileClockClicksCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileClockReadingCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileConcatCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
@@ -3953,7 +3969,7 @@ MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp,
|
||||
struct CompileEnv *envPtr);
|
||||
|
||||
/*
|
||||
* Functions defined in generic/tclVar.c and currenttly exported only for use
|
||||
* Functions defined in generic/tclVar.c and currently exported only for use
|
||||
* by the bytecode compiler and engine. Some of these could later be placed in
|
||||
* the public interface.
|
||||
*/
|
||||
@@ -3967,20 +3983,21 @@ MODULE_SCOPE Var * TclLookupArrayElement(Tcl_Interp *interp,
|
||||
const int flags, const char *msg,
|
||||
const int createPart1, const int createPart2,
|
||||
Var *arrayPtr, int index);
|
||||
MODULE_SCOPE Tcl_Obj * TclPtrGetVar(Tcl_Interp *interp,
|
||||
MODULE_SCOPE Tcl_Obj * TclPtrGetVarIdx(Tcl_Interp *interp,
|
||||
Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, const int flags, int index);
|
||||
MODULE_SCOPE Tcl_Obj * TclPtrSetVar(Tcl_Interp *interp,
|
||||
MODULE_SCOPE Tcl_Obj * TclPtrSetVarIdx(Tcl_Interp *interp,
|
||||
Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr,
|
||||
const int flags, int index);
|
||||
MODULE_SCOPE Tcl_Obj * TclPtrIncrObjVar(Tcl_Interp *interp,
|
||||
MODULE_SCOPE Tcl_Obj * TclPtrIncrObjVarIdx(Tcl_Interp *interp,
|
||||
Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr,
|
||||
const int flags, int index);
|
||||
MODULE_SCOPE int TclPtrObjMakeUpvar(Tcl_Interp *interp, Var *otherPtr,
|
||||
Tcl_Obj *myNamePtr, int myFlags, int index);
|
||||
MODULE_SCOPE int TclPtrUnsetVar(Tcl_Interp *interp, Var *varPtr,
|
||||
MODULE_SCOPE int TclPtrObjMakeUpvarIdx(Tcl_Interp *interp,
|
||||
Var *otherPtr, Tcl_Obj *myNamePtr, int myFlags,
|
||||
int index);
|
||||
MODULE_SCOPE int TclPtrUnsetVarIdx(Tcl_Interp *interp, Var *varPtr,
|
||||
Var *arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, const int flags,
|
||||
int index);
|
||||
@@ -4064,7 +4081,7 @@ typedef const char *TclDTraceStr;
|
||||
TclIncrObjsAllocated(); \
|
||||
TclAllocObjStorage(objPtr); \
|
||||
(objPtr)->refCount = 0; \
|
||||
(objPtr)->bytes = tclEmptyStringRep; \
|
||||
(objPtr)->bytes = &tclEmptyString; \
|
||||
(objPtr)->length = 0; \
|
||||
(objPtr)->typePtr = NULL; \
|
||||
TCL_DTRACE_OBJ_CREATE(objPtr)
|
||||
@@ -4081,7 +4098,7 @@ typedef const char *TclDTraceStr;
|
||||
if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \
|
||||
TCL_DTRACE_OBJ_FREE(objPtr); \
|
||||
if ((objPtr)->bytes \
|
||||
&& ((objPtr)->bytes != tclEmptyStringRep)) { \
|
||||
&& ((objPtr)->bytes != &tclEmptyString)) { \
|
||||
ckfree((objPtr)->bytes); \
|
||||
} \
|
||||
(objPtr)->length = -1; \
|
||||
@@ -4242,7 +4259,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
|
||||
#define TclInitStringRep(objPtr, bytePtr, len) \
|
||||
if ((len) == 0) { \
|
||||
(objPtr)->bytes = tclEmptyStringRep; \
|
||||
(objPtr)->bytes = &tclEmptyString; \
|
||||
(objPtr)->length = 0; \
|
||||
} else { \
|
||||
(objPtr)->bytes = (char *) ckalloc((unsigned) ((len) + 1)); \
|
||||
@@ -4300,7 +4317,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
|
||||
#define TclInvalidateStringRep(objPtr) \
|
||||
if ((objPtr)->bytes != NULL) { \
|
||||
if ((objPtr)->bytes != tclEmptyStringRep) { \
|
||||
if ((objPtr)->bytes != &tclEmptyString) { \
|
||||
ckfree((objPtr)->bytes); \
|
||||
} \
|
||||
(objPtr)->bytes = NULL; \
|
||||
@@ -4338,13 +4355,13 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
#define TCL_MAX_TOKENS (int)(UINT_MAX / sizeof(Tcl_Token))
|
||||
#define TclGrowTokenArray(tokenPtr, used, available, append, staticPtr) \
|
||||
do { \
|
||||
int needed = (used) + (append); \
|
||||
if (needed > TCL_MAX_TOKENS) { \
|
||||
int _needed = (used) + (append); \
|
||||
if (_needed > TCL_MAX_TOKENS) { \
|
||||
Tcl_Panic("max # of tokens for a Tcl parse (%d) exceeded", \
|
||||
TCL_MAX_TOKENS); \
|
||||
} \
|
||||
if (needed > (available)) { \
|
||||
int allocated = 2 * needed; \
|
||||
if (_needed > (available)) { \
|
||||
int allocated = 2 * _needed; \
|
||||
Tcl_Token *oldPtr = (tokenPtr); \
|
||||
Tcl_Token *newPtr; \
|
||||
if (oldPtr == (staticPtr)) { \
|
||||
@@ -4356,7 +4373,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
newPtr = (Tcl_Token *) attemptckrealloc((char *) oldPtr, \
|
||||
(unsigned int) (allocated * sizeof(Tcl_Token))); \
|
||||
if (newPtr == NULL) { \
|
||||
allocated = needed + (append) + TCL_MIN_TOKEN_GROWTH; \
|
||||
allocated = _needed + (append) + TCL_MIN_TOKEN_GROWTH; \
|
||||
if (allocated > TCL_MAX_TOKENS) { \
|
||||
allocated = TCL_MAX_TOKENS; \
|
||||
} \
|
||||
@@ -4408,14 +4425,14 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
|
||||
#define TclNumUtfChars(numChars, bytes, numBytes) \
|
||||
do { \
|
||||
int count, i = (numBytes); \
|
||||
unsigned char *str = (unsigned char *) (bytes); \
|
||||
while (i && (*str < 0xC0)) { i--; str++; } \
|
||||
count = (numBytes) - i; \
|
||||
if (i) { \
|
||||
count += Tcl_NumUtfChars((bytes) + count, i); \
|
||||
int _count, _i = (numBytes); \
|
||||
unsigned char *_str = (unsigned char *) (bytes); \
|
||||
while (_i && (*_str < 0xC0)) { _i--; _str++; } \
|
||||
_count = (numBytes) - _i; \
|
||||
if (_i) { \
|
||||
_count += Tcl_NumUtfChars((bytes) + _count, _i); \
|
||||
} \
|
||||
(numChars) = count; \
|
||||
(numChars) = _count; \
|
||||
} while (0);
|
||||
|
||||
/*
|
||||
@@ -4515,9 +4532,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
* core. They should only be called on unshared objects. The ANSI C
|
||||
* "prototypes" for these macros are:
|
||||
*
|
||||
* MODULE_SCOPE void TclSetIntObj(Tcl_Obj *objPtr, int intValue);
|
||||
* MODULE_SCOPE void TclSetLongObj(Tcl_Obj *objPtr, long longValue);
|
||||
* MODULE_SCOPE void TclSetBooleanObj(Tcl_Obj *objPtr, long boolValue);
|
||||
* MODULE_SCOPE void TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
|
||||
* MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d);
|
||||
*----------------------------------------------------------------
|
||||
@@ -4531,19 +4546,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
(objPtr)->typePtr = &tclIntType; \
|
||||
} while (0)
|
||||
|
||||
#define TclSetIntObj(objPtr, l) \
|
||||
TclSetLongObj(objPtr, l)
|
||||
|
||||
/*
|
||||
* NOTE: There is to be no such thing as a "pure" boolean. Boolean values set
|
||||
* programmatically go straight to being "int" Tcl_Obj's, with value 0 or 1.
|
||||
* The only "boolean" Tcl_Obj's shall be those holding the cached boolean
|
||||
* value of strings like: "yes", "no", "true", "false", "on", "off".
|
||||
*/
|
||||
|
||||
#define TclSetBooleanObj(objPtr, b) \
|
||||
TclSetLongObj(objPtr, (b)!=0);
|
||||
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
#define TclSetWideIntObj(objPtr, w) \
|
||||
do { \
|
||||
@@ -4569,7 +4571,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
* the core. The ANSI C "prototypes" for these macros are:
|
||||
*
|
||||
* MODULE_SCOPE void TclNewLongObj(Tcl_Obj *objPtr, long l);
|
||||
* MODULE_SCOPE void TclNewBooleanObj(Tcl_Obj *objPtr, int b);
|
||||
* MODULE_SCOPE void TclNewWideObj(Tcl_Obj *objPtr, Tcl_WideInt w);
|
||||
* MODULE_SCOPE void TclNewDoubleObj(Tcl_Obj *objPtr, double d);
|
||||
* MODULE_SCOPE void TclNewStringObj(Tcl_Obj *objPtr, const char *s, int len);
|
||||
@@ -4590,13 +4591,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
TCL_DTRACE_OBJ_CREATE(objPtr); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* NOTE: There is to be no such thing as a "pure" boolean.
|
||||
* See comment above TclSetBooleanObj macro above.
|
||||
*/
|
||||
#define TclNewBooleanObj(objPtr, b) \
|
||||
TclNewLongObj((objPtr), (b)!=0)
|
||||
|
||||
#define TclNewDoubleObj(objPtr, d) \
|
||||
do { \
|
||||
TclIncrObjsAllocated(); \
|
||||
@@ -4622,9 +4616,6 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
#define TclNewLongObj(objPtr, l) \
|
||||
(objPtr) = Tcl_NewLongObj(l)
|
||||
|
||||
#define TclNewBooleanObj(objPtr, b) \
|
||||
(objPtr) = Tcl_NewBooleanObj(b)
|
||||
|
||||
#define TclNewDoubleObj(objPtr, d) \
|
||||
(objPtr) = Tcl_NewDoubleObj(d)
|
||||
|
||||
@@ -4766,11 +4757,11 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
#ifndef TCL_MEM_DEBUG
|
||||
#define TclSmallAllocEx(interp, nbytes, memPtr) \
|
||||
do { \
|
||||
Tcl_Obj *objPtr; \
|
||||
Tcl_Obj *_objPtr; \
|
||||
TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj)); \
|
||||
TclIncrObjsAllocated(); \
|
||||
TclAllocObjStorageEx((interp), (objPtr)); \
|
||||
memPtr = (ClientData) (objPtr); \
|
||||
TclAllocObjStorageEx((interp), (_objPtr)); \
|
||||
memPtr = (ClientData) (_objPtr); \
|
||||
} while (0)
|
||||
|
||||
#define TclSmallFreeEx(interp, memPtr) \
|
||||
@@ -4782,19 +4773,19 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
#else /* TCL_MEM_DEBUG */
|
||||
#define TclSmallAllocEx(interp, nbytes, memPtr) \
|
||||
do { \
|
||||
Tcl_Obj *objPtr; \
|
||||
Tcl_Obj *_objPtr; \
|
||||
TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj)); \
|
||||
TclNewObj(objPtr); \
|
||||
memPtr = (ClientData) objPtr; \
|
||||
TclNewObj(_objPtr); \
|
||||
memPtr = (ClientData) _objPtr; \
|
||||
} while (0)
|
||||
|
||||
#define TclSmallFreeEx(interp, memPtr) \
|
||||
do { \
|
||||
Tcl_Obj *objPtr = (Tcl_Obj *) memPtr; \
|
||||
objPtr->bytes = NULL; \
|
||||
objPtr->typePtr = NULL; \
|
||||
objPtr->refCount = 1; \
|
||||
TclDecrRefCount(objPtr); \
|
||||
Tcl_Obj *_objPtr = (Tcl_Obj *) memPtr; \
|
||||
_objPtr->bytes = NULL; \
|
||||
_objPtr->typePtr = NULL; \
|
||||
_objPtr->refCount = 1; \
|
||||
TclDecrRefCount(_objPtr); \
|
||||
} while (0)
|
||||
#endif /* TCL_MEM_DEBUG */
|
||||
|
||||
@@ -4846,15 +4837,15 @@ typedef struct NRE_callback {
|
||||
|
||||
#define TclNRAddCallback(interp,postProcPtr,data0,data1,data2,data3) \
|
||||
do { \
|
||||
NRE_callback *callbackPtr; \
|
||||
TCLNR_ALLOC((interp), (callbackPtr)); \
|
||||
callbackPtr->procPtr = (postProcPtr); \
|
||||
callbackPtr->data[0] = (ClientData)(data0); \
|
||||
callbackPtr->data[1] = (ClientData)(data1); \
|
||||
callbackPtr->data[2] = (ClientData)(data2); \
|
||||
callbackPtr->data[3] = (ClientData)(data3); \
|
||||
callbackPtr->nextPtr = TOP_CB(interp); \
|
||||
TOP_CB(interp) = callbackPtr; \
|
||||
NRE_callback *_callbackPtr; \
|
||||
TCLNR_ALLOC((interp), (_callbackPtr)); \
|
||||
_callbackPtr->procPtr = (postProcPtr); \
|
||||
_callbackPtr->data[0] = (ClientData)(data0); \
|
||||
_callbackPtr->data[1] = (ClientData)(data1); \
|
||||
_callbackPtr->data[2] = (ClientData)(data2); \
|
||||
_callbackPtr->data[3] = (ClientData)(data3); \
|
||||
_callbackPtr->nextPtr = TOP_CB(interp); \
|
||||
TOP_CB(interp) = _callbackPtr; \
|
||||
} while (0)
|
||||
|
||||
#if NRE_USE_SMALL_ALLOC
|
||||
|
||||
@@ -617,6 +617,28 @@ EXTERN void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags,
|
||||
/* 251 */
|
||||
EXTERN int TclRegisterLiteral(void *envPtr, const char *bytes,
|
||||
int length, int flags);
|
||||
/* 252 */
|
||||
EXTERN Tcl_Obj * TclPtrGetVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, const int flags);
|
||||
/* 253 */
|
||||
EXTERN Tcl_Obj * TclPtrSetVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr,
|
||||
const int flags);
|
||||
/* 254 */
|
||||
EXTERN Tcl_Obj * TclPtrIncrObjVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr,
|
||||
const int flags);
|
||||
/* 255 */
|
||||
EXTERN int TclPtrObjMakeUpvar(Tcl_Interp *interp,
|
||||
Tcl_Var otherPtr, Tcl_Obj *myNamePtr,
|
||||
int myFlags);
|
||||
/* 256 */
|
||||
EXTERN int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, const int flags);
|
||||
|
||||
typedef struct TclIntStubs {
|
||||
int magic;
|
||||
@@ -874,6 +896,11 @@ typedef struct TclIntStubs {
|
||||
char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */
|
||||
void (*tclSetSlaveCancelFlags) (Tcl_Interp *interp, int flags, int force); /* 250 */
|
||||
int (*tclRegisterLiteral) (void *envPtr, const char *bytes, int length, int flags); /* 251 */
|
||||
Tcl_Obj * (*tclPtrGetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 252 */
|
||||
Tcl_Obj * (*tclPtrSetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, const int flags); /* 253 */
|
||||
Tcl_Obj * (*tclPtrIncrObjVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, const int flags); /* 254 */
|
||||
int (*tclPtrObjMakeUpvar) (Tcl_Interp *interp, Tcl_Var otherPtr, Tcl_Obj *myNamePtr, int myFlags); /* 255 */
|
||||
int (*tclPtrUnsetVar) (Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags); /* 256 */
|
||||
} TclIntStubs;
|
||||
|
||||
extern const TclIntStubs *tclIntStubsPtr;
|
||||
@@ -1305,6 +1332,16 @@ extern const TclIntStubs *tclIntStubsPtr;
|
||||
(tclIntStubsPtr->tclSetSlaveCancelFlags) /* 250 */
|
||||
#define TclRegisterLiteral \
|
||||
(tclIntStubsPtr->tclRegisterLiteral) /* 251 */
|
||||
#define TclPtrGetVar \
|
||||
(tclIntStubsPtr->tclPtrGetVar) /* 252 */
|
||||
#define TclPtrSetVar \
|
||||
(tclIntStubsPtr->tclPtrSetVar) /* 253 */
|
||||
#define TclPtrIncrObjVar \
|
||||
(tclIntStubsPtr->tclPtrIncrObjVar) /* 254 */
|
||||
#define TclPtrObjMakeUpvar \
|
||||
(tclIntStubsPtr->tclPtrObjMakeUpvar) /* 255 */
|
||||
#define TclPtrUnsetVar \
|
||||
(tclIntStubsPtr->tclPtrUnsetVar) /* 256 */
|
||||
|
||||
#endif /* defined(USE_TCL_STUBS) */
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user