Compare commits
607
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b55d5cc57e | ||
|
|
e4356f7d64 | ||
|
|
0480b5d79b | ||
|
|
10a9305777 | ||
|
|
d8596e5583 | ||
|
|
5528e1c1a2 | ||
|
|
785f1059e4 | ||
|
|
274ab123a8 | ||
|
|
d33ee7bc07 | ||
|
|
8bb421f959 | ||
|
|
2ff3ecb534 | ||
|
|
e0578530b0 | ||
|
|
a79bc3c8ce | ||
|
|
30c40c4540 | ||
|
|
c5865fcd24 | ||
|
|
c8342af338 | ||
|
|
1d0751deb7 | ||
|
|
bed6e18d15 | ||
|
|
c668ed46ec | ||
|
|
0a3f9ca6fc | ||
|
|
261012ce98 | ||
|
|
2f8bbbe141 | ||
|
|
4ab9cb5418 | ||
|
|
3888c4fda4 | ||
|
|
fa2e7e8949 | ||
|
|
053a74e0fa | ||
|
|
30c6827ee1 | ||
|
|
eb2cfa3e6f | ||
|
|
40d9b81e23 | ||
|
|
1552384787 | ||
|
|
9306fa604c | ||
|
|
d5f679a3f6 | ||
|
|
e532a0de84 | ||
|
|
745b43f627 | ||
|
|
f18d453679 | ||
|
|
2332ac45ca | ||
|
|
634213a9c8 | ||
|
|
8e537759cf | ||
|
|
fada619052 | ||
|
|
319b71965b | ||
|
|
47a0727695 | ||
|
|
45d0977a5c | ||
|
|
4407704316 | ||
|
|
e9b584f81b | ||
|
|
cdb25d8946 | ||
|
|
56d6e9480f | ||
|
|
df974e71f9 | ||
|
|
7393032d5e | ||
|
|
252f75d8c8 | ||
|
|
69030a86c8 | ||
|
|
8a910c1a53 | ||
|
|
e7582d10c6 | ||
|
|
5064777d16 | ||
|
|
5b74714749 | ||
|
|
15a7950c9e | ||
|
|
c925a86988 | ||
|
|
75ecb090c6 | ||
|
|
b8e5e2909e | ||
|
|
fd6a064ee7 | ||
|
|
6881a1a274 | ||
|
|
b0fe49c36d | ||
|
|
a52f0db3e4 | ||
|
|
4bf8f43b3a | ||
|
|
d45863129f | ||
|
|
1b28405773 | ||
|
|
65703d1f87 | ||
|
|
f75f76c9d4 | ||
|
|
f5ea63343e | ||
|
|
a708ae2da2 | ||
|
|
d4e73bcab5 | ||
|
|
8f339500a2 | ||
|
|
bf01a303da | ||
|
|
99d940211c | ||
|
|
7b8b406719 | ||
|
|
db3273f346 | ||
|
|
c659b044b1 | ||
|
|
3e55dbb18c | ||
|
|
b2446d8d41 | ||
|
|
e86e8a501d | ||
|
|
d03a4dcc88 | ||
|
|
4ce5b276eb | ||
|
|
877e9d6b11 | ||
|
|
413fe66650 | ||
|
|
ca70072a99 | ||
|
|
d9f2bf1d17 | ||
|
|
c2846c0f5c | ||
|
|
a15279ffd1 | ||
|
|
b74f59a5b4 | ||
|
|
e08c86934d | ||
|
|
a3dfc55957 | ||
|
|
e3f7bc2783 | ||
|
|
564b991088 | ||
|
|
0ff317501d | ||
|
|
f42f0060be | ||
|
|
3ec5b35deb | ||
|
|
7afc6b1c17 | ||
|
|
ce58cdff9f | ||
|
|
4b9e6d92be | ||
|
|
e28f1eece4 | ||
|
|
4ce83fdb43 | ||
|
|
ce32fdecb2 | ||
|
|
105a61c09b | ||
|
|
25b97a7df9 | ||
|
|
432e75210f | ||
|
|
595e613479 | ||
|
|
c0e413055e | ||
|
|
11719ccf59 | ||
|
|
7c7a396fc5 | ||
|
|
7aafa756ac | ||
|
|
6d8b0c705f | ||
|
|
faaf0a0fe6 | ||
|
|
07bcf919d6 | ||
|
|
f70c0ac860 | ||
|
|
97d25d7902 | ||
|
|
c3d5808cdd | ||
|
|
187a67149b | ||
|
|
2d65cb7514 | ||
|
|
92a05930af | ||
|
|
1ef0babc38 | ||
|
|
92265d56a3 | ||
|
|
4264a4f6ab | ||
|
|
a95a7dd265 | ||
|
|
2e9194366a | ||
|
|
ce72664606 | ||
|
|
5210283d10 | ||
|
|
0eb18d8f91 | ||
|
|
29be40bf89 | ||
|
|
e6336bb806 | ||
|
|
a04094e9a5 | ||
|
|
922d8a71a5 | ||
|
|
13d9910fd6 | ||
|
|
277f101d7f | ||
|
|
a50a381b04 | ||
|
|
e513ec3916 | ||
|
|
89fcfadbbf | ||
|
|
89ce4defb5 | ||
|
|
ad9bc7297d | ||
|
|
0079285837 | ||
|
|
8ccd8d10ef | ||
|
|
aedd652645 | ||
|
|
4056a4dc4b | ||
|
|
ffaeeeddaa | ||
|
|
c2982f8f62 | ||
|
|
587206a660 | ||
|
|
545f5e64be | ||
|
|
385b618c74 | ||
|
|
3a07a6d26f | ||
|
|
df9ea61fbf | ||
|
|
5f7ca471e4 | ||
|
|
ac8ddf5d4a | ||
|
|
664774bec4 | ||
|
|
3cf11a1ce9 | ||
|
|
6da97c627b | ||
|
|
735ca3d3a8 | ||
|
|
72396a1929 | ||
|
|
816674cdb7 | ||
|
|
6bcfd54d3a | ||
|
|
bb331bf1d8 | ||
|
|
b095f046e6 | ||
|
|
cee94b0658 | ||
|
|
f94f5914a8 | ||
|
|
9dd9b629b3 | ||
|
|
440dbbf620 | ||
|
|
b1243f2603 | ||
|
|
f553fe3b01 | ||
|
|
457f43e25b | ||
|
|
578eeb06bc | ||
|
|
515f0f32c0 | ||
|
|
bcb9c34521 | ||
|
|
af0816e0ca | ||
|
|
ac0fdb5bf8 | ||
|
|
2ee7180448 | ||
|
|
5541cc57f7 | ||
|
|
692ea37c40 | ||
|
|
58dd15c51d | ||
|
|
d0996f3402 | ||
|
|
39356c4079 | ||
|
|
a646f081bc | ||
|
|
89f6884455 | ||
|
|
45cf14ed03 | ||
|
|
5314bbe0ef | ||
|
|
5b2c81a0f3 | ||
|
|
f242dd36bd | ||
|
|
fb2aa596ab | ||
|
|
5621809b18 | ||
|
|
7a8a4b15c4 | ||
|
|
f4615ea166 | ||
|
|
2bd7095b87 | ||
|
|
400f9d27f5 | ||
|
|
5d68b7ef56 | ||
|
|
ba387de8cd | ||
|
|
70d12096d5 | ||
|
|
3dedad17ed | ||
|
|
a9c238476a | ||
|
|
cfafc391f2 | ||
|
|
0fbade1cf8 | ||
|
|
dd54301fb6 | ||
|
|
6352a07912 | ||
|
|
440f85800c | ||
|
|
2a11adb848 | ||
|
|
77f95f38bf | ||
|
|
2710235273 | ||
|
|
042e99227a | ||
|
|
64c9b509b0 | ||
|
|
d39c33303f | ||
|
|
6454bee19b | ||
|
|
45175dd264 | ||
|
|
9983a05a80 | ||
|
|
20b4459b9d | ||
|
|
c488b70a47 | ||
|
|
952acc3754 | ||
|
|
73f548527a | ||
|
|
3923106cf7 | ||
|
|
17711009b6 | ||
|
|
b3bda726c1 | ||
|
|
e1b4ae0798 | ||
|
|
aca86a46ff | ||
|
|
94754be1d7 | ||
|
|
9ddb31d522 | ||
|
|
6123ba004c | ||
|
|
56ea73145f | ||
|
|
bc4db4d40e | ||
|
|
0f0ca3d932 | ||
|
|
2cdd3134ab | ||
|
|
107760e1da | ||
|
|
d453cdacec | ||
|
|
e8d9fe8ebe | ||
|
|
6168d91b0e | ||
|
|
ad34457a54 | ||
|
|
2712a556fb | ||
|
|
3f2eb64de8 | ||
|
|
4b81f6ff43 | ||
|
|
cc72d116bd | ||
|
|
94b635d569 | ||
|
|
de1c1f0f47 | ||
|
|
a4f7145579 | ||
|
|
bbcbd64e3b | ||
|
|
36d9205d97 | ||
|
|
7673d614a9 | ||
|
|
c348386388 | ||
|
|
878c874975 | ||
|
|
b796f3dee7 | ||
|
|
dd96539335 | ||
|
|
23ab25afdc | ||
|
|
192d5ccf32 | ||
|
|
9ce3a23afe | ||
|
|
c2e241f3cd | ||
|
|
9562ecd7fa | ||
|
|
16f3f234e8 | ||
|
|
fbfe81cc7b | ||
|
|
73a3dfdeea | ||
|
|
4cf238f3c3 | ||
|
|
1b667ef114 | ||
|
|
0aa0da515c | ||
|
|
5667bb5f8e | ||
|
|
f8bc248cc3 | ||
|
|
b0146fbd50 | ||
|
|
615771f0b6 | ||
|
|
8d78b23f96 | ||
|
|
fab7d970af | ||
|
|
617e92d7b4 | ||
|
|
7edce7686e | ||
|
|
3d8a0152af | ||
|
|
cb68061d12 | ||
|
|
5c4bb0f4e9 | ||
|
|
f165025992 | ||
|
|
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 | ||
|
|
919fc57599 | ||
|
|
5badb6535f | ||
|
|
cf0cf6ad90 | ||
|
|
f3ea991996 | ||
|
|
8a90be9a10 | ||
|
|
14949f27a3 | ||
|
|
c571887777 | ||
|
|
f100bae746 | ||
|
|
4db003c2bf | ||
|
|
62e71e311e | ||
|
|
df664778c8 | ||
|
|
82ddcc716b | ||
|
|
2f9e40fef1 | ||
|
|
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 | ||
|
|
0d218fca03 | ||
|
|
2130fd8582 | ||
|
|
f32ecd5894 | ||
|
|
1ed15145a6 | ||
|
|
46f75926ff | ||
|
|
f9d42ebf8c | ||
|
|
ca65694482 | ||
|
|
69865e4f83 | ||
|
|
71a9a4406a | ||
|
|
0177abb172 | ||
|
|
dd53d408e3 | ||
|
|
ce501f14c5 | ||
|
|
b96146d014 | ||
|
|
6f18f8d375 | ||
|
|
63cf0366bd | ||
|
|
fd7ea3420f | ||
|
|
52e520be10 | ||
|
|
af718696fb | ||
|
|
2c5a00c966 | ||
|
|
3d65f9905d | ||
|
|
709366bdfe | ||
|
|
910200b637 | ||
|
|
be831d7ecb | ||
|
|
44c544160a | ||
|
|
262df0197b | ||
|
|
ed853e1ffb | ||
|
|
799554b1c5 | ||
|
|
5d0864fb41 | ||
|
|
90ffbb4170 | ||
|
|
77822d9462 | ||
|
|
adfd841d9d | ||
|
|
237c46512c | ||
|
|
64f999ee89 | ||
|
|
198407b5ba | ||
|
|
ab5586a7a3 | ||
|
|
79426acd55 | ||
|
|
14f579844d | ||
|
|
83495af5ce | ||
|
|
dc9c72819c | ||
|
|
1200929a72 | ||
|
|
10ab52081d | ||
|
|
fecff1bcf0 | ||
|
|
513d77788d | ||
|
|
2f5a766c71 | ||
|
|
0b9703a36f | ||
|
|
2bf6ae09b3 | ||
|
|
879750b278 | ||
|
|
e3a9350e58 | ||
|
|
78a7a5b561 | ||
|
|
04086099d0 | ||
|
|
757450b24f | ||
|
|
fbbc93906e | ||
|
|
85dbf412fd | ||
|
|
1f25f80d5b | ||
|
|
99143db529 | ||
|
|
7fde7fcf7b | ||
|
|
2f99ece694 | ||
|
|
251dc3a322 | ||
|
|
c1b1e9af62 | ||
|
|
bcbbf6dacf | ||
|
|
cdccb19d1c | ||
|
|
93a924d020 | ||
|
|
6f7ac0e29c | ||
|
|
a3fdca376e | ||
|
|
bfdfb7479d | ||
|
|
56739b8036 | ||
|
|
2c5d1036db | ||
|
|
15b0a7813d | ||
|
|
490e5ace3a | ||
|
|
d2595ccfea | ||
|
|
6be0cf66e0 | ||
|
|
5b059dfd6b | ||
|
|
1a3c0d9be9 | ||
|
|
ea1a2f3fbf | ||
|
|
5ba18ec98d | ||
|
|
62b2b9bf45 | ||
|
|
244e69a10a | ||
|
|
e006ff39be | ||
|
|
9faad3da69 | ||
|
|
47a749742a | ||
|
|
9d252ff7d2 | ||
|
|
9b4213bb3f | ||
|
|
0cc7fd3498 | ||
|
|
1e22d92c69 | ||
|
|
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 | ||
|
|
f3a4ae987d | ||
|
|
85397cf893 | ||
|
|
d10ba45b4b | ||
|
|
ce7746b49e | ||
|
|
5e45fd7662 | ||
|
|
354e08673b | ||
|
|
c552943f9e | ||
|
|
810395f913 | ||
|
|
8dfdec39fd | ||
|
|
0abecbc87d | ||
|
|
efbb62b5bd | ||
|
|
24f5b98e8c | ||
|
|
dd5e309d31 | ||
|
|
0c0b1e1498 | ||
|
|
0d54bf3711 | ||
|
|
920aa8280f | ||
|
|
8a2c820213 | ||
|
|
ab08379d1c | ||
|
|
321cd769b7 | ||
|
|
802974ec84 | ||
|
|
91cb892574 | ||
|
|
4703c1399d | ||
|
|
e58e9e1fb9 | ||
|
|
d7802b428a | ||
|
|
5894e1b085 | ||
|
|
dc25a1a62b | ||
|
|
754b233873 | ||
|
|
b8d35358ad | ||
|
|
5617ad7c18 | ||
|
|
909f1a1a30 | ||
|
|
f6837a8ef4 | ||
|
|
d287c6c8b0 | ||
|
|
488735e4a2 | ||
|
|
43d597b30f | ||
|
|
a3f676461c | ||
|
|
607667f89d | ||
|
|
6212b342f6 | ||
|
|
5ddb691286 | ||
|
|
daac4e5d34 | ||
|
|
6f905e1f0f | ||
|
|
4ccedfaec4 | ||
|
|
c010901ea9 | ||
|
|
c0bedd810f | ||
|
|
57ceb807ca | ||
|
|
5d66bf5a1f | ||
|
|
d4b614d655 | ||
|
|
91d32c4556 | ||
|
|
e9e0f57d92 | ||
|
|
f090fee89b | ||
|
|
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 | ||
|
|
4c239ca4d9 | ||
|
|
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 | ||
|
|
cdb6b73776 | ||
|
|
fad7a0e23d | ||
|
|
da7cc28446 | ||
|
|
e6e391530f | ||
|
|
a0256cda63 | ||
|
|
85daeb5e16 |
@@ -0,0 +1,17 @@
|
||||
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
|
||||
libtommath/*.dsp
|
||||
libtommath/*.sln
|
||||
libtommath/*.vcproj
|
||||
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
|
||||
@@ -3,11 +3,13 @@ compat/zlib/contrib/vstudio/readme.txt
|
||||
compat/zlib/contrib/vstudio/*/zlib.rc
|
||||
compat/zlib/win32/*.txt
|
||||
compat/zlib/win64/*.txt
|
||||
libtommath/*.dsp
|
||||
libtommath/*.sln
|
||||
libtommath/*.vcproj
|
||||
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
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/tclsh*
|
||||
*/tcltest*
|
||||
*/versions.vc
|
||||
*/version.vc
|
||||
html
|
||||
libtommath/bn.ilg
|
||||
libtommath/bn.ind
|
||||
@@ -40,7 +41,8 @@ unix/dltest.marker
|
||||
unix/tcl.pc
|
||||
unix/tclIndex
|
||||
unix/pkgs/*
|
||||
win/Debug_VC*
|
||||
win/Release_VC*
|
||||
win/Debug*
|
||||
win/Release*
|
||||
win/pkgs/*
|
||||
win/tcl.hpj
|
||||
win/tcl.hpj
|
||||
win/nmhlp-out.txt
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
README: Tcl
|
||||
This is the Tcl 8.7a0 source distribution.
|
||||
This is the Tcl 8.7a2 source distribution.
|
||||
http://sourceforge.net/projects/tcl/files/Tcl/
|
||||
You can get any source release of Tcl from the URL above.
|
||||
|
||||
|
||||
@@ -8234,7 +8234,7 @@ Dropped support for OS X versions less than 10.4 (Tiger) (fellows)
|
||||
|
||||
2013-05-16 (platform support) mingw-4.0 (nijtmans)
|
||||
|
||||
2013-05-19 (platform support) FreeBSD updates (cerutti)
|
||||
2013-05-19 (platform support) FreeBSD updates (gahr)
|
||||
|
||||
2013-05-20 (bug fix)[3613567] access error temp file creation (keene)
|
||||
|
||||
@@ -8624,3 +8624,220 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
|
||||
2016-02-22 (bug)[9b4702] [info exists env(missing)] kills trace (nijtmans)
|
||||
|
||||
--- Released 8.6.5, February 29, 2016 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2016-03-01 (bug)[803042] mem leak due to reference cycle (porter)
|
||||
|
||||
2016-03-08 (bug)[bbc304] reflected watch race condition (porter)
|
||||
|
||||
2016-03-17 (bug)[fadc99] compile-5.3 (rodriguez,porter)
|
||||
|
||||
2016-03-17 (enhancement)[1a25fd] compile [variable ${ns}::v] (porter)
|
||||
|
||||
2016-03-20 (bug)[1af8de] crash in compiled [string replace] (harder,fellows)
|
||||
|
||||
2016-03-21 (bug)[d30718] segv in notifier finalize (hirofumi,nijtmans)
|
||||
|
||||
2016-03-23 (enhancement)[7d0db7] parallel make (yarda,nijtmans)
|
||||
|
||||
2016-03-23 [f12535] enable test bindings customization (vogel,nijtmans)
|
||||
|
||||
2016-04-04 (bug)[47ac84] compiled [lreplace] fixes (aspect,ferrieux,fellows)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-04-08 (bug)[866368] RE \w includes 'Punctuation Connector' (nijtmans)
|
||||
|
||||
2016-04-08 (bug)[2538f3] Win crash Tcl_OpenTcpServer() (griffin)
|
||||
|
||||
2016-04-10 [07d13d] Restore TclBlend support lost in 8.6.1 (buratti)
|
||||
|
||||
2016-05-13 (bug)[3154ea] Mem corruption in assembler exceptions (tkob,kenny)
|
||||
|
||||
2016-05-13 (bug) registry package support any Unicode env (nijtmans)
|
||||
=> registry 1.3.2
|
||||
|
||||
2016-05-21 (bug)[f7d4e] [namespace delete] performance (fellows)
|
||||
|
||||
2016-06-02 (TIP 447) execution time verbosity option (gahr)
|
||||
=> tcltest 2.4.0
|
||||
|
||||
2016-06-16 (bug)[16828b] crash due to [vwait] trace undo fail (dah,porter)
|
||||
|
||||
2016-06-16 (enhancement)[4b61af] good [info frame] from more cases (beric)
|
||||
|
||||
2016-06-21 (bug)[c383eb] crash in [glob -path a] (oehlmann,porter)
|
||||
|
||||
2016-06-21 (update) Update Unicode data to 9.0 (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-06-22 (bug)[16896d] Tcl_DString tolerate append to self. (dah,porter)
|
||||
|
||||
2016-06-23 (bug)[d55322] crash in [dict update] (yorick,fellows)
|
||||
|
||||
2016-06-27 (bug)[dd260a] crash in [chan configure -dictionary] (madden,aspect)
|
||||
|
||||
2016-07-02 (bug)[f961d7] usage message with parameters with spaces (porter)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-07-02 (enhancement)[09fabc] Sort order of -relateddir (lanam)
|
||||
|
||||
2016-07-07 (bug)[5d7ca0] Win: [file executable] for .cmd and .ps1 (nadkarni)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-07-08 (bug)[a47641] [file normalize] & Windows junctions (nadkarni)
|
||||
|
||||
2016-07-09 [ae61a6] [file] handling of Win hardcoded names (CON) (nadkarni)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-07-09 [3613671] [file owned] (more) useful on Win (nadkarni)
|
||||
|
||||
2016-07-09 (bug)[1493a4] [namespace upvar] use of resolvers (beric,fellows)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-07-10 (bug)[da340d] integer division in clock math (nadkarni)
|
||||
|
||||
2016-07-20 tzdata updated to Olson's tzdata2016f (venkat)
|
||||
|
||||
--- Released 8.6.6, July 27, 2016 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2016-09-07 (bug)[c09edf] Bad caching with custom resolver (neumann,nijtmans)
|
||||
|
||||
2016-09-07 (bug)[4dbdd9] Memleak in test var-8.3 (mr_calvin,porter)
|
||||
|
||||
2016-10-03 (bug)[2bf561] Allow empty command as alias target (yorick,nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-10-04 (bug)[4d5ae7] Crash in async connects host no address (gahr,fellows)
|
||||
|
||||
2016-10-08 (bug)[838e99] treat application/xml as text (gahr,fellows)
|
||||
=> http 2.8.10
|
||||
|
||||
2016-10-11 (bug)[3cc1d9] Thread finalization crash in zippy (neumann)
|
||||
|
||||
2016-10-12 (bug)[be003d] Fix [scan 0x1 %b], [scan 0x1 %o] (porter)
|
||||
|
||||
2016-10-14 (bug)[eb6b68] Fix stringComp-14.5 (porter)
|
||||
|
||||
2016-10-30 (bug)[b26e38] Fix zlib-7.8 (fellows)
|
||||
|
||||
2016-10-30 (bug)[1ae129] Fix memleak in [history] destruction (fellows)
|
||||
|
||||
2016-11-04 (feature) Provisional Tcl 9 support in msgcat and tcltest (nijtmans)
|
||||
=> msgcat 1.6.1
|
||||
=> tcltest 2.4.1
|
||||
|
||||
2016-11-04 (bug)[824752] Crash in Tcl_ListObjReplace() (gahr,porter)
|
||||
|
||||
2016-11-11 (bug)[79614f] invalidate VFS mounts on sytem encoding change (yorick)
|
||||
|
||||
2016-11-14 OSX: End panic() as legacy support macro; system conflicts (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-11-15 (bug) TclOO fix stops crash mixing Itcl and snit (fellows)
|
||||
|
||||
2016-11-17 (update) Reconcile libtommath updates; purge unused files (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-01-09 (bug)[b87ad7] Repair drifts in timer clock (sebres)
|
||||
|
||||
2017-01-17 (update) => zlib 1.2.11 (nijtmans)
|
||||
|
||||
2017-01-31 (bug)[39f630] Revise Tcl_LinkVar to tolerate some prefixes (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-02-01 (bug)[d0f7ba] Improper NAN optimization. expr-22.1[01] (aspect)
|
||||
|
||||
2017-02-26 (bug)[25842c] zlib stream finalization (aspect)
|
||||
|
||||
2017-03-07 (deprecate) Remove unmaintained makefile.bc file (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-03-14 (enhancement) [clock] and [encoding] are now ensembles (kenny)
|
||||
|
||||
2017-03-15 (enhancement) several [clock] subcommands bytecoded (kenny)
|
||||
|
||||
2017-03-23 tzdata updated to Olson's tzdata2017b (jima)
|
||||
|
||||
2017-03-29 (bug)[900cb0] Fix OO unexport introspection (napier)
|
||||
|
||||
2017-04-12 (bug)[42202b] Nesting imbalance in coro injection (nadkarni,sebres)
|
||||
|
||||
2017-04-18 (bug)[bc4322] http package support for safe interps (nash,nijtmans)
|
||||
|
||||
2017-04-28 (bug)[f34cf8] [file join a //b] => /b (neumann,porter)
|
||||
|
||||
2017-05-01 (bug)[8bd13f] Windows threads and pipes (sebres,nijtmans)
|
||||
|
||||
2017-05-01 (bug)[f9fe90] [file join //a b] EIAS violation (aspect,porter)
|
||||
|
||||
2017-05-04 (bug) Make test filesystem-1.52 pass on Windows (nijtmans)
|
||||
|
||||
2017-05-05 (bug)[601522] [binary] field spec overflow -> segfault (porter)
|
||||
|
||||
2017-05-08 (bug)[6ca52a] http memleak handling keep-alive (aspect,nijtmans)
|
||||
=> http 2.8.11
|
||||
|
||||
2017-05-29 (bug)[a3fb33] crash in [lsort] on long lists (sebres)
|
||||
|
||||
2017-06-05 (bug)[67aa9a] Tcl_UtfToUniChar() revised handling invalid UTF-8 (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-06-08 (bug)[2738427] Tcl_NumUtfChars() corner case utf-4.9 (nijtmans)
|
||||
|
||||
2017-06-22 (update) Update Unicode data to 10.0 (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2017-06-22 (TIP 473) Let [oo::copy] specify target namespace (fellows)
|
||||
|
||||
2017-06-26 (bug)[46f801] Repair autoloader fragility (porter)
|
||||
|
||||
2017-07-06 (bug)[adb198] Plug memleak in TclJoinPath (sebres,porter)
|
||||
|
||||
2017-07-17 (bug)[fb2208] Repeatable tclIndex generation (wiedemann,nijtmans)
|
||||
|
||||
--- Released 8.6.7, August 9, 2017 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2016-03-17 (bug)[0b8c38] socket accept callbacks always in global ns (porter)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2016-07-01 Hack accommodations for legacy Itcl 3 disabled (porter)
|
||||
|
||||
2016-07-12 Make TCL_HASH_TYPE build-time configurable (nijtmans)
|
||||
|
||||
2016-07-19 (bug)[0363f0] Partial array search ID reform (porter)
|
||||
|
||||
2016-07-19 (feature removed) Tcl_ObjType "array search" unregistered (porter)
|
||||
*** POTENTIAL INCOMPATIBILITY for Tcl_GetObjType("array search") ***
|
||||
|
||||
2016-10-04 Server socket on port 0 chooses port supporting IPv4 * IPv6 (max)
|
||||
|
||||
2016-11-25 [array named -regexp] supports backrefs (goth)
|
||||
|
||||
2017-01-04 (TIP 456) New routine Tcl_OpenTcpServerEx() (limeboy)
|
||||
|
||||
2017-01-04 (TIP 459) New subcommand [package files] (nijtmans)
|
||||
|
||||
2017-01-16 threaded allocator initialization repair (vasiljevic,nijtmans)
|
||||
|
||||
2017-01-30 Add to Win shell builtins: assoc ftype move (ashok)
|
||||
|
||||
2017-03-31 TCL_MEM_DEBUG facilities better support 64-bit memory (nijtmans)
|
||||
|
||||
2017-04-13 \u escaped content in msg files converted to true utf-8 (nijtmans)
|
||||
|
||||
2017-05-18 (TIP 458) New epoll or kqueue notifiers are default (alborboz)
|
||||
|
||||
2017-05-31 Purge build support for SunOS-4.* (stu)
|
||||
|
||||
2017-06-22 (TIP 463) New option [regsub ... -command ...] (fellows)
|
||||
|
||||
2017-06-22 (TIP 470) Tcl_GetDefineContextObject();[oo::define [self]] (fellows)
|
||||
=> TclOO 1.2.0
|
||||
|
||||
2017-06-23 (TIP 472) Support 0d as prefix of decimal numbers (iyer,griffin)
|
||||
|
||||
2017-08-31 (bug)[2a9465] http state 100 continue handling broken (oehlmann)
|
||||
=> http 2.8.12
|
||||
|
||||
2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter)
|
||||
|
||||
--- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
@@ -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
|
||||
+5
-2
@@ -57,6 +57,9 @@ after the optional white space and sign are
|
||||
.QW \fB0x\fR
|
||||
then \fIsrc\fR is expected to be in hexadecimal form; otherwise,
|
||||
if the first such characters are
|
||||
.QW \fB0d\fR
|
||||
then \fIsrc\fR is expected to be in decimal form; otherwise,
|
||||
if the first such characters are
|
||||
.QW \fB0o\fR
|
||||
then \fIsrc\fR is expected to be in octal form; otherwise,
|
||||
if the first such characters are
|
||||
@@ -65,8 +68,8 @@ then \fIsrc\fR is expected to be in binary form; otherwise,
|
||||
if the first such character is
|
||||
.QW \fB0\fR
|
||||
then \fIsrc\fR
|
||||
is expected to be in octal form; otherwise, \fIsrc\fR is
|
||||
expected to be in decimal form.
|
||||
is expected to be in octal form; otherwise, \fIsrc\fR
|
||||
is expected to be in decimal form.
|
||||
.PP
|
||||
\fBTcl_GetDouble\fR expects \fIsrc\fR to consist of a floating-point
|
||||
number, which is: white space; a sign; a sequence of digits; a
|
||||
|
||||
+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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ exception to occur.
|
||||
The exception causes the current script to be aborted
|
||||
out to the innermost containing loop command, which then
|
||||
continues with the next iteration of the loop.
|
||||
Catch exceptions are also handled in a few other situations, such
|
||||
Continue exceptions are also handled in a few other situations, such
|
||||
as the \fBcatch\fR command and the outermost scripts of procedure
|
||||
bodies.
|
||||
.SH EXAMPLE
|
||||
|
||||
+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:
|
||||
|
||||
+2
-1
@@ -46,7 +46,8 @@ value is the form produced by the \fB%g\fR format specifier of Tcl's
|
||||
An expression consists of a combination of operands, operators, parentheses and
|
||||
commas, possibly with whitespace between any of these elements, which is
|
||||
ignored.
|
||||
An integer operand may be specified in decimal, binary
|
||||
An integer operand may be specified in decimal (the normal case, the optional
|
||||
first two characters are \fB0d\fR), binary
|
||||
(the first two characters are \fB0b\fR), octal
|
||||
(the first two characters are \fB0o\fR), or hexadecimal
|
||||
(the first two characters are \fB0x\fR) form. For
|
||||
|
||||
@@ -89,6 +89,8 @@ For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively)
|
||||
will be added to the beginning of the result unless it is zero.
|
||||
For \fBb\fR conversions, \fB0b\fR
|
||||
will be added to the beginning of the result unless it is zero.
|
||||
For \fBd\fR conversions, \fB0d\fR will be added to the beginning
|
||||
of the result unless it is zero.
|
||||
For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
|
||||
\fBg\fR, and \fBG\fR) it guarantees that the result always
|
||||
has a decimal point.
|
||||
|
||||
+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
|
||||
|
||||
+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,33 @@ 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 \fIsubSpec\fR so that it is not treated
|
||||
as a template for a substitution string and the substrings
|
||||
.QW &
|
||||
and
|
||||
.QW \e\fIn\fR
|
||||
no longer have special meaning. Instead \fIsubSpec\fR must be a
|
||||
command prefix, that is, a non-empty list. The substring of \fIstring\fR
|
||||
that matches \fIexp\fR, and then each substring that matches each
|
||||
capturing sub-RE within \fIexp\fR are appended as additional elements
|
||||
to that list. (The items appended to the list are much like what
|
||||
\fBregexp\fR \fB-inline\fR would return). The completed list is then
|
||||
evaluated as a Tcl command, and the result of that command is the
|
||||
substitution string. Any error or exception from command evaluation
|
||||
becomes an error or exception from the \fBregsub\fR command.
|
||||
.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 +210,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
|
||||
};
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
*/
|
||||
|
||||
#define NOTREACHED 0
|
||||
#define xxx 1
|
||||
|
||||
#define DUPMAX _POSIX2_RE_DUP_MAX
|
||||
#define DUPINF (DUPMAX+1)
|
||||
|
||||
+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,
|
||||
|
||||
+29
-25
@@ -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
|
||||
@@ -56,11 +55,12 @@ extern "C" {
|
||||
#define TCL_MAJOR_VERSION 8
|
||||
#define TCL_MINOR_VERSION 7
|
||||
#define TCL_RELEASE_LEVEL TCL_ALPHA_RELEASE
|
||||
#define TCL_RELEASE_SERIAL 0
|
||||
#define TCL_RELEASE_SERIAL 2
|
||||
|
||||
#define TCL_VERSION "8.7"
|
||||
#define TCL_PATCH_LEVEL "8.7a0"
|
||||
#define TCL_PATCH_LEVEL "8.7a2"
|
||||
|
||||
#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
|
||||
@@ -2262,6 +2263,8 @@ typedef struct mp_int mp_int;
|
||||
#define MP_INT_DECLARED
|
||||
typedef unsigned int mp_digit;
|
||||
#define MP_DIGIT_DECLARED
|
||||
typedef unsigned TCL_WIDE_INT_TYPE mp_word;
|
||||
#define MP_WORD_DECLARED
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -2534,7 +2537,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 +2630,6 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
# define panic Tcl_Panic
|
||||
#endif
|
||||
# define panicVA Tcl_PanicVA
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -2638,6 +2640,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");
|
||||
|
||||
+170
-81
@@ -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);
|
||||
@@ -2042,11 +2053,11 @@ Tcl_CreateCommand(
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ImportRef *oldRefPtr = NULL;
|
||||
Namespace *nsPtr, *dummy1, *dummy2;
|
||||
Command *cmdPtr, *refCmdPtr;
|
||||
Namespace *nsPtr;
|
||||
Command *cmdPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
const char *tail;
|
||||
int isNew;
|
||||
int isNew = 0, deleted = 0;
|
||||
ImportedCmdData *dataPtr;
|
||||
|
||||
if (iPtr->flags & DELETED) {
|
||||
@@ -2059,32 +2070,52 @@ Tcl_CreateCommand(
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine where the command should reside. If its name contains
|
||||
* namespace qualifiers, we put it in the specified namespace; otherwise,
|
||||
* we always put it in the global namespace.
|
||||
* If the command name we seek to create already exists, we need to
|
||||
* delete that first. That can be tricky in the presence of traces.
|
||||
* Loop until we no longer find an existing command in the way, or
|
||||
* until we've deleted one command and that didn't finish the job.
|
||||
*/
|
||||
|
||||
if (strstr(cmdName, "::") != NULL) {
|
||||
TclGetNamespaceForQualName(interp, cmdName, NULL,
|
||||
TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
|
||||
if ((nsPtr == NULL) || (tail == NULL)) {
|
||||
return (Tcl_Command) NULL;
|
||||
}
|
||||
} else {
|
||||
nsPtr = iPtr->globalNsPtr;
|
||||
tail = cmdName;
|
||||
}
|
||||
while (1) {
|
||||
/*
|
||||
* Determine where the command should reside. If its name contains
|
||||
* namespace qualifiers, we put it in the specified namespace;
|
||||
* otherwise, we always put it in the global namespace.
|
||||
*/
|
||||
|
||||
if (strstr(cmdName, "::") != NULL) {
|
||||
Namespace *dummy1, *dummy2;
|
||||
|
||||
TclGetNamespaceForQualName(interp, cmdName, NULL,
|
||||
TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
|
||||
if ((nsPtr == NULL) || (tail == NULL)) {
|
||||
return (Tcl_Command) NULL;
|
||||
}
|
||||
} else {
|
||||
nsPtr = iPtr->globalNsPtr;
|
||||
tail = cmdName;
|
||||
}
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
|
||||
if (isNew || deleted) {
|
||||
/*
|
||||
* isNew - No conflict with existing command.
|
||||
* deleted - We've already deleted a conflicting command
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* An existing command conflicts. Try to delete it.. */
|
||||
cmdPtr = Tcl_GetHashValue(hPtr);
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
if (!isNew) {
|
||||
/*
|
||||
* Command already exists. Delete the old one. Be careful to preserve
|
||||
* Be careful to preserve
|
||||
* any existing import links so we can restore them down below. That
|
||||
* way, you can redefine a command and its import status will remain
|
||||
* intact.
|
||||
*/
|
||||
|
||||
cmdPtr = Tcl_GetHashValue(hPtr);
|
||||
cmdPtr->refCount++;
|
||||
if (cmdPtr->importRefPtr) {
|
||||
cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
|
||||
@@ -2097,18 +2128,21 @@ Tcl_CreateCommand(
|
||||
cmdPtr->importRefPtr = NULL;
|
||||
}
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
deleted = 1;
|
||||
}
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
if (!isNew) {
|
||||
/*
|
||||
* If the deletion callback recreated the command, just throw away
|
||||
* the new command (if we try to delete it again, we could get
|
||||
* stuck in an infinite loop).
|
||||
*/
|
||||
if (!isNew) {
|
||||
/*
|
||||
* If the deletion callback recreated the command, just throw away
|
||||
* the new command (if we try to delete it again, we could get
|
||||
* stuck in an infinite loop).
|
||||
*/
|
||||
|
||||
ckfree(Tcl_GetHashValue(hPtr));
|
||||
}
|
||||
|
||||
if (!deleted) {
|
||||
|
||||
ckfree(Tcl_GetHashValue(hPtr));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Command resolvers (per-interp, per-namespace) might have resolved
|
||||
* to a command for the given namespace scope with this command not
|
||||
@@ -2156,7 +2190,7 @@ Tcl_CreateCommand(
|
||||
if (oldRefPtr != NULL) {
|
||||
cmdPtr->importRefPtr = oldRefPtr;
|
||||
while (oldRefPtr != NULL) {
|
||||
refCmdPtr = oldRefPtr->importedCmdPtr;
|
||||
Command *refCmdPtr = oldRefPtr->importedCmdPtr;
|
||||
dataPtr = refCmdPtr->objClientData;
|
||||
dataPtr->realCmdPtr = cmdPtr;
|
||||
oldRefPtr = oldRefPtr->nextPtr;
|
||||
@@ -2217,11 +2251,11 @@ Tcl_CreateObjCommand(
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ImportRef *oldRefPtr = NULL;
|
||||
Namespace *nsPtr, *dummy1, *dummy2;
|
||||
Command *cmdPtr, *refCmdPtr;
|
||||
Namespace *nsPtr;
|
||||
Command *cmdPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
const char *tail;
|
||||
int isNew;
|
||||
int isNew = 0, deleted = 0;
|
||||
ImportedCmdData *dataPtr;
|
||||
|
||||
if (iPtr->flags & DELETED) {
|
||||
@@ -2234,29 +2268,45 @@ Tcl_CreateObjCommand(
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine where the command should reside. If its name contains
|
||||
* namespace qualifiers, we put it in the specified namespace; otherwise,
|
||||
* we always put it in the global namespace.
|
||||
* If the command name we seek to create already exists, we need to
|
||||
* delete that first. That can be tricky in the presence of traces.
|
||||
* Loop until we no longer find an existing command in the way, or
|
||||
* until we've deleted one command and that didn't finish the job.
|
||||
*/
|
||||
|
||||
if (strstr(cmdName, "::") != NULL) {
|
||||
TclGetNamespaceForQualName(interp, cmdName, NULL,
|
||||
while (1) {
|
||||
/*
|
||||
* Determine where the command should reside. If its name contains
|
||||
* namespace qualifiers, we put it in the specified namespace;
|
||||
* otherwise, we always put it in the global namespace.
|
||||
*/
|
||||
|
||||
if (strstr(cmdName, "::") != NULL) {
|
||||
Namespace *dummy1, *dummy2;
|
||||
|
||||
TclGetNamespaceForQualName(interp, cmdName, NULL,
|
||||
TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
|
||||
if ((nsPtr == NULL) || (tail == NULL)) {
|
||||
return (Tcl_Command) NULL;
|
||||
}
|
||||
} else {
|
||||
nsPtr = iPtr->globalNsPtr;
|
||||
tail = cmdName;
|
||||
}
|
||||
if ((nsPtr == NULL) || (tail == NULL)) {
|
||||
return (Tcl_Command) NULL;
|
||||
}
|
||||
} else {
|
||||
nsPtr = iPtr->globalNsPtr;
|
||||
tail = cmdName;
|
||||
}
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
TclInvalidateNsPath(nsPtr);
|
||||
if (!isNew) {
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
|
||||
if (isNew || deleted) {
|
||||
/*
|
||||
* isNew - No conflict with existing command.
|
||||
* deleted - We've already deleted a conflicting command
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
/* An existing command conflicts. Try to delete it.. */
|
||||
cmdPtr = Tcl_GetHashValue(hPtr);
|
||||
|
||||
/* Command already exists. */
|
||||
|
||||
/*
|
||||
* [***] This is wrong. See Tcl Bug a16752c252.
|
||||
* However, this buggy behavior is kept under particular
|
||||
@@ -2293,18 +2343,20 @@ Tcl_CreateObjCommand(
|
||||
cmdPtr->importRefPtr = NULL;
|
||||
}
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
deleted = 1;
|
||||
}
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
if (!isNew) {
|
||||
/*
|
||||
* If the deletion callback recreated the command, just throw away
|
||||
* the new command (if we try to delete it again, we could get
|
||||
* stuck in an infinite loop).
|
||||
*/
|
||||
if (!isNew) {
|
||||
/*
|
||||
* If the deletion callback recreated the command, just throw away
|
||||
* the new command (if we try to delete it again, we could get
|
||||
* stuck in an infinite loop).
|
||||
*/
|
||||
|
||||
ckfree(Tcl_GetHashValue(hPtr));
|
||||
}
|
||||
} else {
|
||||
ckfree(Tcl_GetHashValue(hPtr));
|
||||
}
|
||||
|
||||
if (!deleted) {
|
||||
/*
|
||||
* Command resolvers (per-interp, per-namespace) might have resolved
|
||||
* to a command for the given namespace scope with this command not
|
||||
@@ -2324,6 +2376,7 @@ Tcl_CreateObjCommand(
|
||||
*/
|
||||
|
||||
TclInvalidateNsCmdLookup(nsPtr);
|
||||
TclInvalidateNsPath(nsPtr);
|
||||
}
|
||||
cmdPtr = ckalloc(sizeof(Command));
|
||||
Tcl_SetHashValue(hPtr, cmdPtr);
|
||||
@@ -2351,7 +2404,7 @@ Tcl_CreateObjCommand(
|
||||
if (oldRefPtr != NULL) {
|
||||
cmdPtr->importRefPtr = oldRefPtr;
|
||||
while (oldRefPtr != NULL) {
|
||||
refCmdPtr = oldRefPtr->importedCmdPtr;
|
||||
Command *refCmdPtr = oldRefPtr->importedCmdPtr;
|
||||
dataPtr = refCmdPtr->objClientData;
|
||||
dataPtr->realCmdPtr = cmdPtr;
|
||||
oldRefPtr = oldRefPtr->nextPtr;
|
||||
@@ -3059,7 +3112,7 @@ Tcl_DeleteCommandFromToken(
|
||||
/*
|
||||
* We must delete this command, even though both traces and delete procs
|
||||
* may try to avoid this (renaming the command etc). Also traces and
|
||||
* delete procs may try to delete the command themsevles. This flag
|
||||
* delete procs may try to delete the command themselves. This flag
|
||||
* declares that a delete is in progress and that recursive deletes should
|
||||
* be ignored.
|
||||
*/
|
||||
@@ -3550,7 +3603,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 +3629,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 +4758,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 +5903,7 @@ TclArgumentGet(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_Eval
|
||||
int
|
||||
Tcl_Eval(
|
||||
@@ -5902,6 +5956,7 @@ Tcl_GlobalEvalObj(
|
||||
{
|
||||
return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -6728,6 +6783,7 @@ Tcl_AppendObjToErrorInfo(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_AddErrorInfo
|
||||
void
|
||||
Tcl_AddErrorInfo(
|
||||
@@ -6737,6 +6793,7 @@ Tcl_AddErrorInfo(
|
||||
{
|
||||
Tcl_AddObjErrorInfo(interp, message, -1);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -6909,6 +6966,7 @@ Tcl_VarEval(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_GlobalEval
|
||||
int
|
||||
Tcl_GlobalEval(
|
||||
@@ -6926,6 +6984,7 @@ Tcl_GlobalEval(
|
||||
iPtr->varFramePtr = savedVarFramePtr;
|
||||
return result;
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -7179,7 +7238,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) {
|
||||
@@ -7401,7 +7460,7 @@ ExprAbsFunc(
|
||||
}
|
||||
goto unChanged;
|
||||
} else if (l == LONG_MIN) {
|
||||
TclBNInitBignumFromLong(&big, l);
|
||||
TclInitBignumFromLong(&big, l);
|
||||
goto tooLarge;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(-l));
|
||||
@@ -7436,7 +7495,7 @@ ExprAbsFunc(
|
||||
goto unChanged;
|
||||
}
|
||||
if (w == LLONG_MIN) {
|
||||
TclBNInitBignumFromWideInt(&big, w);
|
||||
TclInitBignumFromWideInt(&big, w);
|
||||
goto tooLarge;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-w));
|
||||
@@ -7622,7 +7681,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 +7692,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));
|
||||
@@ -7663,8 +7722,8 @@ ExprRandFunc(
|
||||
iPtr->flags |= RAND_SEED_INITIALIZED;
|
||||
|
||||
/*
|
||||
* Take into consideration the thread this interp is running in order
|
||||
* to insure different seeds in different threads (bug #416643)
|
||||
* To ensure different seeds in different threads (bug #416643),
|
||||
* take into consideration the thread this interp is running in.
|
||||
*/
|
||||
|
||||
iPtr->randSeed = TclpGetClicks() + (PTR2INT(Tcl_GetCurrentThread())<<12);
|
||||
@@ -8750,6 +8809,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 +8892,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;
|
||||
@@ -9002,7 +9091,7 @@ TclNRCoroutineObjCmd(
|
||||
TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* insure that the command is looked up in the correct namespace */
|
||||
/* ensure that the command is looked up in the correct namespace */
|
||||
iPtr->lookupNsPtr = lookupNsPtr;
|
||||
Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
|
||||
iPtr->numLevels--;
|
||||
|
||||
+16
-8
@@ -536,7 +536,7 @@ SetByteArrayFromAny(
|
||||
const char *src, *srcEnd;
|
||||
unsigned char *dst;
|
||||
ByteArray *byteArrayPtr;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
if (objPtr->typePtr == &properByteArrayType) {
|
||||
return TCL_OK;
|
||||
@@ -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);
|
||||
}
|
||||
@@ -1300,10 +1300,10 @@ BinaryFormatCmd(
|
||||
|
||||
badField:
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
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));
|
||||
@@ -1670,10 +1670,10 @@ BinaryScanCmd(
|
||||
|
||||
badField:
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
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;
|
||||
}
|
||||
@@ -2276,7 +2284,7 @@ ScanNumber(
|
||||
Tcl_Obj *bigObj = NULL;
|
||||
mp_int big;
|
||||
|
||||
TclBNInitBignumFromWideUInt(&big, uwvalue);
|
||||
TclInitBignumFromWideUInt(&big, uwvalue);
|
||||
bigObj = Tcl_NewBignumObj(&big);
|
||||
return bigObj;
|
||||
}
|
||||
|
||||
+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))
|
||||
|
||||
+349
-71
@@ -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,
|
||||
@@ -542,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;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -642,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\"",
|
||||
@@ -664,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;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+21
-22
@@ -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;
|
||||
}
|
||||
|
||||
@@ -4371,7 +4370,7 @@ static int
|
||||
DictionaryCompare(
|
||||
const char *left, const char *right) /* The strings to compare. */
|
||||
{
|
||||
Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower;
|
||||
Tcl_UniChar uniLeft = 0, uniRight = 0, uniLeftLower, uniRightLower;
|
||||
int diff, zeros;
|
||||
int secondaryDiff = 0;
|
||||
|
||||
@@ -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
|
||||
|
||||
+125
-13
@@ -487,26 +487,27 @@ 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;
|
||||
Tcl_RegExp regExpr;
|
||||
Tcl_RegExpInfo info;
|
||||
Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
|
||||
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 +529,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 +589,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 +665,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 +704,9 @@ Tcl_RegsubObjCmd(
|
||||
} else {
|
||||
subPtr = objv[2];
|
||||
}
|
||||
wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen);
|
||||
if (!command) {
|
||||
wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen);
|
||||
}
|
||||
|
||||
result = TCL_OK;
|
||||
|
||||
@@ -736,6 +764,90 @@ 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) {
|
||||
Tcl_Obj **args = NULL, **parts;
|
||||
int numArgs;
|
||||
|
||||
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
|
||||
* afterwards; 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]);
|
||||
}
|
||||
ckfree(args);
|
||||
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
|
||||
@@ -1061,7 +1173,7 @@ Tcl_SplitObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
int len;
|
||||
const char *splitChars;
|
||||
const char *stringPtr;
|
||||
@@ -1146,7 +1258,7 @@ Tcl_SplitObjCmd(
|
||||
} else {
|
||||
const char *element, *p, *splitEnd;
|
||||
int splitLen;
|
||||
Tcl_UniChar splitChar;
|
||||
Tcl_UniChar splitChar = 0;
|
||||
|
||||
/*
|
||||
* Normal case: split on any of a given set of characters. Discard
|
||||
@@ -1370,7 +1482,7 @@ StringIsCmd(
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
const char *string1, *end, *stop;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
int (*chcomp)(int) = NULL; /* The UniChar comparison function. */
|
||||
int i, failat = 0, result = 1, strict = 0, index, length1, length2;
|
||||
Tcl_Obj *objPtr, *failVarObj = NULL;
|
||||
@@ -1565,7 +1677,7 @@ StringIsCmd(
|
||||
}
|
||||
break;
|
||||
case STR_IS_WIDE:
|
||||
if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {
|
||||
if (TCL_OK == TclGetWideIntFromObj(NULL, objPtr, &w)) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2298,7 +2410,7 @@ StringStartCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
const char *p, *string;
|
||||
int cur, index, length, numChars;
|
||||
|
||||
@@ -2359,7 +2471,7 @@ StringEndCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
const char *p, *end, *string;
|
||||
int cur, index, length, numChars;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
@@ -1885,7 +1885,7 @@ ParseLexeme(
|
||||
{
|
||||
const char *end;
|
||||
int scanned;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
Tcl_Obj *literal = NULL;
|
||||
unsigned char byte;
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
+40
-8
@@ -23,6 +23,15 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(BUILD_tcl)
|
||||
# define TCL_DEPRECATED(msg) EXTERN TCL_DEPRECATED_API(msg)
|
||||
#elif defined(TCL_NO_DEPRECATED)
|
||||
# define TCL_DEPRECATED(msg) MODULE_SCOPE
|
||||
#else
|
||||
# define TCL_DEPRECATED(msg) EXTERN
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* WARNING: This file is automatically generated by the tools/genStubs.tcl
|
||||
* script. Any modifications to the function declarations below should be made
|
||||
@@ -878,7 +887,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 +2160,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 +3844,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)
|
||||
@@ -3870,6 +3879,29 @@ extern const TclStubs *tclStubsPtr;
|
||||
#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 { \
|
||||
@@ -3939,10 +3971,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 */
|
||||
|
||||
@@ -2331,7 +2331,9 @@ DictAppendCmd(
|
||||
valuePtr = Tcl_DuplicateObj(valuePtr);
|
||||
}
|
||||
|
||||
Tcl_IncrRefCount(appendObjPtr);
|
||||
Tcl_AppendObjToObj(valuePtr, appendObjPtr);
|
||||
Tcl_DecrRefCount(appendObjPtr);
|
||||
}
|
||||
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
|
||||
@@ -3562,7 +3564,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 +3647,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.
|
||||
|
||||
+71
-58
@@ -563,7 +563,7 @@ TclInitEncodingSubsystem(void)
|
||||
* formed UTF-8 into a properly formed stream.
|
||||
*/
|
||||
|
||||
type.encodingName = "identity";
|
||||
type.encodingName = NULL;
|
||||
type.toUtfProc = BinaryProc;
|
||||
type.fromUtfProc = BinaryProc;
|
||||
type.freeProc = NULL;
|
||||
@@ -851,7 +851,9 @@ FreeEncoding(
|
||||
if (encodingPtr->hPtr != NULL) {
|
||||
Tcl_DeleteHashEntry(encodingPtr->hPtr);
|
||||
}
|
||||
ckfree(encodingPtr->name);
|
||||
if (encodingPtr->name) {
|
||||
ckfree(encodingPtr->name);
|
||||
}
|
||||
ckfree(encodingPtr);
|
||||
}
|
||||
}
|
||||
@@ -1040,27 +1042,8 @@ Tcl_CreateEncoding(
|
||||
const Tcl_EncodingType *typePtr)
|
||||
/* The encoding type. */
|
||||
{
|
||||
Tcl_HashEntry *hPtr;
|
||||
int isNew;
|
||||
Encoding *encodingPtr;
|
||||
char *name;
|
||||
|
||||
Tcl_MutexLock(&encodingMutex);
|
||||
hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &isNew);
|
||||
if (isNew == 0) {
|
||||
/*
|
||||
* Remove old encoding from hash table, but don't delete it until last
|
||||
* reference goes away.
|
||||
*/
|
||||
|
||||
encodingPtr = Tcl_GetHashValue(hPtr);
|
||||
encodingPtr->hPtr = NULL;
|
||||
}
|
||||
|
||||
name = ckalloc(strlen(typePtr->encodingName) + 1);
|
||||
|
||||
encodingPtr = ckalloc(sizeof(Encoding));
|
||||
encodingPtr->name = strcpy(name, typePtr->encodingName);
|
||||
Encoding *encodingPtr = ckalloc(sizeof(Encoding));
|
||||
encodingPtr->name = NULL;
|
||||
encodingPtr->toUtfProc = typePtr->toUtfProc;
|
||||
encodingPtr->fromUtfProc = typePtr->fromUtfProc;
|
||||
encodingPtr->freeProc = typePtr->freeProc;
|
||||
@@ -1072,11 +1055,32 @@ Tcl_CreateEncoding(
|
||||
encodingPtr->lengthProc = (LengthProc *) unilen;
|
||||
}
|
||||
encodingPtr->refCount = 1;
|
||||
encodingPtr->hPtr = NULL;
|
||||
|
||||
if (typePtr->encodingName) {
|
||||
Tcl_HashEntry *hPtr;
|
||||
int isNew;
|
||||
char *name;
|
||||
|
||||
Tcl_MutexLock(&encodingMutex);
|
||||
hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &isNew);
|
||||
if (isNew == 0) {
|
||||
/*
|
||||
* Remove old encoding from hash table, but don't delete it until last
|
||||
* reference goes away.
|
||||
*/
|
||||
|
||||
Encoding *replaceMe = Tcl_GetHashValue(hPtr);
|
||||
replaceMe->hPtr = NULL;
|
||||
}
|
||||
|
||||
name = ckalloc(strlen(typePtr->encodingName) + 1);
|
||||
encodingPtr->name = strcpy(name, typePtr->encodingName);
|
||||
encodingPtr->hPtr = hPtr;
|
||||
Tcl_SetHashValue(hPtr, encodingPtr);
|
||||
|
||||
Tcl_MutexUnlock(&encodingMutex);
|
||||
|
||||
}
|
||||
return (Tcl_Encoding) encodingPtr;
|
||||
}
|
||||
|
||||
@@ -2293,8 +2297,11 @@ UtfToUtfProc(
|
||||
const char *srcStart, *srcEnd, *srcClose;
|
||||
const char *dstStart, *dstEnd;
|
||||
int result, numChars, charLimit = INT_MAX;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr;
|
||||
|
||||
if (flags & TCL_ENCODING_START) {
|
||||
*statePtr = 0;
|
||||
}
|
||||
result = TCL_OK;
|
||||
|
||||
srcStart = src;
|
||||
@@ -2326,7 +2333,7 @@ UtfToUtfProc(
|
||||
}
|
||||
if (UCHAR(*src) < 0x80 && !(UCHAR(*src) == 0 && pureNullMode == 0)) {
|
||||
/*
|
||||
* Copy 7bit chatacters, but skip null-bytes when we are in input
|
||||
* Copy 7bit characters, but skip null-bytes when we are in input
|
||||
* mode, so that they get converted to 0xc080.
|
||||
*/
|
||||
|
||||
@@ -2341,17 +2348,17 @@ UtfToUtfProc(
|
||||
src += 2;
|
||||
} else if (!Tcl_UtfCharComplete(src, srcEnd - src)) {
|
||||
/*
|
||||
* Always check before using Tcl_UtfToUniChar. 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.
|
||||
* Always check before using TclUtfToUniChar. Not doing can so
|
||||
* cause it run beyond the end of the buffer! If we happen such an
|
||||
* incomplete char its bytes are made to represent themselves.
|
||||
*/
|
||||
|
||||
ch = (unsigned char) *src;
|
||||
*chPtr = (unsigned char) *src;
|
||||
src += 1;
|
||||
dst += Tcl_UniCharToUtf(ch, dst);
|
||||
dst += Tcl_UniCharToUtf(*chPtr, dst);
|
||||
} else {
|
||||
src += Tcl_UtfToUniChar(src, &ch);
|
||||
dst += Tcl_UniCharToUtf(ch, dst);
|
||||
src += TclUtfToUniChar(src, chPtr);
|
||||
dst += Tcl_UniCharToUtf(*chPtr, dst);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2407,8 +2414,11 @@ UnicodeToUtfProc(
|
||||
const char *srcStart, *srcEnd;
|
||||
const char *dstEnd, *dstStart;
|
||||
int result, numChars, charLimit = INT_MAX;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr;
|
||||
|
||||
if (flags & TCL_ENCODING_START) {
|
||||
*statePtr = 0;
|
||||
}
|
||||
if (flags & TCL_ENCODING_CHAR_LIMIT) {
|
||||
charLimit = *dstCharsPtr;
|
||||
}
|
||||
@@ -2436,11 +2446,11 @@ UnicodeToUtfProc(
|
||||
* Tcl_UniChar-size data.
|
||||
*/
|
||||
|
||||
ch = *(Tcl_UniChar *)src;
|
||||
if (ch && ch < 0x80) {
|
||||
*dst++ = (ch & 0xFF);
|
||||
*chPtr = *(Tcl_UniChar *)src;
|
||||
if (*chPtr && *chPtr < 0x80) {
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
} else {
|
||||
dst += Tcl_UniCharToUtf(ch, dst);
|
||||
dst += Tcl_UniCharToUtf(*chPtr, dst);
|
||||
}
|
||||
src += sizeof(Tcl_UniChar);
|
||||
}
|
||||
@@ -2497,8 +2507,11 @@ UtfToUnicodeProc(
|
||||
{
|
||||
const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
|
||||
int result, numChars;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr;
|
||||
|
||||
if (flags & TCL_ENCODING_START) {
|
||||
*statePtr = 0;
|
||||
}
|
||||
srcStart = src;
|
||||
srcEnd = src + srcLen;
|
||||
srcClose = srcEnd;
|
||||
@@ -2524,7 +2537,7 @@ UtfToUnicodeProc(
|
||||
result = TCL_CONVERT_NOSPACE;
|
||||
break;
|
||||
}
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
src += TclUtfToUniChar(src, chPtr);
|
||||
|
||||
/*
|
||||
* Need to handle this in a way that won't cause misalignment by
|
||||
@@ -2533,23 +2546,23 @@ UtfToUnicodeProc(
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if TCL_UTF_MAX > 4
|
||||
*dst++ = (ch >> 24);
|
||||
*dst++ = ((ch >> 16) & 0xFF);
|
||||
*dst++ = ((ch >> 8) & 0xFF);
|
||||
*dst++ = (ch & 0xFF);
|
||||
*dst++ = (*chPtr >> 24);
|
||||
*dst++ = ((*chPtr >> 16) & 0xFF);
|
||||
*dst++ = ((*chPtr >> 8) & 0xFF);
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
#else
|
||||
*dst++ = (ch >> 8);
|
||||
*dst++ = (ch & 0xFF);
|
||||
*dst++ = (*chPtr >> 8);
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
#endif
|
||||
#else
|
||||
#if TCL_UTF_MAX > 4
|
||||
*dst++ = (ch & 0xFF);
|
||||
*dst++ = ((ch >> 8) & 0xFF);
|
||||
*dst++ = ((ch >> 16) & 0xFF);
|
||||
*dst++ = (ch >> 24);
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
*dst++ = ((*chPtr >> 8) & 0xFF);
|
||||
*dst++ = ((*chPtr >> 16) & 0xFF);
|
||||
*dst++ = (*chPtr >> 24);
|
||||
#else
|
||||
*dst++ = (ch & 0xFF);
|
||||
*dst++ = (ch >> 8);
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
*dst++ = (*chPtr >> 8);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
@@ -2607,7 +2620,7 @@ TableToUtfProc(
|
||||
const char *srcStart, *srcEnd;
|
||||
const char *dstEnd, *dstStart, *prefixBytes;
|
||||
int result, byte, numChars, charLimit = INT_MAX;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
const unsigned short *const *toUnicode;
|
||||
const unsigned short *pageZero;
|
||||
TableEncodingData *dataPtr = clientData;
|
||||
@@ -2719,7 +2732,7 @@ TableFromUtfProc(
|
||||
{
|
||||
const char *srcStart, *srcEnd, *srcClose;
|
||||
const char *dstStart, *dstEnd, *prefixBytes;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
int result, len, word, numChars;
|
||||
TableEncodingData *dataPtr = clientData;
|
||||
const unsigned short *const *fromUnicode;
|
||||
@@ -2853,7 +2866,7 @@ Iso88591ToUtfProc(
|
||||
|
||||
result = TCL_OK;
|
||||
for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
if (dst > dstEnd) {
|
||||
result = TCL_CONVERT_NOSPACE;
|
||||
@@ -2939,7 +2952,7 @@ Iso88591FromUtfProc(
|
||||
dstEnd = dst + dstLen - 1;
|
||||
|
||||
for (numChars = 0; src < srcEnd; numChars++) {
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
int len;
|
||||
|
||||
if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
|
||||
@@ -3326,7 +3339,7 @@ EscapeFromUtfProc(
|
||||
for (numChars = 0; src < srcEnd; numChars++) {
|
||||
unsigned len;
|
||||
int word;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
|
||||
/*
|
||||
@@ -3371,7 +3384,7 @@ EscapeFromUtfProc(
|
||||
|
||||
/*
|
||||
* The state variable has the value of oldState when word is 0.
|
||||
* In this case, the escape sequense should not be copied to dst
|
||||
* In this case, the escape sequence should not be copied to dst
|
||||
* because the current character set is not changed.
|
||||
*/
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -130,6 +130,7 @@ TclSetupEnv(
|
||||
* '='; ignore the entry.
|
||||
*/
|
||||
|
||||
Tcl_DStringFree(&envString);
|
||||
continue;
|
||||
}
|
||||
p2++;
|
||||
|
||||
+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
|
||||
|
||||
+65
-31
@@ -510,8 +510,7 @@ VarHashCreateVar(
|
||||
: (*(tPtr) = TCL_NUMBER_DOUBLE)), \
|
||||
*(ptrPtr) = (ClientData) \
|
||||
(&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
|
||||
((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \
|
||||
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \
|
||||
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \
|
||||
? TCL_ERROR : \
|
||||
TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
|
||||
#else /* !TCL_WIDE_INT_IS_LONG */
|
||||
@@ -530,8 +529,7 @@ VarHashCreateVar(
|
||||
: (*(tPtr) = TCL_NUMBER_DOUBLE)), \
|
||||
*(ptrPtr) = (ClientData) \
|
||||
(&((objPtr)->internalRep.doubleValue)), TCL_OK) : \
|
||||
((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) || \
|
||||
(((objPtr)->bytes != NULL) && ((objPtr)->length == 0))) \
|
||||
(((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;
|
||||
@@ -6764,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((
|
||||
@@ -6935,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",
|
||||
@@ -7158,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) {
|
||||
@@ -7232,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);
|
||||
@@ -7261,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) {
|
||||
@@ -7370,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);
|
||||
@@ -7464,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) {
|
||||
@@ -7497,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();
|
||||
@@ -7524,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) {
|
||||
@@ -7554,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) {
|
||||
@@ -7573,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) {
|
||||
@@ -7664,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 */
|
||||
@@ -8184,7 +8218,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
* Arguments are opposite sign; remainder is sum.
|
||||
*/
|
||||
|
||||
TclBNInitBignumFromWideInt(&big1, w1);
|
||||
TclInitBignumFromWideInt(&big1, w1);
|
||||
mp_add(&big2, &big1, &big2);
|
||||
mp_clear(&big1);
|
||||
BIG_RESULT(&big2);
|
||||
@@ -9150,7 +9184,7 @@ ExecuteExtendedUnaryMathOp(
|
||||
if (w != LLONG_MIN) {
|
||||
WIDE_RESULT(-w);
|
||||
}
|
||||
TclBNInitBignumFromLong(&big, *(const long *) ptr);
|
||||
TclInitBignumFromLong(&big, *(const long *) ptr);
|
||||
break;
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
case TCL_NUMBER_WIDE:
|
||||
@@ -9158,7 +9192,7 @@ ExecuteExtendedUnaryMathOp(
|
||||
if (w != LLONG_MIN) {
|
||||
WIDE_RESULT(-w);
|
||||
}
|
||||
TclBNInitBignumFromWideInt(&big, w);
|
||||
TclInitBignumFromWideInt(&big, w);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
@@ -9199,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;
|
||||
|
||||
@@ -1904,7 +1904,7 @@ TclGlob(
|
||||
}
|
||||
|
||||
/*
|
||||
* To process a [glob] invokation, this function may be called multiple
|
||||
* To process a [glob] invocation, this function may be called multiple
|
||||
* times. Each time, the previously discovered filenames are in the
|
||||
* interpreter result. We stash that away here so the result is free for
|
||||
* error messsages.
|
||||
|
||||
@@ -45,19 +45,6 @@ static Tcl_HashEntry * AllocArrayEntry(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
static int CompareArrayKeys(void *keyPtr, Tcl_HashEntry *hPtr);
|
||||
static TCL_HASH_TYPE HashArrayKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
|
||||
/*
|
||||
* Prototypes for the one word hash key methods. Not actually declared because
|
||||
* this is a critical path that is implemented in the core hash table access
|
||||
* function.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static Tcl_HashEntry * AllocOneWordEntry(Tcl_HashTable *tablePtr,
|
||||
void *keyPtr);
|
||||
static int CompareOneWordKeys(void *keyPtr, Tcl_HashEntry *hPtr);
|
||||
static unsigned int HashOneWordKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prototypes for the string hash key methods.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
+402
-333
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);
|
||||
|
||||
+46
-25
@@ -41,6 +41,8 @@ static void ReflectWatch(ClientData clientData, int mask);
|
||||
static int ReflectBlock(ClientData clientData, int mode);
|
||||
#ifdef TCL_THREADS
|
||||
static void ReflectThread(ClientData clientData, int action);
|
||||
static int ReflectEventRun(Tcl_Event *ev, int flags);
|
||||
static int ReflectEventDelete(Tcl_Event *ev, ClientData cd);
|
||||
#endif
|
||||
static Tcl_WideInt ReflectSeekWide(ClientData clientData,
|
||||
Tcl_WideInt offset, int mode, int *errorCodePtr);
|
||||
@@ -234,7 +236,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 +311,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 +348,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 +725,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 +750,8 @@ TclChanCreateObjCmd(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef struct ReflectEvent {
|
||||
#ifdef TCL_THREADS
|
||||
typedef struct {
|
||||
Tcl_Event header;
|
||||
ReflectedChannel *rcPtr;
|
||||
int events;
|
||||
@@ -791,6 +794,7 @@ ReflectEventDelete(
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
TclChanPostEventObjCmd(
|
||||
@@ -851,11 +855,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 +944,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 +1227,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 +1278,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 +1384,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 +1438,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 +2385,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 +2572,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 +2690,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 +2722,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 +2779,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 +2830,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 +2909,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+32
-25
@@ -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.
|
||||
*/
|
||||
@@ -1762,7 +1764,7 @@ Tcl_FSEvalFileEx(
|
||||
* this cross-platform to allow for scripted documents. [Bug: 2040]
|
||||
*/
|
||||
|
||||
Tcl_SetChannelOption(interp, chan, "-eofchar", "\32");
|
||||
Tcl_SetChannelOption(interp, chan, "-eofchar", "\32 {}");
|
||||
|
||||
/*
|
||||
* If the encoding is specified, set it for the channel. Else don't touch
|
||||
@@ -1897,7 +1899,7 @@ TclNREvalFile(
|
||||
* this cross-platform to allow for scripted documents. [Bug: 2040]
|
||||
*/
|
||||
|
||||
Tcl_SetChannelOption(interp, chan, "-eofchar", "\32");
|
||||
Tcl_SetChannelOption(interp, chan, "-eofchar", "\32 {}");
|
||||
|
||||
/*
|
||||
* If the encoding is specified, set it for the channel. Else don't touch
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
||||
+86
-85
@@ -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. */
|
||||
@@ -2435,8 +2445,8 @@ typedef struct List {
|
||||
#define TCL_EACH_COLLECT 1 /* Collect iteration result like [lmap] */
|
||||
|
||||
/*
|
||||
* Macros providing a faster path to integers: Tcl_GetLongFromObj everywhere,
|
||||
* Tcl_GetIntFromObj and TclGetIntForIndex on platforms where longs are ints.
|
||||
* Macros providing a faster path to integers: Tcl_GetLongFromObj,
|
||||
* Tcl_GetIntFromObj and TclGetIntForIndex.
|
||||
*
|
||||
* WARNING: these macros eval their args more than once.
|
||||
*/
|
||||
@@ -2457,9 +2467,17 @@ typedef struct List {
|
||||
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
|
||||
#else
|
||||
#define TclGetIntFromObj(interp, objPtr, intPtr) \
|
||||
Tcl_GetIntFromObj((interp), (objPtr), (intPtr))
|
||||
#define TclGetIntForIndexM(interp, objPtr, ignore, idxPtr) \
|
||||
TclGetIntForIndex(interp, objPtr, ignore, idxPtr)
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.longValue >= -(Tcl_WideInt)(UINT_MAX) \
|
||||
&& (objPtr)->internalRep.longValue <= (Tcl_WideInt)(UINT_MAX)) \
|
||||
? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
|
||||
: Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
|
||||
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.longValue >= INT_MIN \
|
||||
&& (objPtr)->internalRep.longValue <= INT_MAX) \
|
||||
? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
|
||||
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2620,7 +2638,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. */
|
||||
@@ -2961,7 +2979,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,
|
||||
@@ -2996,6 +3015,9 @@ MODULE_SCOPE int TclInfoLocalsCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclInfoVarsCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE void TclInitAlloc(void);
|
||||
MODULE_SCOPE void TclInitBignumFromLong(mp_int *, long);
|
||||
MODULE_SCOPE void TclInitBignumFromWideInt(mp_int *, Tcl_WideInt);
|
||||
MODULE_SCOPE void TclInitBignumFromWideUInt(mp_int *, Tcl_WideUInt);
|
||||
MODULE_SCOPE void TclInitDbCkalloc(void);
|
||||
MODULE_SCOPE void TclInitDoubleConversion(void);
|
||||
MODULE_SCOPE void TclInitEmbeddedConfigurationInformation(
|
||||
@@ -3114,7 +3136,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);
|
||||
@@ -3277,10 +3299,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[]);
|
||||
@@ -3518,6 +3538,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);
|
||||
@@ -3954,7 +3980,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.
|
||||
*/
|
||||
@@ -3968,20 +3994,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);
|
||||
@@ -4339,13 +4366,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)) { \
|
||||
@@ -4357,7 +4384,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; \
|
||||
} \
|
||||
@@ -4392,7 +4419,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
|
||||
#define TclUtfToUniChar(str, chPtr) \
|
||||
((((unsigned char) *(str)) < 0xC0) ? \
|
||||
((*(chPtr) = (Tcl_UniChar) *(str)), 1) \
|
||||
((*(chPtr) = (unsigned char) *(str)), 1) \
|
||||
: Tcl_UtfToUniChar(str, chPtr))
|
||||
|
||||
/*
|
||||
@@ -4409,14 +4436,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);
|
||||
|
||||
/*
|
||||
@@ -4516,9 +4543,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);
|
||||
*----------------------------------------------------------------
|
||||
@@ -4532,19 +4557,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 { \
|
||||
@@ -4570,7 +4582,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);
|
||||
@@ -4591,13 +4602,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(); \
|
||||
@@ -4623,9 +4627,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)
|
||||
|
||||
@@ -4767,11 +4768,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) \
|
||||
@@ -4783,19 +4784,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 */
|
||||
|
||||
@@ -4847,15 +4848,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) */
|
||||
|
||||
|
||||
@@ -3533,9 +3533,6 @@ Tcl_LimitAddHandler(
|
||||
if (deleteProc == (Tcl_LimitHandlerDeleteProc *) TCL_DYNAMIC) {
|
||||
deleteProc = (Tcl_LimitHandlerDeleteProc *) Tcl_Free;
|
||||
}
|
||||
if (deleteProc == (Tcl_LimitHandlerDeleteProc *) TCL_STATIC) {
|
||||
deleteProc = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a handler record.
|
||||
|
||||
+18
-2
@@ -36,8 +36,10 @@ typedef struct Link {
|
||||
unsigned int ui;
|
||||
short s;
|
||||
unsigned short us;
|
||||
#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__)
|
||||
long l;
|
||||
unsigned long ul;
|
||||
#endif
|
||||
Tcl_WideInt w;
|
||||
Tcl_WideUInt uw;
|
||||
float f;
|
||||
@@ -129,6 +131,14 @@ Tcl_LinkVar(
|
||||
Tcl_IncrRefCount(linkPtr->varName);
|
||||
linkPtr->addr = addr;
|
||||
linkPtr->type = type & ~TCL_LINK_READ_ONLY;
|
||||
#if !defined(TCL_NO_DEPRECATED) && (defined(TCL_WIDE_INT_IS_LONG) \
|
||||
|| defined(_WIN32) || defined(__CYGWIN__))
|
||||
if (linkPtr->type == 11 /* legacy TCL_LINK_LONG */) {
|
||||
linkPtr->type = TCL_LINK_LONG;
|
||||
} else if (linkPtr->type == 12 /* legacy TCL_LINK_ULONG */) {
|
||||
linkPtr->type = TCL_LINK_ULONG;
|
||||
}
|
||||
#endif
|
||||
if (type & TCL_LINK_READ_ONLY) {
|
||||
linkPtr->flags = LINK_READ_ONLY;
|
||||
} else {
|
||||
@@ -335,12 +345,14 @@ LinkTraceProc(
|
||||
case TCL_LINK_UINT:
|
||||
changed = (LinkedVar(unsigned int) != linkPtr->lastValue.ui);
|
||||
break;
|
||||
#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__)
|
||||
case TCL_LINK_LONG:
|
||||
changed = (LinkedVar(long) != linkPtr->lastValue.l);
|
||||
break;
|
||||
case TCL_LINK_ULONG:
|
||||
changed = (LinkedVar(unsigned long) != linkPtr->lastValue.ul);
|
||||
break;
|
||||
#endif
|
||||
case TCL_LINK_FLOAT:
|
||||
changed = (LinkedVar(float) != linkPtr->lastValue.f);
|
||||
break;
|
||||
@@ -483,6 +495,7 @@ LinkTraceProc(
|
||||
LinkedVar(unsigned int) = linkPtr->lastValue.ui = (unsigned int)valueWide;
|
||||
break;
|
||||
|
||||
#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__)
|
||||
case TCL_LINK_LONG:
|
||||
if ((Tcl_GetWideIntFromObj(NULL, valueObj, &valueWide) != TCL_OK
|
||||
&& GetInvalidWideFromObj(valueObj, &valueWide) != TCL_OK)
|
||||
@@ -504,6 +517,7 @@ LinkTraceProc(
|
||||
}
|
||||
LinkedVar(unsigned long) = linkPtr->lastValue.ul = (unsigned long)valueWide;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case TCL_LINK_WIDE_UINT:
|
||||
/*
|
||||
@@ -597,12 +611,14 @@ ObjValue(
|
||||
case TCL_LINK_UINT:
|
||||
linkPtr->lastValue.ui = LinkedVar(unsigned int);
|
||||
return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.ui);
|
||||
#if !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__CYGWIN__)
|
||||
case TCL_LINK_LONG:
|
||||
linkPtr->lastValue.l = LinkedVar(long);
|
||||
return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.l);
|
||||
case TCL_LINK_ULONG:
|
||||
linkPtr->lastValue.ul = LinkedVar(unsigned long);
|
||||
return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.ul);
|
||||
#endif
|
||||
case TCL_LINK_FLOAT:
|
||||
linkPtr->lastValue.f = LinkedVar(float);
|
||||
return Tcl_NewDoubleObj(linkPtr->lastValue.f);
|
||||
@@ -676,7 +692,7 @@ SetInvalidRealFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr) {
|
||||
/*
|
||||
* This function checks for integer representations, which are valid
|
||||
* when linking with C variables, but which are invalid in other
|
||||
* contexts in Tcl. Handled are "+", "-", "", "0x", "0b" and "0o"
|
||||
* contexts in Tcl. Handled are "+", "-", "", "0x", "0b", "0d" and "0o"
|
||||
* (upperand lowercase). See bug [39f6304c2e].
|
||||
*/
|
||||
int
|
||||
@@ -685,7 +701,7 @@ GetInvalidIntFromObj(Tcl_Obj *objPtr, int *intPtr)
|
||||
const char *str = TclGetString(objPtr);
|
||||
|
||||
if ((objPtr->length == 0) ||
|
||||
((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoO", str[1]))) {
|
||||
((objPtr->length == 2) && (str[0] == '0') && strchr("xXbBoOdD", str[1]))) {
|
||||
*intPtr = 0;
|
||||
return TCL_OK;
|
||||
} else if ((objPtr->length == 1) && strchr("+-", str[0])) {
|
||||
|
||||
+2
-2
@@ -130,7 +130,7 @@ Tcl_LoadObjCmd(
|
||||
Tcl_PackageInitProc *initProc;
|
||||
const char *p, *fullFileName, *packageName;
|
||||
Tcl_LoadHandle loadHandle;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
unsigned len;
|
||||
int index, flags = 0;
|
||||
Tcl_Obj *const *savedobjv = objv;
|
||||
@@ -336,7 +336,7 @@ Tcl_LoadObjCmd(
|
||||
}
|
||||
#endif /* __CYGWIN__ */
|
||||
for (p = pkgGuess; *p != 0; p += offset) {
|
||||
offset = Tcl_UtfToUniChar(p, &ch);
|
||||
offset = TclUtfToUniChar(p, &ch);
|
||||
if ((ch > 0x100)
|
||||
|| !(isalpha(UCHAR(ch)) /* INTL: ISO only */
|
||||
|| (UCHAR(ch) == '_'))) {
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
* limited to a single interpreter.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
size_t numNsCreated; /* Count of the number of namespaces created
|
||||
* within the thread. This value is used as a
|
||||
* unique id for each namespace. Cannot be
|
||||
|
||||
+39
-10
@@ -41,6 +41,7 @@ static const struct {
|
||||
{"forward", TclOODefineForwardObjCmd, 1},
|
||||
{"method", TclOODefineMethodObjCmd, 1},
|
||||
{"renamemethod", TclOODefineRenameMethodObjCmd, 1},
|
||||
{"self", TclOODefineObjSelfObjCmd, 0},
|
||||
{"unexport", TclOODefineUnexportObjCmd, 1},
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
@@ -879,7 +880,7 @@ ObjectRenamedTrace(
|
||||
* 2950259]
|
||||
*/
|
||||
|
||||
if (((Namespace *) oPtr->namespacePtr)->earlyDeleteProc != NULL) {
|
||||
if (oPtr->namespacePtr && ((Namespace *) oPtr->namespacePtr)->earlyDeleteProc != NULL) {
|
||||
Tcl_DeleteNamespace(oPtr->namespacePtr);
|
||||
}
|
||||
if (oPtr->classPtr) {
|
||||
@@ -1005,8 +1006,18 @@ ReleaseClassContents(
|
||||
}
|
||||
for(j=0 ; j<instancePtr->mixins.num ; j++) {
|
||||
Class *mixin = instancePtr->mixins.list[j];
|
||||
Class *nextMixin = NULL;
|
||||
if (mixin == clsPtr) {
|
||||
instancePtr->mixins.list[j] = NULL;
|
||||
if (j < instancePtr->mixins.num - 1) {
|
||||
nextMixin = instancePtr->mixins.list[j+1];
|
||||
}
|
||||
if (j == 0) {
|
||||
instancePtr->mixins.num = 0;
|
||||
instancePtr->mixins.list = NULL;
|
||||
} else {
|
||||
instancePtr->mixins.list[j-1] = nextMixin;
|
||||
}
|
||||
instancePtr->mixins.num -= 1;
|
||||
}
|
||||
}
|
||||
if (instancePtr != NULL && !IsRoot(instancePtr)) {
|
||||
@@ -1167,7 +1178,7 @@ ObjectNamespaceDeleted(
|
||||
Class *clsPtr = oPtr->classPtr, *mixinPtr;
|
||||
Method *mPtr;
|
||||
Tcl_Obj *filterObj, *variableObj;
|
||||
int i;
|
||||
int deleteAlreadyInProgress = 0, i;
|
||||
|
||||
/*
|
||||
* Instruct everyone to no longer use any allocated fields of the object.
|
||||
@@ -1177,6 +1188,15 @@ ObjectNamespaceDeleted(
|
||||
*/
|
||||
|
||||
if (oPtr->command) {
|
||||
if ((((Command *)oPtr->command)->flags && CMD_IS_DELETED)) {
|
||||
/*
|
||||
* Namespace deletion must have been triggered by a trace on command
|
||||
* deletion , meaning that ObjectRenamedTrace() is eventually going
|
||||
* to be called .
|
||||
*/
|
||||
deleteAlreadyInProgress = 1;
|
||||
}
|
||||
|
||||
Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
|
||||
}
|
||||
if (oPtr->myCommand) {
|
||||
@@ -1272,14 +1292,17 @@ ObjectNamespaceDeleted(
|
||||
|
||||
if (clsPtr->subclasses.list) {
|
||||
ckfree(clsPtr->subclasses.list);
|
||||
clsPtr->subclasses.list = NULL;
|
||||
clsPtr->subclasses.num = 0;
|
||||
}
|
||||
if (clsPtr->instances.list) {
|
||||
ckfree(clsPtr->instances.list);
|
||||
clsPtr->instances.list = NULL;
|
||||
clsPtr->instances.num = 0;
|
||||
}
|
||||
if (clsPtr->mixinSubs.list) {
|
||||
ckfree(clsPtr->mixinSubs.list);
|
||||
clsPtr->mixinSubs.list = NULL;
|
||||
clsPtr->mixinSubs.num = 0;
|
||||
}
|
||||
|
||||
@@ -1304,7 +1327,13 @@ ObjectNamespaceDeleted(
|
||||
* Delete the object structure itself.
|
||||
*/
|
||||
|
||||
DelRef(oPtr);
|
||||
if (deleteAlreadyInProgress) {
|
||||
oPtr->classPtr = NULL;
|
||||
oPtr->namespacePtr = NULL;
|
||||
} else {
|
||||
DelRef(oPtr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2432,7 +2461,7 @@ Tcl_ObjectSetMetadata(
|
||||
*
|
||||
* PublicObjectCmd, PrivateObjectCmd, TclOOInvokeObject --
|
||||
*
|
||||
* Main entry point for object invokations. The Public* and Private*
|
||||
* Main entry point for object invocations. The Public* and Private*
|
||||
* wrapper functions (implementations of both object instance commands
|
||||
* and [my]) are just thin wrappers round the main TclOOObjectCmdCore
|
||||
* function. Note that the core is function is NRE-aware.
|
||||
@@ -2517,8 +2546,8 @@ TclOOInvokeObject(
|
||||
*
|
||||
* TclOOObjectCmdCore, FinalizeObjectCall --
|
||||
*
|
||||
* Main function for object invokations. Does call chain creation,
|
||||
* management and invokation. The function FinalizeObjectCall exists to
|
||||
* Main function for object invocations. Does call chain creation,
|
||||
* management and invocation. The function FinalizeObjectCall exists to
|
||||
* clean up after the non-recursive processing of TclOOObjectCmdCore.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -2530,7 +2559,7 @@ TclOOObjectCmdCore(
|
||||
Tcl_Interp *interp, /* The interpreter containing the object. */
|
||||
int objc, /* How many arguments are being passed in. */
|
||||
Tcl_Obj *const *objv, /* The array of arguments. */
|
||||
int flags, /* Whether this is an invokation through the
|
||||
int flags, /* Whether this is an invocation through the
|
||||
* public or the private command interface. */
|
||||
Class *startCls) /* Where to start in the call chain, or NULL
|
||||
* if we are to start at the front with
|
||||
@@ -2719,7 +2748,7 @@ Tcl_ObjectContextInvokeNext(
|
||||
* call context while we process the body. However, need to adjust the
|
||||
* argument-skip control because we're guaranteed to have a single prefix
|
||||
* arg (i.e., 'next') and not the variable amount that can happen because
|
||||
* method invokations (i.e., '$obj meth' and 'my meth'), constructors
|
||||
* method invocations (i.e., '$obj meth' and 'my meth'), constructors
|
||||
* (i.e., '$cls new' and '$cls create obj') and destructors (no args at
|
||||
* all) come through the same code.
|
||||
*/
|
||||
@@ -2788,7 +2817,7 @@ TclNRObjectContextInvokeNext(
|
||||
* call context while we process the body. However, need to adjust the
|
||||
* argument-skip control because we're guaranteed to have a single prefix
|
||||
* arg (i.e., 'next') and not the variable amount that can happen because
|
||||
* method invokations (i.e., '$obj meth' and 'my meth'), constructors
|
||||
* method invocations (i.e., '$obj meth' and 'my meth'), constructors
|
||||
* (i.e., '$cls new' and '$cls create obj') and destructors (no args at
|
||||
* all) come through the same code.
|
||||
*/
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
* win/tclooConfig.sh
|
||||
*/
|
||||
|
||||
#define TCLOO_VERSION "1.0.4"
|
||||
#define TCLOO_VERSION "1.2.0"
|
||||
#define TCLOO_PATCHLEVEL TCLOO_VERSION
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
+27
-5
@@ -1183,8 +1183,9 @@ TclOOCopyObjectCmd(
|
||||
{
|
||||
Tcl_Object oPtr, o2Ptr;
|
||||
|
||||
if (objc < 2 || objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "sourceName ?targetName?");
|
||||
if (objc < 2 || objc > 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"sourceName ?targetName? ?targetNamespace?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1204,12 +1205,14 @@ TclOOCopyObjectCmd(
|
||||
if (objc == 2) {
|
||||
o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, NULL, NULL);
|
||||
} else {
|
||||
const char *name;
|
||||
const char *name, *namespaceName;
|
||||
Tcl_DString buffer;
|
||||
|
||||
name = TclGetString(objv[2]);
|
||||
Tcl_DStringInit(&buffer);
|
||||
if (name[0]!=':' || name[1]!=':') {
|
||||
if (name[0] == '\0') {
|
||||
name = NULL;
|
||||
} else if (name[0]!=':' || name[1]!=':') {
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
|
||||
if (iPtr->varFramePtr != NULL) {
|
||||
@@ -1220,7 +1223,26 @@ TclOOCopyObjectCmd(
|
||||
Tcl_DStringAppend(&buffer, name, -1);
|
||||
name = Tcl_DStringValue(&buffer);
|
||||
}
|
||||
o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, name, NULL);
|
||||
|
||||
/*
|
||||
* Choose a unique namespace name if the user didn't supply one.
|
||||
*/
|
||||
|
||||
namespaceName = NULL;
|
||||
if (objc == 4) {
|
||||
namespaceName = TclGetString(objv[3]);
|
||||
|
||||
if (namespaceName[0] == '\0') {
|
||||
namespaceName = NULL;
|
||||
} else if (Tcl_FindNamespace(interp, namespaceName, NULL,
|
||||
0) != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%s refers to an existing namespace", namespaceName));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, name, namespaceName);
|
||||
Tcl_DStringFree(&buffer);
|
||||
}
|
||||
|
||||
|
||||
+61
-23
@@ -53,7 +53,8 @@ static void AddClassFiltersToCallContext(Object *const oPtr,
|
||||
Class *clsPtr, struct ChainBuilder *const cbPtr,
|
||||
Tcl_HashTable *const doneFilters, int flags);
|
||||
static void AddClassMethodNames(Class *clsPtr, const int flags,
|
||||
Tcl_HashTable *const namesPtr);
|
||||
Tcl_HashTable *const namesPtr,
|
||||
Tcl_HashTable *const examinedClassesPtr);
|
||||
static inline void AddMethodToCallChain(Method *const mPtr,
|
||||
struct ChainBuilder *const cbPtr,
|
||||
Tcl_HashTable *const doneFilters,
|
||||
@@ -232,7 +233,7 @@ FreeMethodNameRep(
|
||||
* TclOOInvokeContext --
|
||||
*
|
||||
* Invokes a single step along a method call-chain context. Note that the
|
||||
* invokation of a step along the chain can cause further steps along the
|
||||
* invocation of a step along the chain can cause further steps along the
|
||||
* chain to be invoked. Note that this function is written to be as light
|
||||
* in stack usage as possible.
|
||||
*
|
||||
@@ -367,6 +368,10 @@ TclOOGetSortedMethodList(
|
||||
{
|
||||
Tcl_HashTable names; /* Tcl_Obj* method name to "wanted in list"
|
||||
* mapping. */
|
||||
Tcl_HashTable examinedClasses;
|
||||
/* Used to track what classes have been looked
|
||||
* at. Is set-like in nature and keyed by
|
||||
* pointer to class. */
|
||||
FOREACH_HASH_DECLS;
|
||||
int i;
|
||||
Class *mixinPtr;
|
||||
@@ -376,6 +381,7 @@ TclOOGetSortedMethodList(
|
||||
void *isWanted;
|
||||
|
||||
Tcl_InitObjHashTable(&names);
|
||||
Tcl_InitHashTable(&examinedClasses, TCL_ONE_WORD_KEYS);
|
||||
|
||||
/*
|
||||
* Name the bits used in the names table values.
|
||||
@@ -436,11 +442,14 @@ TclOOGetSortedMethodList(
|
||||
* hierarchy.
|
||||
*/
|
||||
|
||||
AddClassMethodNames(oPtr->selfCls, flags, &names);
|
||||
AddClassMethodNames(oPtr->selfCls, flags, &names, &examinedClasses);
|
||||
FOREACH(mixinPtr, oPtr->mixins) {
|
||||
AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, &names);
|
||||
AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, &names,
|
||||
&examinedClasses);
|
||||
}
|
||||
|
||||
Tcl_DeleteHashTable(&examinedClasses);
|
||||
|
||||
/*
|
||||
* See how many (visible) method names there are. If none, we do not (and
|
||||
* should not) try to sort the list of them.
|
||||
@@ -495,18 +504,24 @@ TclOOGetSortedClassMethodList(
|
||||
{
|
||||
Tcl_HashTable names; /* Tcl_Obj* method name to "wanted in list"
|
||||
* mapping. */
|
||||
Tcl_HashTable examinedClasses;
|
||||
/* Used to track what classes have been looked
|
||||
* at. Is set-like in nature and keyed by
|
||||
* pointer to class. */
|
||||
FOREACH_HASH_DECLS;
|
||||
int i;
|
||||
Tcl_Obj *namePtr;
|
||||
void *isWanted;
|
||||
|
||||
Tcl_InitObjHashTable(&names);
|
||||
Tcl_InitHashTable(&examinedClasses, TCL_ONE_WORD_KEYS);
|
||||
|
||||
/*
|
||||
* Process method names from the class hierarchy and the mixin hierarchy.
|
||||
*/
|
||||
|
||||
AddClassMethodNames(clsPtr, flags, &names);
|
||||
AddClassMethodNames(clsPtr, flags, &names, &examinedClasses);
|
||||
Tcl_DeleteHashTable(&examinedClasses);
|
||||
|
||||
/*
|
||||
* See how many (visible) method names there are. If none, we do not (and
|
||||
@@ -581,14 +596,28 @@ AddClassMethodNames(
|
||||
Class *clsPtr, /* Class to get method names from. */
|
||||
const int flags, /* Whether we are interested in just the
|
||||
* public method names. */
|
||||
Tcl_HashTable *const namesPtr)
|
||||
Tcl_HashTable *const namesPtr,
|
||||
/* Reference to the hash table to put the
|
||||
* information in. The hash table maps the
|
||||
* Tcl_Obj * method name to an integral value
|
||||
* describing whether the method is wanted.
|
||||
* This ensures that public/private override
|
||||
* semantics are handled correctly.*/
|
||||
* semantics are handled correctly. */
|
||||
Tcl_HashTable *const examinedClassesPtr)
|
||||
/* Hash table that tracks what classes have
|
||||
* already been looked at. The keys are the
|
||||
* pointers to the classes, and the values are
|
||||
* immaterial. */
|
||||
{
|
||||
/*
|
||||
* If we've already started looking at this class, stop working on it now
|
||||
* to prevent repeated work.
|
||||
*/
|
||||
|
||||
if (Tcl_FindHashEntry(examinedClassesPtr, (char *) clsPtr)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scope all declarations so that the compiler can stand a good chance of
|
||||
* making the recursive step highly efficient. We also hand-implement the
|
||||
@@ -596,29 +625,37 @@ AddClassMethodNames(
|
||||
* tail-recursion optimization usefully.
|
||||
*/
|
||||
|
||||
if (clsPtr->mixins.num != 0) {
|
||||
Class *mixinPtr;
|
||||
int i;
|
||||
|
||||
/* TODO: Beware of infinite loops! */
|
||||
FOREACH(mixinPtr, clsPtr->mixins) {
|
||||
AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, namesPtr);
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
FOREACH_HASH_DECLS;
|
||||
Tcl_Obj *namePtr;
|
||||
Method *mPtr;
|
||||
int isNew;
|
||||
|
||||
(void) Tcl_CreateHashEntry(examinedClassesPtr, (char *) clsPtr,
|
||||
&isNew);
|
||||
if (!isNew) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (clsPtr->mixins.num != 0) {
|
||||
Class *mixinPtr;
|
||||
int i;
|
||||
|
||||
FOREACH(mixinPtr, clsPtr->mixins) {
|
||||
if (mixinPtr != clsPtr) {
|
||||
AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN,
|
||||
namesPtr, examinedClassesPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FOREACH_HASH(namePtr, mPtr, &clsPtr->classMethods) {
|
||||
int isNew;
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(namesPtr, (char *) namePtr, &isNew);
|
||||
if (isNew) {
|
||||
int isWanted = (!(flags & PUBLIC_METHOD)
|
||||
|| (mPtr->flags & PUBLIC_METHOD)) ? IN_LIST : 0;
|
||||
|
||||
isWanted |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0);
|
||||
Tcl_SetHashValue(hPtr, INT2PTR(isWanted));
|
||||
} else if ((PTR2INT(Tcl_GetHashValue(hPtr)) & NO_IMPLEMENTATION)
|
||||
&& mPtr->typePtr != NULL) {
|
||||
@@ -639,7 +676,8 @@ AddClassMethodNames(
|
||||
int i;
|
||||
|
||||
FOREACH(superPtr, clsPtr->superclasses) {
|
||||
AddClassMethodNames(superPtr, flags, namesPtr);
|
||||
AddClassMethodNames(superPtr, flags, namesPtr,
|
||||
examinedClassesPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -792,7 +830,7 @@ AddMethodToCallChain(
|
||||
* Call chain semantics states that methods come as *late* in the
|
||||
* call chain as possible. This is done by copying down the
|
||||
* following methods. Note that this does not change the number of
|
||||
* method invokations in the call chain; it just rearranges them.
|
||||
* method invocations in the call chain; it just rearranges them.
|
||||
*/
|
||||
|
||||
Class *declCls = callPtr->chain[i].filterDeclarer;
|
||||
@@ -897,7 +935,7 @@ IsStillValid(
|
||||
* TclOOGetCallContext --
|
||||
*
|
||||
* Responsible for constructing the call context, an ordered list of all
|
||||
* method implementations to be called as part of a method invokation.
|
||||
* method implementations to be called as part of a method invocation.
|
||||
* This method is central to the whole operation of the OO system.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -1479,7 +1517,7 @@ TclOORenderCallChain(
|
||||
/*
|
||||
* Do the actual construction of the descriptions. They consist of a list
|
||||
* of triples that describe the details of how a method is understood. For
|
||||
* each triple, the first word is the type of invokation ("method" is
|
||||
* each triple, the first word is the type of invocation ("method" is
|
||||
* normal, "unknown" is special because it adds the method name as an
|
||||
* extra argument when handled by some method types, and "filter" is
|
||||
* special because it's a filter method). The second word is the name of
|
||||
|
||||
+112
-131
@@ -47,8 +47,11 @@ struct DeclaredSlot {
|
||||
static inline void BumpGlobalEpoch(Tcl_Interp *interp, Class *classPtr);
|
||||
static Tcl_Command FindCommand(Tcl_Interp *interp, Tcl_Obj *stringObj,
|
||||
Tcl_Namespace *const namespacePtr);
|
||||
static void GenerateErrorInfo(Tcl_Interp *interp, Object *oPtr,
|
||||
static inline void GenerateErrorInfo(Tcl_Interp *interp, Object *oPtr,
|
||||
Tcl_Obj *savedNameObj, const char *typeOfSubject);
|
||||
static inline int MagicDefinitionInvoke(Tcl_Interp *interp,
|
||||
Tcl_Namespace *nsPtr, int cmdIndex,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static inline Class * GetClassInOuterContext(Tcl_Interp *interp,
|
||||
Tcl_Obj *className, const char *errMsg);
|
||||
static inline int InitDefineContext(Tcl_Interp *interp,
|
||||
@@ -755,7 +758,7 @@ GetClassInOuterContext(
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
static inline void
|
||||
GenerateErrorInfo(
|
||||
Tcl_Interp *interp, /* Where to store the error info trace. */
|
||||
Object *oPtr, /* What object (or class) was being configured
|
||||
@@ -784,6 +787,69 @@ GenerateErrorInfo(
|
||||
(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* MagicDefinitionInvoke --
|
||||
* Part of the implementation of the "oo::define" and "oo::objdefine"
|
||||
* commands that is used to implement the more-than-one-argument case,
|
||||
* applying ensemble-like tricks with dispatch so that error messages are
|
||||
* clearer. Doesn't handle the management of the stack frame.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline int
|
||||
MagicDefinitionInvoke(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Namespace *nsPtr,
|
||||
int cmdIndex,
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Tcl_Obj *objPtr, *obj2Ptr, **objs;
|
||||
Tcl_Command cmd;
|
||||
int isRoot, dummy, result, offset = cmdIndex + 1;
|
||||
|
||||
/*
|
||||
* More than one argument: fire them through the ensemble processing
|
||||
* engine so that everything appears to be good and proper in error
|
||||
* messages. Note that we cannot just concatenate and send through
|
||||
* Tcl_EvalObjEx, as that doesn't do ensemble processing, and we cannot go
|
||||
* through Tcl_EvalObjv without the extra work to pre-find the command, as
|
||||
* that finds command names in the wrong namespace at the moment. Ugly!
|
||||
*/
|
||||
|
||||
isRoot = TclInitRewriteEnsemble(interp, offset, 1, objv);
|
||||
|
||||
/*
|
||||
* Build the list of arguments using a Tcl_Obj as a workspace. See
|
||||
* comments above for why these contortions are necessary.
|
||||
*/
|
||||
|
||||
objPtr = Tcl_NewObj();
|
||||
obj2Ptr = Tcl_NewObj();
|
||||
cmd = FindCommand(interp, objv[cmdIndex], nsPtr);
|
||||
if (cmd == NULL) {
|
||||
/* punt this case! */
|
||||
Tcl_AppendObjToObj(obj2Ptr, objv[cmdIndex]);
|
||||
} else {
|
||||
Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
|
||||
/* TODO: overflow? */
|
||||
Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-offset, objv+offset);
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
|
||||
|
||||
result = Tcl_EvalObjv(interp, objc-cmdIndex, objs, TCL_EVAL_INVOKE);
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
@@ -805,8 +871,8 @@ TclOODefineObjCmd(
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
int result;
|
||||
Object *oPtr;
|
||||
int result;
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "className arg ?arg ...?");
|
||||
@@ -846,46 +912,7 @@ TclOODefineObjCmd(
|
||||
}
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
Tcl_Obj *objPtr, *obj2Ptr, **objs;
|
||||
Tcl_Command cmd;
|
||||
int isRoot, dummy;
|
||||
|
||||
/*
|
||||
* More than one argument: fire them through the ensemble processing
|
||||
* engine so that everything appears to be good and proper in error
|
||||
* messages. Note that we cannot just concatenate and send through
|
||||
* Tcl_EvalObjEx, as that doesn't do ensemble processing, and we
|
||||
* cannot go through Tcl_EvalObjv without the extra work to pre-find
|
||||
* the command, as that finds command names in the wrong namespace at
|
||||
* the moment. Ugly!
|
||||
*/
|
||||
|
||||
isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
|
||||
|
||||
/*
|
||||
* Build the list of arguments using a Tcl_Obj as a workspace. See
|
||||
* comments above for why these contortions are necessary.
|
||||
*/
|
||||
|
||||
objPtr = Tcl_NewObj();
|
||||
obj2Ptr = Tcl_NewObj();
|
||||
cmd = FindCommand(interp, objv[2], fPtr->defineNs);
|
||||
if (cmd == NULL) {
|
||||
/* punt this case! */
|
||||
Tcl_AppendObjToObj(obj2Ptr, objv[2]);
|
||||
} else {
|
||||
Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
|
||||
/* TODO: overflow? */
|
||||
Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-3, objv+3);
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
|
||||
|
||||
result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
result = MagicDefinitionInvoke(interp, fPtr->defineNs, 2, objc, objv);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
|
||||
@@ -918,8 +945,8 @@ TclOOObjDefObjCmd(
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
int isRoot, result;
|
||||
Object *oPtr;
|
||||
int result;
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "objectName arg ?arg ...?");
|
||||
@@ -952,47 +979,7 @@ TclOOObjDefObjCmd(
|
||||
}
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
Tcl_Obj *objPtr, *obj2Ptr, **objs;
|
||||
Tcl_Command cmd;
|
||||
int dummy;
|
||||
|
||||
/*
|
||||
* More than one argument: fire them through the ensemble processing
|
||||
* engine so that everything appears to be good and proper in error
|
||||
* messages. Note that we cannot just concatenate and send through
|
||||
* Tcl_EvalObjEx, as that doesn't do ensemble processing, and we
|
||||
* cannot go through Tcl_EvalObjv without the extra work to pre-find
|
||||
* the command, as that finds command names in the wrong namespace at
|
||||
* the moment. Ugly!
|
||||
*/
|
||||
|
||||
isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
|
||||
|
||||
/*
|
||||
* Build the list of arguments using a Tcl_Obj as a workspace. See
|
||||
* comments above for why these contortions are necessary.
|
||||
*/
|
||||
|
||||
objPtr = Tcl_NewObj();
|
||||
obj2Ptr = Tcl_NewObj();
|
||||
cmd = FindCommand(interp, objv[2], fPtr->objdefNs);
|
||||
if (cmd == NULL) {
|
||||
/* punt this case! */
|
||||
Tcl_AppendObjToObj(obj2Ptr, objv[2]);
|
||||
} else {
|
||||
Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
|
||||
/* TODO: overflow? */
|
||||
Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-3, objv+3);
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
|
||||
|
||||
result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
|
||||
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 2, objc, objv);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
|
||||
@@ -1025,19 +1012,19 @@ TclOODefineSelfObjCmd(
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
int result;
|
||||
Object *oPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
int result;
|
||||
|
||||
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_SetObjResult(interp, TclOOObjectName(interp, oPtr));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the oo::objdefine namespace the current namespace and evaluate the
|
||||
* command(s).
|
||||
@@ -1059,46 +1046,7 @@ TclOODefineSelfObjCmd(
|
||||
}
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
Tcl_Obj *objPtr, *obj2Ptr, **objs;
|
||||
Tcl_Command cmd;
|
||||
int isRoot, dummy;
|
||||
|
||||
/*
|
||||
* More than one argument: fire them through the ensemble processing
|
||||
* engine so that everything appears to be good and proper in error
|
||||
* messages. Note that we cannot just concatenate and send through
|
||||
* Tcl_EvalObjEx, as that doesn't do ensemble processing, and we
|
||||
* cannot go through Tcl_EvalObjv without the extra work to pre-find
|
||||
* the command, as that finds command names in the wrong namespace at
|
||||
* the moment. Ugly!
|
||||
*/
|
||||
|
||||
isRoot = TclInitRewriteEnsemble(interp, 2, 1, objv);
|
||||
|
||||
/*
|
||||
* Build the list of arguments using a Tcl_Obj as a workspace. See
|
||||
* comments above for why these contortions are necessary.
|
||||
*/
|
||||
|
||||
objPtr = Tcl_NewObj();
|
||||
obj2Ptr = Tcl_NewObj();
|
||||
cmd = FindCommand(interp, objv[1], fPtr->objdefNs);
|
||||
if (cmd == NULL) {
|
||||
/* punt this case! */
|
||||
Tcl_AppendObjToObj(obj2Ptr, objv[1]);
|
||||
} else {
|
||||
Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
|
||||
/* TODO: overflow? */
|
||||
Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-2, objv+2);
|
||||
Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
|
||||
|
||||
result = Tcl_EvalObjv(interp, objc-1, objs, TCL_EVAL_INVOKE);
|
||||
if (isRoot) {
|
||||
TclResetRewriteEnsemble(interp, 1);
|
||||
}
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 1, objc, objv);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
|
||||
@@ -1110,6 +1058,39 @@ TclOODefineSelfObjCmd(
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineObjSelfObjCmd --
|
||||
* Implementation of the "self" subcommand of the "oo::objdefine"
|
||||
* command.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclOODefineObjSelfObjCmd(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Object *oPtr;
|
||||
|
||||
if (objc != 1) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, TclOOObjectName(interp, oPtr));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+11
-8
@@ -149,8 +149,8 @@ typedef struct Object {
|
||||
struct Foundation *fPtr; /* The basis for the object system. Putting
|
||||
* this here allows the avoidance of quite a
|
||||
* lot of hash lookups on the critical path
|
||||
* for object invokation and creation. */
|
||||
Tcl_Namespace *namespacePtr;/* This object's tame namespace. */
|
||||
* for object invocation and creation. */
|
||||
Tcl_Namespace *namespacePtr;/* This object's namespace. */
|
||||
Tcl_Command command; /* Reference to this object's public
|
||||
* command. */
|
||||
Tcl_Command myCommand; /* Reference to this object's internal
|
||||
@@ -162,12 +162,12 @@ typedef struct Object {
|
||||
/* Classes mixed into this object. */
|
||||
LIST_STATIC(Tcl_Obj *) filters;
|
||||
/* List of filter names. */
|
||||
struct Class *classPtr; /* All classes have this non-NULL; it points
|
||||
* to the class structure. Everything else has
|
||||
* this NULL. */
|
||||
struct Class *classPtr; /* This is non-NULL for all classes, and NULL
|
||||
* for everything else. It points to the class
|
||||
* structure. */
|
||||
int refCount; /* Number of strong references to this object.
|
||||
* Note that there may be many more weak
|
||||
* references; this mechanism is there to
|
||||
* references; this mechanism exists to
|
||||
* avoid Tcl_Preserve. */
|
||||
int flags;
|
||||
int creationEpoch; /* Unique value to make comparisons of objects
|
||||
@@ -323,7 +323,7 @@ typedef struct Foundation {
|
||||
} Foundation;
|
||||
|
||||
/*
|
||||
* A call context structure is built when a method is called. They contain the
|
||||
* A call context structure is built when a method is called. It contains the
|
||||
* chain of method implementations that are to be invoked by a particular
|
||||
* call, and the process of calling walks the chain, with the [next] command
|
||||
* proceeding to the next entry in the chain.
|
||||
@@ -334,7 +334,7 @@ typedef struct Foundation {
|
||||
struct MInvoke {
|
||||
Method *mPtr; /* Reference to the method implementation
|
||||
* record. */
|
||||
int isFilter; /* Whether this is a filter invokation. */
|
||||
int isFilter; /* Whether this is a filter invocation. */
|
||||
Class *filterDeclarer; /* What class decided to add the filter; if
|
||||
* NULL, it was added by the object. */
|
||||
};
|
||||
@@ -431,6 +431,9 @@ MODULE_SCOPE int TclOODefineClassObjCmd(ClientData clientData,
|
||||
MODULE_SCOPE int TclOODefineSelfObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const *objv);
|
||||
MODULE_SCOPE int TclOODefineObjSelfObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const *objv);
|
||||
MODULE_SCOPE int TclOOUnknownDefinition(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const *objv);
|
||||
|
||||
@@ -1314,6 +1314,7 @@ CloneProcedureMethod(
|
||||
*/
|
||||
|
||||
bodyObj = Tcl_DuplicateObj(pmPtr->procPtr->bodyPtr);
|
||||
Tcl_GetString(bodyObj);
|
||||
TclFreeIntRep(bodyObj);
|
||||
|
||||
/*
|
||||
|
||||
+25
-22
@@ -75,7 +75,7 @@ typedef struct ObjData {
|
||||
* The structure defined below is used in this file only.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
Tcl_HashTable *lineCLPtr; /* This table remembers for each Tcl_Obj
|
||||
* generated by a call to the function
|
||||
* TclSubstTokens() from a literal text
|
||||
@@ -344,17 +344,17 @@ typedef struct ResolvedCmdName {
|
||||
* reference (not the namespace that contains
|
||||
* the referenced command). NULL if the name
|
||||
* is fully qualified.*/
|
||||
long refNsId; /* refNsPtr's unique namespace id. Used to
|
||||
size_t refNsId; /* refNsPtr's unique namespace id. Used to
|
||||
* verify that refNsPtr is still valid (e.g.,
|
||||
* it's possible that the cmd's containing
|
||||
* namespace was deleted and a new one created
|
||||
* at the same address). */
|
||||
int refNsCmdEpoch; /* Value of the referencing namespace's
|
||||
size_t refNsCmdEpoch; /* Value of the referencing namespace's
|
||||
* cmdRefEpoch when the pointer was cached.
|
||||
* Before using the cached pointer, we check
|
||||
* if the namespace's epoch was incremented;
|
||||
* if so, this cached pointer is invalid. */
|
||||
int cmdEpoch; /* Value of the command's cmdEpoch when this
|
||||
size_t cmdEpoch; /* Value of the command's cmdEpoch when this
|
||||
* pointer was cached. Before using the cached
|
||||
* pointer, we check if the cmd's epoch was
|
||||
* incremented; if so, the cmd was renamed,
|
||||
@@ -1732,7 +1732,7 @@ Tcl_InvalidateStringRep(
|
||||
* is coerced to 1.
|
||||
*
|
||||
* When TCL_MEM_DEBUG is defined, this function just returns the result
|
||||
* of calling the debugging version Tcl_DbNewBooleanObj.
|
||||
* of calling the debugging version Tcl_DbNewLongObj.
|
||||
*
|
||||
* Results:
|
||||
* The newly created object is returned. This object will have an invalid
|
||||
@@ -1751,7 +1751,7 @@ Tcl_Obj *
|
||||
Tcl_NewBooleanObj(
|
||||
register int boolValue) /* Boolean used to initialize new object. */
|
||||
{
|
||||
return Tcl_DbNewBooleanObj(boolValue, "unknown", 0);
|
||||
return Tcl_DbNewLongObj(boolValue!=0, "unknown", 0);
|
||||
}
|
||||
|
||||
#else /* if not TCL_MEM_DEBUG */
|
||||
@@ -1762,7 +1762,7 @@ Tcl_NewBooleanObj(
|
||||
{
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclNewBooleanObj(objPtr, boolValue);
|
||||
TclNewLongObj(objPtr, boolValue!=0);
|
||||
return objPtr;
|
||||
}
|
||||
#endif /* TCL_MEM_DEBUG */
|
||||
@@ -1793,6 +1793,7 @@ Tcl_NewBooleanObj(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_DbNewBooleanObj
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
|
||||
@@ -1856,8 +1857,9 @@ Tcl_SetBooleanObj(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetBooleanObj");
|
||||
}
|
||||
|
||||
TclSetBooleanObj(objPtr, boolValue);
|
||||
TclSetLongObj(objPtr, boolValue!=0);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2458,7 +2460,7 @@ Tcl_SetIntObj(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetIntObj");
|
||||
}
|
||||
|
||||
TclSetIntObj(objPtr, intValue);
|
||||
TclSetLongObj(objPtr, intValue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3036,7 +3038,7 @@ Tcl_SetWideIntObj(
|
||||
#else
|
||||
mp_int big;
|
||||
|
||||
TclBNInitBignumFromWideInt(&big, wideValue);
|
||||
TclInitBignumFromWideInt(&big, wideValue);
|
||||
Tcl_SetBignumObj(objPtr, &big);
|
||||
#endif
|
||||
}
|
||||
@@ -3400,12 +3402,12 @@ GetBignumFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
TclBNInitBignumFromLong(bignumValue, objPtr->internalRep.longValue);
|
||||
TclInitBignumFromLong(bignumValue, objPtr->internalRep.longValue);
|
||||
return TCL_OK;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
TclBNInitBignumFromWideInt(bignumValue,
|
||||
TclInitBignumFromWideInt(bignumValue,
|
||||
objPtr->internalRep.wideValue);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -4453,7 +4455,6 @@ Tcl_RepresentationCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
char ptrBuffer[2*TCL_INTEGER_SPACE+6];
|
||||
Tcl_Obj *descObj;
|
||||
|
||||
if (objc != 2) {
|
||||
@@ -4467,18 +4468,20 @@ Tcl_RepresentationCmd(
|
||||
* "1872361827361287"
|
||||
*/
|
||||
|
||||
sprintf(ptrBuffer, "%p", (void *) objv[1]);
|
||||
descObj = Tcl_ObjPrintf("value is a %s with a refcount of %d,"
|
||||
" object pointer at %s",
|
||||
objv[1]->typePtr ? objv[1]->typePtr->name : "pure string",
|
||||
objv[1]->refCount, ptrBuffer);
|
||||
" object pointer at %p",
|
||||
objv[1]->typePtr ? objv[1]->typePtr->name : "pure string",
|
||||
objv[1]->refCount, objv[1]);
|
||||
|
||||
if (objv[1]->typePtr) {
|
||||
sprintf(ptrBuffer, "%p:%p",
|
||||
(void *) objv[1]->internalRep.twoPtrValue.ptr1,
|
||||
(void *) objv[1]->internalRep.twoPtrValue.ptr2);
|
||||
Tcl_AppendPrintfToObj(descObj, ", internal representation %s",
|
||||
ptrBuffer);
|
||||
if (objv[1]->typePtr == &tclDoubleType) {
|
||||
Tcl_AppendPrintfToObj(descObj, ", internal representation %g",
|
||||
objv[1]->internalRep.doubleValue);
|
||||
} else {
|
||||
Tcl_AppendPrintfToObj(descObj, ", internal representation %p:%p",
|
||||
(void *) objv[1]->internalRep.twoPtrValue.ptr1,
|
||||
(void *) objv[1]->internalRep.twoPtrValue.ptr2);
|
||||
}
|
||||
}
|
||||
|
||||
if (objv[1]->bytes) {
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ Tcl_PanicVA(
|
||||
__builtin_trap();
|
||||
# elif defined(_WIN64)
|
||||
__debugbreak();
|
||||
# elif defined(_MSC_VER)
|
||||
# elif defined(_MSC_VER) && defined (_M_IX86)
|
||||
_asm {int 3}
|
||||
# else
|
||||
DebugBreak();
|
||||
|
||||
+7
-4
@@ -829,7 +829,7 @@ TclParseBackslash(
|
||||
* written there. */
|
||||
{
|
||||
register const char *p = src+1;
|
||||
Tcl_UniChar unichar;
|
||||
Tcl_UniChar unichar = 0;
|
||||
int result;
|
||||
int count;
|
||||
char buf[TCL_UTF_MAX];
|
||||
@@ -963,13 +963,13 @@ TclParseBackslash(
|
||||
*/
|
||||
|
||||
if (Tcl_UtfCharComplete(p, numBytes - 1)) {
|
||||
count = Tcl_UtfToUniChar(p, &unichar) + 1; /* +1 for '\' */
|
||||
count = TclUtfToUniChar(p, &unichar) + 1; /* +1 for '\' */
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
|
||||
memcpy(utfBytes, p, (size_t) (numBytes - 1));
|
||||
utfBytes[numBytes - 1] = '\0';
|
||||
count = Tcl_UtfToUniChar(utfBytes, &unichar) + 1;
|
||||
count = TclUtfToUniChar(utfBytes, &unichar) + 1;
|
||||
}
|
||||
result = unichar;
|
||||
break;
|
||||
@@ -1169,6 +1169,8 @@ ParseTokens(
|
||||
numBytes--;
|
||||
nestedPtr = TclStackAlloc(parsePtr->interp, sizeof(Tcl_Parse));
|
||||
while (1) {
|
||||
const char *curEnd;
|
||||
|
||||
if (Tcl_ParseCommand(parsePtr->interp, src, numBytes, 1,
|
||||
nestedPtr) != TCL_OK) {
|
||||
parsePtr->errorType = nestedPtr->errorType;
|
||||
@@ -1177,8 +1179,9 @@ ParseTokens(
|
||||
TclStackFree(parsePtr->interp, nestedPtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
curEnd = src + numBytes;
|
||||
src = nestedPtr->commandStart + nestedPtr->commandSize;
|
||||
numBytes = parsePtr->end - src;
|
||||
numBytes = curEnd - src;
|
||||
Tcl_FreeParse(nestedPtr);
|
||||
|
||||
/*
|
||||
|
||||
+48
-33
@@ -13,6 +13,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclFileSystem.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Prototypes for functions defined later in this file.
|
||||
@@ -849,18 +850,20 @@ TclJoinPath(
|
||||
int elements,
|
||||
Tcl_Obj * const objv[])
|
||||
{
|
||||
Tcl_Obj *res;
|
||||
Tcl_Obj *res = NULL;
|
||||
int i;
|
||||
const Tcl_Filesystem *fsPtr = NULL;
|
||||
|
||||
res = NULL;
|
||||
assert ( elements >= 0 );
|
||||
|
||||
for (i = 0; i < elements; i++) {
|
||||
int driveNameLength, strEltLen, length;
|
||||
Tcl_PathType type;
|
||||
char *strElt, *ptr;
|
||||
Tcl_Obj *driveName = NULL;
|
||||
Tcl_Obj *elt = objv[i];
|
||||
if (elements == 0) {
|
||||
return Tcl_NewObj();
|
||||
}
|
||||
|
||||
assert ( elements > 0 );
|
||||
|
||||
if (elements == 2) {
|
||||
Tcl_Obj *elt = objv[0];
|
||||
|
||||
/*
|
||||
* This is a special case where we can be much more efficient, where
|
||||
@@ -869,18 +872,17 @@ TclJoinPath(
|
||||
* object which can be normalized more efficiently. Currently we only
|
||||
* use the special case when we have exactly two elements, but we
|
||||
* could expand that in the future.
|
||||
*
|
||||
* Bugfix [a47641a0]. TclNewFSPathObj requires first argument
|
||||
* to be an absolute path. Added a check for that elt is absolute.
|
||||
*
|
||||
* Bugfix [a47641a0]. TclNewFSPathObj requires first argument
|
||||
* to be an absolute path. Added a check for that elt is absolute.
|
||||
*/
|
||||
|
||||
if ((i == (elements-2)) && (i == 0)
|
||||
&& (elt->typePtr == &tclFsPathType)
|
||||
if ((elt->typePtr == &tclFsPathType)
|
||||
&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))
|
||||
&& TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
|
||||
Tcl_Obj *tailObj = objv[i+1];
|
||||
Tcl_Obj *tailObj = objv[1];
|
||||
Tcl_PathType type = TclGetPathType(tailObj, NULL, NULL, NULL);
|
||||
|
||||
type = TclGetPathType(tailObj, NULL, NULL, NULL);
|
||||
if (type == TCL_PATH_RELATIVE) {
|
||||
const char *str;
|
||||
int len;
|
||||
@@ -893,9 +895,6 @@ TclJoinPath(
|
||||
* the base itself is just fine!
|
||||
*/
|
||||
|
||||
if (res != NULL) {
|
||||
TclDecrRefCount(res);
|
||||
}
|
||||
return elt;
|
||||
}
|
||||
|
||||
@@ -918,10 +917,17 @@ TclJoinPath(
|
||||
|
||||
if ((tclPlatform != TCL_PLATFORM_WINDOWS)
|
||||
|| (strchr(Tcl_GetString(elt), '\\') == NULL)) {
|
||||
if (res != NULL) {
|
||||
TclDecrRefCount(res);
|
||||
|
||||
if (PATHFLAGS(elt)) {
|
||||
return TclNewFSPathObj(elt, str, len);
|
||||
}
|
||||
if (TCL_PATH_ABSOLUTE != Tcl_FSGetPathType(elt)) {
|
||||
return TclNewFSPathObj(elt, str, len);
|
||||
}
|
||||
(void) Tcl_FSGetNormalizedPath(NULL, elt);
|
||||
if (elt == PATHOBJ(elt)->normPathPtr) {
|
||||
return TclNewFSPathObj(elt, str, len);
|
||||
}
|
||||
return TclNewFSPathObj(elt, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -930,24 +936,30 @@ TclJoinPath(
|
||||
* more general code below handle things.
|
||||
*/
|
||||
} else if (tclPlatform == TCL_PLATFORM_UNIX) {
|
||||
if (res != NULL) {
|
||||
TclDecrRefCount(res);
|
||||
}
|
||||
return tailObj;
|
||||
} else {
|
||||
const char *str = TclGetString(tailObj);
|
||||
|
||||
if (tclPlatform == TCL_PLATFORM_WINDOWS) {
|
||||
if (strchr(str, '\\') == NULL) {
|
||||
if (res != NULL) {
|
||||
TclDecrRefCount(res);
|
||||
}
|
||||
return tailObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert ( res == NULL );
|
||||
|
||||
for (i = 0; i < elements; i++) {
|
||||
int driveNameLength, strEltLen, length;
|
||||
Tcl_PathType type;
|
||||
char *strElt, *ptr;
|
||||
Tcl_Obj *driveName = NULL;
|
||||
Tcl_Obj *elt = objv[i];
|
||||
|
||||
strElt = TclGetStringFromObj(elt, &strEltLen);
|
||||
driveNameLength = 0;
|
||||
type = TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
|
||||
if (type != TCL_PATH_RELATIVE) {
|
||||
/*
|
||||
@@ -1003,6 +1015,12 @@ TclJoinPath(
|
||||
}
|
||||
}
|
||||
ptr = strElt;
|
||||
/* [Bug f34cf83dd0] */
|
||||
if (driveNameLength > 0) {
|
||||
if (ptr[0] == '/' && ptr[-1] == '/') {
|
||||
goto noQuickReturn;
|
||||
}
|
||||
}
|
||||
while (*ptr != '\0') {
|
||||
if (*ptr == '/' && (ptr[1] == '/' || ptr[1] == '\0')) {
|
||||
/*
|
||||
@@ -1034,10 +1052,8 @@ TclJoinPath(
|
||||
noQuickReturn:
|
||||
if (res == NULL) {
|
||||
res = Tcl_NewObj();
|
||||
ptr = TclGetStringFromObj(res, &length);
|
||||
} else {
|
||||
ptr = TclGetStringFromObj(res, &length);
|
||||
}
|
||||
ptr = TclGetStringFromObj(res, &length);
|
||||
|
||||
/*
|
||||
* Strip off any './' before a tilde, unless this is the beginning of
|
||||
@@ -1070,6 +1086,7 @@ TclJoinPath(
|
||||
|
||||
if (sep != NULL) {
|
||||
separator = TclGetString(sep)[0];
|
||||
TclDecrRefCount(sep);
|
||||
}
|
||||
/* Safety check in case the VFS driver caused sharing */
|
||||
if (Tcl_IsShared(res)) {
|
||||
@@ -1105,9 +1122,7 @@ TclJoinPath(
|
||||
Tcl_SetObjLength(res, length);
|
||||
}
|
||||
}
|
||||
if (res == NULL) {
|
||||
res = Tcl_NewObj();
|
||||
}
|
||||
assert ( res != NULL );
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -668,7 +668,13 @@ TclCreatePipeline(
|
||||
if (*p == '>') {
|
||||
p++;
|
||||
atOK = 0;
|
||||
flags = O_WRONLY | O_CREAT;
|
||||
|
||||
/*
|
||||
* Note that the O_APPEND flag only has an effect on POSIX
|
||||
* platforms. On Windows, we just have to carry on regardless.
|
||||
*/
|
||||
|
||||
flags = O_WRONLY | O_CREAT | O_APPEND;
|
||||
}
|
||||
if (errorClose != 0) {
|
||||
errorClose = 0;
|
||||
|
||||
+6
-12
@@ -224,6 +224,7 @@ static void PkgFilesCleanupProc(ClientData clientData,
|
||||
entry = Tcl_NextHashEntry(&search);
|
||||
}
|
||||
Tcl_DeleteHashTable(&pkgFiles->table);
|
||||
ckfree(pkgFiles);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -330,8 +331,8 @@ Tcl_PkgRequireEx(
|
||||
*
|
||||
* Second, how does this work? If we reach this point, then the global
|
||||
* variable tclEmptyStringRep has the value NULL. Compare that with
|
||||
* the definition of tclEmptyStringRep near the top of the file
|
||||
* generic/tclObj.c. It clearly should not have the value NULL; it
|
||||
* the definition of tclEmptyStringRep near the top of this file.
|
||||
* It clearly should not have the value NULL; it
|
||||
* should point to the char tclEmptyString. If we see it having the
|
||||
* value NULL, then somehow we are seeing a Tcl library that isn't
|
||||
* completely initialized, and that's an indicator for the error
|
||||
@@ -347,18 +348,11 @@ Tcl_PkgRequireEx(
|
||||
* After all, two Tcl libraries can't be a good thing!)
|
||||
*
|
||||
* Trouble is that's going to be tricky. We're now using a Tcl library
|
||||
* that's not fully initialized. In particular, it doesn't have a
|
||||
* proper value for tclEmptyStringRep. The Tcl_Obj system heavily
|
||||
* depends on the value of tclEmptyStringRep and all of Tcl depends
|
||||
* (increasingly) on the Tcl_Obj system, we need to correct that flaw
|
||||
* before making the calls to set the interpreter result to the error
|
||||
* message. That's the only flaw corrected; other problems with
|
||||
* initialization of the Tcl library are not remedied, so be very
|
||||
* careful about adding any other calls here without checking how they
|
||||
* behave when initialization is incomplete.
|
||||
* that's not fully initialized. Functions in it may not work
|
||||
* reliably, so be very careful about adding any other calls here
|
||||
* without checking how they behave when initialization is incomplete.
|
||||
*/
|
||||
|
||||
tclEmptyStringRep = &tclEmptyString;
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"Cannot load package \"%s\" in standalone executable:"
|
||||
" This package is not compiled with stub support", name));
|
||||
|
||||
@@ -155,7 +155,7 @@ Tcl_Preserve(
|
||||
refPtr->clientData = clientData;
|
||||
refPtr->refCount = 1;
|
||||
refPtr->mustFree = 0;
|
||||
refPtr->freeProc = TCL_STATIC;
|
||||
refPtr->freeProc = 0;
|
||||
inUse += 1;
|
||||
Tcl_MutexUnlock(&preserveMutex);
|
||||
}
|
||||
|
||||
@@ -2749,6 +2749,41 @@ MakeLambdaError(
|
||||
(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclGetCmdFrameForProcedure --
|
||||
*
|
||||
* How to get the CmdFrame information for a procedure.
|
||||
*
|
||||
* Results:
|
||||
* A pointer to the CmdFrame (only guaranteed to be valid until the next
|
||||
* Tcl command is processed or the interpreter's state is otherwise
|
||||
* modified) or a NULL if the information is not available.
|
||||
*
|
||||
* Side effects:
|
||||
* none.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
CmdFrame *
|
||||
TclGetCmdFrameForProcedure(
|
||||
Proc *procPtr) /* The procedure whose cmd-frame is to be
|
||||
* looked up. */
|
||||
{
|
||||
Tcl_HashEntry *hePtr;
|
||||
|
||||
if (procPtr == NULL || procPtr->iPtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
hePtr = Tcl_FindHashEntry(procPtr->iPtr->linePBodyPtr, procPtr);
|
||||
if (hePtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return (CmdFrame *) Tcl_GetHashValue(hePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
|
||||
+2
-2
@@ -64,7 +64,7 @@
|
||||
|
||||
#define NUM_REGEXPS 30
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
typedef struct {
|
||||
int initialized; /* Set to 1 when the module is initialized. */
|
||||
char *patterns[NUM_REGEXPS];/* Strings corresponding to compiled regular
|
||||
* expression patterns. NULL means that this
|
||||
@@ -679,7 +679,7 @@ TclRegAbout(
|
||||
|
||||
resultObj = Tcl_NewObj();
|
||||
Tcl_ListObjAppendElement(NULL, resultObj,
|
||||
Tcl_NewIntObj((int) regexpPtr->re.re_nsub));
|
||||
Tcl_NewWideIntObj((Tcl_WideInt) regexpPtr->re.re_nsub));
|
||||
|
||||
/*
|
||||
* Now append a list of all the bit-flags set for the RE.
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ typedef struct TclRegexp {
|
||||
* of subexpressions. */
|
||||
rm_detail_t details; /* Detailed information on match (currently
|
||||
* used only for REG_EXPECT). */
|
||||
unsigned int refCount; /* Count of number of references to this
|
||||
size_t refCount; /* Count of number of references to this
|
||||
* compiled regexp. */
|
||||
} TclRegexp;
|
||||
|
||||
|
||||
+1
-1
@@ -232,6 +232,7 @@ Tcl_DiscardInterpState(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_SaveResult
|
||||
void
|
||||
Tcl_SaveResult(
|
||||
@@ -409,7 +410,6 @@ Tcl_DiscardResult(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
void
|
||||
Tcl_SetResult(
|
||||
Tcl_Interp *interp, /* Interpreter with which to associate the
|
||||
|
||||
+36
-36
@@ -72,17 +72,17 @@ BuildCharSet(
|
||||
CharSet *cset,
|
||||
const char *format) /* Points to first char of set. */
|
||||
{
|
||||
Tcl_UniChar ch, start;
|
||||
Tcl_UniChar ch = 0, start;
|
||||
int offset, nranges;
|
||||
const char *end;
|
||||
|
||||
memset(cset, 0, sizeof(CharSet));
|
||||
|
||||
offset = Tcl_UtfToUniChar(format, &ch);
|
||||
offset = TclUtfToUniChar(format, &ch);
|
||||
if (ch == '^') {
|
||||
cset->exclude = 1;
|
||||
format += offset;
|
||||
offset = Tcl_UtfToUniChar(format, &ch);
|
||||
offset = TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
end = format + offset;
|
||||
|
||||
@@ -91,14 +91,14 @@ BuildCharSet(
|
||||
*/
|
||||
|
||||
if (ch == ']') {
|
||||
end += Tcl_UtfToUniChar(end, &ch);
|
||||
end += TclUtfToUniChar(end, &ch);
|
||||
}
|
||||
nranges = 0;
|
||||
while (ch != ']') {
|
||||
if (ch == '-') {
|
||||
nranges++;
|
||||
}
|
||||
end += Tcl_UtfToUniChar(end, &ch);
|
||||
end += TclUtfToUniChar(end, &ch);
|
||||
}
|
||||
|
||||
cset->chars = ckalloc(sizeof(Tcl_UniChar) * (end - format - 1));
|
||||
@@ -113,11 +113,11 @@ BuildCharSet(
|
||||
*/
|
||||
|
||||
cset->nchars = cset->nranges = 0;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
start = ch;
|
||||
if (ch == ']' || ch == '-') {
|
||||
cset->chars[cset->nchars++] = ch;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
while (ch != ']') {
|
||||
if (*format == '-') {
|
||||
@@ -138,7 +138,7 @@ BuildCharSet(
|
||||
cset->chars[cset->nchars++] = start;
|
||||
cset->chars[cset->nchars++] = ch;
|
||||
} else {
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
|
||||
/*
|
||||
* Check to see if the range is in reverse order.
|
||||
@@ -156,7 +156,7 @@ BuildCharSet(
|
||||
} else {
|
||||
cset->chars[cset->nchars++] = ch;
|
||||
}
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
return format;
|
||||
}
|
||||
@@ -257,7 +257,7 @@ ValidateFormat(
|
||||
{
|
||||
int gotXpg, gotSequential, value, i, flags;
|
||||
char *end;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
int objIndex, xpgSize, nspace = numVars;
|
||||
int *nassign = TclStackAlloc(interp, nspace * sizeof(int));
|
||||
char buf[TCL_UTF_MAX+1];
|
||||
@@ -279,20 +279,20 @@ ValidateFormat(
|
||||
xpgSize = objIndex = gotXpg = gotSequential = 0;
|
||||
|
||||
while (*format != '\0') {
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
|
||||
flags = 0;
|
||||
|
||||
if (ch != '%') {
|
||||
continue;
|
||||
}
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
if (ch == '%') {
|
||||
continue;
|
||||
}
|
||||
if (ch == '*') {
|
||||
flags |= SCAN_SUPPRESS;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
goto xpgCheckDone;
|
||||
}
|
||||
|
||||
@@ -308,7 +308,7 @@ ValidateFormat(
|
||||
goto notXpg;
|
||||
}
|
||||
format = end+1;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
gotXpg = 1;
|
||||
if (gotSequential) {
|
||||
goto mixedXPG;
|
||||
@@ -347,7 +347,7 @@ ValidateFormat(
|
||||
if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
|
||||
value = strtoul(format-1, (char **) &format, 10); /* INTL: "C" locale. */
|
||||
flags |= SCAN_WIDTH;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -359,13 +359,13 @@ ValidateFormat(
|
||||
if (*format == 'l') {
|
||||
flags |= SCAN_BIG;
|
||||
format += 1;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
break;
|
||||
}
|
||||
case 'L':
|
||||
flags |= SCAN_LONGER;
|
||||
case 'h':
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
|
||||
if (!(flags & SCAN_SUPPRESS) && numVars && (objIndex >= numVars)) {
|
||||
@@ -434,24 +434,24 @@ ValidateFormat(
|
||||
if (*format == '\0') {
|
||||
goto badSet;
|
||||
}
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
if (ch == '^') {
|
||||
if (*format == '\0') {
|
||||
goto badSet;
|
||||
}
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
if (ch == ']') {
|
||||
if (*format == '\0') {
|
||||
goto badSet;
|
||||
}
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
while (ch != ']') {
|
||||
if (*format == '\0') {
|
||||
goto badSet;
|
||||
}
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
break;
|
||||
badSet:
|
||||
@@ -582,7 +582,7 @@ Tcl_ScanObjCmd(
|
||||
char op = 0;
|
||||
int width, underflow = 0;
|
||||
Tcl_WideInt wideValue;
|
||||
Tcl_UniChar ch, sch;
|
||||
Tcl_UniChar ch = 0, sch = 0;
|
||||
Tcl_Obj **objs = NULL, *objPtr = NULL;
|
||||
int flags;
|
||||
char buf[513]; /* Temporary buffer to hold scanned number
|
||||
@@ -630,7 +630,7 @@ Tcl_ScanObjCmd(
|
||||
nconversions = 0;
|
||||
while (*format != '\0') {
|
||||
int parseFlag = TCL_PARSE_NO_WHITESPACE;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
|
||||
flags = 0;
|
||||
|
||||
@@ -639,13 +639,13 @@ Tcl_ScanObjCmd(
|
||||
*/
|
||||
|
||||
if (Tcl_UniCharIsSpace(ch)) {
|
||||
offset = Tcl_UtfToUniChar(string, &sch);
|
||||
offset = TclUtfToUniChar(string, &sch);
|
||||
while (Tcl_UniCharIsSpace(sch)) {
|
||||
if (*string == '\0') {
|
||||
goto done;
|
||||
}
|
||||
string += offset;
|
||||
offset = Tcl_UtfToUniChar(string, &sch);
|
||||
offset = TclUtfToUniChar(string, &sch);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -656,14 +656,14 @@ Tcl_ScanObjCmd(
|
||||
underflow = 1;
|
||||
goto done;
|
||||
}
|
||||
string += Tcl_UtfToUniChar(string, &sch);
|
||||
string += TclUtfToUniChar(string, &sch);
|
||||
if (ch != sch) {
|
||||
goto done;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
if (ch == '%') {
|
||||
goto literal;
|
||||
}
|
||||
@@ -675,13 +675,13 @@ Tcl_ScanObjCmd(
|
||||
|
||||
if (ch == '*') {
|
||||
flags |= SCAN_SUPPRESS;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
} else if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
|
||||
char *formatEnd;
|
||||
value = strtoul(format-1, &formatEnd, 10);/* INTL: "C" locale. */
|
||||
if (*formatEnd == '$') {
|
||||
format = formatEnd+1;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
objIndex = (int) value - 1;
|
||||
}
|
||||
}
|
||||
@@ -692,7 +692,7 @@ Tcl_ScanObjCmd(
|
||||
|
||||
if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */
|
||||
width = (int) strtoul(format-1, (char **) &format, 10);/* INTL: "C" locale. */
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
} else {
|
||||
width = 0;
|
||||
}
|
||||
@@ -706,7 +706,7 @@ Tcl_ScanObjCmd(
|
||||
if (*format == 'l') {
|
||||
flags |= SCAN_BIG;
|
||||
format += 1;
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
break;
|
||||
}
|
||||
case 'L':
|
||||
@@ -715,7 +715,7 @@ Tcl_ScanObjCmd(
|
||||
* Fall through so we skip to the next character.
|
||||
*/
|
||||
case 'h':
|
||||
format += Tcl_UtfToUniChar(format, &ch);
|
||||
format += TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -799,7 +799,7 @@ Tcl_ScanObjCmd(
|
||||
|
||||
if (!(flags & SCAN_NOSKIP)) {
|
||||
while (*string != '\0') {
|
||||
offset = Tcl_UtfToUniChar(string, &sch);
|
||||
offset = TclUtfToUniChar(string, &sch);
|
||||
if (!Tcl_UniCharIsSpace(sch)) {
|
||||
break;
|
||||
}
|
||||
@@ -826,7 +826,7 @@ Tcl_ScanObjCmd(
|
||||
}
|
||||
end = string;
|
||||
while (*end != '\0') {
|
||||
offset = Tcl_UtfToUniChar(end, &sch);
|
||||
offset = TclUtfToUniChar(end, &sch);
|
||||
if (Tcl_UniCharIsSpace(sch)) {
|
||||
break;
|
||||
}
|
||||
@@ -854,7 +854,7 @@ Tcl_ScanObjCmd(
|
||||
|
||||
format = BuildCharSet(&cset, format);
|
||||
while (*end != '\0') {
|
||||
offset = Tcl_UtfToUniChar(end, &sch);
|
||||
offset = TclUtfToUniChar(end, &sch);
|
||||
if (!CharInSet(&cset, (int)sch)) {
|
||||
break;
|
||||
}
|
||||
@@ -885,7 +885,7 @@ Tcl_ScanObjCmd(
|
||||
* Scan a single Unicode character.
|
||||
*/
|
||||
|
||||
string += Tcl_UtfToUniChar(string, &sch);
|
||||
string += TclUtfToUniChar(string, &sch);
|
||||
if (!(flags & SCAN_SUPPRESS)) {
|
||||
objPtr = Tcl_NewIntObj((int)sch);
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
|
||||
+78
-56
@@ -17,13 +17,6 @@
|
||||
#include "tommath.h"
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
* Define KILL_OCTAL to suppress interpretation of numbers with leading zero
|
||||
* as octal. (Ceterum censeo: numeros octonarios delendos esse.)
|
||||
*/
|
||||
|
||||
#undef KILL_OCTAL
|
||||
|
||||
/*
|
||||
* This code supports (at least hypothetically), IBM, Cray, VAX and IEEE-754
|
||||
* floating point; of these, only IEEE-754 can represent NaN. IEEE-754 can be
|
||||
@@ -489,7 +482,7 @@ TclParseNumber(
|
||||
{
|
||||
enum State {
|
||||
INITIAL, SIGNUM, ZERO, ZERO_X,
|
||||
ZERO_O, ZERO_B, BINARY,
|
||||
ZERO_O, ZERO_B, ZERO_D, BINARY,
|
||||
HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL,
|
||||
LEADING_RADIX_POINT, FRACTION,
|
||||
EXPONENT_START, EXPONENT_SIGNUM, EXPONENT,
|
||||
@@ -546,6 +539,20 @@ TclParseNumber(
|
||||
*/
|
||||
|
||||
if (bytes == NULL) {
|
||||
if (interp == NULL && endPtrPtr == NULL) {
|
||||
if (objPtr->typePtr == &tclDictType) {
|
||||
/* A dict can never be a (single) number */
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objPtr->typePtr == &tclListType) {
|
||||
int length;
|
||||
/* A list can only be a (single) number if its length == 1 */
|
||||
TclListObjLength(NULL, objPtr, &length);
|
||||
if (length != 1) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
bytes = TclGetString(objPtr);
|
||||
}
|
||||
|
||||
@@ -657,7 +664,11 @@ TclParseNumber(
|
||||
state = ZERO_O;
|
||||
break;
|
||||
}
|
||||
#ifdef KILL_OCTAL
|
||||
if (c == 'd' || c == 'D') {
|
||||
state = ZERO_D;
|
||||
break;
|
||||
}
|
||||
#ifdef TCL_NO_DEPRECATED
|
||||
goto decimal;
|
||||
#endif
|
||||
/* FALLTHROUGH */
|
||||
@@ -700,7 +711,7 @@ TclParseNumber(
|
||||
|| (octalSignificandWide >
|
||||
(~(Tcl_WideUInt)0 >> shift)))) {
|
||||
octalSignificandOverflow = 1;
|
||||
TclBNInitBignumFromWideUInt(&octalSignificandBig,
|
||||
TclInitBignumFromWideUInt(&octalSignificandBig,
|
||||
octalSignificandWide);
|
||||
}
|
||||
}
|
||||
@@ -740,7 +751,7 @@ TclParseNumber(
|
||||
|
||||
goto endgame;
|
||||
}
|
||||
#ifndef KILL_OCTAL
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
|
||||
/*
|
||||
* Scanned a number with a leading zero that contains an 8, 9,
|
||||
@@ -817,7 +828,7 @@ TclParseNumber(
|
||||
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
|
||||
significandWide > (~(Tcl_WideUInt)0 >> shift))) {
|
||||
significandOverflow = 1;
|
||||
TclBNInitBignumFromWideUInt(&significandBig,
|
||||
TclInitBignumFromWideUInt(&significandBig,
|
||||
significandWide);
|
||||
}
|
||||
}
|
||||
@@ -858,7 +869,7 @@ TclParseNumber(
|
||||
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
|
||||
significandWide > (~(Tcl_WideUInt)0 >> shift))) {
|
||||
significandOverflow = 1;
|
||||
TclBNInitBignumFromWideUInt(&significandBig,
|
||||
TclInitBignumFromWideUInt(&significandBig,
|
||||
significandWide);
|
||||
}
|
||||
}
|
||||
@@ -873,13 +884,23 @@ TclParseNumber(
|
||||
state = BINARY;
|
||||
break;
|
||||
|
||||
case ZERO_D:
|
||||
if (c == '0') {
|
||||
numTrailZeros++;
|
||||
} else if ( ! isdigit(UCHAR(c))) {
|
||||
goto endgame;
|
||||
}
|
||||
state = DECIMAL;
|
||||
flags |= TCL_PARSE_INTEGER_ONLY;
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case DECIMAL:
|
||||
/*
|
||||
* Scanned an optional + or - followed by a string of decimal
|
||||
* digits.
|
||||
*/
|
||||
|
||||
#ifdef KILL_OCTAL
|
||||
#ifdef TCL_NO_DEPRECATED
|
||||
decimal:
|
||||
#endif
|
||||
acceptState = state;
|
||||
@@ -1169,6 +1190,7 @@ TclParseNumber(
|
||||
case ZERO_X:
|
||||
case ZERO_O:
|
||||
case ZERO_B:
|
||||
case ZERO_D:
|
||||
case LEADING_RADIX_POINT:
|
||||
case EXPONENT_START:
|
||||
case EXPONENT_SIGNUM:
|
||||
@@ -1183,16 +1205,16 @@ TclParseNumber(
|
||||
case sNA:
|
||||
case sNANPAREN:
|
||||
case sNANHEX:
|
||||
#endif
|
||||
Tcl_Panic("TclParseNumber: bad acceptState %d parsing '%s'",
|
||||
acceptState, bytes);
|
||||
#endif
|
||||
case BINARY:
|
||||
shift = numTrailZeros;
|
||||
if (!significandOverflow && significandWide != 0 &&
|
||||
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
|
||||
significandWide > (MOST_BITS + signum) >> shift)) {
|
||||
significandOverflow = 1;
|
||||
TclBNInitBignumFromWideUInt(&significandBig, significandWide);
|
||||
TclInitBignumFromWideUInt(&significandBig, significandWide);
|
||||
}
|
||||
if (shift) {
|
||||
if (!significandOverflow) {
|
||||
@@ -1213,7 +1235,7 @@ TclParseNumber(
|
||||
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
|
||||
significandWide > (MOST_BITS + signum) >> shift)) {
|
||||
significandOverflow = 1;
|
||||
TclBNInitBignumFromWideUInt(&significandBig, significandWide);
|
||||
TclInitBignumFromWideUInt(&significandBig, significandWide);
|
||||
}
|
||||
if (shift) {
|
||||
if (!significandOverflow) {
|
||||
@@ -1234,7 +1256,7 @@ TclParseNumber(
|
||||
((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
|
||||
octalSignificandWide > (MOST_BITS + signum) >> shift)) {
|
||||
octalSignificandOverflow = 1;
|
||||
TclBNInitBignumFromWideUInt(&octalSignificandBig,
|
||||
TclInitBignumFromWideUInt(&octalSignificandBig,
|
||||
octalSignificandWide);
|
||||
}
|
||||
if (shift) {
|
||||
@@ -1261,7 +1283,7 @@ TclParseNumber(
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
TclBNInitBignumFromWideUInt(&octalSignificandBig,
|
||||
TclInitBignumFromWideUInt(&octalSignificandBig,
|
||||
octalSignificandWide);
|
||||
octalSignificandOverflow = 1;
|
||||
} else {
|
||||
@@ -1289,7 +1311,7 @@ TclParseNumber(
|
||||
&significandWide, &significandBig, significandOverflow);
|
||||
if (!significandOverflow && (significandWide > MOST_BITS+signum)){
|
||||
significandOverflow = 1;
|
||||
TclBNInitBignumFromWideUInt(&significandBig, significandWide);
|
||||
TclInitBignumFromWideUInt(&significandBig, significandWide);
|
||||
}
|
||||
returnInteger:
|
||||
if (!significandOverflow) {
|
||||
@@ -1308,7 +1330,7 @@ TclParseNumber(
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
TclBNInitBignumFromWideUInt(&significandBig,
|
||||
TclInitBignumFromWideUInt(&significandBig,
|
||||
significandWide);
|
||||
significandOverflow = 1;
|
||||
} else {
|
||||
@@ -1463,7 +1485,7 @@ AccumulateDecimalDigit(
|
||||
* bignum and fall through into the bignum case.
|
||||
*/
|
||||
|
||||
TclBNInitBignumFromWideUInt(bignumRepPtr, w);
|
||||
TclInitBignumFromWideUInt(bignumRepPtr, w);
|
||||
} else {
|
||||
/*
|
||||
* Wide multiplication.
|
||||
@@ -1606,7 +1628,7 @@ MakeLowPrecisionDouble(
|
||||
* call MakeHighPrecisionDouble to do it the hard way.
|
||||
*/
|
||||
|
||||
TclBNInitBignumFromWideUInt(&significandBig, significand);
|
||||
TclInitBignumFromWideUInt(&significandBig, significand);
|
||||
retval = MakeHighPrecisionDouble(0, &significandBig, numSigDigs,
|
||||
exponent);
|
||||
mp_clear(&significandBig);
|
||||
@@ -1973,7 +1995,7 @@ RefineApproximation(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static void
|
||||
static inline void
|
||||
MulPow5(
|
||||
mp_int *base, /* Number to multiply. */
|
||||
unsigned n, /* Power of 5 to multiply by. */
|
||||
@@ -2018,7 +2040,7 @@ MulPow5(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
NormalizeRightward(
|
||||
Tcl_WideUInt *wPtr) /* INOUT: Number to shift. */
|
||||
{
|
||||
@@ -2109,7 +2131,7 @@ RequiredPrecision(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static void
|
||||
static inline void
|
||||
DoubleToExpAndSig(
|
||||
double dv, /* Number to convert. */
|
||||
Tcl_WideUInt *significand, /* OUTPUT: Significand of the number. */
|
||||
@@ -2157,7 +2179,7 @@ DoubleToExpAndSig(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static void
|
||||
static inline void
|
||||
TakeAbsoluteValue(
|
||||
Double *d, /* Number to replace with absolute value. */
|
||||
int *sign) /* Place to put the signum. */
|
||||
@@ -2188,7 +2210,7 @@ TakeAbsoluteValue(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
FormatInfAndNaN(
|
||||
Double *d, /* Exceptional number to format. */
|
||||
int *decpt, /* Decimal point to set to a bogus value. */
|
||||
@@ -2230,7 +2252,7 @@ FormatInfAndNaN(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
FormatZero(
|
||||
int *decpt, /* Location of the decimal point. */
|
||||
char **endPtr) /* Pointer to the end of the formatted data */
|
||||
@@ -2260,7 +2282,7 @@ FormatZero(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
ApproximateLog10(
|
||||
Tcl_WideUInt bw, /* Integer significand of the number. */
|
||||
int be, /* Power of two to scale bw. */
|
||||
@@ -2308,7 +2330,7 @@ ApproximateLog10(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
BetterLog10(
|
||||
double d, /* Original number to format. */
|
||||
int k, /* Characteristic(Log base 10) of the
|
||||
@@ -2351,7 +2373,7 @@ BetterLog10(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static void
|
||||
static inline void
|
||||
ComputeScale(
|
||||
int be, /* Exponent part of number: d = bw * 2**be. */
|
||||
int k, /* Characteristic of log10(number). */
|
||||
@@ -2414,7 +2436,7 @@ ComputeScale(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static void
|
||||
static inline void
|
||||
SetPrecisionLimits(
|
||||
int convType, /* Type of conversion: TCL_DD_SHORTEST,
|
||||
* TCL_DD_STEELE0, TCL_DD_E_FMT,
|
||||
@@ -2475,7 +2497,7 @@ SetPrecisionLimits(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
BumpUp(
|
||||
char *s, /* Cursor pointing one past the end of the
|
||||
* string. */
|
||||
@@ -2509,7 +2531,7 @@ BumpUp(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
AdjustRange(
|
||||
double *dPtr, /* INOUT: Number to adjust. */
|
||||
int k) /* IN: floor(log10(d)) */
|
||||
@@ -2582,7 +2604,7 @@ AdjustRange(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
ShorteningQuickFormat(
|
||||
double d, /* Number to convert. */
|
||||
int k, /* floor(log10(d)) */
|
||||
@@ -2657,7 +2679,7 @@ ShorteningQuickFormat(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
StrictQuickFormat(
|
||||
double d, /* Number to convert. */
|
||||
int k, /* floor(log10(d)) */
|
||||
@@ -2731,7 +2753,7 @@ StrictQuickFormat(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
QuickConversion(
|
||||
double e, /* Number to format. */
|
||||
int k, /* floor(log10(d)), approximately. */
|
||||
@@ -2836,7 +2858,7 @@ QuickConversion(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static void
|
||||
static inline void
|
||||
CastOutPowersOf2(
|
||||
int *b2, /* Power of 2 to multiply the significand. */
|
||||
int *m2, /* Power of 2 to multiply 1/2 ulp. */
|
||||
@@ -2880,7 +2902,7 @@ CastOutPowersOf2(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
ShorteningInt64Conversion(
|
||||
Double *dPtr, /* Original number to convert. */
|
||||
int convType, /* Type of conversion (shortest, Steele,
|
||||
@@ -3049,7 +3071,7 @@ ShorteningInt64Conversion(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
StrictInt64Conversion(
|
||||
Double *dPtr, /* Original number to convert. */
|
||||
int convType, /* Type of conversion (shortest, Steele,
|
||||
@@ -3155,7 +3177,7 @@ StrictInt64Conversion(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
ShouldBankerRoundUpPowD(
|
||||
mp_int *b, /* Numerator of the fraction. */
|
||||
int sd, /* Denominator is 2**(sd*DIGIT_BIT). */
|
||||
@@ -3193,7 +3215,7 @@ ShouldBankerRoundUpPowD(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
ShouldBankerRoundUpToNextPowD(
|
||||
mp_int *b, /* Numerator of the fraction. */
|
||||
mp_int *m, /* Numerator of the rounding tolerance. */
|
||||
@@ -3256,7 +3278,7 @@ ShouldBankerRoundUpToNextPowD(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
ShorteningBignumConversionPowD(
|
||||
Double *dPtr, /* Original number to convert. */
|
||||
int convType, /* Type of conversion (shortest, Steele,
|
||||
@@ -3293,7 +3315,7 @@ ShorteningBignumConversionPowD(
|
||||
* mminus = 5**m5
|
||||
*/
|
||||
|
||||
TclBNInitBignumFromWideUInt(&b, bw);
|
||||
TclInitBignumFromWideUInt(&b, bw);
|
||||
mp_init_set_int(&mminus, 1);
|
||||
MulPow5(&b, b5, &b);
|
||||
mp_mul_2d(&b, b2, &b);
|
||||
@@ -3449,7 +3471,7 @@ ShorteningBignumConversionPowD(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
StrictBignumConversionPowD(
|
||||
Double *dPtr, /* Original number to convert. */
|
||||
int convType, /* Type of conversion (shortest, Steele,
|
||||
@@ -3480,7 +3502,7 @@ StrictBignumConversionPowD(
|
||||
* b = bw * 2**b2 * 5**b5
|
||||
*/
|
||||
|
||||
TclBNInitBignumFromWideUInt(&b, bw);
|
||||
TclInitBignumFromWideUInt(&b, bw);
|
||||
MulPow5(&b, b5, &b);
|
||||
mp_mul_2d(&b, b2, &b);
|
||||
|
||||
@@ -3565,7 +3587,7 @@ StrictBignumConversionPowD(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
ShouldBankerRoundUp(
|
||||
mp_int *twor, /* 2x the remainder from thd division that
|
||||
* produced the last digit. */
|
||||
@@ -3600,7 +3622,7 @@ ShouldBankerRoundUp(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static int
|
||||
static inline int
|
||||
ShouldBankerRoundUpToNext(
|
||||
mp_int *b, /* Remainder from the division that produced
|
||||
* the last digit. */
|
||||
@@ -3654,7 +3676,7 @@ ShouldBankerRoundUpToNext(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
ShorteningBignumConversion(
|
||||
Double *dPtr, /* Original number being converted. */
|
||||
int convType, /* Conversion type. */
|
||||
@@ -3688,7 +3710,7 @@ ShorteningBignumConversion(
|
||||
* S = 2**s2 * 5*s5
|
||||
*/
|
||||
|
||||
TclBNInitBignumFromWideUInt(&b, bw);
|
||||
TclInitBignumFromWideUInt(&b, bw);
|
||||
mp_mul_2d(&b, b2, &b);
|
||||
mp_init_set_int(&S, 1);
|
||||
MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
|
||||
@@ -3798,7 +3820,7 @@ ShorteningBignumConversion(
|
||||
--s5;
|
||||
|
||||
/*
|
||||
* IDEA: It might possibly be a win to fall back to int64
|
||||
* IDEA: It might possibly be a win to fall back to int64_t
|
||||
* arithmetic here if S < 2**64/10. But it's a win only for
|
||||
* a fairly narrow range of magnitudes so perhaps not worth
|
||||
* bothering. We already know that we shorten the
|
||||
@@ -3870,7 +3892,7 @@ ShorteningBignumConversion(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
inline static char *
|
||||
static inline char *
|
||||
StrictBignumConversion(
|
||||
Double *dPtr, /* Original number being converted. */
|
||||
int convType, /* Conversion type. */
|
||||
@@ -3901,7 +3923,7 @@ StrictBignumConversion(
|
||||
*/
|
||||
|
||||
mp_init_multi(&temp, &dig, NULL);
|
||||
TclBNInitBignumFromWideUInt(&b, bw);
|
||||
TclInitBignumFromWideUInt(&b, bw);
|
||||
mp_mul_2d(&b, b2, &b);
|
||||
mp_init_set_int(&S, 1);
|
||||
MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
|
||||
@@ -3963,7 +3985,7 @@ StrictBignumConversion(
|
||||
* As with the shortening bignum conversion, it's possible at this
|
||||
* point that we will have reduced the denominator to less than
|
||||
* 2**64/10, at which point it would be possible to fall back to
|
||||
* to int64 arithmetic. But the potential payoff is tremendously
|
||||
* to int64_t arithmetic. But the potential payoff is tremendously
|
||||
* less - unless we're working in F format - because we know that
|
||||
* three groups of digits will always suffice for %#.17e, the
|
||||
* longest format that doesn't introduce empty precision.
|
||||
@@ -4557,7 +4579,7 @@ Tcl_InitBignumFromDouble(
|
||||
Tcl_WideInt w = (Tcl_WideInt) ldexp(fract, mantBits);
|
||||
int shift = expt - mantBits;
|
||||
|
||||
TclBNInitBignumFromWideInt(b, w);
|
||||
TclInitBignumFromWideInt(b, w);
|
||||
if (shift < 0) {
|
||||
mp_div_2d(b, -shift, b, NULL);
|
||||
} else if (shift > 0) {
|
||||
|
||||
+247
-100
@@ -1650,6 +1650,7 @@ Tcl_AppendFormatToObj(
|
||||
const char *span = format, *msg, *errCode;
|
||||
int numBytes = 0, objIndex = 0, gotXpg = 0, gotSequential = 0;
|
||||
int originalLength, limit;
|
||||
Tcl_UniChar ch = 0;
|
||||
static const char *mixedXPG =
|
||||
"cannot mix \"%\" and \"%n$\" conversion specifiers";
|
||||
static const char *const badIndex[2] = {
|
||||
@@ -1670,12 +1671,14 @@ Tcl_AppendFormatToObj(
|
||||
|
||||
while (*format != '\0') {
|
||||
char *end;
|
||||
int gotMinus, gotHash, gotZero, gotSpace, gotPlus, sawFlag;
|
||||
int width, gotPrecision, precision, useShort, useWide, useBig;
|
||||
int gotMinus = 0, gotHash = 0, gotZero = 0, gotSpace = 0, gotPlus = 0;
|
||||
int width, gotPrecision, precision, sawFlag, useShort = 0, useBig = 0;
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
int useWide = 0;
|
||||
#endif
|
||||
int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes;
|
||||
Tcl_Obj *segment;
|
||||
Tcl_UniChar ch;
|
||||
int step = Tcl_UtfToUniChar(format, &ch);
|
||||
int step = TclUtfToUniChar(format, &ch);
|
||||
|
||||
format += step;
|
||||
if (ch != '%') {
|
||||
@@ -1699,7 +1702,7 @@ Tcl_AppendFormatToObj(
|
||||
* Step 0. Handle special case of escaped format marker (i.e., %%).
|
||||
*/
|
||||
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
if (ch == '%') {
|
||||
span = format;
|
||||
numBytes = step;
|
||||
@@ -1719,7 +1722,7 @@ Tcl_AppendFormatToObj(
|
||||
newXpg = 1;
|
||||
objIndex = position - 1;
|
||||
format = end + 1;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
}
|
||||
if (newXpg) {
|
||||
@@ -1747,7 +1750,6 @@ Tcl_AppendFormatToObj(
|
||||
* Step 2. Set of flags.
|
||||
*/
|
||||
|
||||
gotMinus = gotHash = gotZero = gotSpace = gotPlus = 0;
|
||||
sawFlag = 1;
|
||||
do {
|
||||
switch (ch) {
|
||||
@@ -1771,7 +1773,7 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
if (sawFlag) {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
} while (sawFlag);
|
||||
|
||||
@@ -1783,7 +1785,7 @@ Tcl_AppendFormatToObj(
|
||||
if (isdigit(UCHAR(ch))) {
|
||||
width = strtoul(format, &end, 10);
|
||||
format = end;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
} else if (ch == '*') {
|
||||
if (objIndex >= objc - 1) {
|
||||
msg = badIndex[gotXpg];
|
||||
@@ -1799,7 +1801,7 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
objIndex++;
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
if (width > limit) {
|
||||
msg = overflow;
|
||||
@@ -1815,12 +1817,12 @@ Tcl_AppendFormatToObj(
|
||||
if (ch == '.') {
|
||||
gotPrecision = 1;
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
if (isdigit(UCHAR(ch))) {
|
||||
precision = strtoul(format, &end, 10);
|
||||
format = end;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
} else if (ch == '*') {
|
||||
if (objIndex >= objc - 1) {
|
||||
msg = badIndex[gotXpg];
|
||||
@@ -1841,38 +1843,57 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
objIndex++;
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* Step 5. Length modifier.
|
||||
*/
|
||||
|
||||
useShort = useWide = useBig = 0;
|
||||
if (ch == 'h') {
|
||||
useShort = 1;
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
} else if (ch == 'l') {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
if (ch == 'l') {
|
||||
useBig = 1;
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else {
|
||||
useWide = 1;
|
||||
#endif
|
||||
}
|
||||
} else if ((ch == 'I') && (format[1] == '6') && (format[2] == '4')) {
|
||||
format += (step + 2);
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
useBig = 1;
|
||||
} else if (ch == 'L') {
|
||||
} else if (ch == 'I') {
|
||||
if ((format[1] == '6') && (format[2] == '4')) {
|
||||
format += (step + 2);
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
useWide = 1;
|
||||
#endif
|
||||
} else if ((format[1] == '3') && (format[2] == '2')) {
|
||||
format += (step + 2);
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
} else {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
}
|
||||
} else if ((ch == 't') || (ch == 'z')) {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
useBig = 1;
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (sizeof(size_t) > sizeof(int)) {
|
||||
useWide = 1;
|
||||
}
|
||||
#endif
|
||||
} else if ((ch == 'q') ||(ch == 'j')) {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
useWide = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
format += step;
|
||||
@@ -1925,6 +1946,7 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
case 'd':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'b': {
|
||||
@@ -1935,11 +1957,17 @@ Tcl_AppendFormatToObj(
|
||||
mp_int big;
|
||||
int toAppend, isNegative = 0;
|
||||
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (ch == 'p') {
|
||||
useWide = 1;
|
||||
}
|
||||
#endif
|
||||
if (useBig) {
|
||||
if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) {
|
||||
goto error;
|
||||
}
|
||||
isNegative = (mp_cmp_d(&big, 0) == MP_LT);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else if (useWide) {
|
||||
if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
|
||||
Tcl_Obj *objPtr;
|
||||
@@ -1954,6 +1982,7 @@ Tcl_AppendFormatToObj(
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
}
|
||||
isNegative = (w < (Tcl_WideInt) 0);
|
||||
#endif
|
||||
} else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) {
|
||||
if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
|
||||
Tcl_Obj *objPtr;
|
||||
@@ -1993,15 +2022,19 @@ Tcl_AppendFormatToObj(
|
||||
segmentLimit -= 1;
|
||||
}
|
||||
|
||||
if (gotHash) {
|
||||
if (gotHash || (ch == 'p')) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
Tcl_AppendToObj(segment, "0", 1);
|
||||
segmentLimit -= 1;
|
||||
precision--;
|
||||
break;
|
||||
case 'x':
|
||||
case 'X':
|
||||
Tcl_AppendToObj(segment, "0X", 2);
|
||||
segmentLimit -= 2;
|
||||
break;
|
||||
case 'p':
|
||||
case 'x':
|
||||
Tcl_AppendToObj(segment, "0x", 2);
|
||||
segmentLimit -= 2;
|
||||
break;
|
||||
@@ -2009,6 +2042,10 @@ Tcl_AppendFormatToObj(
|
||||
Tcl_AppendToObj(segment, "0b", 2);
|
||||
segmentLimit -= 2;
|
||||
break;
|
||||
case 'd':
|
||||
Tcl_AppendToObj(segment, "0d", 2);
|
||||
segmentLimit -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2020,8 +2057,10 @@ Tcl_AppendFormatToObj(
|
||||
|
||||
if (useShort) {
|
||||
pure = Tcl_NewIntObj((int) s);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else if (useWide) {
|
||||
pure = Tcl_NewWideIntObj(w);
|
||||
#endif
|
||||
} else if (useBig) {
|
||||
pure = Tcl_NewBignumObj(&big);
|
||||
} else {
|
||||
@@ -2078,6 +2117,7 @@ Tcl_AppendFormatToObj(
|
||||
|
||||
case 'u':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'b': {
|
||||
@@ -2104,6 +2144,7 @@ Tcl_AppendFormatToObj(
|
||||
numDigits++;
|
||||
us /= base;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else if (useWide) {
|
||||
Tcl_WideUInt uw = (Tcl_WideUInt) w;
|
||||
|
||||
@@ -2112,6 +2153,7 @@ Tcl_AppendFormatToObj(
|
||||
numDigits++;
|
||||
uw /= base;
|
||||
}
|
||||
#endif
|
||||
} else if (useBig && big.used) {
|
||||
int leftover = (big.used * DIGIT_BIT) % numBits;
|
||||
mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover);
|
||||
@@ -2161,7 +2203,11 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
digitOffset = (int) (bits % base);
|
||||
if (digitOffset > 9) {
|
||||
bytes[numDigits] = 'a' + digitOffset - 10;
|
||||
if (ch == 'X') {
|
||||
bytes[numDigits] = 'A' + digitOffset - 10;
|
||||
} else {
|
||||
bytes[numDigits] = 'a' + digitOffset - 10;
|
||||
}
|
||||
} else {
|
||||
bytes[numDigits] = '0' + digitOffset;
|
||||
}
|
||||
@@ -2283,14 +2329,6 @@ Tcl_AppendFormatToObj(
|
||||
goto error;
|
||||
}
|
||||
|
||||
switch (ch) {
|
||||
case 'E':
|
||||
case 'G':
|
||||
case 'X': {
|
||||
Tcl_SetObjLength(segment, Tcl_UtfToUpper(TclGetString(segment)));
|
||||
}
|
||||
}
|
||||
|
||||
if (width>0 && numChars<0) {
|
||||
numChars = Tcl_GetCharLength(segment);
|
||||
}
|
||||
@@ -2467,6 +2505,7 @@ AppendPrintfToObjVA(
|
||||
case 'u':
|
||||
case 'd':
|
||||
case 'o':
|
||||
case 'p':
|
||||
case 'x':
|
||||
case 'X':
|
||||
seekingConversion = 0;
|
||||
@@ -2517,7 +2556,15 @@ AppendPrintfToObjVA(
|
||||
++size;
|
||||
p++;
|
||||
break;
|
||||
case 'L':
|
||||
case 't':
|
||||
case 'z':
|
||||
if (sizeof(size_t) == sizeof(Tcl_WideInt)) {
|
||||
size = 2;
|
||||
}
|
||||
p++;
|
||||
break;
|
||||
case 'j':
|
||||
case 'q':
|
||||
size = 2;
|
||||
p++;
|
||||
break;
|
||||
@@ -2525,6 +2572,10 @@ AppendPrintfToObjVA(
|
||||
if (p[1]=='6' && p[2]=='4') {
|
||||
p += 2;
|
||||
size = 2;
|
||||
} else if (p[1]=='3' && p[2]=='2') {
|
||||
p += 2;
|
||||
} else if (sizeof(size_t) == sizeof(Tcl_WideInt)) {
|
||||
size = 2;
|
||||
}
|
||||
p++;
|
||||
break;
|
||||
@@ -2732,7 +2783,7 @@ TclStringRepeat(
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"string size overflow: unable to alloc %"
|
||||
TCL_LL_MODIFIER "u bytes",
|
||||
TCL_LL_MODIFIER "d bytes",
|
||||
(Tcl_WideUInt)STRING_SIZE(count*length)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
@@ -2799,11 +2850,21 @@ TclStringCatObjv(
|
||||
Tcl_Obj * const objv[],
|
||||
Tcl_Obj **objPtrPtr)
|
||||
{
|
||||
Tcl_Obj *objPtr, *objResultPtr, * const *ov;
|
||||
int oc, length = 0, binary = 1, first = 0;
|
||||
Tcl_Obj *objResultPtr, * const *ov;
|
||||
int oc, length = 0, binary = 1;
|
||||
int allowUniChar = 1, requestUniChar = 0;
|
||||
int first = objc - 1; /* Index of first value possibly not empty */
|
||||
int last = 0; /* Index of last value possibly not empty */
|
||||
|
||||
/* assert (objc >= 2) */
|
||||
/* assert ( objc >= 0 ) */
|
||||
|
||||
if (objc <= 1) {
|
||||
/* Only one or no objects; return first or empty */
|
||||
*objPtrPtr = objc ? objv[0] : Tcl_NewObj();
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* assert ( objc >= 2 ) */
|
||||
|
||||
/*
|
||||
* Analyze to determine what representation result should be.
|
||||
@@ -2813,8 +2874,8 @@ TclStringCatObjv(
|
||||
*/
|
||||
|
||||
ov = objv, oc = objc;
|
||||
while (oc-- && (binary || allowUniChar)) {
|
||||
objPtr = *ov++;
|
||||
do {
|
||||
Tcl_Obj *objPtr = *ov++;
|
||||
|
||||
if (objPtr->bytes) {
|
||||
/* Value has a string rep. */
|
||||
@@ -2844,72 +2905,144 @@ TclStringCatObjv(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (--oc && (binary || allowUniChar));
|
||||
|
||||
if (binary) {
|
||||
/* Result will be pure byte array. Pre-size it */
|
||||
ov = objv; oc = objc;
|
||||
while (oc-- && (length >= 0)) {
|
||||
objPtr = *ov++;
|
||||
do {
|
||||
Tcl_Obj *objPtr = *ov++;
|
||||
|
||||
if (objPtr->bytes == NULL) {
|
||||
int numBytes;
|
||||
|
||||
Tcl_GetByteArrayFromObj(objPtr, &numBytes); /* PANIC? */
|
||||
if (length == 0) {
|
||||
first = objc - oc - 1;
|
||||
if (numBytes) {
|
||||
last = objc - oc;
|
||||
if (length == 0) {
|
||||
first = last;
|
||||
} else if (numBytes > INT_MAX - length) {
|
||||
goto overflow;
|
||||
}
|
||||
length += numBytes;
|
||||
}
|
||||
length += numBytes;
|
||||
}
|
||||
}
|
||||
} while (--oc);
|
||||
} else if (allowUniChar && requestUniChar) {
|
||||
/* Result will be pure Tcl_UniChar array. Pre-size it. */
|
||||
ov = objv; oc = objc;
|
||||
while (oc-- && (length >= 0)) {
|
||||
objPtr = *ov++;
|
||||
do {
|
||||
Tcl_Obj *objPtr = *ov++;
|
||||
|
||||
if ((objPtr->bytes == NULL) || (objPtr->length)) {
|
||||
int numChars;
|
||||
|
||||
Tcl_GetUnicodeFromObj(objPtr, &numChars); /* PANIC? */
|
||||
if (length == 0) {
|
||||
first = objc - oc - 1;
|
||||
if (numChars) {
|
||||
last = objc - oc;
|
||||
if (length == 0) {
|
||||
first = last;
|
||||
} else if (numChars > INT_MAX - length) {
|
||||
goto overflow;
|
||||
}
|
||||
length += numChars;
|
||||
}
|
||||
length += numChars;
|
||||
}
|
||||
}
|
||||
} while (--oc);
|
||||
} else {
|
||||
/* Result will be concat of string reps. Pre-size it. */
|
||||
ov = objv; oc = objc;
|
||||
while (oc-- && (length >= 0)) {
|
||||
int numBytes;
|
||||
do {
|
||||
Tcl_Obj *pendingPtr = NULL;
|
||||
|
||||
objPtr = *ov++;
|
||||
/*
|
||||
* Loop until a possibly non-empty value is reached.
|
||||
* Keep string rep generation pending when possible.
|
||||
*/
|
||||
|
||||
Tcl_GetStringFromObj(objPtr, &numBytes); /* PANIC? */
|
||||
if ((length == 0) && numBytes) {
|
||||
first = objc - oc - 1;
|
||||
do {
|
||||
/* assert ( pendingPtr == NULL ) */
|
||||
/* assert ( length == 0 ) */
|
||||
|
||||
Tcl_Obj *objPtr = *ov++;
|
||||
|
||||
if (objPtr->bytes == NULL) {
|
||||
/* No string rep; Take the chance we can avoid making it */
|
||||
pendingPtr = objPtr;
|
||||
} else {
|
||||
Tcl_GetStringFromObj(objPtr, &length); /* PANIC? */
|
||||
}
|
||||
} while (--oc && (length == 0) && (pendingPtr == NULL));
|
||||
|
||||
/*
|
||||
* Either we found a possibly non-empty value, and we
|
||||
* remember this index as the first and last such value so
|
||||
* far seen, or (oc == 0) and all values are known empty,
|
||||
* so first = last = objc - 1 signals the right quick return.
|
||||
*/
|
||||
|
||||
first = last = objc - oc - 1;
|
||||
|
||||
if (oc && (length == 0)) {
|
||||
int numBytes;
|
||||
|
||||
/* assert ( pendingPtr != NULL ) */
|
||||
|
||||
/*
|
||||
* There's a pending value followed by more values.
|
||||
* Loop over remaining values generating strings until
|
||||
* a non-empty value is found, or the pending value gets
|
||||
* its string generated.
|
||||
*/
|
||||
|
||||
do {
|
||||
Tcl_Obj *objPtr = *ov++;
|
||||
Tcl_GetStringFromObj(objPtr, &numBytes); /* PANIC? */
|
||||
} while (--oc && numBytes == 0 && pendingPtr->bytes == NULL);
|
||||
|
||||
if (numBytes) {
|
||||
last = objc -oc -1;
|
||||
}
|
||||
if (oc || numBytes) {
|
||||
Tcl_GetStringFromObj(pendingPtr, &length);
|
||||
}
|
||||
if (length == 0) {
|
||||
if (numBytes) {
|
||||
first = last;
|
||||
}
|
||||
} else if (numBytes > INT_MAX - length) {
|
||||
goto overflow;
|
||||
}
|
||||
length += numBytes;
|
||||
}
|
||||
length += numBytes;
|
||||
} while (oc && (length == 0));
|
||||
|
||||
while (oc) {
|
||||
int numBytes;
|
||||
Tcl_Obj *objPtr = *ov++;
|
||||
|
||||
/* assert ( length > 0 && pendingPtr == NULL ) */
|
||||
|
||||
Tcl_GetStringFromObj(objPtr, &numBytes); /* PANIC? */
|
||||
if (numBytes) {
|
||||
last = objc - oc;
|
||||
if (numBytes > INT_MAX - length) {
|
||||
goto overflow;
|
||||
}
|
||||
length += numBytes;
|
||||
}
|
||||
--oc;
|
||||
}
|
||||
}
|
||||
|
||||
if (length < 0) {
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"max size for a Tcl value (%d bytes) exceeded", INT_MAX));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
/* Total length of zero means every value has length zero */
|
||||
*objPtrPtr = objv[0];
|
||||
if (last <= first /*|| length == 0 */) {
|
||||
/* Only one non-empty value or zero length; return first */
|
||||
/* NOTE: (length == 0) implies (last <= first) */
|
||||
*objPtrPtr = objv[first];
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
objv += first; objc -= first;
|
||||
objv += first; objc = (last - first + 1);
|
||||
|
||||
if (binary) {
|
||||
/* Efficiently produce a pure byte array result */
|
||||
@@ -2956,7 +3089,7 @@ TclStringCatObjv(
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"concatenation failed: unable to alloc %"
|
||||
TCL_LL_MODIFIER "u bytes",
|
||||
TCL_LL_MODIFIER "d bytes",
|
||||
(Tcl_WideUInt)STRING_SIZE(length)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
@@ -2969,10 +3102,11 @@ TclStringCatObjv(
|
||||
/* Ugly interface! No scheme to init array size. */
|
||||
objResultPtr = Tcl_NewUnicodeObj(&ch, 0); /* PANIC? */
|
||||
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
|
||||
Tcl_DecrRefCount(objResultPtr);
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"concatenation failed: unable to alloc %"
|
||||
TCL_LL_MODIFIER "u bytes",
|
||||
TCL_LL_MODIFIER "d bytes",
|
||||
(Tcl_WideUInt)STRING_SIZE(length)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
@@ -3010,12 +3144,13 @@ TclStringCatObjv(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dst = Tcl_GetString(objResultPtr) + start;
|
||||
if (length > start) {
|
||||
TclFreeIntRep(objResultPtr);
|
||||
}
|
||||
|
||||
/* assert ( length > start ) */
|
||||
TclFreeIntRep(objResultPtr);
|
||||
} else {
|
||||
objResultPtr = Tcl_NewObj(); /* PANIC? */
|
||||
if (0 == Tcl_AttemptSetObjLength(objResultPtr, length)) {
|
||||
Tcl_DecrRefCount(objResultPtr);
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"concatenation failed: unable to alloc %u bytes",
|
||||
@@ -3039,6 +3174,14 @@ TclStringCatObjv(
|
||||
}
|
||||
*objPtrPtr = objResultPtr;
|
||||
return TCL_OK;
|
||||
|
||||
overflow:
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"max size for a Tcl value (%d bytes) exceeded", INT_MAX));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3099,40 +3242,44 @@ TclStringFind(
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we have two strings of single-byte characters. If we have, we
|
||||
* can use strstr() to do the search. Note that we can sometimes have
|
||||
* multibyte characters when the string could be minimally represented
|
||||
* using single byte characters; we can't assume that a mismatch here
|
||||
* means no match.
|
||||
*/
|
||||
|
||||
lh = Tcl_GetCharLength(haystack);
|
||||
if (haystack->bytes && (lh == haystack->length)) {
|
||||
/* haystack is all single-byte chars */
|
||||
if (haystack->bytes && (lh == haystack->length) && needle->bytes
|
||||
&& (ln == needle->length)) {
|
||||
/*
|
||||
* Both haystack and needle are all single-byte chars.
|
||||
*/
|
||||
|
||||
if (needle->bytes && (ln == needle->length)) {
|
||||
/* needle is also all single-byte chars */
|
||||
char *found = strstr(haystack->bytes + start, needle->bytes);
|
||||
char *found = strstr(haystack->bytes + start, needle->bytes);
|
||||
|
||||
if (found) {
|
||||
return (found - haystack->bytes);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
if (found) {
|
||||
return (found - haystack->bytes);
|
||||
} else {
|
||||
/*
|
||||
* Cannot find substring with a multi-byte char inside
|
||||
* a string with no multi-byte chars.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Do the search on the unicode representation for simplicity.
|
||||
*/
|
||||
|
||||
Tcl_UniChar *try, *end, *uh;
|
||||
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
|
||||
|
||||
uh = Tcl_GetUnicodeFromObj(haystack, &lh);
|
||||
end = uh + lh;
|
||||
|
||||
try = uh + start;
|
||||
while (try + ln <= end) {
|
||||
if ((*try == *un)
|
||||
&& (0 == memcmp(try+1, un+1, (ln-1)*sizeof(Tcl_UniChar)))) {
|
||||
for (try = uh + start; try + ln <= end; try++) {
|
||||
if ((*try == *un) && (0 ==
|
||||
memcmp(try + 1, un + 1, (ln-1) * sizeof(Tcl_UniChar)))) {
|
||||
return (try - uh);
|
||||
}
|
||||
try++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -3287,7 +3434,7 @@ TclStringObjReverse(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
String *stringPtr;
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
int numBytes;
|
||||
@@ -3361,7 +3508,7 @@ TclStringObjReverse(
|
||||
* It's part of the contract for objPtr->bytes values.
|
||||
* Thus, we can skip calling Tcl_UtfCharComplete() here.
|
||||
*/
|
||||
int bytesInChar = Tcl_UtfToUniChar(from, &ch);
|
||||
int bytesInChar = TclUtfToUniChar(from, &ch);
|
||||
|
||||
ReverseBytes((unsigned char *)to, (unsigned char *)from,
|
||||
bytesInChar);
|
||||
|
||||
+94
-12
@@ -41,15 +41,15 @@
|
||||
#undef Tcl_FindExecutable
|
||||
#undef TclpGetPid
|
||||
#undef TclSockMinimumBuffers
|
||||
#define TclBackgroundException Tcl_BackgroundException
|
||||
#undef Tcl_SetIntObj
|
||||
#undef TclpInetNtoa
|
||||
#undef TclWinGetServByName
|
||||
#undef TclWinGetSockOpt
|
||||
#undef TclWinSetSockOpt
|
||||
#undef TclWinNToHS
|
||||
|
||||
/* See bug 510001: TclSockMinimumBuffers needs plat imp */
|
||||
#ifdef _WIN64
|
||||
#if defined(_WIN64) || defined(TCL_NO_DEPRECATED)
|
||||
# define TclSockMinimumBuffersOld 0
|
||||
#else
|
||||
#define TclSockMinimumBuffersOld sockMinimumBuffersOld
|
||||
@@ -59,6 +59,20 @@ static int TclSockMinimumBuffersOld(int sock, int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TCL_NO_DEPRECATED)
|
||||
# define TclSetStartupScriptPath 0
|
||||
# define TclGetStartupScriptPath 0
|
||||
# define TclSetStartupScriptFileName 0
|
||||
# define TclGetStartupScriptFileName 0
|
||||
# define TclpInetNtoa 0
|
||||
# define TclWinGetServByName 0
|
||||
# define TclWinGetSockOpt 0
|
||||
# define TclWinSetSockOpt 0
|
||||
# define TclWinNToHS 0
|
||||
# define TclBNInitBignumFromWideUInt 0
|
||||
# define TclBNInitBignumFromWideInt 0
|
||||
# define TclBNInitBignumFromLong 0
|
||||
#else
|
||||
#define TclSetStartupScriptPath setStartupScriptPath
|
||||
static void TclSetStartupScriptPath(Tcl_Obj *path)
|
||||
{
|
||||
@@ -92,6 +106,10 @@ static unsigned short TclWinNToHS(unsigned short ns) {
|
||||
return ntohs(ns);
|
||||
}
|
||||
#endif
|
||||
# define TclBNInitBignumFromWideUInt TclInitBignumFromWideUInt
|
||||
# define TclBNInitBignumFromWideInt TclInitBignumFromWideInt
|
||||
# define TclBNInitBignumFromLong TclInitBignumFromLong
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
#ifdef _WIN32
|
||||
# define TclUnixWaitForFile 0
|
||||
@@ -131,6 +149,7 @@ void *TclWinGetTclInstance()
|
||||
return hInstance;
|
||||
}
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#define TclWinSetSockOpt winSetSockOpt
|
||||
static int
|
||||
TclWinSetSockOpt(SOCKET s, int level, int optname,
|
||||
@@ -153,6 +172,7 @@ TclWinGetServByName(const char *name, const char *proto)
|
||||
{
|
||||
return getservbyname(name, proto);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
#define TclWinNoBackslash winNoBackslash
|
||||
static char *
|
||||
@@ -287,26 +307,79 @@ static int formatInt(char *buffer, int n){
|
||||
}
|
||||
#define TclFormatInt (int(*)(char *, long))formatInt
|
||||
|
||||
#endif
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
#else /* UNIX and MAC */
|
||||
# ifdef TCL_NO_DEPRECATED
|
||||
# define TclpLocaltime_unix 0
|
||||
# define TclpGmtime_unix 0
|
||||
# else
|
||||
# define TclpLocaltime_unix TclpLocaltime
|
||||
# define TclpGmtime_unix TclpGmtime
|
||||
# endif
|
||||
#endif
|
||||
#endif /* __CYGWIN__ */
|
||||
|
||||
#ifdef TCL_NO_DEPRECATED
|
||||
# define Tcl_SeekOld 0
|
||||
# define Tcl_TellOld 0
|
||||
# undef Tcl_SetBooleanObj
|
||||
# define Tcl_SetBooleanObj 0
|
||||
# undef Tcl_PkgPresent
|
||||
# define Tcl_PkgPresent 0
|
||||
# undef Tcl_PkgProvide
|
||||
# define Tcl_PkgProvide 0
|
||||
# undef Tcl_PkgRequire
|
||||
# define Tcl_PkgRequire 0
|
||||
# undef Tcl_GetIndexFromObj
|
||||
# define Tcl_GetIndexFromObj 0
|
||||
# define Tcl_NewBooleanObj 0
|
||||
# undef Tcl_DbNewBooleanObj
|
||||
# define Tcl_DbNewBooleanObj 0
|
||||
# undef Tcl_SetBooleanObj
|
||||
# define Tcl_SetBooleanObj 0
|
||||
# undef Tcl_SetVar
|
||||
# define Tcl_SetVar 0
|
||||
# undef Tcl_UnsetVar
|
||||
# define Tcl_UnsetVar 0
|
||||
# undef Tcl_GetVar
|
||||
# define Tcl_GetVar 0
|
||||
# undef Tcl_TraceVar
|
||||
# define Tcl_TraceVar 0
|
||||
# undef Tcl_UntraceVar
|
||||
# define Tcl_UntraceVar 0
|
||||
# undef Tcl_VarTraceInfo
|
||||
# define Tcl_VarTraceInfo 0
|
||||
# undef Tcl_UpVar
|
||||
# define Tcl_UpVar 0
|
||||
# undef Tcl_AddErrorInfo
|
||||
# define Tcl_AddErrorInfo 0
|
||||
# undef Tcl_AddObjErrorInfo
|
||||
# define Tcl_AddObjErrorInfo 0
|
||||
# undef Tcl_Eval
|
||||
# define Tcl_Eval 0
|
||||
# undef Tcl_GlobalEval
|
||||
# define Tcl_GlobalEval 0
|
||||
# undef Tcl_SaveResult
|
||||
# define Tcl_SaveResult 0
|
||||
# undef Tcl_RestoreResult
|
||||
# define Tcl_RestoreResult 0
|
||||
# undef Tcl_DiscardResult
|
||||
# define Tcl_DiscardResult 0
|
||||
# undef Tcl_SetResult
|
||||
# define Tcl_SetResult 0
|
||||
# undef Tcl_EvalObj
|
||||
# define Tcl_EvalObj 0
|
||||
# undef Tcl_GlobalEvalObj
|
||||
# define Tcl_GlobalEvalObj 0
|
||||
# define TclBackgroundException 0
|
||||
# undef TclpReaddir
|
||||
# define TclpReaddir 0
|
||||
# undef TclpGetDate
|
||||
# define TclpGetDate 0
|
||||
# undef TclpLocaltime
|
||||
# define TclpLocaltime 0
|
||||
# undef TclpGmtime
|
||||
# define TclpGmtime 0
|
||||
# define TclpLocaltime_unix 0
|
||||
# define TclpGmtime_unix 0
|
||||
#else /* TCL_NO_DEPRECATED */
|
||||
# define Tcl_SeekOld seekOld
|
||||
# define Tcl_TellOld tellOld
|
||||
# define TclBackgroundException Tcl_BackgroundException
|
||||
# define TclpLocaltime_unix TclpLocaltime
|
||||
# define TclpGmtime_unix TclpGmtime
|
||||
|
||||
static int
|
||||
seekOld(
|
||||
@@ -597,6 +670,11 @@ static const TclIntStubs tclIntStubs = {
|
||||
TclDoubleDigits, /* 249 */
|
||||
TclSetSlaveCancelFlags, /* 250 */
|
||||
TclRegisterLiteral, /* 251 */
|
||||
TclPtrGetVar, /* 252 */
|
||||
TclPtrSetVar, /* 253 */
|
||||
TclPtrIncrObjVar, /* 254 */
|
||||
TclPtrObjMakeUpvar, /* 255 */
|
||||
TclPtrUnsetVar, /* 256 */
|
||||
};
|
||||
|
||||
static const TclIntPlatStubs tclIntPlatStubs = {
|
||||
@@ -787,6 +865,10 @@ const TclTomMathStubs tclTomMathStubs = {
|
||||
TclBNInitBignumFromWideInt, /* 65 */
|
||||
TclBNInitBignumFromWideUInt, /* 66 */
|
||||
TclBN_mp_expt_d_ex, /* 67 */
|
||||
TclBN_mp_set_long_long, /* 68 */
|
||||
TclBN_mp_get_long_long, /* 69 */
|
||||
TclBN_mp_set_long, /* 70 */
|
||||
TclBN_mp_get_long, /* 71 */
|
||||
};
|
||||
|
||||
static const TclStubHooks tclStubHooks = {
|
||||
|
||||
@@ -67,7 +67,7 @@ Tcl_InitStubs(
|
||||
|
||||
if (!stubsPtr || (stubsPtr->magic != (((exact&0xff00) >= 0x900) ? magic : TCL_STUB_MAGIC))) {
|
||||
iPtr->result = (char *)"interpreter uses an incompatible stubs mechanism";
|
||||
iPtr->freeProc = TCL_STATIC;
|
||||
iPtr->freeProc = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
+137
-9
@@ -67,6 +67,18 @@ typedef struct TestAsyncHandler {
|
||||
/* Next is list of handlers. */
|
||||
} TestAsyncHandler;
|
||||
|
||||
/*
|
||||
* Start of the socket driver state structure to acces field testFlags
|
||||
*/
|
||||
|
||||
typedef struct TcpState TcpState;
|
||||
|
||||
struct TcpState {
|
||||
Tcl_Channel channel; /* Channel associated with this socket. */
|
||||
int testFlags; /* bit field for tests. Is set by testsocket
|
||||
* test procedure */
|
||||
};
|
||||
|
||||
TCL_DECLARE_MUTEX(asyncTestMutex)
|
||||
|
||||
static TestAsyncHandler *firstHandler = NULL;
|
||||
@@ -215,6 +227,9 @@ static int TestasyncCmd(ClientData dummy,
|
||||
static int TestbytestringObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int TeststringbytesObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int TestcmdinfoCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int TestcmdtokenCmd(ClientData dummy,
|
||||
@@ -364,6 +379,8 @@ static int TestChannelCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int TestChannelEventCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int TestSocketCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int TestFilesystemObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -567,6 +584,7 @@ Tcltest_Init(
|
||||
Tcl_CreateCommand(interp, "noop", NoopCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testbytestring", TestbytestringObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "teststringbytes", TeststringbytesObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
|
||||
NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testfilesystem", TestFilesystemObjCmd,
|
||||
@@ -676,6 +694,8 @@ Tcltest_Init(
|
||||
TestNumUtfCharsCmd, NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd,
|
||||
NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "testsocket", TestSocketCmd,
|
||||
NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd,
|
||||
NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "testtranslatefilename",
|
||||
@@ -1969,9 +1989,12 @@ TestencodingObjCmd(
|
||||
if (objc != 3) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
encoding = Tcl_GetEncoding(NULL, Tcl_GetString(objv[2]));
|
||||
Tcl_FreeEncoding(encoding);
|
||||
Tcl_FreeEncoding(encoding);
|
||||
if (TCL_OK != Tcl_GetEncodingFromObj(interp, objv[2], &encoding)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_FreeEncoding(encoding); /* Free returned reference */
|
||||
Tcl_FreeEncoding(encoding); /* Free to match CREATE */
|
||||
TclFreeIntRep(objv[2]); /* Free the cached ref */
|
||||
break;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -3405,7 +3428,7 @@ TestMathFunc2(
|
||||
resultPtr->type = TCL_WIDE_INT;
|
||||
resultPtr->wideValue = ((w0 > w1)? w0 : w1);
|
||||
} else {
|
||||
Tcl_SetResult(interp, (char *)"T3: wrong type for arg 2", TCL_STATIC);
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else if (args[0].type == TCL_DOUBLE) {
|
||||
@@ -3427,7 +3450,7 @@ TestMathFunc2(
|
||||
resultPtr->type = TCL_DOUBLE;
|
||||
resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
|
||||
} else {
|
||||
Tcl_SetResult(interp, (char *)"T3: wrong type for arg 2", TCL_STATIC);
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else if (args[0].type == TCL_WIDE_INT) {
|
||||
@@ -3450,11 +3473,11 @@ TestMathFunc2(
|
||||
resultPtr->type = TCL_WIDE_INT;
|
||||
resultPtr->wideValue = ((w0 > w1)? w0 : w1);
|
||||
} else {
|
||||
Tcl_SetResult(interp, (char *)"T3: wrong type for arg 2", TCL_STATIC);
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
Tcl_SetResult(interp, (char *)"T3: wrong type for arg 1", TCL_STATIC);
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 1", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
return result;
|
||||
@@ -3847,6 +3870,7 @@ TestprintObjCmd(
|
||||
Tcl_Obj *const objv[]) /* The argument objects. */
|
||||
{
|
||||
Tcl_WideInt argv1 = 0;
|
||||
size_t argv2;
|
||||
|
||||
if (objc < 2 || objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "format wideint");
|
||||
@@ -3855,7 +3879,8 @@ TestprintObjCmd(
|
||||
if (objc > 1) {
|
||||
Tcl_GetWideIntFromObj(interp, objv[2], &argv1);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(Tcl_GetString(objv[1]), argv1));
|
||||
argv2 = (size_t)argv1;
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(Tcl_GetString(objv[1]), argv1, argv2, argv2));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -5025,6 +5050,40 @@ NoopObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TeststringbytesObjCmd --
|
||||
* Returns bytearray value of the bytes in argument string rep
|
||||
*
|
||||
* Results:
|
||||
* Returns the TCL_OK result code.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
TeststringbytesObjCmd(
|
||||
ClientData unused, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* The argument objects. */
|
||||
{
|
||||
int n;
|
||||
const unsigned char *p;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "value");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
p = (const unsigned char *)Tcl_GetStringFromObj(objv[1], &n);
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(p, n));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -6076,6 +6135,75 @@ TestChannelEventCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TestSocketCmd --
|
||||
*
|
||||
* Implements the Tcl "testsocket" debugging command and its
|
||||
* subcommands. This is part of the testing environment.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
TestSocketCmd(
|
||||
ClientData clientData, /* Not used. */
|
||||
Tcl_Interp *interp, /* Interpreter for result. */
|
||||
int argc, /* Count of additional args. */
|
||||
const char **argv) /* Additional arg strings. */
|
||||
{
|
||||
const char *cmdName; /* Sub command. */
|
||||
size_t len; /* Length of subcommand string. */
|
||||
|
||||
if (argc < 2) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" subcommand ?additional args..?\"", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
cmdName = argv[1];
|
||||
len = strlen(cmdName);
|
||||
|
||||
if ((cmdName[0] == 't') && (strncmp(cmdName, "testflags", len) == 0)) {
|
||||
Tcl_Channel hChannel;
|
||||
int modePtr;
|
||||
TcpState *statePtr;
|
||||
/* Set test value in the socket driver
|
||||
*/
|
||||
/* Check for argument "channel name"
|
||||
*/
|
||||
if (argc < 4) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" testflags channel flags\"", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
hChannel = Tcl_GetChannel(interp, argv[2], &modePtr);
|
||||
if ( NULL == hChannel ) {
|
||||
Tcl_AppendResult(interp, "unknown channel:", argv[2], NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
statePtr = (TcpState *)Tcl_GetChannelInstanceData(hChannel);
|
||||
if ( NULL == statePtr) {
|
||||
Tcl_AppendResult(interp, "No channel instance data:", argv[2],
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
statePtr->testFlags = atoi(argv[3]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be "
|
||||
"testflags", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -6749,7 +6877,7 @@ TestNumUtfCharsCmd(
|
||||
int len = -1;
|
||||
|
||||
if (objc > 2) {
|
||||
(void) Tcl_GetStringFromObj(objv[1], &len);
|
||||
(void) Tcl_GetIntFromObj(interp, objv[2], &len);
|
||||
}
|
||||
len = Tcl_NumUtfChars(Tcl_GetString(objv[1]), len);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(len));
|
||||
|
||||
@@ -341,7 +341,7 @@ ThreadObjCmd(
|
||||
} else if (objc == 3
|
||||
&& strcmp("-main", Tcl_GetString(objv[2])) == 0) {
|
||||
Tcl_MutexLock(&threadMutex);
|
||||
idObj = Tcl_NewLongObj((long)(size_t)mainThreadId);
|
||||
idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)mainThreadId);
|
||||
Tcl_MutexUnlock(&threadMutex);
|
||||
} else {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, NULL);
|
||||
@@ -655,7 +655,7 @@ ThreadErrorProc(
|
||||
char *script;
|
||||
char buf[TCL_DOUBLE_SPACE+1];
|
||||
|
||||
sprintf(buf, "%" TCL_LL_MODIFIER "d", (Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
|
||||
sprintf(buf, "%p", Tcl_GetCurrentThread());
|
||||
|
||||
errorInfo = Tcl_GetVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
|
||||
if (errorProcString == NULL) {
|
||||
|
||||
+9
-3
@@ -1053,11 +1053,17 @@ AfterDelay(
|
||||
if (diff > TCL_TIME_MAXIMUM_SLICE) {
|
||||
diff = TCL_TIME_MAXIMUM_SLICE;
|
||||
}
|
||||
if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) diff = 1;
|
||||
if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) {
|
||||
diff = 1;
|
||||
}
|
||||
if (diff > 0) {
|
||||
Tcl_Sleep((long) diff);
|
||||
if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) break;
|
||||
} else break;
|
||||
if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
|
||||
+49
-36
@@ -30,13 +30,13 @@ declare 1 {
|
||||
}
|
||||
|
||||
declare 2 {
|
||||
int TclBN_mp_add(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 3 {
|
||||
int TclBN_mp_add_d(mp_int *a, mp_digit b, mp_int *c)
|
||||
int TclBN_mp_add_d(const mp_int *a, mp_digit b, mp_int *c)
|
||||
}
|
||||
declare 4 {
|
||||
int TclBN_mp_and(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_mp_and(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 5 {
|
||||
void TclBN_mp_clamp(mp_int *a)
|
||||
@@ -63,25 +63,25 @@ declare 12 {
|
||||
int TclBN_mp_count_bits(const mp_int *a)
|
||||
}
|
||||
declare 13 {
|
||||
int TclBN_mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r)
|
||||
int TclBN_mp_div(const mp_int *a, const mp_int *b, mp_int *q, mp_int *r)
|
||||
}
|
||||
declare 14 {
|
||||
int TclBN_mp_div_d(mp_int *a, mp_digit b, mp_int *q, mp_digit *r)
|
||||
int TclBN_mp_div_d(const mp_int *a, mp_digit b, mp_int *q, mp_digit *r)
|
||||
}
|
||||
declare 15 {
|
||||
int TclBN_mp_div_2(mp_int *a, mp_int *q)
|
||||
int TclBN_mp_div_2(const mp_int *a, mp_int *q)
|
||||
}
|
||||
declare 16 {
|
||||
int TclBN_mp_div_2d(const mp_int *a, int b, mp_int *q, mp_int *r)
|
||||
}
|
||||
declare 17 {
|
||||
int TclBN_mp_div_3(mp_int *a, mp_int *q, mp_digit *r)
|
||||
int TclBN_mp_div_3(const mp_int *a, mp_int *q, mp_digit *r)
|
||||
}
|
||||
declare 18 {
|
||||
void TclBN_mp_exch(mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 19 {
|
||||
int TclBN_mp_expt_d(mp_int *a, mp_digit b, mp_int *c)
|
||||
int TclBN_mp_expt_d(const mp_int *a, mp_digit b, mp_int *c)
|
||||
}
|
||||
declare 20 {
|
||||
int TclBN_mp_grow(mp_int *a, int size)
|
||||
@@ -105,19 +105,19 @@ declare 26 {
|
||||
int TclBN_mp_lshd(mp_int *a, int shift)
|
||||
}
|
||||
declare 27 {
|
||||
int TclBN_mp_mod(mp_int *a, mp_int *b, mp_int *r)
|
||||
int TclBN_mp_mod(const mp_int *a, const mp_int *b, mp_int *r)
|
||||
}
|
||||
declare 28 {
|
||||
int TclBN_mp_mod_2d(const mp_int *a, int b, mp_int *r)
|
||||
}
|
||||
declare 29 {
|
||||
int TclBN_mp_mul(mp_int *a, mp_int *b, mp_int *p)
|
||||
int TclBN_mp_mul(const mp_int *a, const mp_int *b, mp_int *p)
|
||||
}
|
||||
declare 30 {
|
||||
int TclBN_mp_mul_d(mp_int *a, mp_digit b, mp_int *p)
|
||||
int TclBN_mp_mul_d(const mp_int *a, mp_digit b, mp_int *p)
|
||||
}
|
||||
declare 31 {
|
||||
int TclBN_mp_mul_2(mp_int *a, mp_int *p)
|
||||
int TclBN_mp_mul_2(const mp_int *a, mp_int *p)
|
||||
}
|
||||
declare 32 {
|
||||
int TclBN_mp_mul_2d(const mp_int *a, int d, mp_int *p)
|
||||
@@ -126,7 +126,7 @@ declare 33 {
|
||||
int TclBN_mp_neg(const mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 34 {
|
||||
int TclBN_mp_or(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_mp_or(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 35 {
|
||||
int TclBN_mp_radix_size(const mp_int *a, int radix, int *size)
|
||||
@@ -144,32 +144,32 @@ declare 39 {
|
||||
void TclBN_mp_set(mp_int *a, mp_digit b)
|
||||
}
|
||||
declare 40 {
|
||||
int TclBN_mp_sqr(mp_int *a, mp_int *b)
|
||||
int TclBN_mp_sqr(const mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 41 {
|
||||
int TclBN_mp_sqrt(mp_int *a, mp_int *b)
|
||||
int TclBN_mp_sqrt(const mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 42 {
|
||||
int TclBN_mp_sub(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 43 {
|
||||
int TclBN_mp_sub_d(mp_int *a, mp_digit b, mp_int *c)
|
||||
int TclBN_mp_sub_d(const mp_int *a, mp_digit b, mp_int *c)
|
||||
}
|
||||
declare 44 {
|
||||
int TclBN_mp_to_unsigned_bin(mp_int *a, unsigned char *b)
|
||||
int TclBN_mp_to_unsigned_bin(const mp_int *a, unsigned char *b)
|
||||
}
|
||||
declare 45 {
|
||||
int TclBN_mp_to_unsigned_bin_n(mp_int *a, unsigned char *b,
|
||||
int TclBN_mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b,
|
||||
unsigned long *outlen)
|
||||
}
|
||||
declare 46 {
|
||||
int TclBN_mp_toradix_n(mp_int *a, char *str, int radix, int maxlen)
|
||||
int TclBN_mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen)
|
||||
}
|
||||
declare 47 {
|
||||
int TclBN_mp_unsigned_bin_size(mp_int *a)
|
||||
int TclBN_mp_unsigned_bin_size(const mp_int *a)
|
||||
}
|
||||
declare 48 {
|
||||
int TclBN_mp_xor(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_mp_xor(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 49 {
|
||||
void TclBN_mp_zero(mp_int *a)
|
||||
@@ -182,34 +182,34 @@ declare 50 {
|
||||
void TclBN_reverse(unsigned char *s, int len)
|
||||
}
|
||||
declare 51 {
|
||||
int TclBN_fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
|
||||
int TclBN_fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
|
||||
}
|
||||
declare 52 {
|
||||
int TclBN_fast_s_mp_sqr(mp_int *a, mp_int *b)
|
||||
int TclBN_fast_s_mp_sqr(const mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 53 {
|
||||
int TclBN_mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_mp_karatsuba_mul(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 54 {
|
||||
int TclBN_mp_karatsuba_sqr(mp_int *a, mp_int *b)
|
||||
int TclBN_mp_karatsuba_sqr(const mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 55 {
|
||||
int TclBN_mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_mp_toom_mul(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 56 {
|
||||
int TclBN_mp_toom_sqr(mp_int *a, mp_int *b)
|
||||
int TclBN_mp_toom_sqr(const mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 57 {
|
||||
int TclBN_s_mp_add(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_s_mp_add(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 58 {
|
||||
int TclBN_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
|
||||
int TclBN_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
|
||||
}
|
||||
declare 59 {
|
||||
int TclBN_s_mp_sqr(mp_int *a, mp_int *b)
|
||||
int TclBN_s_mp_sqr(const mp_int *a, mp_int *b)
|
||||
}
|
||||
declare 60 {
|
||||
int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c)
|
||||
int TclBN_s_mp_sub(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
}
|
||||
declare 61 {
|
||||
int TclBN_mp_init_set_int(mp_int *a, unsigned long i)
|
||||
@@ -223,19 +223,32 @@ declare 63 {
|
||||
|
||||
# Formerly internal API to allow initialisation of bignums without knowing the
|
||||
# typedefs of how a bignum works internally.
|
||||
declare 64 {
|
||||
declare 64 {deprecated {Use mp_init() + mp_set_long_long()}} {
|
||||
void TclBNInitBignumFromLong(mp_int *bignum, long initVal)
|
||||
}
|
||||
declare 65 {
|
||||
declare 65 {deprecated {Use mp_init() + mp_set_long_long()}} {
|
||||
void TclBNInitBignumFromWideInt(mp_int *bignum, Tcl_WideInt initVal)
|
||||
}
|
||||
declare 66 {
|
||||
declare 66 {deprecated {Use mp_init() + mp_set_long_long()}} {
|
||||
void TclBNInitBignumFromWideUInt(mp_int *bignum, Tcl_WideUInt initVal)
|
||||
}
|
||||
|
||||
# Added in libtommath 1.0
|
||||
declare 67 {
|
||||
int TclBN_mp_expt_d_ex(mp_int *a, mp_digit b, mp_int *c, int fast)
|
||||
int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast)
|
||||
}
|
||||
# Added in libtommath 1.0.1
|
||||
declare 68 {
|
||||
int TclBN_mp_set_long_long(mp_int *a, Tcl_WideUInt i)
|
||||
}
|
||||
declare 69 {
|
||||
Tcl_WideUInt TclBN_mp_get_long_long(const mp_int *a)
|
||||
}
|
||||
declare 70 {
|
||||
int TclBN_mp_set_long(mp_int *a, unsigned long i)
|
||||
}
|
||||
declare 71 {
|
||||
unsigned long TclBN_mp_get_long(const mp_int *a)
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
|
||||
+159
-148
@@ -27,10 +27,10 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* detect 64-bit mode if possible */
|
||||
#if defined(NEVER) /* 128-bit ints fail in too many places */
|
||||
#if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
|
||||
#define MP_64BIT
|
||||
#endif
|
||||
#if defined(NEVER) /* 128-bit ints fail in too many places */
|
||||
# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
|
||||
# define MP_64BIT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* some default configurations.
|
||||
@@ -43,89 +43,94 @@ extern "C" {
|
||||
*/
|
||||
#ifdef MP_8BIT
|
||||
#ifndef MP_DIGIT_DECLARED
|
||||
typedef uint8_t mp_digit;
|
||||
typedef uint8_t mp_digit;
|
||||
#define MP_DIGIT_DECLARED
|
||||
#endif
|
||||
typedef uint16_t mp_word;
|
||||
#define MP_SIZEOF_MP_DIGIT 1
|
||||
#ifdef DIGIT_BIT
|
||||
#error You must not define DIGIT_BIT when using MP_8BIT
|
||||
#ifndef MP_WORD_DECLARED
|
||||
typedef uint16_t mp_word;
|
||||
#define MP_WORD_DECLARED
|
||||
#endif
|
||||
# define MP_SIZEOF_MP_DIGIT 1
|
||||
# ifdef DIGIT_BIT
|
||||
# error You must not define DIGIT_BIT when using MP_8BIT
|
||||
# endif
|
||||
#elif defined(MP_16BIT)
|
||||
#ifndef MP_DIGIT_DECLARED
|
||||
typedef uint16_t mp_digit;
|
||||
typedef uint16_t mp_digit;
|
||||
#define MP_DIGIT_DECLARED
|
||||
#endif
|
||||
typedef uint32_t mp_word;
|
||||
#define MP_SIZEOF_MP_DIGIT 2
|
||||
#ifdef DIGIT_BIT
|
||||
#error You must not define DIGIT_BIT when using MP_16BIT
|
||||
#ifndef MP_WORD_DECLARED
|
||||
typedef uint32_t mp_word;
|
||||
#define MP_WORD_DECLARED
|
||||
#endif
|
||||
# define MP_SIZEOF_MP_DIGIT 2
|
||||
# ifdef DIGIT_BIT
|
||||
# error You must not define DIGIT_BIT when using MP_16BIT
|
||||
# endif
|
||||
#elif defined(MP_64BIT)
|
||||
/* for GCC only on supported platforms */
|
||||
#ifndef CRYPT
|
||||
typedef unsigned long long ulong64;
|
||||
typedef signed long long long64;
|
||||
#endif
|
||||
|
||||
/* for GCC only on supported platforms */
|
||||
#ifndef MP_DIGIT_DECLARED
|
||||
typedef ulong64 mp_digit;
|
||||
typedef uint64_t mp_digit;
|
||||
#define MP_DIGIT_DECLARED
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
typedef unsigned __int128 mp_word;
|
||||
#elif defined(__GNUC__)
|
||||
typedef unsigned long mp_word __attribute__ ((mode(TI)));
|
||||
#else
|
||||
/* it seems you have a problem
|
||||
* but we assume you can somewhere define your own uint128_t */
|
||||
typedef uint128_t mp_word;
|
||||
# if defined(_WIN32)
|
||||
#ifndef MP_WORD_DECLARED
|
||||
typedef unsigned __int128 mp_word;
|
||||
#define MP_WORD_DECLARED
|
||||
#endif
|
||||
|
||||
#define DIGIT_BIT 60
|
||||
#else
|
||||
/* this is the default case, 28-bit digits */
|
||||
|
||||
/* this is to make porting into LibTomCrypt easier :-) */
|
||||
#ifndef CRYPT
|
||||
typedef unsigned long long ulong64;
|
||||
typedef signed long long long64;
|
||||
# elif defined(__GNUC__)
|
||||
typedef unsigned long mp_word __attribute__((mode(TI)));
|
||||
# else
|
||||
/* it seems you have a problem
|
||||
* but we assume you can somewhere define your own uint128_t */
|
||||
#ifndef MP_WORD_DECLARED
|
||||
typedef uint128_t mp_word;
|
||||
#define MP_WORD_DECLARED
|
||||
#endif
|
||||
# endif
|
||||
|
||||
# define DIGIT_BIT 60
|
||||
#else
|
||||
/* this is the default case, 28-bit digits */
|
||||
|
||||
/* this is to make porting into LibTomCrypt easier :-) */
|
||||
#ifndef MP_DIGIT_DECLARED
|
||||
typedef uint32_t mp_digit;
|
||||
typedef uint32_t mp_digit;
|
||||
#define MP_DIGIT_DECLARED
|
||||
#endif
|
||||
typedef ulong64 mp_word;
|
||||
|
||||
#ifdef MP_31BIT
|
||||
/* this is an extension that uses 31-bit digits */
|
||||
#define DIGIT_BIT 31
|
||||
#else
|
||||
/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
|
||||
#define DIGIT_BIT 28
|
||||
#define MP_28BIT
|
||||
#ifndef MP_WORD_DECLARED
|
||||
typedef uint64_t mp_word;
|
||||
#define MP_WORD_DECLARED
|
||||
#endif
|
||||
|
||||
# ifdef MP_31BIT
|
||||
/* this is an extension that uses 31-bit digits */
|
||||
# define DIGIT_BIT 31
|
||||
# else
|
||||
/* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
|
||||
# define DIGIT_BIT 28
|
||||
# define MP_28BIT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
|
||||
#ifndef DIGIT_BIT
|
||||
#define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
|
||||
typedef uint_least32_t mp_min_u32;
|
||||
# define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
|
||||
typedef uint_least32_t mp_min_u32;
|
||||
#else
|
||||
typedef mp_digit mp_min_u32;
|
||||
#endif
|
||||
|
||||
/* platforms that can use a better rand function */
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
#define MP_USE_ALT_RAND 1
|
||||
typedef mp_digit mp_min_u32;
|
||||
#endif
|
||||
|
||||
/* use arc4random on platforms that support it */
|
||||
#ifdef MP_USE_ALT_RAND
|
||||
#define MP_GEN_RANDOM() arc4random()
|
||||
#else
|
||||
#define MP_GEN_RANDOM() rand()
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
# define MP_GEN_RANDOM() arc4random()
|
||||
# define MP_GEN_RANDOM_MAX 0xffffffff
|
||||
#endif
|
||||
|
||||
/* use rand() as fall-back if there's no better rand function */
|
||||
#ifndef MP_GEN_RANDOM
|
||||
# define MP_GEN_RANDOM() rand()
|
||||
# define MP_GEN_RANDOM_MAX RAND_MAX
|
||||
#endif
|
||||
|
||||
#define MP_DIGIT_BIT DIGIT_BIT
|
||||
@@ -158,9 +163,9 @@ typedef int mp_err;
|
||||
/* you'll have to tune these... */
|
||||
#if defined(BUILD_tcl) || !defined(_WIN32)
|
||||
MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
|
||||
KARATSUBA_SQR_CUTOFF,
|
||||
TOOM_MUL_CUTOFF,
|
||||
TOOM_SQR_CUTOFF;
|
||||
KARATSUBA_SQR_CUTOFF,
|
||||
TOOM_MUL_CUTOFF,
|
||||
TOOM_SQR_CUTOFF;
|
||||
#endif
|
||||
|
||||
/* define this to use lower memory usage routines (exptmods mostly) */
|
||||
@@ -168,11 +173,11 @@ MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
|
||||
|
||||
/* default precision */
|
||||
#ifndef MP_PREC
|
||||
#ifndef MP_LOW_MEM
|
||||
#define MP_PREC 32 /* default digits of precision */
|
||||
#else
|
||||
#define MP_PREC 8 /* default digits of precision */
|
||||
#endif
|
||||
# ifndef MP_LOW_MEM
|
||||
# define MP_PREC 32 /* default digits of precision */
|
||||
# else
|
||||
# define MP_PREC 8 /* default digits of precision */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
|
||||
@@ -184,17 +189,17 @@ MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
|
||||
typedef struct mp_int mp_int;
|
||||
#endif
|
||||
struct mp_int {
|
||||
int used, alloc, sign;
|
||||
mp_digit *dp;
|
||||
int used, alloc, sign;
|
||||
mp_digit *dp;
|
||||
};
|
||||
|
||||
/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
|
||||
typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
|
||||
|
||||
|
||||
#define USED(m) ((m)->used)
|
||||
#define DIGIT(m,k) ((m)->dp[(k)])
|
||||
#define SIGN(m) ((m)->sign)
|
||||
#define USED(m) ((m)->used)
|
||||
#define DIGIT(m, k) ((m)->dp[(k)])
|
||||
#define SIGN(m) ((m)->sign)
|
||||
|
||||
/* error code to char* string */
|
||||
const char *mp_error_to_string(int code);
|
||||
@@ -272,22 +277,28 @@ int mp_set_long_long(mp_int *a, unsigned long long b);
|
||||
*/
|
||||
|
||||
/* get a 32-bit value */
|
||||
unsigned long mp_get_int(mp_int * a);
|
||||
/*
|
||||
unsigned long mp_get_int(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* get a platform dependent unsigned long value */
|
||||
unsigned long mp_get_long(mp_int * a);
|
||||
/*
|
||||
unsigned long mp_get_long(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* get a platform dependent unsigned long long value */
|
||||
unsigned long long mp_get_long_long(mp_int * a);
|
||||
/*
|
||||
unsigned long long mp_get_long_long(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* initialize and set a digit */
|
||||
/*
|
||||
int mp_init_set (mp_int * a, mp_digit b);
|
||||
int mp_init_set(mp_int *a, mp_digit b);
|
||||
*/
|
||||
|
||||
/* initialize and set 32-bit value */
|
||||
/*
|
||||
int mp_init_set_int (mp_int * a, unsigned long b);
|
||||
int mp_init_set_int(mp_int *a, unsigned long b);
|
||||
*/
|
||||
|
||||
/* copy, b = a */
|
||||
@@ -307,12 +318,12 @@ void mp_clamp(mp_int *a);
|
||||
|
||||
/* import binary data */
|
||||
/*
|
||||
int mp_import(mp_int* rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op);
|
||||
int mp_import(mp_int *rop, size_t count, int order, size_t size, int endian, size_t nails, const void *op);
|
||||
*/
|
||||
|
||||
/* export binary data */
|
||||
/*
|
||||
int mp_export(void* rop, size_t* countp, int order, size_t size, int endian, size_t nails, mp_int* op);
|
||||
int mp_export(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, const mp_int *op);
|
||||
*/
|
||||
|
||||
/* ---> digit manipulation <--- */
|
||||
@@ -334,7 +345,7 @@ int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d);
|
||||
|
||||
/* b = a/2 */
|
||||
/*
|
||||
int mp_div_2(mp_int *a, mp_int *b);
|
||||
int mp_div_2(const mp_int *a, mp_int *b);
|
||||
*/
|
||||
|
||||
/* c = a * 2**b, implemented as c = a << b */
|
||||
@@ -344,7 +355,7 @@ int mp_mul_2d(const mp_int *a, int b, mp_int *c);
|
||||
|
||||
/* b = a*2 */
|
||||
/*
|
||||
int mp_mul_2(mp_int *a, mp_int *b);
|
||||
int mp_mul_2(const mp_int *a, mp_int *b);
|
||||
*/
|
||||
|
||||
/* c = a mod 2**b */
|
||||
@@ -372,17 +383,17 @@ int mp_rand(mp_int *a, int digits);
|
||||
/* ---> binary operations <--- */
|
||||
/* c = a XOR b */
|
||||
/*
|
||||
int mp_xor(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_xor(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = a OR b */
|
||||
/*
|
||||
int mp_or(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_or(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = a AND b */
|
||||
/*
|
||||
int mp_and(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_and(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* ---> Basic arithmetic <--- */
|
||||
@@ -394,7 +405,7 @@ int mp_neg(const mp_int *a, mp_int *b);
|
||||
|
||||
/* b = |a| */
|
||||
/*
|
||||
int mp_abs(mp_int *a, mp_int *b);
|
||||
int mp_abs(const mp_int *a, mp_int *b);
|
||||
*/
|
||||
|
||||
/* compare a to b */
|
||||
@@ -409,32 +420,32 @@ int mp_cmp_mag(const mp_int *a, const mp_int *b);
|
||||
|
||||
/* c = a + b */
|
||||
/*
|
||||
int mp_add(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_add(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = a - b */
|
||||
/*
|
||||
int mp_sub(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_sub(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = a * b */
|
||||
/*
|
||||
int mp_mul(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_mul(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* b = a*a */
|
||||
/*
|
||||
int mp_sqr(mp_int *a, mp_int *b);
|
||||
int mp_sqr(const mp_int *a, mp_int *b);
|
||||
*/
|
||||
|
||||
/* a/b => cb + d == a */
|
||||
/*
|
||||
int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
|
||||
int mp_div(const mp_int *a, const mp_int *b, mp_int *c, mp_int *d);
|
||||
*/
|
||||
|
||||
/* c = a mod b, 0 <= c < b */
|
||||
/*
|
||||
int mp_mod(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_mod(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* ---> single digit functions <--- */
|
||||
@@ -446,82 +457,82 @@ int mp_cmp_d(const mp_int *a, mp_digit b);
|
||||
|
||||
/* c = a + b */
|
||||
/*
|
||||
int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
int mp_add_d(const mp_int *a, mp_digit b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = a - b */
|
||||
/*
|
||||
int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
int mp_sub_d(const mp_int *a, mp_digit b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = a * b */
|
||||
/*
|
||||
int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
int mp_mul_d(const mp_int *a, mp_digit b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* a/b => cb + d == a */
|
||||
/*
|
||||
int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
|
||||
int mp_div_d(const mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
|
||||
*/
|
||||
|
||||
/* a/3 => 3c + d == a */
|
||||
/*
|
||||
int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
|
||||
int mp_div_3(const mp_int *a, mp_int *c, mp_digit *d);
|
||||
*/
|
||||
|
||||
/* c = a**b */
|
||||
/*
|
||||
int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
int mp_expt_d(const mp_int *a, mp_digit b, mp_int *c);
|
||||
*/
|
||||
/*
|
||||
int mp_expt_d_ex (mp_int * a, mp_digit b, mp_int * c, int fast);
|
||||
int mp_expt_d_ex(const mp_int *a, mp_digit b, mp_int *c, int fast);
|
||||
*/
|
||||
|
||||
/* c = a mod b, 0 <= c < b */
|
||||
/*
|
||||
int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
|
||||
int mp_mod_d(const mp_int *a, mp_digit b, mp_digit *c);
|
||||
*/
|
||||
|
||||
/* ---> number theory <--- */
|
||||
|
||||
/* d = a + b (mod c) */
|
||||
/*
|
||||
int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
|
||||
int mp_addmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
|
||||
*/
|
||||
|
||||
/* d = a - b (mod c) */
|
||||
/*
|
||||
int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
|
||||
int mp_submod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
|
||||
*/
|
||||
|
||||
/* d = a * b (mod c) */
|
||||
/*
|
||||
int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
|
||||
int mp_mulmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
|
||||
*/
|
||||
|
||||
/* c = a * a (mod b) */
|
||||
/*
|
||||
int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_sqrmod(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = 1/a (mod b) */
|
||||
/*
|
||||
int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_invmod(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* c = (a, b) */
|
||||
/*
|
||||
int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_gcd(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* produces value such that U1*a + U2*b = U3 */
|
||||
/*
|
||||
int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
|
||||
int mp_exteuclid(const mp_int *a, const mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
|
||||
*/
|
||||
|
||||
/* c = [a, b] or (a*b)/(a, b) */
|
||||
/*
|
||||
int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_lcm(const mp_int *a, const mp_int *b, mp_int *c);
|
||||
*/
|
||||
|
||||
/* finds one of the b'th root of a, such that |c|**b <= |a|
|
||||
@@ -529,35 +540,35 @@ int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
|
||||
* returns error if a < 0 and b is even
|
||||
*/
|
||||
/*
|
||||
int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
|
||||
int mp_n_root(const mp_int *a, mp_digit b, mp_int *c);
|
||||
*/
|
||||
/*
|
||||
int mp_n_root_ex (mp_int * a, mp_digit b, mp_int * c, int fast);
|
||||
int mp_n_root_ex(const mp_int *a, mp_digit b, mp_int *c, int fast);
|
||||
*/
|
||||
|
||||
/* special sqrt algo */
|
||||
/*
|
||||
int mp_sqrt(mp_int *arg, mp_int *ret);
|
||||
int mp_sqrt(const mp_int *arg, mp_int *ret);
|
||||
*/
|
||||
|
||||
/* special sqrt (mod prime) */
|
||||
/*
|
||||
int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret);
|
||||
int mp_sqrtmod_prime(const mp_int *arg, const mp_int *prime, mp_int *ret);
|
||||
*/
|
||||
|
||||
/* is number a square? */
|
||||
/*
|
||||
int mp_is_square(mp_int *arg, int *ret);
|
||||
int mp_is_square(const mp_int *arg, int *ret);
|
||||
*/
|
||||
|
||||
/* computes the jacobi c = (a | n) (or Legendre if b is prime) */
|
||||
/*
|
||||
int mp_jacobi(mp_int *a, mp_int *n, int *c);
|
||||
int mp_jacobi(const mp_int *a, const mp_int *n, int *c);
|
||||
*/
|
||||
|
||||
/* used to setup the Barrett reduction for a given modulus b */
|
||||
/*
|
||||
int mp_reduce_setup(mp_int *a, mp_int *b);
|
||||
int mp_reduce_setup(mp_int *a, const mp_int *b);
|
||||
*/
|
||||
|
||||
/* Barrett Reduction, computes a (mod b) with a precomputed value c
|
||||
@@ -566,83 +577,83 @@ int mp_reduce_setup(mp_int *a, mp_int *b);
|
||||
* compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
|
||||
*/
|
||||
/*
|
||||
int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
|
||||
int mp_reduce(mp_int *a, const mp_int *b, const mp_int *c);
|
||||
*/
|
||||
|
||||
/* setups the montgomery reduction */
|
||||
/*
|
||||
int mp_montgomery_setup(mp_int *a, mp_digit *mp);
|
||||
int mp_montgomery_setup(const mp_int *a, mp_digit *mp);
|
||||
*/
|
||||
|
||||
/* computes a = B**n mod b without division or multiplication useful for
|
||||
* normalizing numbers in a Montgomery system.
|
||||
*/
|
||||
/*
|
||||
int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
|
||||
int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b);
|
||||
*/
|
||||
|
||||
/* computes x/R == x (mod N) via Montgomery Reduction */
|
||||
/*
|
||||
int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
|
||||
int mp_montgomery_reduce(mp_int *a, const mp_int *m, mp_digit mp);
|
||||
*/
|
||||
|
||||
/* returns 1 if a is a valid DR modulus */
|
||||
/*
|
||||
int mp_dr_is_modulus(mp_int *a);
|
||||
int mp_dr_is_modulus(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* sets the value of "d" required for mp_dr_reduce */
|
||||
/*
|
||||
void mp_dr_setup(mp_int *a, mp_digit *d);
|
||||
void mp_dr_setup(const mp_int *a, mp_digit *d);
|
||||
*/
|
||||
|
||||
/* reduces a modulo b using the Diminished Radix method */
|
||||
/*
|
||||
int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
|
||||
int mp_dr_reduce(mp_int *a, const mp_int *b, mp_digit mp);
|
||||
*/
|
||||
|
||||
/* returns true if a can be reduced with mp_reduce_2k */
|
||||
/*
|
||||
int mp_reduce_is_2k(mp_int *a);
|
||||
int mp_reduce_is_2k(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* determines k value for 2k reduction */
|
||||
/*
|
||||
int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
|
||||
int mp_reduce_2k_setup(const mp_int *a, mp_digit *d);
|
||||
*/
|
||||
|
||||
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
|
||||
/*
|
||||
int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
|
||||
int mp_reduce_2k(mp_int *a, const mp_int *n, mp_digit d);
|
||||
*/
|
||||
|
||||
/* returns true if a can be reduced with mp_reduce_2k_l */
|
||||
/*
|
||||
int mp_reduce_is_2k_l(mp_int *a);
|
||||
int mp_reduce_is_2k_l(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* determines k value for 2k reduction */
|
||||
/*
|
||||
int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
|
||||
int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d);
|
||||
*/
|
||||
|
||||
/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
|
||||
/*
|
||||
int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
|
||||
int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d);
|
||||
*/
|
||||
|
||||
/* d = a**b (mod c) */
|
||||
/*
|
||||
int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
|
||||
int mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
|
||||
*/
|
||||
|
||||
/* ---> Primes <--- */
|
||||
|
||||
/* number of primes */
|
||||
#ifdef MP_8BIT
|
||||
# define PRIME_SIZE 31
|
||||
# define PRIME_SIZE 31
|
||||
#else
|
||||
# define PRIME_SIZE 256
|
||||
# define PRIME_SIZE 256
|
||||
#endif
|
||||
|
||||
/* table of first PRIME_SIZE primes */
|
||||
@@ -652,21 +663,21 @@ MODULE_SCOPE const mp_digit ltm_prime_tab[PRIME_SIZE];
|
||||
|
||||
/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
|
||||
/*
|
||||
int mp_prime_is_divisible(mp_int *a, int *result);
|
||||
int mp_prime_is_divisible(const mp_int *a, int *result);
|
||||
*/
|
||||
|
||||
/* performs one Fermat test of "a" using base "b".
|
||||
* Sets result to 0 if composite or 1 if probable prime
|
||||
*/
|
||||
/*
|
||||
int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
|
||||
int mp_prime_fermat(const mp_int *a, const mp_int *b, int *result);
|
||||
*/
|
||||
|
||||
/* performs one Miller-Rabin test of "a" using base "b".
|
||||
* Sets result to 0 if composite or 1 if probable prime
|
||||
*/
|
||||
/*
|
||||
int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
|
||||
int mp_prime_miller_rabin(const mp_int *a, const mp_int *b, int *result);
|
||||
*/
|
||||
|
||||
/* This gives [for a given bit size] the number of trials required
|
||||
@@ -684,7 +695,7 @@ int mp_prime_rabin_miller_trials(int size);
|
||||
* Sets result to 1 if probably prime, 0 otherwise
|
||||
*/
|
||||
/*
|
||||
int mp_prime_is_prime(mp_int *a, int t, int *result);
|
||||
int mp_prime_is_prime(const mp_int *a, int t, int *result);
|
||||
*/
|
||||
|
||||
/* finds the next prime after the number "a" using "t" trials
|
||||
@@ -730,39 +741,39 @@ int mp_count_bits(const mp_int *a);
|
||||
*/
|
||||
|
||||
/*
|
||||
int mp_unsigned_bin_size(mp_int *a);
|
||||
int mp_unsigned_bin_size(const mp_int *a);
|
||||
*/
|
||||
/*
|
||||
int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
|
||||
*/
|
||||
/*
|
||||
int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
|
||||
int mp_to_unsigned_bin(const mp_int *a, unsigned char *b);
|
||||
*/
|
||||
/*
|
||||
int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
|
||||
int mp_to_unsigned_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen);
|
||||
*/
|
||||
|
||||
/*
|
||||
int mp_signed_bin_size(mp_int *a);
|
||||
int mp_signed_bin_size(const mp_int *a);
|
||||
*/
|
||||
/*
|
||||
int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
|
||||
*/
|
||||
/*
|
||||
int mp_to_signed_bin(mp_int *a, unsigned char *b);
|
||||
int mp_to_signed_bin(const mp_int *a, unsigned char *b);
|
||||
*/
|
||||
/*
|
||||
int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
|
||||
int mp_to_signed_bin_n(const mp_int *a, unsigned char *b, unsigned long *outlen);
|
||||
*/
|
||||
|
||||
/*
|
||||
int mp_read_radix(mp_int *a, const char *str, int radix);
|
||||
*/
|
||||
/*
|
||||
int mp_toradix(mp_int *a, char *str, int radix);
|
||||
int mp_toradix(const mp_int *a, char *str, int radix);
|
||||
*/
|
||||
/*
|
||||
int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
|
||||
int mp_toradix_n(const mp_int *a, char *str, int radix, int maxlen);
|
||||
*/
|
||||
/*
|
||||
int mp_radix_size(const mp_int *a, int radix, int *size);
|
||||
@@ -773,7 +784,7 @@ int mp_radix_size(const mp_int *a, int radix, int *size);
|
||||
int mp_fread(mp_int *a, int radix, FILE *stream);
|
||||
*/
|
||||
/*
|
||||
int mp_fwrite(mp_int *a, int radix, FILE *stream);
|
||||
int mp_fwrite(const mp_int *a, int radix, FILE *stream);
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -790,13 +801,13 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream);
|
||||
#define mp_tohex(M, S) mp_toradix((M), (S), 16)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
/* ref: $Format:%D$ */
|
||||
/* git commit: $Format:%H$ */
|
||||
/* commit time: $Format:%ai$ */
|
||||
|
||||
|
||||
+123
-79
@@ -74,6 +74,9 @@
|
||||
#define mp_exch TclBN_mp_exch
|
||||
#define mp_expt_d TclBN_mp_expt_d
|
||||
#define mp_expt_d_ex TclBN_mp_expt_d_ex
|
||||
#define mp_get_int TclBN_mp_get_int
|
||||
#define mp_get_long TclBN_mp_get_long
|
||||
#define mp_get_long_long TclBN_mp_get_long_long
|
||||
#define mp_grow TclBN_mp_grow
|
||||
#define mp_init TclBN_mp_init
|
||||
#define mp_init_copy TclBN_mp_init_copy
|
||||
@@ -98,6 +101,8 @@
|
||||
#define mp_s_rmap TclBNMpSRmap
|
||||
#define mp_set TclBN_mp_set
|
||||
#define mp_set_int TclBN_mp_set_int
|
||||
#define mp_set_long TclBN_mp_set_long
|
||||
#define mp_set_long_long TclBN_mp_set_long_long
|
||||
#define mp_shrink TclBN_mp_shrink
|
||||
#define mp_sqr TclBN_mp_sqr
|
||||
#define mp_sqrt TclBN_mp_sqrt
|
||||
@@ -148,11 +153,14 @@ EXTERN int TclBN_epoch(void);
|
||||
/* 1 */
|
||||
EXTERN int TclBN_revision(void);
|
||||
/* 2 */
|
||||
EXTERN int TclBN_mp_add(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_mp_add(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 3 */
|
||||
EXTERN int TclBN_mp_add_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
EXTERN int TclBN_mp_add_d(const mp_int *a, mp_digit b,
|
||||
mp_int *c);
|
||||
/* 4 */
|
||||
EXTERN int TclBN_mp_and(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_mp_and(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 5 */
|
||||
EXTERN void TclBN_mp_clamp(mp_int *a);
|
||||
/* 6 */
|
||||
@@ -170,22 +178,24 @@ EXTERN int TclBN_mp_copy(const mp_int *a, mp_int *b);
|
||||
/* 12 */
|
||||
EXTERN int TclBN_mp_count_bits(const mp_int *a);
|
||||
/* 13 */
|
||||
EXTERN int TclBN_mp_div(mp_int *a, mp_int *b, mp_int *q,
|
||||
mp_int *r);
|
||||
EXTERN int TclBN_mp_div(const mp_int *a, const mp_int *b,
|
||||
mp_int *q, mp_int *r);
|
||||
/* 14 */
|
||||
EXTERN int TclBN_mp_div_d(mp_int *a, mp_digit b, mp_int *q,
|
||||
mp_digit *r);
|
||||
EXTERN int TclBN_mp_div_d(const mp_int *a, mp_digit b,
|
||||
mp_int *q, mp_digit *r);
|
||||
/* 15 */
|
||||
EXTERN int TclBN_mp_div_2(mp_int *a, mp_int *q);
|
||||
EXTERN int TclBN_mp_div_2(const mp_int *a, mp_int *q);
|
||||
/* 16 */
|
||||
EXTERN int TclBN_mp_div_2d(const mp_int *a, int b, mp_int *q,
|
||||
mp_int *r);
|
||||
/* 17 */
|
||||
EXTERN int TclBN_mp_div_3(mp_int *a, mp_int *q, mp_digit *r);
|
||||
EXTERN int TclBN_mp_div_3(const mp_int *a, mp_int *q,
|
||||
mp_digit *r);
|
||||
/* 18 */
|
||||
EXTERN void TclBN_mp_exch(mp_int *a, mp_int *b);
|
||||
/* 19 */
|
||||
EXTERN int TclBN_mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
EXTERN int TclBN_mp_expt_d(const mp_int *a, mp_digit b,
|
||||
mp_int *c);
|
||||
/* 20 */
|
||||
EXTERN int TclBN_mp_grow(mp_int *a, int size);
|
||||
/* 21 */
|
||||
@@ -201,21 +211,25 @@ EXTERN int TclBN_mp_init_size(mp_int *a, int size);
|
||||
/* 26 */
|
||||
EXTERN int TclBN_mp_lshd(mp_int *a, int shift);
|
||||
/* 27 */
|
||||
EXTERN int TclBN_mp_mod(mp_int *a, mp_int *b, mp_int *r);
|
||||
EXTERN int TclBN_mp_mod(const mp_int *a, const mp_int *b,
|
||||
mp_int *r);
|
||||
/* 28 */
|
||||
EXTERN int TclBN_mp_mod_2d(const mp_int *a, int b, mp_int *r);
|
||||
/* 29 */
|
||||
EXTERN int TclBN_mp_mul(mp_int *a, mp_int *b, mp_int *p);
|
||||
EXTERN int TclBN_mp_mul(const mp_int *a, const mp_int *b,
|
||||
mp_int *p);
|
||||
/* 30 */
|
||||
EXTERN int TclBN_mp_mul_d(mp_int *a, mp_digit b, mp_int *p);
|
||||
EXTERN int TclBN_mp_mul_d(const mp_int *a, mp_digit b,
|
||||
mp_int *p);
|
||||
/* 31 */
|
||||
EXTERN int TclBN_mp_mul_2(mp_int *a, mp_int *p);
|
||||
EXTERN int TclBN_mp_mul_2(const mp_int *a, mp_int *p);
|
||||
/* 32 */
|
||||
EXTERN int TclBN_mp_mul_2d(const mp_int *a, int d, mp_int *p);
|
||||
/* 33 */
|
||||
EXTERN int TclBN_mp_neg(const mp_int *a, mp_int *b);
|
||||
/* 34 */
|
||||
EXTERN int TclBN_mp_or(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_mp_or(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 35 */
|
||||
EXTERN int TclBN_mp_radix_size(const mp_int *a, int radix,
|
||||
int *size);
|
||||
@@ -229,52 +243,59 @@ EXTERN int TclBN_mp_shrink(mp_int *a);
|
||||
/* 39 */
|
||||
EXTERN void TclBN_mp_set(mp_int *a, mp_digit b);
|
||||
/* 40 */
|
||||
EXTERN int TclBN_mp_sqr(mp_int *a, mp_int *b);
|
||||
EXTERN int TclBN_mp_sqr(const mp_int *a, mp_int *b);
|
||||
/* 41 */
|
||||
EXTERN int TclBN_mp_sqrt(mp_int *a, mp_int *b);
|
||||
EXTERN int TclBN_mp_sqrt(const mp_int *a, mp_int *b);
|
||||
/* 42 */
|
||||
EXTERN int TclBN_mp_sub(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_mp_sub(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 43 */
|
||||
EXTERN int TclBN_mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
|
||||
EXTERN int TclBN_mp_sub_d(const mp_int *a, mp_digit b,
|
||||
mp_int *c);
|
||||
/* 44 */
|
||||
EXTERN int TclBN_mp_to_unsigned_bin(mp_int *a, unsigned char *b);
|
||||
EXTERN int TclBN_mp_to_unsigned_bin(const mp_int *a,
|
||||
unsigned char *b);
|
||||
/* 45 */
|
||||
EXTERN int TclBN_mp_to_unsigned_bin_n(mp_int *a,
|
||||
EXTERN int TclBN_mp_to_unsigned_bin_n(const mp_int *a,
|
||||
unsigned char *b, unsigned long *outlen);
|
||||
/* 46 */
|
||||
EXTERN int TclBN_mp_toradix_n(mp_int *a, char *str, int radix,
|
||||
int maxlen);
|
||||
EXTERN int TclBN_mp_toradix_n(const mp_int *a, char *str,
|
||||
int radix, int maxlen);
|
||||
/* 47 */
|
||||
EXTERN int TclBN_mp_unsigned_bin_size(mp_int *a);
|
||||
EXTERN int TclBN_mp_unsigned_bin_size(const mp_int *a);
|
||||
/* 48 */
|
||||
EXTERN int TclBN_mp_xor(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_mp_xor(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 49 */
|
||||
EXTERN void TclBN_mp_zero(mp_int *a);
|
||||
/* 50 */
|
||||
EXTERN void TclBN_reverse(unsigned char *s, int len);
|
||||
/* 51 */
|
||||
EXTERN int TclBN_fast_s_mp_mul_digs(mp_int *a, mp_int *b,
|
||||
mp_int *c, int digs);
|
||||
EXTERN int TclBN_fast_s_mp_mul_digs(const mp_int *a,
|
||||
const mp_int *b, mp_int *c, int digs);
|
||||
/* 52 */
|
||||
EXTERN int TclBN_fast_s_mp_sqr(mp_int *a, mp_int *b);
|
||||
EXTERN int TclBN_fast_s_mp_sqr(const mp_int *a, mp_int *b);
|
||||
/* 53 */
|
||||
EXTERN int TclBN_mp_karatsuba_mul(mp_int *a, mp_int *b,
|
||||
mp_int *c);
|
||||
EXTERN int TclBN_mp_karatsuba_mul(const mp_int *a,
|
||||
const mp_int *b, mp_int *c);
|
||||
/* 54 */
|
||||
EXTERN int TclBN_mp_karatsuba_sqr(mp_int *a, mp_int *b);
|
||||
EXTERN int TclBN_mp_karatsuba_sqr(const mp_int *a, mp_int *b);
|
||||
/* 55 */
|
||||
EXTERN int TclBN_mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_mp_toom_mul(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 56 */
|
||||
EXTERN int TclBN_mp_toom_sqr(mp_int *a, mp_int *b);
|
||||
EXTERN int TclBN_mp_toom_sqr(const mp_int *a, mp_int *b);
|
||||
/* 57 */
|
||||
EXTERN int TclBN_s_mp_add(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_s_mp_add(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 58 */
|
||||
EXTERN int TclBN_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c,
|
||||
int digs);
|
||||
EXTERN int TclBN_s_mp_mul_digs(const mp_int *a, const mp_int *b,
|
||||
mp_int *c, int digs);
|
||||
/* 59 */
|
||||
EXTERN int TclBN_s_mp_sqr(mp_int *a, mp_int *b);
|
||||
EXTERN int TclBN_s_mp_sqr(const mp_int *a, mp_int *b);
|
||||
/* 60 */
|
||||
EXTERN int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
|
||||
EXTERN int TclBN_s_mp_sub(const mp_int *a, const mp_int *b,
|
||||
mp_int *c);
|
||||
/* 61 */
|
||||
EXTERN int TclBN_mp_init_set_int(mp_int *a, unsigned long i);
|
||||
/* 62 */
|
||||
@@ -282,16 +303,27 @@ EXTERN int TclBN_mp_set_int(mp_int *a, unsigned long i);
|
||||
/* 63 */
|
||||
EXTERN int TclBN_mp_cnt_lsb(const mp_int *a);
|
||||
/* 64 */
|
||||
EXTERN void TclBNInitBignumFromLong(mp_int *bignum, long initVal);
|
||||
TCL_DEPRECATED("Use mp_init() + mp_set_long_long()")
|
||||
void TclBNInitBignumFromLong(mp_int *bignum, long initVal);
|
||||
/* 65 */
|
||||
EXTERN void TclBNInitBignumFromWideInt(mp_int *bignum,
|
||||
TCL_DEPRECATED("Use mp_init() + mp_set_long_long()")
|
||||
void TclBNInitBignumFromWideInt(mp_int *bignum,
|
||||
Tcl_WideInt initVal);
|
||||
/* 66 */
|
||||
EXTERN void TclBNInitBignumFromWideUInt(mp_int *bignum,
|
||||
TCL_DEPRECATED("Use mp_init() + mp_set_long_long()")
|
||||
void TclBNInitBignumFromWideUInt(mp_int *bignum,
|
||||
Tcl_WideUInt initVal);
|
||||
/* 67 */
|
||||
EXTERN int TclBN_mp_expt_d_ex(mp_int *a, mp_digit b, mp_int *c,
|
||||
int fast);
|
||||
EXTERN int TclBN_mp_expt_d_ex(const mp_int *a, mp_digit b,
|
||||
mp_int *c, int fast);
|
||||
/* 68 */
|
||||
EXTERN int TclBN_mp_set_long_long(mp_int *a, Tcl_WideUInt i);
|
||||
/* 69 */
|
||||
EXTERN Tcl_WideUInt TclBN_mp_get_long_long(const mp_int *a);
|
||||
/* 70 */
|
||||
EXTERN int TclBN_mp_set_long(mp_int *a, unsigned long i);
|
||||
/* 71 */
|
||||
EXTERN unsigned long TclBN_mp_get_long(const mp_int *a);
|
||||
|
||||
typedef struct TclTomMathStubs {
|
||||
int magic;
|
||||
@@ -299,9 +331,9 @@ typedef struct TclTomMathStubs {
|
||||
|
||||
int (*tclBN_epoch) (void); /* 0 */
|
||||
int (*tclBN_revision) (void); /* 1 */
|
||||
int (*tclBN_mp_add) (mp_int *a, mp_int *b, mp_int *c); /* 2 */
|
||||
int (*tclBN_mp_add_d) (mp_int *a, mp_digit b, mp_int *c); /* 3 */
|
||||
int (*tclBN_mp_and) (mp_int *a, mp_int *b, mp_int *c); /* 4 */
|
||||
int (*tclBN_mp_add) (const mp_int *a, const mp_int *b, mp_int *c); /* 2 */
|
||||
int (*tclBN_mp_add_d) (const mp_int *a, mp_digit b, mp_int *c); /* 3 */
|
||||
int (*tclBN_mp_and) (const mp_int *a, const mp_int *b, mp_int *c); /* 4 */
|
||||
void (*tclBN_mp_clamp) (mp_int *a); /* 5 */
|
||||
void (*tclBN_mp_clear) (mp_int *a); /* 6 */
|
||||
void (*tclBN_mp_clear_multi) (mp_int *a, ...); /* 7 */
|
||||
@@ -310,13 +342,13 @@ typedef struct TclTomMathStubs {
|
||||
int (*tclBN_mp_cmp_mag) (const mp_int *a, const mp_int *b); /* 10 */
|
||||
int (*tclBN_mp_copy) (const mp_int *a, mp_int *b); /* 11 */
|
||||
int (*tclBN_mp_count_bits) (const mp_int *a); /* 12 */
|
||||
int (*tclBN_mp_div) (mp_int *a, mp_int *b, mp_int *q, mp_int *r); /* 13 */
|
||||
int (*tclBN_mp_div_d) (mp_int *a, mp_digit b, mp_int *q, mp_digit *r); /* 14 */
|
||||
int (*tclBN_mp_div_2) (mp_int *a, mp_int *q); /* 15 */
|
||||
int (*tclBN_mp_div) (const mp_int *a, const mp_int *b, mp_int *q, mp_int *r); /* 13 */
|
||||
int (*tclBN_mp_div_d) (const mp_int *a, mp_digit b, mp_int *q, mp_digit *r); /* 14 */
|
||||
int (*tclBN_mp_div_2) (const mp_int *a, mp_int *q); /* 15 */
|
||||
int (*tclBN_mp_div_2d) (const mp_int *a, int b, mp_int *q, mp_int *r); /* 16 */
|
||||
int (*tclBN_mp_div_3) (mp_int *a, mp_int *q, mp_digit *r); /* 17 */
|
||||
int (*tclBN_mp_div_3) (const mp_int *a, mp_int *q, mp_digit *r); /* 17 */
|
||||
void (*tclBN_mp_exch) (mp_int *a, mp_int *b); /* 18 */
|
||||
int (*tclBN_mp_expt_d) (mp_int *a, mp_digit b, mp_int *c); /* 19 */
|
||||
int (*tclBN_mp_expt_d) (const mp_int *a, mp_digit b, mp_int *c); /* 19 */
|
||||
int (*tclBN_mp_grow) (mp_int *a, int size); /* 20 */
|
||||
int (*tclBN_mp_init) (mp_int *a); /* 21 */
|
||||
int (*tclBN_mp_init_copy) (mp_int *a, const mp_int *b); /* 22 */
|
||||
@@ -324,47 +356,51 @@ typedef struct TclTomMathStubs {
|
||||
int (*tclBN_mp_init_set) (mp_int *a, mp_digit b); /* 24 */
|
||||
int (*tclBN_mp_init_size) (mp_int *a, int size); /* 25 */
|
||||
int (*tclBN_mp_lshd) (mp_int *a, int shift); /* 26 */
|
||||
int (*tclBN_mp_mod) (mp_int *a, mp_int *b, mp_int *r); /* 27 */
|
||||
int (*tclBN_mp_mod) (const mp_int *a, const mp_int *b, mp_int *r); /* 27 */
|
||||
int (*tclBN_mp_mod_2d) (const mp_int *a, int b, mp_int *r); /* 28 */
|
||||
int (*tclBN_mp_mul) (mp_int *a, mp_int *b, mp_int *p); /* 29 */
|
||||
int (*tclBN_mp_mul_d) (mp_int *a, mp_digit b, mp_int *p); /* 30 */
|
||||
int (*tclBN_mp_mul_2) (mp_int *a, mp_int *p); /* 31 */
|
||||
int (*tclBN_mp_mul) (const mp_int *a, const mp_int *b, mp_int *p); /* 29 */
|
||||
int (*tclBN_mp_mul_d) (const mp_int *a, mp_digit b, mp_int *p); /* 30 */
|
||||
int (*tclBN_mp_mul_2) (const mp_int *a, mp_int *p); /* 31 */
|
||||
int (*tclBN_mp_mul_2d) (const mp_int *a, int d, mp_int *p); /* 32 */
|
||||
int (*tclBN_mp_neg) (const mp_int *a, mp_int *b); /* 33 */
|
||||
int (*tclBN_mp_or) (mp_int *a, mp_int *b, mp_int *c); /* 34 */
|
||||
int (*tclBN_mp_or) (const mp_int *a, const mp_int *b, mp_int *c); /* 34 */
|
||||
int (*tclBN_mp_radix_size) (const mp_int *a, int radix, int *size); /* 35 */
|
||||
int (*tclBN_mp_read_radix) (mp_int *a, const char *str, int radix); /* 36 */
|
||||
void (*tclBN_mp_rshd) (mp_int *a, int shift); /* 37 */
|
||||
int (*tclBN_mp_shrink) (mp_int *a); /* 38 */
|
||||
void (*tclBN_mp_set) (mp_int *a, mp_digit b); /* 39 */
|
||||
int (*tclBN_mp_sqr) (mp_int *a, mp_int *b); /* 40 */
|
||||
int (*tclBN_mp_sqrt) (mp_int *a, mp_int *b); /* 41 */
|
||||
int (*tclBN_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 42 */
|
||||
int (*tclBN_mp_sub_d) (mp_int *a, mp_digit b, mp_int *c); /* 43 */
|
||||
int (*tclBN_mp_to_unsigned_bin) (mp_int *a, unsigned char *b); /* 44 */
|
||||
int (*tclBN_mp_to_unsigned_bin_n) (mp_int *a, unsigned char *b, unsigned long *outlen); /* 45 */
|
||||
int (*tclBN_mp_toradix_n) (mp_int *a, char *str, int radix, int maxlen); /* 46 */
|
||||
int (*tclBN_mp_unsigned_bin_size) (mp_int *a); /* 47 */
|
||||
int (*tclBN_mp_xor) (mp_int *a, mp_int *b, mp_int *c); /* 48 */
|
||||
int (*tclBN_mp_sqr) (const mp_int *a, mp_int *b); /* 40 */
|
||||
int (*tclBN_mp_sqrt) (const mp_int *a, mp_int *b); /* 41 */
|
||||
int (*tclBN_mp_sub) (const mp_int *a, const mp_int *b, mp_int *c); /* 42 */
|
||||
int (*tclBN_mp_sub_d) (const mp_int *a, mp_digit b, mp_int *c); /* 43 */
|
||||
int (*tclBN_mp_to_unsigned_bin) (const mp_int *a, unsigned char *b); /* 44 */
|
||||
int (*tclBN_mp_to_unsigned_bin_n) (const mp_int *a, unsigned char *b, unsigned long *outlen); /* 45 */
|
||||
int (*tclBN_mp_toradix_n) (const mp_int *a, char *str, int radix, int maxlen); /* 46 */
|
||||
int (*tclBN_mp_unsigned_bin_size) (const mp_int *a); /* 47 */
|
||||
int (*tclBN_mp_xor) (const mp_int *a, const mp_int *b, mp_int *c); /* 48 */
|
||||
void (*tclBN_mp_zero) (mp_int *a); /* 49 */
|
||||
void (*tclBN_reverse) (unsigned char *s, int len); /* 50 */
|
||||
int (*tclBN_fast_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 51 */
|
||||
int (*tclBN_fast_s_mp_sqr) (mp_int *a, mp_int *b); /* 52 */
|
||||
int (*tclBN_mp_karatsuba_mul) (mp_int *a, mp_int *b, mp_int *c); /* 53 */
|
||||
int (*tclBN_mp_karatsuba_sqr) (mp_int *a, mp_int *b); /* 54 */
|
||||
int (*tclBN_mp_toom_mul) (mp_int *a, mp_int *b, mp_int *c); /* 55 */
|
||||
int (*tclBN_mp_toom_sqr) (mp_int *a, mp_int *b); /* 56 */
|
||||
int (*tclBN_s_mp_add) (mp_int *a, mp_int *b, mp_int *c); /* 57 */
|
||||
int (*tclBN_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 58 */
|
||||
int (*tclBN_s_mp_sqr) (mp_int *a, mp_int *b); /* 59 */
|
||||
int (*tclBN_s_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 60 */
|
||||
int (*tclBN_fast_s_mp_mul_digs) (const mp_int *a, const mp_int *b, mp_int *c, int digs); /* 51 */
|
||||
int (*tclBN_fast_s_mp_sqr) (const mp_int *a, mp_int *b); /* 52 */
|
||||
int (*tclBN_mp_karatsuba_mul) (const mp_int *a, const mp_int *b, mp_int *c); /* 53 */
|
||||
int (*tclBN_mp_karatsuba_sqr) (const mp_int *a, mp_int *b); /* 54 */
|
||||
int (*tclBN_mp_toom_mul) (const mp_int *a, const mp_int *b, mp_int *c); /* 55 */
|
||||
int (*tclBN_mp_toom_sqr) (const mp_int *a, mp_int *b); /* 56 */
|
||||
int (*tclBN_s_mp_add) (const mp_int *a, const mp_int *b, mp_int *c); /* 57 */
|
||||
int (*tclBN_s_mp_mul_digs) (const mp_int *a, const mp_int *b, mp_int *c, int digs); /* 58 */
|
||||
int (*tclBN_s_mp_sqr) (const mp_int *a, mp_int *b); /* 59 */
|
||||
int (*tclBN_s_mp_sub) (const mp_int *a, const mp_int *b, mp_int *c); /* 60 */
|
||||
int (*tclBN_mp_init_set_int) (mp_int *a, unsigned long i); /* 61 */
|
||||
int (*tclBN_mp_set_int) (mp_int *a, unsigned long i); /* 62 */
|
||||
int (*tclBN_mp_cnt_lsb) (const mp_int *a); /* 63 */
|
||||
void (*tclBNInitBignumFromLong) (mp_int *bignum, long initVal); /* 64 */
|
||||
void (*tclBNInitBignumFromWideInt) (mp_int *bignum, Tcl_WideInt initVal); /* 65 */
|
||||
void (*tclBNInitBignumFromWideUInt) (mp_int *bignum, Tcl_WideUInt initVal); /* 66 */
|
||||
int (*tclBN_mp_expt_d_ex) (mp_int *a, mp_digit b, mp_int *c, int fast); /* 67 */
|
||||
TCL_DEPRECATED_API("Use mp_init() + mp_set_long_long()") void (*tclBNInitBignumFromLong) (mp_int *bignum, long initVal); /* 64 */
|
||||
TCL_DEPRECATED_API("Use mp_init() + mp_set_long_long()") void (*tclBNInitBignumFromWideInt) (mp_int *bignum, Tcl_WideInt initVal); /* 65 */
|
||||
TCL_DEPRECATED_API("Use mp_init() + mp_set_long_long()") void (*tclBNInitBignumFromWideUInt) (mp_int *bignum, Tcl_WideUInt initVal); /* 66 */
|
||||
int (*tclBN_mp_expt_d_ex) (const mp_int *a, mp_digit b, mp_int *c, int fast); /* 67 */
|
||||
int (*tclBN_mp_set_long_long) (mp_int *a, Tcl_WideUInt i); /* 68 */
|
||||
Tcl_WideUInt (*tclBN_mp_get_long_long) (const mp_int *a); /* 69 */
|
||||
int (*tclBN_mp_set_long) (mp_int *a, unsigned long i); /* 70 */
|
||||
unsigned long (*tclBN_mp_get_long) (const mp_int *a); /* 71 */
|
||||
} TclTomMathStubs;
|
||||
|
||||
extern const TclTomMathStubs *tclTomMathStubsPtr;
|
||||
@@ -515,6 +551,14 @@ extern const TclTomMathStubs *tclTomMathStubsPtr;
|
||||
(tclTomMathStubsPtr->tclBNInitBignumFromWideUInt) /* 66 */
|
||||
#define TclBN_mp_expt_d_ex \
|
||||
(tclTomMathStubsPtr->tclBN_mp_expt_d_ex) /* 67 */
|
||||
#define TclBN_mp_set_long_long \
|
||||
(tclTomMathStubsPtr->tclBN_mp_set_long_long) /* 68 */
|
||||
#define TclBN_mp_get_long_long \
|
||||
(tclTomMathStubsPtr->tclBN_mp_get_long_long) /* 69 */
|
||||
#define TclBN_mp_set_long \
|
||||
(tclTomMathStubsPtr->tclBN_mp_set_long) /* 70 */
|
||||
#define TclBN_mp_get_long \
|
||||
(tclTomMathStubsPtr->tclBN_mp_get_long) /* 71 */
|
||||
|
||||
#endif /* defined(USE_TCL_STUBS) */
|
||||
|
||||
|
||||
+23
-143
@@ -89,86 +89,11 @@ TclBN_revision(void)
|
||||
{
|
||||
return TCLTOMMATH_REVISION;
|
||||
}
|
||||
#if 0
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclBNAlloc --
|
||||
*
|
||||
* Allocate memory for libtommath.
|
||||
*
|
||||
* Results:
|
||||
* Returns a pointer to the allocated block.
|
||||
*
|
||||
* This procedure is a wrapper around Tcl_Alloc, needed because of a
|
||||
* mismatched type signature between Tcl_Alloc and malloc.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern void *
|
||||
TclBNAlloc(
|
||||
size_t x)
|
||||
{
|
||||
return (void *) ckalloc((unsigned int) x);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclBNRealloc --
|
||||
*
|
||||
* Change the size of an allocated block of memory in libtommath
|
||||
*
|
||||
* Results:
|
||||
* Returns a pointer to the allocated block.
|
||||
*
|
||||
* This procedure is a wrapper around Tcl_Realloc, needed because of a
|
||||
* mismatched type signature between Tcl_Realloc and realloc.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void *
|
||||
TclBNRealloc(
|
||||
void *p,
|
||||
size_t s)
|
||||
{
|
||||
return (void *) ckrealloc((char *) p, (unsigned int) s);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclBNFree --
|
||||
*
|
||||
* Free allocated memory in libtommath.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Memory is freed.
|
||||
*
|
||||
* This function is simply a wrapper around Tcl_Free, needed in libtommath
|
||||
* because of a type mismatch between free and Tcl_Free.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern void
|
||||
TclBNFree(
|
||||
void *p)
|
||||
{
|
||||
ckree((char *) p);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclBNInitBignumFromLong --
|
||||
* TclInitBignumFromLong --
|
||||
*
|
||||
* Allocate and initialize a 'bignum' from a native 'long'.
|
||||
*
|
||||
@@ -181,47 +106,20 @@ TclBNFree(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern void
|
||||
TclBNInitBignumFromLong(
|
||||
void
|
||||
TclInitBignumFromLong(
|
||||
mp_int *a,
|
||||
long initVal)
|
||||
long v)
|
||||
{
|
||||
int status;
|
||||
unsigned long v;
|
||||
mp_digit *p;
|
||||
|
||||
/*
|
||||
* Allocate enough memory to hold the largest possible long
|
||||
*/
|
||||
|
||||
status = mp_init_size(a,
|
||||
(CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT);
|
||||
if (status != MP_OKAY) {
|
||||
Tcl_Panic("initialization failure in TclBNInitBignumFromLong");
|
||||
if (mp_init_size(a, (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) {
|
||||
Tcl_Panic("initialization failure in TclInitBignumFromLong");
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert arg to sign and magnitude.
|
||||
*/
|
||||
|
||||
if (initVal < 0) {
|
||||
a->sign = MP_NEG;
|
||||
v = -initVal;
|
||||
if (v < (long)0) {
|
||||
mp_set_long_long(a, (Tcl_WideUInt)(-(Tcl_WideInt)v));
|
||||
mp_neg(a, a);
|
||||
} else {
|
||||
a->sign = MP_ZPOS;
|
||||
v = initVal;
|
||||
mp_set_long_long(a, (Tcl_WideUInt)v);
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the magnitude in the bignum.
|
||||
*/
|
||||
|
||||
p = a->dp;
|
||||
while (v) {
|
||||
*p++ = (mp_digit) (v & MP_MASK);
|
||||
v >>= MP_DIGIT_BIT;
|
||||
}
|
||||
a->used = p - a->dp;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -240,16 +138,19 @@ TclBNInitBignumFromLong(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern void
|
||||
TclBNInitBignumFromWideInt(
|
||||
void
|
||||
TclInitBignumFromWideInt(
|
||||
mp_int *a, /* Bignum to initialize */
|
||||
Tcl_WideInt v) /* Initial value */
|
||||
{
|
||||
if (mp_init_size(a, (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) {
|
||||
Tcl_Panic("initialization failure in TclInitBignumFromWideInt");
|
||||
}
|
||||
if (v < (Tcl_WideInt)0) {
|
||||
TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)(-v));
|
||||
mp_set_long_long(a, (Tcl_WideUInt)(-v));
|
||||
mp_neg(a, a);
|
||||
} else {
|
||||
TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)v);
|
||||
mp_set_long_long(a, (Tcl_WideUInt)v);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,36 +170,15 @@ TclBNInitBignumFromWideInt(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
extern void
|
||||
TclBNInitBignumFromWideUInt(
|
||||
void
|
||||
TclInitBignumFromWideUInt(
|
||||
mp_int *a, /* Bignum to initialize */
|
||||
Tcl_WideUInt v) /* Initial value */
|
||||
{
|
||||
int status;
|
||||
mp_digit *p;
|
||||
|
||||
/*
|
||||
* Allocate enough memory to hold the largest possible Tcl_WideUInt.
|
||||
*/
|
||||
|
||||
status = mp_init_size(a,
|
||||
(CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT);
|
||||
if (status != MP_OKAY) {
|
||||
Tcl_Panic("initialization failure in TclBNInitBignumFromWideUInt");
|
||||
}
|
||||
|
||||
a->sign = MP_ZPOS;
|
||||
|
||||
/*
|
||||
* Store the magnitude in the bignum.
|
||||
*/
|
||||
|
||||
p = a->dp;
|
||||
while (v) {
|
||||
*p++ = (mp_digit) (v & MP_MASK);
|
||||
v >>= MP_DIGIT_BIT;
|
||||
}
|
||||
a->used = p - a->dp;
|
||||
if (mp_init_size(a, (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) != MP_OKAY) {
|
||||
Tcl_Panic("initialization failure in TclInitBignumFromWideUInt");
|
||||
}
|
||||
mp_set_long_long(a, v);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2819,6 +2819,7 @@ DisposeTraceResult(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_UntraceVar
|
||||
void
|
||||
Tcl_UntraceVar(
|
||||
@@ -2834,6 +2835,7 @@ Tcl_UntraceVar(
|
||||
{
|
||||
Tcl_UntraceVar2(interp, varName, NULL, flags, proc, clientData);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2988,6 +2990,7 @@ Tcl_UntraceVar2(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_VarTraceInfo
|
||||
ClientData
|
||||
Tcl_VarTraceInfo(
|
||||
@@ -3005,6 +3008,7 @@ Tcl_VarTraceInfo(
|
||||
return Tcl_VarTraceInfo2(interp, varName, NULL, flags, proc,
|
||||
prevClientData);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -3097,6 +3101,7 @@ Tcl_VarTraceInfo2(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_TraceVar
|
||||
int
|
||||
Tcl_TraceVar(
|
||||
@@ -3114,6 +3119,7 @@ Tcl_TraceVar(
|
||||
{
|
||||
return Tcl_TraceVar2(interp, varName, NULL, flags, proc, clientData);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
+644
-626
File diff suppressed because it is too large
Load Diff
+89
-54
@@ -103,7 +103,7 @@ TclUtfCount(
|
||||
return 2;
|
||||
}
|
||||
#if TCL_UTF_MAX > 3
|
||||
if (((unsigned)(ch - 0x10000) <= 0xfffff)) {
|
||||
if (((unsigned)(ch - 0x10000) <= 0xFFFFF)) {
|
||||
return 4;
|
||||
}
|
||||
#endif
|
||||
@@ -253,6 +253,15 @@ Tcl_UniCharToUtfDString(
|
||||
* Tcl_UtfCharComplete() before calling this routine to ensure that
|
||||
* enough bytes remain in the string.
|
||||
*
|
||||
* If TCL_UTF_MAX == 4, special handling of Surrogate pairs is done:
|
||||
* For any UTF-8 string containing a character outside of the BMP, the
|
||||
* first call to this function will fill *chPtr with the high surrogate
|
||||
* and generate a return value of 0. Calling Tcl_UtfToUniChar again
|
||||
* will produce the low surrogate and a return value of 4. Because *chPtr
|
||||
* is used to remember whether the high surrogate is already produced, it
|
||||
* is recommended to initialize the variable it points to as 0 before
|
||||
* the first call to Tcl_UtfToUniChar is done.
|
||||
*
|
||||
* Results:
|
||||
* *chPtr is filled with the Tcl_UniChar, and the return value is the
|
||||
* number of bytes from the UTF-8 string that were consumed.
|
||||
@@ -272,7 +281,7 @@ Tcl_UtfToUniChar(
|
||||
register int byte;
|
||||
|
||||
/*
|
||||
* Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones.
|
||||
* Unroll 1 to 3 (or 4) byte UTF-8 sequences.
|
||||
*/
|
||||
|
||||
byte = *((unsigned char *) src);
|
||||
@@ -292,7 +301,9 @@ Tcl_UtfToUniChar(
|
||||
*/
|
||||
|
||||
*chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (src[1] & 0x3F));
|
||||
return 2;
|
||||
if ((unsigned)(*chPtr - 1) >= (UNICODE_SELF - 1)) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -307,7 +318,9 @@ Tcl_UtfToUniChar(
|
||||
|
||||
*chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12)
|
||||
| ((src[1] & 0x3F) << 6) | (src[2] & 0x3F));
|
||||
return 3;
|
||||
if (*chPtr > 0x7FF) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -321,14 +334,34 @@ Tcl_UtfToUniChar(
|
||||
/*
|
||||
* Four-byte-character lead byte followed by three trail bytes.
|
||||
*/
|
||||
#if TCL_UTF_MAX == 4
|
||||
Tcl_UniChar surrogate;
|
||||
|
||||
*chPtr = (Tcl_UniChar) (((byte & 0x0E) << 18) | ((src[1] & 0x3F) << 12)
|
||||
byte = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
|
||||
| ((src[2] & 0x3F) << 6) | (src[3] & 0x3F)) - 0x10000;
|
||||
surrogate = (Tcl_UniChar) (0xD800 + (byte >> 10));
|
||||
if (byte & 0x100000) {
|
||||
/* out of range, < 0x10000 or > 0x10ffff */
|
||||
} else if (*chPtr != surrogate) {
|
||||
/* produce high surrogate, but don't advance source pointer */
|
||||
*chPtr = surrogate;
|
||||
return 0;
|
||||
} else {
|
||||
/* produce low surrogate, and advance source pointer */
|
||||
*chPtr = (Tcl_UniChar) (0xDC00 | (byte & 0x3FF));
|
||||
return 4;
|
||||
}
|
||||
#else
|
||||
*chPtr = (Tcl_UniChar) (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
|
||||
| ((src[2] & 0x3F) << 6) | (src[3] & 0x3F));
|
||||
return 4;
|
||||
if ((unsigned)(*chPtr - 0x10000) <= 0xFFFFF) {
|
||||
return 4;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* A three-byte-character lead-byte not followed by two trail-bytes
|
||||
* A four-byte-character lead-byte not followed by two trail-bytes
|
||||
* represents itself.
|
||||
*/
|
||||
}
|
||||
@@ -365,7 +398,7 @@ Tcl_UtfToUniCharDString(
|
||||
* appended to this previously initialized
|
||||
* DString. */
|
||||
{
|
||||
Tcl_UniChar *w, *wString;
|
||||
Tcl_UniChar ch, *w, *wString;
|
||||
const char *p, *end;
|
||||
int oldLength;
|
||||
|
||||
@@ -387,8 +420,8 @@ Tcl_UtfToUniCharDString(
|
||||
w = wString;
|
||||
end = src + length;
|
||||
for (p = src; p < end; ) {
|
||||
p += TclUtfToUniChar(p, w);
|
||||
w++;
|
||||
p += TclUtfToUniChar(p, &ch);
|
||||
*w++ = ch;
|
||||
}
|
||||
*w = '\0';
|
||||
Tcl_DStringSetLength(dsPtr,
|
||||
@@ -422,10 +455,7 @@ Tcl_UtfCharComplete(
|
||||
* a complete UTF-8 character. */
|
||||
int length) /* Length of above string in bytes. */
|
||||
{
|
||||
int ch;
|
||||
|
||||
ch = *((unsigned char *) src);
|
||||
return length >= totalBytes[ch];
|
||||
return length >= totalBytes[(unsigned char)*src];
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -452,9 +482,8 @@ Tcl_NumUtfChars(
|
||||
int length) /* The length of the string in bytes, or -1
|
||||
* for strlen(string). */
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
register Tcl_UniChar *chPtr = &ch;
|
||||
register int i;
|
||||
Tcl_UniChar ch = 0;
|
||||
register int i = 0;
|
||||
|
||||
/*
|
||||
* The separate implementations are faster.
|
||||
@@ -463,26 +492,27 @@ Tcl_NumUtfChars(
|
||||
* single-byte char case specially.
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
if (length < 0) {
|
||||
while (*src != '\0') {
|
||||
src += TclUtfToUniChar(src, chPtr);
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
i++;
|
||||
}
|
||||
if (i < 0) i = INT_MAX; /* Bug [2738427] */
|
||||
} else {
|
||||
register int n;
|
||||
register const char *endPtr = src + length - TCL_UTF_MAX;
|
||||
|
||||
while (length > 0) {
|
||||
if (UCHAR(*src) < 0xC0) {
|
||||
length--;
|
||||
src++;
|
||||
} else {
|
||||
n = Tcl_UtfToUniChar(src, chPtr);
|
||||
length -= n;
|
||||
src += n;
|
||||
}
|
||||
while (src < endPtr) {
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
i++;
|
||||
}
|
||||
endPtr += TCL_UTF_MAX;
|
||||
while ((src < endPtr) && Tcl_UtfCharComplete(src, endPtr - src)) {
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
i++;
|
||||
}
|
||||
if (src < endPtr) {
|
||||
i += endPtr - src;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@@ -512,7 +542,7 @@ Tcl_UtfFindFirst(
|
||||
int ch) /* The Tcl_UniChar to search for. */
|
||||
{
|
||||
int len;
|
||||
Tcl_UniChar find;
|
||||
Tcl_UniChar find = 0;
|
||||
|
||||
while (1) {
|
||||
len = TclUtfToUniChar(src, &find);
|
||||
@@ -551,7 +581,7 @@ Tcl_UtfFindLast(
|
||||
int ch) /* The Tcl_UniChar to search for. */
|
||||
{
|
||||
int len;
|
||||
Tcl_UniChar find;
|
||||
Tcl_UniChar find = 0;
|
||||
const char *last;
|
||||
|
||||
last = NULL;
|
||||
@@ -591,9 +621,15 @@ const char *
|
||||
Tcl_UtfNext(
|
||||
const char *src) /* The current location in the string. */
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
int len = TclUtfToUniChar(src, &ch);
|
||||
|
||||
return src + TclUtfToUniChar(src, &ch);
|
||||
#if TCL_UTF_MAX == 4
|
||||
if (len == 0) {
|
||||
len = TclUtfToUniChar(src, &ch);
|
||||
}
|
||||
#endif
|
||||
return src + len;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -626,8 +662,7 @@ Tcl_UtfPrev(
|
||||
const char *look;
|
||||
int i, byte;
|
||||
|
||||
src--;
|
||||
look = src;
|
||||
look = --src;
|
||||
for (i = 0; i < TCL_UTF_MAX; i++) {
|
||||
if (look < start) {
|
||||
if (src < start) {
|
||||
@@ -700,7 +735,7 @@ Tcl_UtfAtIndex(
|
||||
register const char *src, /* The UTF-8 string. */
|
||||
register int index) /* The position of the desired character. */
|
||||
{
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
while (index > 0) {
|
||||
index--;
|
||||
@@ -784,7 +819,7 @@ int
|
||||
Tcl_UtfToUpper(
|
||||
char *str) /* String to convert in place. */
|
||||
{
|
||||
Tcl_UniChar ch, upChar;
|
||||
Tcl_UniChar ch = 0, upChar;
|
||||
char *src, *dst;
|
||||
int bytes;
|
||||
|
||||
@@ -837,7 +872,7 @@ int
|
||||
Tcl_UtfToLower(
|
||||
char *str) /* String to convert in place. */
|
||||
{
|
||||
Tcl_UniChar ch, lowChar;
|
||||
Tcl_UniChar ch = 0, lowChar;
|
||||
char *src, *dst;
|
||||
int bytes;
|
||||
|
||||
@@ -891,7 +926,7 @@ int
|
||||
Tcl_UtfToTitle(
|
||||
char *str) /* String to convert in place. */
|
||||
{
|
||||
Tcl_UniChar ch, titleChar, lowChar;
|
||||
Tcl_UniChar ch = 0, titleChar, lowChar;
|
||||
char *src, *dst;
|
||||
int bytes;
|
||||
|
||||
@@ -1000,11 +1035,11 @@ Tcl_UtfNcmp(
|
||||
const char *ct, /* UTF string cs is compared to. */
|
||||
unsigned long numChars) /* Number of UTF chars to compare. */
|
||||
{
|
||||
Tcl_UniChar ch1, ch2;
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
|
||||
/*
|
||||
* Cannot use 'memcmp(cs, ct, n);' as byte representation of \u0000 (the
|
||||
* pair of bytes 0xc0,0x80) is larger than byte representation of \u0001
|
||||
* pair of bytes 0xC0,0x80) is larger than byte representation of \u0001
|
||||
* (the byte 0x01.)
|
||||
*/
|
||||
|
||||
@@ -1048,7 +1083,7 @@ Tcl_UtfNcasecmp(
|
||||
const char *ct, /* UTF string cs is compared to. */
|
||||
unsigned long numChars) /* Number of UTF chars to compare. */
|
||||
{
|
||||
Tcl_UniChar ch1, ch2;
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
while (numChars-- > 0) {
|
||||
/*
|
||||
* n must be interpreted as chars, not bytes.
|
||||
@@ -1388,11 +1423,11 @@ Tcl_UniCharIsControl(
|
||||
{
|
||||
#if TCL_UTF_MAX > 3
|
||||
if (UNICODE_OUT_OF_RANGE(ch)) {
|
||||
ch &= 0x1fffff;
|
||||
if ((ch == 0xe0001) || ((ch >= 0xe0020) && (ch <= 0xe007f))) {
|
||||
ch &= 0x1FFFFF;
|
||||
if ((ch == 0xE0001) || ((ch >= 0xE0020) && (ch <= 0xE007f))) {
|
||||
return 1;
|
||||
}
|
||||
if ((ch >= 0xf0000) && ((ch & 0xffff) <= 0xfffd)) {
|
||||
if ((ch >= 0xF0000) && ((ch & 0xFFFF) <= 0xFFFD)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -1451,8 +1486,8 @@ Tcl_UniCharIsGraph(
|
||||
{
|
||||
#if TCL_UTF_MAX > 3
|
||||
if (UNICODE_OUT_OF_RANGE(ch)) {
|
||||
ch &= 0x1fffff;
|
||||
return (ch >= 0xe0100) && (ch <= 0xe01ef);
|
||||
ch &= 0x1FFFFF;
|
||||
return (ch >= 0xE0100) && (ch <= 0xE01EF);
|
||||
}
|
||||
#endif
|
||||
return ((GRAPH_BITS >> GetCategory(ch)) & 1);
|
||||
@@ -1508,8 +1543,8 @@ Tcl_UniCharIsPrint(
|
||||
{
|
||||
#if TCL_UTF_MAX > 3
|
||||
if (UNICODE_OUT_OF_RANGE(ch)) {
|
||||
ch &= 0x1fffff;
|
||||
return (ch >= 0xe0100) && (ch <= 0xe01ef);
|
||||
ch &= 0x1FFFFF;
|
||||
return (ch >= 0xE0100) && (ch <= 0xE01EF);
|
||||
}
|
||||
#endif
|
||||
return (((GRAPH_BITS|SPACE_BITS) >> GetCategory(ch)) & 1);
|
||||
@@ -1565,10 +1600,10 @@ Tcl_UniCharIsSpace(
|
||||
{
|
||||
#if TCL_UTF_MAX > 3
|
||||
/* Ignore upper 11 bits. */
|
||||
ch &= 0x1fffff;
|
||||
ch &= 0x1FFFFF;
|
||||
#else
|
||||
/* Ignore upper 16 bits. */
|
||||
ch &= 0xffff;
|
||||
ch &= 0xFFFF;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1582,8 +1617,8 @@ Tcl_UniCharIsSpace(
|
||||
} else if (UNICODE_OUT_OF_RANGE(ch)) {
|
||||
return 0;
|
||||
#endif
|
||||
} else if (ch == 0x0085 || ch == 0x180e || ch == 0x200b
|
||||
|| ch == 0x202f || ch == 0x2060 || ch == 0xfeff) {
|
||||
} else if (ch == 0x0085 || ch == 0x180E || ch == 0x200B
|
||||
|| ch == 0x202F || ch == 0x2060 || ch == 0xFEFF) {
|
||||
return 1;
|
||||
} else {
|
||||
return ((SPACE_BITS >> GetCategory(ch)) & 1);
|
||||
@@ -1677,7 +1712,7 @@ Tcl_UniCharCaseMatch(
|
||||
* characters. */
|
||||
int nocase) /* 0 for case sensitive, 1 for insensitive */
|
||||
{
|
||||
Tcl_UniChar ch1, p;
|
||||
Tcl_UniChar ch1 = 0, p;
|
||||
|
||||
while (1) {
|
||||
p = *uniPattern;
|
||||
|
||||
+3
-3
@@ -1646,7 +1646,7 @@ Tcl_Backslash(
|
||||
* src, unless NULL. */
|
||||
{
|
||||
char buf[TCL_UTF_MAX];
|
||||
Tcl_UniChar ch;
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
Tcl_UtfBackslash(src, readPtr, buf);
|
||||
TclUtfToUniChar(buf, &ch);
|
||||
@@ -3153,7 +3153,7 @@ Tcl_PrintDouble(
|
||||
int signum;
|
||||
char *digits;
|
||||
char *end;
|
||||
int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int));
|
||||
int *precisionPtr = Tcl_GetThreadData(&precisionKey, sizeof(int));
|
||||
|
||||
/*
|
||||
* Handle NaN.
|
||||
@@ -3326,7 +3326,7 @@ TclPrecTraceProc(
|
||||
{
|
||||
Tcl_Obj *value;
|
||||
int prec;
|
||||
int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int));
|
||||
int *precisionPtr = Tcl_GetThreadData(&precisionKey, sizeof(int));
|
||||
|
||||
/*
|
||||
* If the variable is unset, then recreate the trace.
|
||||
|
||||
+258
-35
@@ -1067,6 +1067,7 @@ TclLookupArrayElement(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_GetVar
|
||||
const char *
|
||||
Tcl_GetVar(
|
||||
@@ -1087,6 +1088,7 @@ Tcl_GetVar(
|
||||
}
|
||||
return TclGetString(resultPtr);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1245,7 +1247,7 @@ Tcl_ObjGetVar2(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
return TclPtrGetVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
flags, -1);
|
||||
}
|
||||
|
||||
@@ -1273,6 +1275,52 @@ Tcl_ObjGetVar2(
|
||||
|
||||
Tcl_Obj *
|
||||
TclPtrGetVar(
|
||||
Tcl_Interp *interp, /* Command interpreter in which variable is to
|
||||
* be looked up. */
|
||||
Tcl_Var varPtr, /* The variable to be read.*/
|
||||
Tcl_Var arrayPtr, /* NULL for scalar variables, pointer to the
|
||||
* containing array otherwise. */
|
||||
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
|
||||
* the name of a variable. */
|
||||
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
|
||||
* in the array part1. */
|
||||
const int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and
|
||||
* TCL_LEAVE_ERR_MSG bits. */
|
||||
{
|
||||
if (varPtr == NULL) {
|
||||
Tcl_Panic("varPtr must not be NULL");
|
||||
}
|
||||
if (part1Ptr == NULL) {
|
||||
Tcl_Panic("part1Ptr must not be NULL");
|
||||
}
|
||||
return TclPtrGetVarIdx(interp, (Var *) varPtr, (Var *) arrayPtr,
|
||||
part1Ptr, part2Ptr, flags, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPtrGetVarIdx --
|
||||
*
|
||||
* Return the value of a Tcl variable as a Tcl object, given the pointers
|
||||
* to the variable's (and possibly containing array's) VAR structure.
|
||||
*
|
||||
* Results:
|
||||
* The return value points to the current object value of the variable
|
||||
* given by varPtr. If the specified variable doesn't exist, or if there
|
||||
* is a clash in array usage, then NULL is returned and a message will be
|
||||
* left in the interpreter's result if the TCL_LEAVE_ERR_MSG flag is set.
|
||||
*
|
||||
* Side effects:
|
||||
* The ref count for the returned object is _not_ incremented to reflect
|
||||
* the returned reference; if you want to keep a reference to the object
|
||||
* you must increment its ref count yourself.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *
|
||||
TclPtrGetVarIdx(
|
||||
Tcl_Interp *interp, /* Command interpreter in which variable is to
|
||||
* be looked up. */
|
||||
register Var *varPtr, /* The variable to be read.*/
|
||||
@@ -1410,6 +1458,7 @@ Tcl_SetObjCmd(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_SetVar
|
||||
const char *
|
||||
Tcl_SetVar(
|
||||
@@ -1422,18 +1471,15 @@ Tcl_SetVar(
|
||||
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
|
||||
* TCL_LEAVE_ERR_MSG. */
|
||||
{
|
||||
Tcl_Obj *varValuePtr, *varNamePtr = Tcl_NewStringObj(varName, -1);
|
||||
|
||||
Tcl_IncrRefCount(varNamePtr);
|
||||
varValuePtr = Tcl_ObjSetVar2(interp, varNamePtr, NULL,
|
||||
Tcl_Obj *varValuePtr = Tcl_SetVar2Ex(interp, varName, NULL,
|
||||
Tcl_NewStringObj(newValue, -1), flags);
|
||||
Tcl_DecrRefCount(varNamePtr);
|
||||
|
||||
if (varValuePtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return TclGetString(varValuePtr);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1614,7 +1660,7 @@ Tcl_ObjSetVar2(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
return TclPtrSetVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
newValuePtr, flags, -1);
|
||||
}
|
||||
|
||||
@@ -1645,6 +1691,60 @@ Tcl_ObjSetVar2(
|
||||
|
||||
Tcl_Obj *
|
||||
TclPtrSetVar(
|
||||
Tcl_Interp *interp, /* Command interpreter in which variable is to
|
||||
* be looked up. */
|
||||
Tcl_Var varPtr, /* Reference to the variable to set. */
|
||||
Tcl_Var arrayPtr, /* Reference to the array containing the
|
||||
* variable, or NULL if the variable is a
|
||||
* scalar. */
|
||||
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
|
||||
* the name of a variable. */
|
||||
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
|
||||
* in the array part1. */
|
||||
Tcl_Obj *newValuePtr, /* New value for variable. */
|
||||
const int flags) /* OR-ed combination of TCL_GLOBAL_ONLY, and
|
||||
* TCL_LEAVE_ERR_MSG bits. */
|
||||
{
|
||||
if (varPtr == NULL) {
|
||||
Tcl_Panic("varPtr must not be NULL");
|
||||
}
|
||||
if (part1Ptr == NULL) {
|
||||
Tcl_Panic("part1Ptr must not be NULL");
|
||||
}
|
||||
if (newValuePtr == NULL) {
|
||||
Tcl_Panic("newValuePtr must not be NULL");
|
||||
}
|
||||
return TclPtrSetVarIdx(interp, (Var *) varPtr, (Var *) arrayPtr,
|
||||
part1Ptr, part2Ptr, newValuePtr, flags, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPtrSetVarIdx --
|
||||
*
|
||||
* This function is the same as Tcl_SetVar2Ex above, except that it
|
||||
* requires pointers to the variable's Var structs in addition to the
|
||||
* variable names.
|
||||
*
|
||||
* Results:
|
||||
* Returns a pointer to the Tcl_Obj holding the new value of the
|
||||
* variable. If the write operation was disallowed because an array was
|
||||
* expected but not found (or vice versa), then NULL is returned; if the
|
||||
* TCL_LEAVE_ERR_MSG flag is set, then an explanatory message will be
|
||||
* left in the interpreter's result. Note that the returned object may
|
||||
* not be the same one referenced by newValuePtr; this is because
|
||||
* variable traces may modify the variable's value.
|
||||
*
|
||||
* Side effects:
|
||||
* The value of the given variable is set. If either the array or the
|
||||
* entry didn't exist then a new variable is created.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *
|
||||
TclPtrSetVarIdx(
|
||||
Tcl_Interp *interp, /* Command interpreter in which variable is to
|
||||
* be looked up. */
|
||||
register Var *varPtr, /* Reference to the variable to set. */
|
||||
@@ -1889,7 +1989,7 @@ TclIncrObjVar2(
|
||||
"\n (reading value of variable to increment)");
|
||||
return NULL;
|
||||
}
|
||||
return TclPtrIncrObjVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
return TclPtrIncrObjVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
incrPtr, flags, -1);
|
||||
}
|
||||
|
||||
@@ -1920,6 +2020,62 @@ TclIncrObjVar2(
|
||||
|
||||
Tcl_Obj *
|
||||
TclPtrIncrObjVar(
|
||||
Tcl_Interp *interp, /* Command interpreter in which variable is to
|
||||
* be found. */
|
||||
Tcl_Var varPtr, /* Reference to the variable to set. */
|
||||
Tcl_Var arrayPtr, /* Reference to the array containing the
|
||||
* variable, or NULL if the variable is a
|
||||
* scalar. */
|
||||
Tcl_Obj *part1Ptr, /* Points to an object holding the name of an
|
||||
* array (if part2 is non-NULL) or the name of
|
||||
* a variable. */
|
||||
Tcl_Obj *part2Ptr, /* If non-null, points to an object holding
|
||||
* the name of an element in the array
|
||||
* part1Ptr. */
|
||||
Tcl_Obj *incrPtr, /* Increment value. */
|
||||
/* TODO: Which of these flag values really make sense? */
|
||||
const int flags) /* Various flags that tell how to incr value:
|
||||
* any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
|
||||
* TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
|
||||
* TCL_LEAVE_ERR_MSG. */
|
||||
{
|
||||
if (varPtr == NULL) {
|
||||
Tcl_Panic("varPtr must not be NULL");
|
||||
}
|
||||
if (part1Ptr == NULL) {
|
||||
Tcl_Panic("part1Ptr must not be NULL");
|
||||
}
|
||||
return TclPtrIncrObjVarIdx(interp, (Var *) varPtr, (Var *) arrayPtr,
|
||||
part1Ptr, part2Ptr, incrPtr, flags, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPtrIncrObjVarIdx --
|
||||
*
|
||||
* Given the pointers to a variable and possible containing array,
|
||||
* increment the Tcl object value of the variable by a Tcl_Obj increment.
|
||||
*
|
||||
* Results:
|
||||
* Returns a pointer to the Tcl_Obj holding the new value of the
|
||||
* variable. If the specified variable doesn't exist, or there is a clash
|
||||
* in array usage, or an error occurs while executing variable traces,
|
||||
* then NULL is returned and a message will be left in the interpreter's
|
||||
* result.
|
||||
*
|
||||
* Side effects:
|
||||
* The value of the given variable is incremented by the specified
|
||||
* amount. If either the array or the entry didn't exist then a new
|
||||
* variable is created. The ref count for the returned object is _not_
|
||||
* incremented to reflect the returned reference; if you want to keep a
|
||||
* reference to the object you must increment its ref count yourself.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *
|
||||
TclPtrIncrObjVarIdx(
|
||||
Tcl_Interp *interp, /* Command interpreter in which variable is to
|
||||
* be found. */
|
||||
Var *varPtr, /* Reference to the variable to set. */
|
||||
@@ -1947,8 +2103,8 @@ TclPtrIncrObjVar(
|
||||
if (TclIsVarInHash(varPtr)) {
|
||||
VarHashRefCount(varPtr)++;
|
||||
}
|
||||
varValuePtr = TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
flags, index);
|
||||
varValuePtr = TclPtrGetVarIdx(interp, varPtr, arrayPtr, part1Ptr,
|
||||
part2Ptr, flags, index);
|
||||
if (TclIsVarInHash(varPtr)) {
|
||||
VarHashRefCount(varPtr)--;
|
||||
}
|
||||
@@ -1960,8 +2116,8 @@ TclPtrIncrObjVar(
|
||||
varValuePtr = Tcl_DuplicateObj(varValuePtr);
|
||||
|
||||
if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) {
|
||||
return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
varValuePtr, flags, index);
|
||||
return TclPtrSetVarIdx(interp, varPtr, arrayPtr, part1Ptr,
|
||||
part2Ptr, varValuePtr, flags, index);
|
||||
} else {
|
||||
Tcl_DecrRefCount(varValuePtr);
|
||||
return NULL;
|
||||
@@ -1977,8 +2133,8 @@ TclPtrIncrObjVar(
|
||||
* is the way to make that happen.
|
||||
*/
|
||||
|
||||
return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
varValuePtr, flags, index);
|
||||
return TclPtrSetVarIdx(interp, varPtr, arrayPtr, part1Ptr,
|
||||
part2Ptr, varValuePtr, flags, index);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@@ -2005,6 +2161,7 @@ TclPtrIncrObjVar(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_UnsetVar
|
||||
int
|
||||
Tcl_UnsetVar(
|
||||
@@ -2033,6 +2190,7 @@ Tcl_UnsetVar(
|
||||
Tcl_DecrRefCount(varNamePtr);
|
||||
return result;
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2125,8 +2283,8 @@ TclObjUnsetVar2(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TclPtrUnsetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, flags,
|
||||
-1);
|
||||
return TclPtrUnsetVarIdx(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
|
||||
flags, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2153,6 +2311,53 @@ TclObjUnsetVar2(
|
||||
|
||||
int
|
||||
TclPtrUnsetVar(
|
||||
Tcl_Interp *interp, /* Command interpreter in which varName is to
|
||||
* be looked up. */
|
||||
Tcl_Var varPtr, /* The variable to be unset. */
|
||||
Tcl_Var arrayPtr, /* NULL for scalar variables, pointer to the
|
||||
* containing array otherwise. */
|
||||
Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or
|
||||
* the name of a variable. */
|
||||
Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element
|
||||
* in the array part1. */
|
||||
const int flags) /* OR-ed combination of any of
|
||||
* TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
|
||||
* TCL_LEAVE_ERR_MSG. */
|
||||
{
|
||||
if (varPtr == NULL) {
|
||||
Tcl_Panic("varPtr must not be NULL");
|
||||
}
|
||||
if (part1Ptr == NULL) {
|
||||
Tcl_Panic("part1Ptr must not be NULL");
|
||||
}
|
||||
return TclPtrUnsetVarIdx(interp, (Var *) varPtr, (Var *) arrayPtr,
|
||||
part1Ptr, part2Ptr, flags, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPtrUnsetVarIdx --
|
||||
*
|
||||
* Delete a variable, given the pointers to the variable's (and possibly
|
||||
* containing array's) VAR structure.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK if the variable was successfully deleted, TCL_ERROR if
|
||||
* the variable can't be unset. In the event of an error, if the
|
||||
* TCL_LEAVE_ERR_MSG flag is set then an error message is left in the
|
||||
* interp's result.
|
||||
*
|
||||
* Side effects:
|
||||
* If varPtr and arrayPtr indicate a local or global variable in interp,
|
||||
* it is deleted. If varPtr is an array reference and part2Ptr is NULL,
|
||||
* then the whole array is deleted.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclPtrUnsetVarIdx(
|
||||
Tcl_Interp *interp, /* Command interpreter in which varName is to
|
||||
* be looked up. */
|
||||
register Var *varPtr, /* The variable to be unset. */
|
||||
@@ -2502,11 +2707,11 @@ Tcl_AppendObjCmd(
|
||||
/*
|
||||
* Note that we do not need to increase the refCount of the Var
|
||||
* pointers: should a trace delete the variable, the return value
|
||||
* of TclPtrSetVar will be NULL or emptyObjPtr, and we will not
|
||||
* of TclPtrSetVarIdx will be NULL or emptyObjPtr, and we will not
|
||||
* access the variable again.
|
||||
*/
|
||||
|
||||
varValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, objv[1],
|
||||
varValuePtr = TclPtrSetVarIdx(interp, varPtr, arrayPtr, objv[1],
|
||||
NULL, objv[i], TCL_APPEND_VALUE|TCL_LEAVE_ERR_MSG, -1);
|
||||
if ((varValuePtr == NULL) ||
|
||||
(varValuePtr == ((Interp *) interp)->emptyObjPtr)) {
|
||||
@@ -2586,7 +2791,7 @@ Tcl_LappendObjCmd(
|
||||
createdNewObj = 0;
|
||||
|
||||
/*
|
||||
* Protect the variable pointers around the TclPtrGetVar call
|
||||
* Protect the variable pointers around the TclPtrGetVarIdx call
|
||||
* to insure that they remain valid even if the variable was undefined
|
||||
* and unused.
|
||||
*/
|
||||
@@ -2602,7 +2807,7 @@ Tcl_LappendObjCmd(
|
||||
if (arrayPtr && TclIsVarInHash(arrayPtr)) {
|
||||
VarHashRefCount(arrayPtr)++;
|
||||
}
|
||||
varValuePtr = TclPtrGetVar(interp, varPtr, arrayPtr, objv[1], NULL,
|
||||
varValuePtr = TclPtrGetVarIdx(interp, varPtr, arrayPtr, objv[1], NULL,
|
||||
TCL_LEAVE_ERR_MSG, -1);
|
||||
if (TclIsVarInHash(varPtr)) {
|
||||
VarHashRefCount(varPtr)--;
|
||||
@@ -2643,7 +2848,7 @@ Tcl_LappendObjCmd(
|
||||
* and we didn't create the variable.
|
||||
*/
|
||||
|
||||
newValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, objv[1], NULL,
|
||||
newValuePtr = TclPtrSetVarIdx(interp, varPtr, arrayPtr, objv[1], NULL,
|
||||
varValuePtr, TCL_LEAVE_ERR_MSG, -1);
|
||||
if (newValuePtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
@@ -2744,7 +2949,7 @@ TclArraySet(
|
||||
keyPtr, TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
|
||||
|
||||
if ((elemVarPtr == NULL) ||
|
||||
(TclPtrSetVar(interp, elemVarPtr, varPtr, arrayNameObj,
|
||||
(TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
|
||||
keyPtr, valuePtr, TCL_LEAVE_ERR_MSG, -1) == NULL)) {
|
||||
Tcl_DictObjDone(&search);
|
||||
return TCL_ERROR;
|
||||
@@ -2777,8 +2982,8 @@ TclArraySet(
|
||||
|
||||
/*
|
||||
* We needn't worry about traces invalidating arrayPtr: should that be
|
||||
* the case, TclPtrSetVar will return NULL so that we break out of the
|
||||
* loop and return an error.
|
||||
* the case, TclPtrSetVarIdx will return NULL so that we break out of
|
||||
* the loop and return an error.
|
||||
*/
|
||||
|
||||
copyListObj = TclListObjCopy(NULL, arrayElemObj);
|
||||
@@ -2787,7 +2992,7 @@ TclArraySet(
|
||||
elemPtrs[i], TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
|
||||
|
||||
if ((elemVarPtr == NULL) ||
|
||||
(TclPtrSetVar(interp, elemVarPtr, varPtr, arrayNameObj,
|
||||
(TclPtrSetVarIdx(interp, elemVarPtr, varPtr, arrayNameObj,
|
||||
elemPtrs[i],elemPtrs[i+1],TCL_LEAVE_ERR_MSG,-1) == NULL)){
|
||||
result = TCL_ERROR;
|
||||
break;
|
||||
@@ -3935,8 +4140,8 @@ ArrayUnsetCmd(
|
||||
if (!varPtr2 || TclIsVarUndefined(varPtr2)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
return TclPtrUnsetVar(interp, varPtr2, varPtr, varNameObj, patternObj,
|
||||
unsetFlags, -1);
|
||||
return TclPtrUnsetVarIdx(interp, varPtr2, varPtr, varNameObj,
|
||||
patternObj, unsetFlags, -1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3984,7 +4189,7 @@ ArrayUnsetCmd(
|
||||
|
||||
nameObj = VarHashGetKey(varPtr2);
|
||||
if (Tcl_StringMatch(TclGetString(nameObj), pattern)
|
||||
&& TclPtrUnsetVar(interp, varPtr2, varPtr, varNameObj,
|
||||
&& TclPtrUnsetVarIdx(interp, varPtr2, varPtr, varNameObj,
|
||||
nameObj, unsetFlags, -1) != TCL_OK) {
|
||||
/*
|
||||
* If we incremented a refcount, we must decrement it here as we
|
||||
@@ -4050,7 +4255,7 @@ TclInitArrayCmd(
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl completion code. If an error occurs then an error
|
||||
* message is left in iPtr->result.
|
||||
* message is left in interp.
|
||||
*
|
||||
* Side effects:
|
||||
* The variable given by myName is linked to the variable in framePtr
|
||||
@@ -4131,7 +4336,7 @@ ObjMakeUpvar(
|
||||
}
|
||||
}
|
||||
|
||||
return TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index);
|
||||
return TclPtrObjMakeUpvarIdx(interp, otherPtr, myNamePtr, myFlags, index);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4144,7 +4349,7 @@ ObjMakeUpvar(
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl completion code. If an error occurs then an error
|
||||
* message is left in iPtr->result.
|
||||
* message is left in interp.
|
||||
*
|
||||
* Side effects:
|
||||
* The variable given by myName is linked to the variable in framePtr
|
||||
@@ -4173,17 +4378,32 @@ TclPtrMakeUpvar(
|
||||
myNamePtr = Tcl_NewStringObj(myName, -1);
|
||||
Tcl_IncrRefCount(myNamePtr);
|
||||
}
|
||||
result = TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index);
|
||||
result = TclPtrObjMakeUpvarIdx(interp, otherPtr, myNamePtr, myFlags,
|
||||
index);
|
||||
if (myNamePtr) {
|
||||
Tcl_DecrRefCount(myNamePtr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
TclPtrObjMakeUpvar(
|
||||
Tcl_Interp *interp, /* Interpreter containing variables. Used for
|
||||
* error messages, too. */
|
||||
Tcl_Var otherPtr, /* Pointer to the variable being linked-to. */
|
||||
Tcl_Obj *myNamePtr, /* Name of variable which will refer to
|
||||
* otherP1/otherP2. Must be a scalar. */
|
||||
int myFlags) /* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
|
||||
* indicates scope of myName. */
|
||||
{
|
||||
return TclPtrObjMakeUpvarIdx(interp, (Var *) otherPtr, myNamePtr, myFlags,
|
||||
-1);
|
||||
}
|
||||
|
||||
/* Callers must Incr myNamePtr if they plan to Decr it. */
|
||||
|
||||
int
|
||||
TclPtrObjMakeUpvar(
|
||||
TclPtrObjMakeUpvarIdx(
|
||||
Tcl_Interp *interp, /* Interpreter containing variables. Used for
|
||||
* error messages, too. */
|
||||
Var *otherPtr, /* Pointer to the variable being linked-to. */
|
||||
@@ -4320,6 +4540,7 @@ TclPtrObjMakeUpvar(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_UpVar
|
||||
int
|
||||
Tcl_UpVar(
|
||||
@@ -4353,6 +4574,7 @@ Tcl_UpVar(
|
||||
Tcl_DecrRefCount(localNamePtr);
|
||||
return result;
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -4650,8 +4872,9 @@ Tcl_VariableObjCmd(
|
||||
*/
|
||||
|
||||
if (i+1 < objc) { /* A value was specified. */
|
||||
varValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, varNamePtr,
|
||||
NULL, objv[i+1], TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG,-1);
|
||||
varValuePtr = TclPtrSetVarIdx(interp, varPtr, arrayPtr,
|
||||
varNamePtr, NULL, objv[i+1],
|
||||
(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), -1);
|
||||
if (varValuePtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user