Compare commits
863
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3e6b234a8f | ||
|
|
2ff70c01f6 | ||
|
|
77b60a92d7 | ||
|
|
d7fe4af621 | ||
|
|
4aa1bc24e1 | ||
|
|
8e7a963f7f | ||
|
|
3e3f2b1354 | ||
|
|
cda174b1aa | ||
|
|
934e6a9837 | ||
|
|
2b821c69de | ||
|
|
1dd8dca56f | ||
|
|
6183f41d8c | ||
|
|
2cba0bf573 | ||
|
|
eb0e31e945 | ||
|
|
3e074a01a2 | ||
|
|
df5dff9008 | ||
|
|
2680fee6ce | ||
|
|
2d4e87b986 | ||
|
|
c5abbcaaf4 | ||
|
|
42e81a69ad | ||
|
|
1bbb597217 | ||
|
|
15ff4cc2de | ||
|
|
68061dfef2 | ||
|
|
781c32ac29 | ||
|
|
1763220f4e | ||
|
|
d37dcc7d71 | ||
|
|
efadd7170e | ||
|
|
65baf6c706 | ||
|
|
fa0f595cf9 | ||
|
|
3e2014216a | ||
|
|
fa78a0da14 | ||
|
|
1d47b2fc79 | ||
|
|
7ca040ad88 | ||
|
|
58bdb3f389 | ||
|
|
b930511d5b | ||
|
|
a3ad83e5f8 | ||
|
|
df27b4e4e0 | ||
|
|
78000f7f87 | ||
|
|
bc27eb2430 | ||
|
|
d9929185f3 | ||
|
|
2e2fdf481a | ||
|
|
1568393cf3 | ||
|
|
6d9266494b | ||
|
|
b424e06193 | ||
|
|
00f20c7d65 | ||
|
|
e50b8ab068 | ||
|
|
18c4dc903a | ||
|
|
ecc6d3264b | ||
|
|
a548454c57 | ||
|
|
10591b96c8 | ||
|
|
c561b0e117 | ||
|
|
d0eefe67c8 | ||
|
|
0801e742ab | ||
|
|
2d96b842de | ||
|
|
bfaca50963 | ||
|
|
921a0bbbfb | ||
|
|
5a0260cbcc | ||
|
|
420d238d70 | ||
|
|
cc3041cee0 | ||
|
|
809bbc79fb | ||
|
|
c2cf36e44e | ||
|
|
050b6c3d5f | ||
|
|
f04b875d88 | ||
|
|
4fdbe79875 | ||
|
|
a29e4e5b15 | ||
|
|
57d9952ece | ||
|
|
cbd7fd7dec | ||
|
|
1eba3f12e0 | ||
|
|
82c3e7df6d | ||
|
|
9acb35c45d | ||
|
|
dc75a4866c | ||
|
|
6806ca9630 | ||
|
|
68c0005c84 | ||
|
|
e15d1f5f79 | ||
|
|
b752d879c7 | ||
|
|
886343e50b | ||
|
|
9589c85462 | ||
|
|
2473a591bf | ||
|
|
52ed230e6f | ||
|
|
d273753223 | ||
|
|
f34f39491c | ||
|
|
5fd6fc8ae4 | ||
|
|
fc24d0b9cf | ||
|
|
85b1f06c9c | ||
|
|
b24cecb582 | ||
|
|
963cceee57 | ||
|
|
5add43aac8 | ||
|
|
2d41d8b6e2 | ||
|
|
f7183b361e | ||
|
|
e0587d1564 | ||
|
|
6a355b11a6 | ||
|
|
1890d482a7 | ||
|
|
9a62e42dd6 | ||
|
|
e66cb0c31e | ||
|
|
4b4a960bfb | ||
|
|
0a876f8e00 | ||
|
|
445aa5833b | ||
|
|
9d568b1bdd | ||
|
|
73b6b4eab6 | ||
|
|
3106f9a695 | ||
|
|
04ed7f99da | ||
|
|
9a35ff9fad | ||
|
|
997b332284 | ||
|
|
99be2974c3 | ||
|
|
09eafa22a7 | ||
|
|
d0613a0556 | ||
|
|
4c3bb3d6ba | ||
|
|
3aabb2ae35 | ||
|
|
272e429c2c | ||
|
|
fc5dc8e811 | ||
|
|
8a8e70d5a6 | ||
|
|
2f4e9acf95 | ||
|
|
7518a795db | ||
|
|
0f79f6ed15 | ||
|
|
7cb32717a9 | ||
|
|
af3406f86c | ||
|
|
4247e597c6 | ||
|
|
3621a3fd74 | ||
|
|
1dec12d618 | ||
|
|
0f700f0067 | ||
|
|
a6393381ec | ||
|
|
fa64afb29a | ||
|
|
d53b2ae83f | ||
|
|
5f4d728863 | ||
|
|
523ea309ce | ||
|
|
4a9e46ab99 | ||
|
|
2eaeb73742 | ||
|
|
e3c456752e | ||
|
|
25a1f3d894 | ||
|
|
90153d0224 | ||
|
|
d093125a6e | ||
|
|
c1065a28f9 | ||
|
|
dfb0ed4215 | ||
|
|
d6f67fed94 | ||
|
|
3cf1eb2c23 | ||
|
|
5560716098 | ||
|
|
8f8efbe011 | ||
|
|
6c7d5918b3 | ||
|
|
3dd30ce854 | ||
|
|
257a102789 | ||
|
|
00f134d99d | ||
|
|
1b13dffa8c | ||
|
|
4aca9276df | ||
|
|
2916e34116 | ||
|
|
ae312970b6 | ||
|
|
6933dc6991 | ||
|
|
0e3cc87362 | ||
|
|
4249bc4671 | ||
|
|
631a3b78cb | ||
|
|
ae556e2203 | ||
|
|
73442469a2 | ||
|
|
6504b376c3 | ||
|
|
4693981b23 | ||
|
|
cc6df875d6 | ||
|
|
9ad3d4b7b1 | ||
|
|
97ef187e5b | ||
|
|
1d20d5be0d | ||
|
|
8692d794c4 | ||
|
|
b4745088b1 | ||
|
|
3b1d9efc79 | ||
|
|
9fd97a3b30 | ||
|
|
e0908c3226 | ||
|
|
13ae5915d6 | ||
|
|
d1aae73bf3 | ||
|
|
2593fcb11c | ||
|
|
ae279a393f | ||
|
|
9fe95e59fc | ||
|
|
5004f536d3 | ||
|
|
0813e41bab | ||
|
|
899be54b87 | ||
|
|
a1351d366d | ||
|
|
84425899dd | ||
|
|
905da2b593 | ||
|
|
b5a9fff0ac | ||
|
|
b226057ffc | ||
|
|
a49d060935 | ||
|
|
211afcace9 | ||
|
|
13881cf3db | ||
|
|
6c43931970 | ||
|
|
0513ee0141 | ||
|
|
a0a457ef4c | ||
|
|
c00086981f | ||
|
|
e0e776a57e | ||
|
|
12f94f7a7a | ||
|
|
b143bb3fdd | ||
|
|
05a370b2d2 | ||
|
|
878077e3b0 | ||
|
|
4b795b56c8 | ||
|
|
f55b154644 | ||
|
|
9c5dc4c207 | ||
|
|
1961633531 | ||
|
|
00268d4ae6 | ||
|
|
416725e464 | ||
|
|
a7858d818d | ||
|
|
e2bde4d007 | ||
|
|
b3f8bdaff2 | ||
|
|
72fca75fb1 | ||
|
|
8f18fa7c78 | ||
|
|
8c642fb171 | ||
|
|
c6328d793c | ||
|
|
9fccec3f94 | ||
|
|
bf8595e255 | ||
|
|
8653af3a2e | ||
|
|
d1e9efc1de | ||
|
|
813764c458 | ||
|
|
a694d92cbd | ||
|
|
1c22d353a9 | ||
|
|
cae3501f7a | ||
|
|
c2ce99823e | ||
|
|
5c59a6a505 | ||
|
|
1cf15d2b4d | ||
|
|
fb0f0b6c37 | ||
|
|
e4f3ce78e3 | ||
|
|
dccc93bfb8 | ||
|
|
a89cd349f1 | ||
|
|
a27b613909 | ||
|
|
0e7af6107e | ||
|
|
f49b401512 | ||
|
|
3c7c613ec1 | ||
|
|
e02fb5a67b | ||
|
|
3a4b0be0b1 | ||
|
|
e9c1676826 | ||
|
|
fcfb05f5d3 | ||
|
|
8c233c93c1 | ||
|
|
0e5ff41021 | ||
|
|
23102369d1 | ||
|
|
1c46dc5929 | ||
|
|
fcf70e503f | ||
|
|
1aa5869ece | ||
|
|
e537ff7be6 | ||
|
|
e39bbfbe99 | ||
|
|
52768f711a | ||
|
|
1fae54c8c0 | ||
|
|
35299947e3 | ||
|
|
38f743a2c7 | ||
|
|
4a6019f7a6 | ||
|
|
fa3d7ed178 | ||
|
|
d1e5b0f72f | ||
|
|
dca8be01de | ||
|
|
511765faae | ||
|
|
3046c87be9 | ||
|
|
f2d42d756e | ||
|
|
8d9924c328 | ||
|
|
54488f1714 | ||
|
|
5b4a1fcaf3 | ||
|
|
e348eadefd | ||
|
|
b3d56cb364 | ||
|
|
65ae2c205e | ||
|
|
5e8ed94397 | ||
|
|
0eccb10a23 | ||
|
|
b16a1198d9 | ||
|
|
4402274b45 | ||
|
|
237b0edf0d | ||
|
|
77a9cc76b1 | ||
|
|
fc38a30572 | ||
|
|
fa2ceeffff | ||
|
|
18b503297b | ||
|
|
44fd5b0f83 | ||
|
|
13f704914a | ||
|
|
3166f1ad45 | ||
|
|
b82e966961 | ||
|
|
6fe99b6e66 | ||
|
|
cbbc8d66b8 | ||
|
|
4dc3934516 | ||
|
|
bd29989aab | ||
|
|
3416e2d194 | ||
|
|
730f1c88eb | ||
|
|
d16fc1a584 | ||
|
|
563ffe0ad3 | ||
|
|
5deb25bc9b | ||
|
|
0f4e877214 | ||
|
|
4df4dafad6 | ||
|
|
83ec300abd | ||
|
|
ddae61a859 | ||
|
|
75399e97a8 | ||
|
|
13446e004a | ||
|
|
4930197d21 | ||
|
|
008a36f3e4 | ||
|
|
dc53840e35 | ||
|
|
5471354571 | ||
|
|
7d16c9044e | ||
|
|
155f409a38 | ||
|
|
20c06fad80 | ||
|
|
4abbc2cf7d | ||
|
|
a6d8a3e498 | ||
|
|
c1c94e4437 | ||
|
|
c5bbe85f29 | ||
|
|
29a883d89f | ||
|
|
d6bc59fcc3 | ||
|
|
3475b52b60 | ||
|
|
efa3f28435 | ||
|
|
931a2a1ad2 | ||
|
|
3a8f5fae79 | ||
|
|
cef3740779 | ||
|
|
4d25d5aefd | ||
|
|
3c18b618a5 | ||
|
|
179e8f4df7 | ||
|
|
2798a075ee | ||
|
|
5429d6aeaf | ||
|
|
1c2958d455 | ||
|
|
e2d299f771 | ||
|
|
57f1472371 | ||
|
|
bea160e7f6 | ||
|
|
d739e9b6a8 | ||
|
|
2577d3bd45 | ||
|
|
c65da32867 | ||
|
|
ff9bd4ad1c | ||
|
|
3788abb994 | ||
|
|
a0c7ff582a | ||
|
|
b3dceb5360 | ||
|
|
500a1629c4 | ||
|
|
4c1c62892a | ||
|
|
434a115a3c | ||
|
|
74707353e8 | ||
|
|
dbdd83e5d0 | ||
|
|
538c6791ab | ||
|
|
22a5d73ebf | ||
|
|
820cc5a23d | ||
|
|
f7dfeb706f | ||
|
|
78ef9a971b | ||
|
|
ce6023fade | ||
|
|
4e9742386c | ||
|
|
030a749dc8 | ||
|
|
2f4c1aecdb | ||
|
|
b3291aebaa | ||
|
|
569b59f564 | ||
|
|
ccbbac847a | ||
|
|
8e4701fd31 | ||
|
|
de66468301 | ||
|
|
56f89b9850 | ||
|
|
1ff54c600e | ||
|
|
1337738c22 | ||
|
|
96b9e6e871 | ||
|
|
af5d98388a | ||
|
|
fd15b04d3b | ||
|
|
3dc41c544f | ||
|
|
52c009322f | ||
|
|
fd54886393 | ||
|
|
016dc0c5f0 | ||
|
|
97ed5b117d | ||
|
|
fbc8feeb40 | ||
|
|
a870464cc5 | ||
|
|
5f392f74b6 | ||
|
|
fef802ea7a | ||
|
|
d7a697aa50 | ||
|
|
9654f8c692 | ||
|
|
b28e8c3bd1 | ||
|
|
7ecdd17b4d | ||
|
|
125b29bfe3 | ||
|
|
63802cdd70 | ||
|
|
c69ccc749e | ||
|
|
f44fb9b450 | ||
|
|
f338047c19 | ||
|
|
691b2ab5c4 | ||
|
|
352d056288 | ||
|
|
335774aef1 | ||
|
|
cb2049e18e | ||
|
|
6457b295e1 | ||
|
|
bf9af9a408 | ||
|
|
231a11e2ce | ||
|
|
b7495e42ca | ||
|
|
7e4b0ec852 | ||
|
|
9db751daeb | ||
|
|
a883ddbe3e | ||
|
|
7e67cf48eb | ||
|
|
4ad4d79d41 | ||
|
|
90d55a9da9 | ||
|
|
983b95bdbd | ||
|
|
394e22ef5d | ||
|
|
140cd14f15 | ||
|
|
5b1614f31a | ||
|
|
c4e867d8dd | ||
|
|
0748314c35 | ||
|
|
f8876cc390 | ||
|
|
36f2cb4d7d | ||
|
|
86013715f6 | ||
|
|
cee756478e | ||
|
|
2517987176 | ||
|
|
49cd80a29d | ||
|
|
68cad4302a | ||
|
|
c201290179 | ||
|
|
8c05c20df4 | ||
|
|
3ecac0e0ab | ||
|
|
e4c108f3d7 | ||
|
|
d2c82fc45a | ||
|
|
7c2e55d3fd | ||
|
|
0c78f5bbad | ||
|
|
37c458acb7 | ||
|
|
775ce545d2 | ||
|
|
9b417d4592 | ||
|
|
2e0a0b5305 | ||
|
|
1caba8a761 | ||
|
|
6efd8f71f2 | ||
|
|
e5cf3448bd | ||
|
|
ea29292705 | ||
|
|
d32d625787 | ||
|
|
50ae8fdcf6 | ||
|
|
cb061edef8 | ||
|
|
49aba3d99e | ||
|
|
d8decf16a5 | ||
|
|
74357f24f8 | ||
|
|
fca6e38924 | ||
|
|
09446c7544 | ||
|
|
8bfcffa20a | ||
|
|
8a4ad6884b | ||
|
|
2021349249 | ||
|
|
e7392a5c22 | ||
|
|
6b0dccd9d5 | ||
|
|
90221ac971 | ||
|
|
e006418946 | ||
|
|
49ebd1264d | ||
|
|
94d07354ce | ||
|
|
2881b5c3df | ||
|
|
e0209e39ea | ||
|
|
e154c51512 | ||
|
|
e1196c53f2 | ||
|
|
56b431c4c2 | ||
|
|
ac4291f473 | ||
|
|
4dbcfc37b3 | ||
|
|
f59c9faee2 | ||
|
|
94c0eede77 | ||
|
|
61a92173cc | ||
|
|
c393791ed5 | ||
|
|
239ba78ee4 | ||
|
|
359b371edd | ||
|
|
67b4e0d544 | ||
|
|
2482413c83 | ||
|
|
de2192ab20 | ||
|
|
7fcc213b7a | ||
|
|
5aceb08fb4 | ||
|
|
1d465c4012 | ||
|
|
cc945fabb7 | ||
|
|
621251ae2e | ||
|
|
13e35220c2 | ||
|
|
45e6ca04f5 | ||
|
|
7c859988ba | ||
|
|
a221655e1a | ||
|
|
af3a20ad4e | ||
|
|
f4f6ef461b | ||
|
|
5719d6ca30 | ||
|
|
d918760272 | ||
|
|
58d332cff9 | ||
|
|
1f2c3cb141 | ||
|
|
398efeba2d | ||
|
|
0591917a06 | ||
|
|
9e61a85e86 | ||
|
|
bbdb1f12a0 | ||
|
|
fed4d43bd5 | ||
|
|
f9a4d9f781 | ||
|
|
1a664df87f | ||
|
|
eec0f0f9da | ||
|
|
77282aad96 | ||
|
|
c9301353fc | ||
|
|
4b7747b505 | ||
|
|
e7a40e1084 | ||
|
|
ee49fa81d9 | ||
|
|
cc4dae5c0f | ||
|
|
3826a26f8a | ||
|
|
045e0f533d | ||
|
|
e13c5f55a1 | ||
|
|
c74364be4c | ||
|
|
084fba1d17 | ||
|
|
c414b83e0a | ||
|
|
66dc9d1fbf | ||
|
|
e170502d63 | ||
|
|
71e4ddb74f | ||
|
|
4603752cef | ||
|
|
1795b4118f | ||
|
|
b47bd89d44 | ||
|
|
33201eb14c | ||
|
|
079f1e33dc | ||
|
|
cf341f6a19 | ||
|
|
ce13b82329 | ||
|
|
2afacbce95 | ||
|
|
c8e7bb7653 | ||
|
|
eeebae7172 | ||
|
|
80d62f0547 | ||
|
|
e588745d77 | ||
|
|
b3fc99501e | ||
|
|
c475df7cfb | ||
|
|
51ce0579e8 | ||
|
|
57102e40e9 | ||
|
|
afc4e512cb | ||
|
|
eeead325b4 | ||
|
|
5a177e9aaf | ||
|
|
9bd3b59e1d | ||
|
|
77bd578d9f | ||
|
|
fd7ecfb877 | ||
|
|
d60637c153 | ||
|
|
f206e0fb4b | ||
|
|
050e383cf2 | ||
|
|
29bbdb74d3 | ||
|
|
1545e31557 | ||
|
|
71f7b946a6 | ||
|
|
83a8197fe9 | ||
|
|
153e32d613 | ||
|
|
1b580435fc | ||
|
|
f185b8c243 | ||
|
|
991ad56e9c | ||
|
|
371c0aec0b | ||
|
|
2f35271c9d | ||
|
|
3cf665c0f5 | ||
|
|
ef90044383 | ||
|
|
5fb141ae40 | ||
|
|
da19723bdc | ||
|
|
d1b1eb61ee | ||
|
|
bacdc67e69 | ||
|
|
fc3ea33681 | ||
|
|
86fa45a2d2 | ||
|
|
e3d338650f | ||
|
|
88f8e603d9 | ||
|
|
2c4913d479 | ||
|
|
3681b8fdb5 | ||
|
|
9b3dad29d7 | ||
|
|
743a4fee3d | ||
|
|
35b9322dc3 | ||
|
|
a194fa9779 | ||
|
|
b8ef30620b | ||
|
|
46c8ea3458 | ||
|
|
10673db0ce | ||
|
|
14c5c590e0 | ||
|
|
533ca10a79 | ||
|
|
916a8e7276 | ||
|
|
baa4ae5c90 | ||
|
|
ae8248cd39 | ||
|
|
2293dabf3f | ||
|
|
90c1f734c0 | ||
|
|
2db0464fd9 | ||
|
|
202eeb707c | ||
|
|
2a340ce4c1 | ||
|
|
ae6192f9cb | ||
|
|
4d9ba4a652 | ||
|
|
9ff5b7077a | ||
|
|
351c77bca3 | ||
|
|
c1555b7cfd | ||
|
|
48ed067359 | ||
|
|
7234985a63 | ||
|
|
434c0fa7fb | ||
|
|
3fe69cba13 | ||
|
|
27f230c6bf | ||
|
|
a3204f806c | ||
|
|
be8b7d25f6 | ||
|
|
0bef3861ff | ||
|
|
dc5861414a | ||
|
|
3616fc519b | ||
|
|
bd9f2eb15d | ||
|
|
1dbb35b63b | ||
|
|
5fd49d1907 | ||
|
|
7024801722 | ||
|
|
40dfdbd929 | ||
|
|
0cb6effe14 | ||
|
|
a0c07fcf28 | ||
|
|
221f1bc18e | ||
|
|
c0c1cce296 | ||
|
|
a628ce605f | ||
|
|
3607c177d9 | ||
|
|
e1efe253d2 | ||
|
|
544d338e0e | ||
|
|
a9e916f1b9 | ||
|
|
c908681186 | ||
|
|
3b3a5ff07f | ||
|
|
e239fa05dd | ||
|
|
c5a85dbfdc | ||
|
|
d49ccd64f2 | ||
|
|
2815504547 | ||
|
|
19d052ff26 | ||
|
|
90806d3525 | ||
|
|
24886887f9 | ||
|
|
c0012125d2 | ||
|
|
896002d66a | ||
|
|
4389db676e | ||
|
|
1af6acb542 | ||
|
|
e9ccb8b496 | ||
|
|
8ffa3470bb | ||
|
|
77c0d1662a | ||
|
|
8fa6374b22 | ||
|
|
adb60835f7 | ||
|
|
fb62f4567b | ||
|
|
49e332ded2 | ||
|
|
079887fe42 | ||
|
|
8a227678b2 | ||
|
|
c7c8527ce3 | ||
|
|
1462dc4b66 | ||
|
|
0a2f847ac9 | ||
|
|
cc64de63b9 | ||
|
|
0708073b35 | ||
|
|
f88eecc172 | ||
|
|
f92a2c43b3 | ||
|
|
42ed459018 | ||
|
|
67e505d2ab | ||
|
|
802b562cbf | ||
|
|
336cf18ae8 | ||
|
|
5e8c17ac4e | ||
|
|
22ef6f7e0d | ||
|
|
de970528d7 | ||
|
|
2af8b0203e | ||
|
|
3bd15d3a70 | ||
|
|
d67fcf3f9c | ||
|
|
a65e5f86de | ||
|
|
8b268fb161 | ||
|
|
415a0e9de3 | ||
|
|
41765c8938 | ||
|
|
de6b083f58 | ||
|
|
ed8604f566 | ||
|
|
bbcc51539b | ||
|
|
b1dc2099c7 | ||
|
|
89524bf484 | ||
|
|
9b5022802e | ||
|
|
d6ea58f110 | ||
|
|
c53cfa6c6a | ||
|
|
5381389cdd | ||
|
|
08d9bb4c7c | ||
|
|
e51352557d | ||
|
|
159d4b2635 | ||
|
|
b16fb594ee | ||
|
|
23c0ba0065 | ||
|
|
2ebce7dad7 | ||
|
|
a8960a0876 | ||
|
|
9bd337033d | ||
|
|
cca5a0c27a | ||
|
|
b20173ba38 | ||
|
|
12edf1f533 | ||
|
|
9e607ddb5a | ||
|
|
33602d0a11 | ||
|
|
4b7fc1bb11 | ||
|
|
9a51ddaa6e | ||
|
|
e72c67b399 | ||
|
|
b81fc4d41d | ||
|
|
bfa8e4f4dc | ||
|
|
ed0399c961 | ||
|
|
68b7104563 | ||
|
|
6c2d2971a2 | ||
|
|
a592eefcbe | ||
|
|
2fce52b2ae | ||
|
|
750bed46fd | ||
|
|
d48588c89c | ||
|
|
d5552e2fbe | ||
|
|
0cdd360369 | ||
|
|
449ce271b1 | ||
|
|
9011c35db1 | ||
|
|
ccbd8395f4 | ||
|
|
25084ac51a | ||
|
|
4c1161c24a | ||
|
|
05d83f7b1a | ||
|
|
5a70bbe10b | ||
|
|
43e76a45e9 | ||
|
|
e78b0c8945 | ||
|
|
7cfeb436e4 | ||
|
|
1212cb034f | ||
|
|
6c3fce3382 | ||
|
|
bc2940927e | ||
|
|
5c21b9c7c7 | ||
|
|
2b692ce09c | ||
|
|
d236581f7b | ||
|
|
555cf46f2a | ||
|
|
00a454298c | ||
|
|
fb1a2c58dd | ||
|
|
40ee63b6ff | ||
|
|
38670f6730 | ||
|
|
fd1058d488 | ||
|
|
16ad898a13 | ||
|
|
90fc87af1c | ||
|
|
dc151ef624 | ||
|
|
37143a57b5 | ||
|
|
44b5581c48 | ||
|
|
fde54630a5 | ||
|
|
d72bb516ef | ||
|
|
a316791c49 | ||
|
|
42e84df47a | ||
|
|
abc071c974 | ||
|
|
ee6c9c9f00 | ||
|
|
bc213f0ba3 | ||
|
|
1e4644762a | ||
|
|
2efba704b3 | ||
|
|
fd49860e24 | ||
|
|
e615b54704 | ||
|
|
e2d691eda8 | ||
|
|
16483765ba | ||
|
|
9b461748a0 | ||
|
|
fbc3a63f6c | ||
|
|
f2262dec1c | ||
|
|
506f1152a8 | ||
|
|
33d0dac397 | ||
|
|
4cb3305614 | ||
|
|
029c8634fd | ||
|
|
9fde0d3e5a | ||
|
|
aec96db016 | ||
|
|
e97fab49d3 | ||
|
|
eee33c1731 | ||
|
|
ec7df3f449 | ||
|
|
7b2a90493f | ||
|
|
3304a8bc1e | ||
|
|
d0002e5394 | ||
|
|
3119d45e4c | ||
|
|
f87d2e5bb6 | ||
|
|
ffc62d0068 | ||
|
|
07b7df0b0e | ||
|
|
227c81511f | ||
|
|
bc8b826f65 | ||
|
|
d7890f281b | ||
|
|
3e5f21836f | ||
|
|
7d307a1ae7 | ||
|
|
f989073e0d | ||
|
|
837e136aa6 | ||
|
|
f211f9c476 | ||
|
|
43c2d3e981 | ||
|
|
15a1396579 | ||
|
|
40d62156ac | ||
|
|
df55f87e2d | ||
|
|
dbb5e86cde | ||
|
|
d9dbe7bb1e | ||
|
|
bb9fba63c4 | ||
|
|
33458f6fe4 | ||
|
|
020fdb84f4 | ||
|
|
059410842d | ||
|
|
a13a688507 | ||
|
|
792e537014 | ||
|
|
9a0684671a | ||
|
|
e2e1132eba | ||
|
|
ca5093b1ea | ||
|
|
694ffb7454 | ||
|
|
d28c66ab23 | ||
|
|
d5fb92d9a3 | ||
|
|
6abeee6109 | ||
|
|
3408cb4cab | ||
|
|
3f704efe4e | ||
|
|
7add065e0f | ||
|
|
3f1e1192cb | ||
|
|
a9aed18760 | ||
|
|
50dbacbaf0 | ||
|
|
cebf94f0db | ||
|
|
c8d1b2568b | ||
|
|
f707c50e9d | ||
|
|
6c3864d50e | ||
|
|
2c218563b3 | ||
|
|
0d83fc1704 | ||
|
|
9f2bd1e80f | ||
|
|
c22277cf6a | ||
|
|
2e23e829d9 | ||
|
|
be804ed5e6 | ||
|
|
29704cd895 | ||
|
|
8819aab738 | ||
|
|
aeecfffbb1 | ||
|
|
712675a744 | ||
|
|
53c50e58bf | ||
|
|
5ebe18e5ec | ||
|
|
a56a457941 | ||
|
|
2c83a6f53e | ||
|
|
22da94979e | ||
|
|
17cdd5f2d2 | ||
|
|
188ebe6ceb | ||
|
|
b42de3a4f3 | ||
|
|
f51c126c9d | ||
|
|
9cf82aad7e | ||
|
|
99b30a2b32 | ||
|
|
08b6a144bd | ||
|
|
cf086db3f2 | ||
|
|
90bb5bf23c | ||
|
|
cbfce81f38 | ||
|
|
68e9e6b533 | ||
|
|
6661778d6e | ||
|
|
aec00dd13c | ||
|
|
e51db8046c | ||
|
|
f28ed288b8 | ||
|
|
1dc5de0179 | ||
|
|
0a4081dc57 | ||
|
|
7721fe8b51 | ||
|
|
f324e94785 | ||
|
|
30d0cf44cb | ||
|
|
4a7725e917 | ||
|
|
dcb52d2ea8 | ||
|
|
e29e96a9e1 | ||
|
|
25fa1a3a8c | ||
|
|
6fd2ed3f11 | ||
|
|
0276b6e644 | ||
|
|
3bd8840931 | ||
|
|
36cf99464d | ||
|
|
f19cbcbff5 | ||
|
|
c7039276a0 | ||
|
|
1f136d8cb6 | ||
|
|
a5e1e1f33e | ||
|
|
1bebb796bb | ||
|
|
a19375e928 | ||
|
|
413706af15 | ||
|
|
8370f3e275 | ||
|
|
959413c95a | ||
|
|
325b2f4ade | ||
|
|
83ac8470a0 | ||
|
|
f6b543ae94 | ||
|
|
e9a10d7cda | ||
|
|
dc0adeafb4 | ||
|
|
80bc5b30c2 | ||
|
|
0412f3af19 | ||
|
|
c79a28077f | ||
|
|
6bd1189ac2 | ||
|
|
422d353b0a | ||
|
|
847f2ba0d5 | ||
|
|
cae0944eda | ||
|
|
37f5c2af03 | ||
|
|
95de12dbb4 | ||
|
|
de712c24fb | ||
|
|
26f9497dd4 | ||
|
|
dd1274d805 | ||
|
|
5587ec4f28 | ||
|
|
02e0c5c152 | ||
|
|
c7e456e77d | ||
|
|
e2eaca874e | ||
|
|
4fb87dc8de | ||
|
|
217acf1c4c | ||
|
|
c60bcbe173 | ||
|
|
666e80e5bd | ||
|
|
9597c478f9 | ||
|
|
1575eb36c1 | ||
|
|
b3e0829c50 | ||
|
|
403350cc99 | ||
|
|
a8069e81b7 | ||
|
|
11cd48efa3 | ||
|
|
96c666ffcf | ||
|
|
9b6ba77224 | ||
|
|
1c6910c2ec | ||
|
|
3557938100 | ||
|
|
ffb8dbaeee | ||
|
|
0cffbf8eb7 | ||
|
|
334a96f761 | ||
|
|
50cb73a76e | ||
|
|
35c72808bf | ||
|
|
859eff84db | ||
|
|
38dfb78b4e | ||
|
|
a1db4012d9 | ||
|
|
3f0cb9473b | ||
|
|
2edb721609 | ||
|
|
82abe83414 | ||
|
|
1bf1abb40a | ||
|
|
dd7b94054a | ||
|
|
ea1ff58500 | ||
|
|
9bbbadaa57 | ||
|
|
3c1c246415 | ||
|
|
52d39094e4 | ||
|
|
4aba0742ce | ||
|
|
6f1a0f1c60 | ||
|
|
99359a48d9 | ||
|
|
ef405dbe9c | ||
|
|
ee1f2a2484 | ||
|
|
9e6f2e579a | ||
|
|
ddb07346c0 | ||
|
|
2d8bb440c9 | ||
|
|
a23ee46c67 | ||
|
|
8d9808cb4d | ||
|
|
fa56a98ba9 | ||
|
|
bb95c2d8e9 | ||
|
|
51e67d70c4 | ||
|
|
bdafa7afcb | ||
|
|
51ab423164 | ||
|
|
94ad48ea87 | ||
|
|
99af655c4c | ||
|
|
4085af6b83 | ||
|
|
db9c41f45c | ||
|
|
03fec9c7fe | ||
|
|
06cfc731c6 | ||
|
|
e6dbc77e0e | ||
|
|
d321f40d3b | ||
|
|
b9098ee927 | ||
|
|
0d4a963517 |
@@ -4,7 +4,6 @@ compat/zlib/win64/zdll.lib
|
||||
compat/zlib/win64/zlib1.dll
|
||||
compat/zlib/win64/libz.dll.a
|
||||
compat/zlib/zlib.3.pdf
|
||||
tools/empty.zip
|
||||
*.bmp
|
||||
*.gif
|
||||
*.png
|
||||
@@ -1,19 +0,0 @@
|
||||
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/rules-ext.vc
|
||||
win/targets.vc
|
||||
win/tcl.dsp
|
||||
win/tcl.dsw
|
||||
win/tcl.hpj.in
|
||||
@@ -19,6 +19,8 @@
|
||||
*/tcltest*
|
||||
*/versions.vc
|
||||
*/version.vc
|
||||
*/libtcl.vfs
|
||||
*/libtcl_*.zip
|
||||
html
|
||||
libtommath/bn.ilg
|
||||
libtommath/bn.ind
|
||||
|
||||
+223
@@ -0,0 +1,223 @@
|
||||
sudo: false
|
||||
language: c
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: clang
|
||||
env:
|
||||
- CFGOPT=--disable-shared
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc
|
||||
env:
|
||||
- CFGOPT=--disable-shared
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-4.9
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.9
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-5
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-5
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-6
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-6
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-7
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-7
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-7
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-7
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- CFGOPT=CFLAGS=-DTCL_UTF_MAX=6
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: gcc-7
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-7
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- CFGOPT=CFLAGS=-DTCL_NO_DEPRECATED=1
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
env:
|
||||
- BUILD_DIR=unix
|
||||
- os: osx
|
||||
osx_image: xcode8
|
||||
env:
|
||||
- BUILD_DIR=macosx
|
||||
- NO_DIRECT_CONFIGURE=1
|
||||
- os: osx
|
||||
osx_image: xcode9
|
||||
env:
|
||||
- BUILD_DIR=macosx
|
||||
- NO_DIRECT_CONFIGURE=1
|
||||
- os: osx
|
||||
osx_image: xcode10.2
|
||||
env:
|
||||
- BUILD_DIR=macosx
|
||||
- NO_DIRECT_CONFIGURE=1
|
||||
### C builds not currently supported on Windows instances
|
||||
# - os: windows
|
||||
# env:
|
||||
# - BUILD_DIR=win
|
||||
### ... so proxy with a Mingw cross-compile
|
||||
# Test with mingw-w64 (32 bit)
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: i686-w64-mingw32-gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-mingw-w64-base
|
||||
- binutils-mingw-w64-i686
|
||||
- gcc-mingw-w64-i686
|
||||
- gcc-mingw-w64
|
||||
- gcc-multilib
|
||||
- wine
|
||||
env:
|
||||
- BUILD_DIR=win
|
||||
- CFGOPT=--host=i686-w64-mingw32
|
||||
- NO_DIRECT_TEST=1
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: i686-w64-mingw32-gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-mingw-w64-base
|
||||
- binutils-mingw-w64-i686
|
||||
- gcc-mingw-w64-i686
|
||||
- gcc-mingw-w64
|
||||
- gcc-multilib
|
||||
- wine
|
||||
env:
|
||||
- BUILD_DIR=win
|
||||
- CFGOPT="--host=i686-w64-mingw32 CFLAGS=-DTCL_UTF_MAX=6"
|
||||
- NO_DIRECT_TEST=1
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: i686-w64-mingw32-gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-mingw-w64-base
|
||||
- binutils-mingw-w64-i686
|
||||
- gcc-mingw-w64-i686
|
||||
- gcc-mingw-w64
|
||||
- gcc-multilib
|
||||
- wine
|
||||
env:
|
||||
- BUILD_DIR=win
|
||||
- CFGOPT="--host=i686-w64-mingw32 CFLAGS=-DTCL_NO_DEPRECATED=1"
|
||||
- NO_DIRECT_TEST=1
|
||||
# Test with mingw-w64 (64 bit)
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: x86_64-w64-mingw32-gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-mingw-w64-base
|
||||
- binutils-mingw-w64-x86-64
|
||||
- gcc-mingw-w64-x86-64
|
||||
- gcc-mingw-w64
|
||||
- wine
|
||||
env:
|
||||
- BUILD_DIR=win
|
||||
- CFGOPT="--host=x86_64-w64-mingw32 --enable-64bit"
|
||||
- NO_DIRECT_TEST=1
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: x86_64-w64-mingw32-gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-mingw-w64-base
|
||||
- binutils-mingw-w64-x86-64
|
||||
- gcc-mingw-w64-x86-64
|
||||
- gcc-mingw-w64
|
||||
- wine
|
||||
env:
|
||||
- BUILD_DIR=win
|
||||
- CFGOPT="--host=x86_64-w64-mingw32 --enable-64bit CFLAGS=-DTCL_UTF_MAX=6"
|
||||
- NO_DIRECT_TEST=1
|
||||
- os: linux
|
||||
dist: xenial
|
||||
compiler: x86_64-w64-mingw32-gcc
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gcc-mingw-w64-base
|
||||
- binutils-mingw-w64-x86-64
|
||||
- gcc-mingw-w64-x86-64
|
||||
- gcc-mingw-w64
|
||||
- wine
|
||||
env:
|
||||
- BUILD_DIR=win
|
||||
- CFGOPT="--host=x86_64-w64-mingw32 --enable-64bit CFLAGS=-DTCL_NO_DEPRECATED=1"
|
||||
- NO_DIRECT_TEST=1
|
||||
before_install:
|
||||
- export ERROR_ON_FAILURES=1
|
||||
- cd ${BUILD_DIR}
|
||||
install:
|
||||
- test -n "$NO_DIRECT_CONFIGURE" || ./configure ${CFGOPT}
|
||||
script:
|
||||
- make
|
||||
# The styles=develop avoids some weird problems on OSX
|
||||
- test -n "$NO_DIRECT_TEST" || make test styles=develop
|
||||
@@ -1,6 +1,6 @@
|
||||
A NOTE ON THE CHANGELOG:
|
||||
Starting in early 2011, Tcl source code has been under the management of
|
||||
fossil, hosted at http://core.tcl.tk/tcl/ . Fossil presents a "Timeline"
|
||||
fossil, hosted at https://core.tcl-lang.org/tcl/ . Fossil presents a "Timeline"
|
||||
view of changes made that is superior in every way to a hand edited log file.
|
||||
Because of this, many Tcl developers are now out of the habit of maintaining
|
||||
this log file. You may still find useful things in it, but the Timeline is
|
||||
|
||||
+1
-1
@@ -1426,7 +1426,7 @@
|
||||
initialization assumptions of the TIP 280 code in CompileWord().
|
||||
|
||||
* generic/tclCompExpr.c: Suppress the attempt to convert to
|
||||
numeric when pre-compiling a constant expresion indicates an error.
|
||||
numeric when pre-compiling a constant expression indicates an error.
|
||||
|
||||
2007-08-22 Miguel Sofer <msofer@users.sf.net>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ Tcl is maintained, enhanced, and distributed freely by the Tcl community.
|
||||
Source code development and tracking of bug reports and feature requests
|
||||
takes place at:
|
||||
|
||||
http://core.tcl.tk/
|
||||
http://core.tcl-lang.org/
|
||||
|
||||
Tcl/Tk release and mailing list services are hosted by SourceForge:
|
||||
|
||||
@@ -37,7 +37,7 @@ Tcl/Tk release and mailing list services are hosted by SourceForge:
|
||||
|
||||
with the Tcl Developer Xchange hosted at:
|
||||
|
||||
http://www.tcl.tk/
|
||||
http://www.tcl-lang.org/
|
||||
|
||||
Tcl is a freely available open source package. You can do virtually
|
||||
anything you like with it, such as modifying it, redistributing it,
|
||||
@@ -49,21 +49,21 @@ and selling it either in whole or in part. See the file
|
||||
|
||||
Extensive documentation is available at our website.
|
||||
The home page for this release, including new features, is
|
||||
http://www.tcl.tk/software/tcltk/8.7.html
|
||||
http://www.tcl-lang.org/software/tcltk/8.7.html
|
||||
|
||||
Detailed release notes can be found at the file distributions page
|
||||
by clicking on the relevant version.
|
||||
http://sourceforge.net/projects/tcl/files/Tcl/
|
||||
|
||||
Information about Tcl itself can be found at
|
||||
http://www.tcl.tk/about/
|
||||
http://www.tcl-lang.org/about/
|
||||
|
||||
There have been many Tcl books on the market. Many are mentioned in the Wiki:
|
||||
http://wiki.tcl.tk/_/ref?N=25206
|
||||
http://wiki.tcl-lang.org/_/ref?N=25206
|
||||
|
||||
To view the complete set of reference manual entries for Tcl 8.7 online,
|
||||
visit the URL:
|
||||
http://www.tcl.tk/man/tcl8.7/
|
||||
http://www.tcl-lang.org/man/tcl8.7/
|
||||
|
||||
2a. Unix Documentation
|
||||
----------------------
|
||||
@@ -101,7 +101,7 @@ There are brief notes in the unix/README, win/README, and macosx/README about
|
||||
compiling on these different platforms. There is additional information
|
||||
about building Tcl from sources at
|
||||
|
||||
http://www.tcl.tk/doc/howto/compile.html
|
||||
http://www.tcl-lang.org/doc/howto/compile.html
|
||||
|
||||
4. Development tools
|
||||
---------------------------
|
||||
@@ -127,7 +127,7 @@ see the "Support and bug fixes" section below.
|
||||
|
||||
A Wiki-based open community site covering all aspects of Tcl/Tk is at:
|
||||
|
||||
http://wiki.tcl.tk/
|
||||
http://wiki.tcl-lang.org/
|
||||
|
||||
It is dedicated to the Tcl programming language and its extensions. A
|
||||
wealth of useful information can be found there. It contains code
|
||||
@@ -153,7 +153,7 @@ We are very interested in receiving bug reports, patches, and suggestions
|
||||
for improvements. We prefer that you send this information to us as
|
||||
tickets entered into our tracker at:
|
||||
|
||||
http://core.tcl.tk/tcl/reportlist
|
||||
http://core.tcl-lang.org/tcl/reportlist
|
||||
|
||||
We will log and follow-up on each bug, although we cannot promise a
|
||||
specific turn-around time. Enhancements may take longer and may not happen
|
||||
@@ -169,13 +169,13 @@ questions for which no one else is likely to know the answer. In addition,
|
||||
see the following Web site for links to other organizations that offer
|
||||
Tcl/Tk training:
|
||||
|
||||
http://wiki.tcl.tk/training
|
||||
http://wiki.tcl-lang.org/training
|
||||
|
||||
9. Tracking Development
|
||||
-----------------------
|
||||
|
||||
Tcl is developed in public. To keep an eye on how Tcl is changing, see
|
||||
http://core.tcl.tk/
|
||||
http://core.tcl-lang.org/
|
||||
|
||||
10. Thank You
|
||||
-------------
|
||||
|
||||
@@ -8831,6 +8831,70 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
|
||||
|
||||
--- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2018-02-11 (enhance) stop blocking conversion of object to/from class (coulter)
|
||||
|
||||
2018-02-12 (enhance) NR-enable [package require] (coulter)
|
||||
|
||||
2018-02-14 (bug)[9fd5c6] crash in object deletion, test oo-11.5 (coulter)
|
||||
|
||||
2018-02-14 (bug)[3c32a3] crash deleting object with class mixed in (coulter)
|
||||
|
||||
2018-02-15 (platform) stop using -lieee, removed from glibc-2.27 (porter)
|
||||
***POTENTIAL INCOMPATIBILITY for math programs that embed Tcl***
|
||||
|
||||
2018-02-23 (bug)[8e6a9a] bad binary [string match], test string-11.55 (porter)
|
||||
|
||||
2018-03-05 (bug)[1873ea] repair multi-thread std channel init (sebres)
|
||||
|
||||
2018-03-09 (bug)[db36fa] broken bytecode for index values (porter)
|
||||
|
||||
2018-03-13 (bug) broken compiled [string replace], test string-14.19 (porter)
|
||||
|
||||
2018-03-14 (bug) [string trim*] engine crashed on invalid UTF (sebres)
|
||||
|
||||
2018-04-17 (bug) missing trace in compiled [array set], test var-20.11 (porter)
|
||||
|
||||
2018-04-22 (bug)[46a241] crash in unset array with search, var-13.[23] (goth)
|
||||
|
||||
2018-04-30 (bug)[27b682] race made [file delete] raise "no such file" (sebres)
|
||||
|
||||
2018-06-04 (bug)[925643] 32/64 cleanup of filesystem DIR operations (sebres)
|
||||
|
||||
2018-06-18 (bug) leaks in TclSetEnv and env cache (coulter)
|
||||
|
||||
2018-06-24 (bug)[3592747] [yieldto] dying namespace, tailcall-14.1 (coulter)
|
||||
|
||||
2018-07-09 (bug)[270f78] race in [file mkdir] (sebres)
|
||||
|
||||
2018-07-12 (bug)[3f7af0] [file delete] raised "permission denied" (sebres)
|
||||
|
||||
2018-07-26 (bug)[d051b7] overflow crash in [format] (sebres)
|
||||
|
||||
2018-08-29 revised quoting of [exec] args in generated command line (sebres)
|
||||
***POTENTIAL INCOMPATIBILITY***
|
||||
|
||||
2018-09-20 HTTP Keep-Alive with pipelined requests (nash)
|
||||
=> http 2.9.0
|
||||
|
||||
2018-09-27 (new)[TIP 505] [lreplace] accepts all out of range indices (porter)
|
||||
|
||||
2018-10-04 (bug) Prevent crash from NULL keyName (nijtmans)
|
||||
=> registry 1.3.3
|
||||
|
||||
2018-10-26 (enhance) advance dde version (nijtmans)
|
||||
=> dde 1.4.1
|
||||
|
||||
2018-10-27 tzdata updated to Olson's tzdata2018g (jima)
|
||||
|
||||
2018-10-29 Update tcltest package for Travis support (fellows)
|
||||
=> tcltest 2.5.0
|
||||
|
||||
2018-11-09 (bug)[35a8f1] overlong string length of some lists (owens)
|
||||
|
||||
2018-11-16 (bug)[00d04c] Repair [binary encode base64] (sebres)
|
||||
|
||||
- Released 8.6.9, November 16, 2018 - details at http://core.tcl-lang.org/tcl/ -
|
||||
|
||||
Changes to 8.7a1 include all changes to the 8.6 line through 8.6.7,
|
||||
plus the following, which focuses on the high-level feature changes
|
||||
in this changeset (new minor version) rather than bug fixes:
|
||||
@@ -8849,7 +8913,7 @@ in this changeset (new minor version) rather than bug fixes:
|
||||
|
||||
2016-10-04 Server socket on port 0 chooses port supporting IPv4 * IPv6 (max)
|
||||
|
||||
2016-11-25 [array named -regexp] supports backrefs (goth)
|
||||
2016-11-25 [array names -regexp] supports backrefs (goth)
|
||||
|
||||
2017-01-04 (TIP 456) New routine Tcl_OpenTcpServerEx() (limeboy)
|
||||
|
||||
@@ -8884,3 +8948,5 @@ in this changeset (new minor version) rather than bug fixes:
|
||||
|
||||
2018-03-12 (TIP 499) custom locale preference list (oehlmann)
|
||||
=> msgcat 1.7.0
|
||||
|
||||
- Released 8.7a3, Nov 30, 2018 --- http://core.tcl-lang.org/tcl/ for details -
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* fixstrtod.c --
|
||||
*
|
||||
* Source code for the "fixstrtod" procedure. This procedure is
|
||||
* used in place of strtod under Solaris 2.4, in order to fix
|
||||
* a bug where the "end" pointer gets set incorrectly.
|
||||
*
|
||||
* Copyright (c) 1995 Sun Microsystems, Inc.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#undef strtod
|
||||
|
||||
/*
|
||||
* Declare strtod explicitly rather than including stdlib.h, since in
|
||||
* somes systems (e.g. SunOS 4.1.4) stdlib.h doesn't declare strtod.
|
||||
*/
|
||||
|
||||
extern double strtod(char *, char **);
|
||||
|
||||
double
|
||||
fixstrtod(
|
||||
char *string,
|
||||
char **endPtr)
|
||||
{
|
||||
double d;
|
||||
d = strtod(string, endPtr);
|
||||
if ((endPtr != NULL) && (*endPtr != string) && ((*endPtr)[-1] == 0)) {
|
||||
*endPtr -= 1;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@@ -29,7 +29,6 @@ extern char * malloc(unsigned int numBytes);
|
||||
extern void qsort(void *base, int n, int size, int (*compar)(
|
||||
const void *element1, const void *element2));
|
||||
extern char * realloc(char *ptr, unsigned int numBytes);
|
||||
extern double strtod(const char *string, char **endPtr);
|
||||
extern long strtol(const char *string, char **endPtr, int base);
|
||||
extern unsigned long strtoul(const char *string, char **endPtr, int base);
|
||||
|
||||
|
||||
-252
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* strtod.c --
|
||||
*
|
||||
* Source code for the "strtod" library procedure.
|
||||
*
|
||||
* Copyright (c) 1988-1993 The Regents of the University of California.
|
||||
* Copyright (c) 1994 Sun Microsystems, Inc.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
static const int maxExponent = 511; /* Largest possible base 10 exponent. Any
|
||||
* exponent larger than this will already
|
||||
* produce underflow or overflow, so there's
|
||||
* no need to worry about additional digits.
|
||||
*/
|
||||
static const double powersOf10[] = { /* Table giving binary powers of 10. Entry */
|
||||
10., /* is 10^2^i. Used to convert decimal */
|
||||
100., /* exponents into floating-point numbers. */
|
||||
1.0e4,
|
||||
1.0e8,
|
||||
1.0e16,
|
||||
1.0e32,
|
||||
1.0e64,
|
||||
1.0e128,
|
||||
1.0e256
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* strtod --
|
||||
*
|
||||
* This procedure converts a floating-point number from an ASCII
|
||||
* decimal representation to internal double-precision format.
|
||||
*
|
||||
* Results:
|
||||
* The return value is the double-precision floating-point
|
||||
* representation of the characters in string. If endPtr isn't
|
||||
* NULL, then *endPtr is filled in with the address of the
|
||||
* next character after the last one that was part of the
|
||||
* floating-point number.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
double
|
||||
strtod(
|
||||
const char *string, /* A decimal ASCII floating-point number,
|
||||
* optionally preceded by white space. Must
|
||||
* have form "-I.FE-X", where I is the integer
|
||||
* part of the mantissa, F is the fractional
|
||||
* part of the mantissa, and X is the
|
||||
* exponent. Either of the signs may be "+",
|
||||
* "-", or omitted. Either I or F may be
|
||||
* omitted, or both. The decimal point isn't
|
||||
* necessary unless F is present. The "E" may
|
||||
* actually be an "e". E and X may both be
|
||||
* omitted (but not just one). */
|
||||
char **endPtr) /* If non-NULL, store terminating character's
|
||||
* address here. */
|
||||
{
|
||||
int sign, expSign = FALSE;
|
||||
double fraction, dblExp;
|
||||
const double *d;
|
||||
register const char *p;
|
||||
register int c;
|
||||
int exp = 0; /* Exponent read from "EX" field. */
|
||||
int fracExp = 0; /* Exponent that derives from the fractional
|
||||
* part. Under normal circumstatnces, it is
|
||||
* the negative of the number of digits in F.
|
||||
* However, if I is very long, the last digits
|
||||
* of I get dropped (otherwise a long I with a
|
||||
* large negative exponent could cause an
|
||||
* unnecessary overflow on I alone). In this
|
||||
* case, fracExp is incremented one for each
|
||||
* dropped digit. */
|
||||
int mantSize; /* Number of digits in mantissa. */
|
||||
int decPt; /* Number of mantissa digits BEFORE decimal
|
||||
* point. */
|
||||
const char *pExp; /* Temporarily holds location of exponent in
|
||||
* string. */
|
||||
|
||||
/*
|
||||
* Strip off leading blanks and check for a sign.
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace(UCHAR(*p))) {
|
||||
p += 1;
|
||||
}
|
||||
if (*p == '-') {
|
||||
sign = TRUE;
|
||||
p += 1;
|
||||
} else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
}
|
||||
sign = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count the number of digits in the mantissa (including the decimal
|
||||
* point), and also locate the decimal point.
|
||||
*/
|
||||
|
||||
decPt = -1;
|
||||
for (mantSize = 0; ; mantSize += 1)
|
||||
{
|
||||
c = *p;
|
||||
if (!isdigit(c)) {
|
||||
if ((c != '.') || (decPt >= 0)) {
|
||||
break;
|
||||
}
|
||||
decPt = mantSize;
|
||||
}
|
||||
p += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now suck up the digits in the mantissa. Use two integers to collect 9
|
||||
* digits each (this is faster than using floating-point). If the mantissa
|
||||
* has more than 18 digits, ignore the extras, since they can't affect the
|
||||
* value anyway.
|
||||
*/
|
||||
|
||||
pExp = p;
|
||||
p -= mantSize;
|
||||
if (decPt < 0) {
|
||||
decPt = mantSize;
|
||||
} else {
|
||||
mantSize -= 1; /* One of the digits was the point. */
|
||||
}
|
||||
if (mantSize > 18) {
|
||||
fracExp = decPt - 18;
|
||||
mantSize = 18;
|
||||
} else {
|
||||
fracExp = decPt - mantSize;
|
||||
}
|
||||
if (mantSize == 0) {
|
||||
fraction = 0.0;
|
||||
p = string;
|
||||
goto done;
|
||||
} else {
|
||||
int frac1, frac2;
|
||||
|
||||
frac1 = 0;
|
||||
for ( ; mantSize > 9; mantSize -= 1) {
|
||||
c = *p;
|
||||
p += 1;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
}
|
||||
frac1 = 10*frac1 + (c - '0');
|
||||
}
|
||||
frac2 = 0;
|
||||
for (; mantSize > 0; mantSize -= 1) {
|
||||
c = *p;
|
||||
p += 1;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
}
|
||||
frac2 = 10*frac2 + (c - '0');
|
||||
}
|
||||
fraction = (1.0e9 * frac1) + frac2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skim off the exponent.
|
||||
*/
|
||||
|
||||
p = pExp;
|
||||
if ((*p == 'E') || (*p == 'e')) {
|
||||
p += 1;
|
||||
if (*p == '-') {
|
||||
expSign = TRUE;
|
||||
p += 1;
|
||||
} else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
}
|
||||
expSign = FALSE;
|
||||
}
|
||||
if (!isdigit(UCHAR(*p))) {
|
||||
p = pExp;
|
||||
goto done;
|
||||
}
|
||||
while (isdigit(UCHAR(*p))) {
|
||||
exp = exp * 10 + (*p - '0');
|
||||
p += 1;
|
||||
}
|
||||
}
|
||||
if (expSign) {
|
||||
exp = fracExp - exp;
|
||||
} else {
|
||||
exp = fracExp + exp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a floating-point number that represents the exponent. Do this
|
||||
* by processing the exponent one bit at a time to combine many powers of
|
||||
* 2 of 10. Then combine the exponent with the fraction.
|
||||
*/
|
||||
|
||||
if (exp < 0) {
|
||||
expSign = TRUE;
|
||||
exp = -exp;
|
||||
} else {
|
||||
expSign = FALSE;
|
||||
}
|
||||
if (exp > maxExponent) {
|
||||
exp = maxExponent;
|
||||
errno = ERANGE;
|
||||
}
|
||||
dblExp = 1.0;
|
||||
for (d = powersOf10; exp != 0; exp >>= 1, ++d) {
|
||||
if (exp & 01) {
|
||||
dblExp *= *d;
|
||||
}
|
||||
}
|
||||
if (expSign) {
|
||||
fraction /= dblExp;
|
||||
} else {
|
||||
fraction *= dblExp;
|
||||
}
|
||||
|
||||
done:
|
||||
if (endPtr != NULL) {
|
||||
*endPtr = (char *) p;
|
||||
}
|
||||
|
||||
if (sign) {
|
||||
return -fraction;
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
+1
-1
@@ -53,7 +53,7 @@ strtol(
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace(UCHAR(*p))) {
|
||||
while (TclIsSpaceProc(*p)) {
|
||||
p += 1;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ strtoul(
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace(UCHAR(*p))) {
|
||||
while (TclIsSpaceProc(*p)) {
|
||||
p += 1;
|
||||
}
|
||||
if (*p == '-') {
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* unistd.h --
|
||||
*
|
||||
* Macros, constants and prototypes for Posix conformance.
|
||||
*
|
||||
* Copyright 1989 Regents of the University of California Permission to use,
|
||||
* copy, modify, and distribute this software and its documentation for any
|
||||
* purpose and without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies. The University of California makes
|
||||
* no representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
#ifndef _UNISTD
|
||||
#define _UNISTD
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Strict POSIX stuff goes here. Extensions go down below, in the ifndef
|
||||
* _POSIX_SOURCE section.
|
||||
*/
|
||||
|
||||
extern void _exit(int status);
|
||||
extern int access(const char *path, int mode);
|
||||
extern int chdir(const char *path);
|
||||
extern int chown(const char *path, uid_t owner, gid_t group);
|
||||
extern int close(int fd);
|
||||
extern int dup(int oldfd);
|
||||
extern int dup2(int oldfd, int newfd);
|
||||
extern int execl(const char *path, ...);
|
||||
extern int execle(const char *path, ...);
|
||||
extern int execlp(const char *file, ...);
|
||||
extern int execv(const char *path, char **argv);
|
||||
extern int execve(const char *path, char **argv, char **envp);
|
||||
extern int execvpw(const char *file, char **argv);
|
||||
extern pid_t fork(void);
|
||||
extern char * getcwd(char *buf, size_t size);
|
||||
extern gid_t getegid(void);
|
||||
extern uid_t geteuid(void);
|
||||
extern gid_t getgid(void);
|
||||
extern int getgroups(int bufSize, int *buffer);
|
||||
extern pid_t getpid(void);
|
||||
extern uid_t getuid(void);
|
||||
extern int isatty(int fd);
|
||||
extern long lseek(int fd, long offset, int whence);
|
||||
extern int pipe(int *fildes);
|
||||
extern int read(int fd, char *buf, size_t size);
|
||||
extern int setgid(gid_t group);
|
||||
extern int setuid(uid_t user);
|
||||
extern unsigned sleep(unsigned seconds);
|
||||
extern char * ttyname(int fd);
|
||||
extern int unlink(const char *path);
|
||||
extern int write(int fd, const char *buf, size_t size);
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
extern char * crypt(const char *, const char *);
|
||||
extern int fchown(int fd, uid_t owner, gid_t group);
|
||||
extern int flock(int fd, int operation);
|
||||
extern int ftruncate(int fd, unsigned long length);
|
||||
extern int ioctl(int fd, int request, ...);
|
||||
extern int readlink(const char *path, char *buf, int bufsize);
|
||||
extern int setegid(gid_t group);
|
||||
extern int seteuidw(uid_t user);
|
||||
extern int setreuid(int ruid, int euid);
|
||||
extern int symlink(const char *, const char *);
|
||||
extern int ttyslot(void);
|
||||
extern int truncate(const char *path, unsigned long length);
|
||||
extern int vfork(void);
|
||||
#endif /* _POSIX_SOURCE */
|
||||
|
||||
#endif /* _UNISTD */
|
||||
@@ -29,6 +29,12 @@
|
||||
|
||||
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
|
||||
|
||||
#ifdef Z_U4
|
||||
typedef Z_U4 z_crc_t;
|
||||
#else
|
||||
typedef unsigned long z_crc_t;
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Return the next byte in the pseudo-random sequence
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,7 @@ void change_file_date(filename,dosdate,tmu_date)
|
||||
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
|
||||
CloseHandle(hFile);
|
||||
#else
|
||||
#ifdef unix || __APPLE__
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
struct utimbuf ut;
|
||||
struct tm newdate;
|
||||
newdate.tm_sec = tmu_date.tm_sec;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) || defined(IOAPI_NO_64)
|
||||
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
|
||||
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
|
||||
#define FTELLO_FUNC(stream) ftello(stream)
|
||||
@@ -92,7 +92,7 @@ uLong filetime(f, tmzip, dt)
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#ifdef unix || __APPLE__
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
uLong filetime(f, tmzip, dt)
|
||||
char *f; /* name of file to get info on */
|
||||
tm_zip *tmzip; /* return value: access, modific. and creation times */
|
||||
@@ -359,7 +359,7 @@ void addFileToZip(zipFile zf, const char *filenameinzip, const char *password, i
|
||||
void addPathToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) {
|
||||
tinydir_dir dir;
|
||||
int i;
|
||||
char *newname[512];
|
||||
char newname[512];
|
||||
|
||||
tinydir_open_sorted(&dir, filenameinzip);
|
||||
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
.so man.macros
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj Tcl_RegisterCommandTypeName, Tcl_GetCommandTypeName \- implement new commands in C
|
||||
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj, Tcl_RegisterCommandTypeName, Tcl_GetCommandTypeName \- implement new commands in C
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
|
||||
@@ -134,6 +134,9 @@ finalization of Tcl's subsystems via \fBTcl_Finalize\fR at an
|
||||
appropriate time. The argument passed to \fIproc\fR when it is
|
||||
invoked will be the exit status code (as passed to \fBTcl_Exit\fR)
|
||||
cast to a ClientData value.
|
||||
.PP
|
||||
\fBTcl_SetExitProc\fR can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH "SEE ALSO"
|
||||
exit(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+3
-1
@@ -58,6 +58,8 @@ internal full path name of the executable file as computed by
|
||||
equivalent to the \fBinfo nameofexecutable\fR command. NULL
|
||||
is returned if the internal full path name has not been
|
||||
computed or unknown.
|
||||
|
||||
.PP
|
||||
\fBTcl_FindExecutable\fR can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH KEYWORDS
|
||||
binary, executable file
|
||||
|
||||
+5
-1
@@ -93,7 +93,11 @@ have a panic message displayed the same way that panic messages from Tcl
|
||||
will be displayed.
|
||||
.PP
|
||||
\fBTcl_PanicVA\fR is the same as \fBTcl_Panic\fR except that instead of
|
||||
taking a variable number of arguments it takes an argument list.
|
||||
taking a variable number of arguments it takes an argument list. This
|
||||
function is deprecated and will be removed in Tcl 9.0.
|
||||
.PP
|
||||
This function can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH "SEE ALSO"
|
||||
abort(3), printf(3), exec(n), format(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+2
-2
@@ -103,8 +103,8 @@ the argument's value. The following values are acceptable values for
|
||||
\fBTCL_ARGV_CONSTANT\fR
|
||||
.
|
||||
The argument does not take any following value argument. If this argument is
|
||||
present, the int pointed to by the \fIsrcPtr\fR field is copied to the
|
||||
\fIdstPtr\fR field. The \fIclientData\fR field is ignored.
|
||||
present, the \fIsrcPtr\fR field (casted to \fIint\fR) is copied to the variable
|
||||
pointed to by the \fIdstPtr\fR field. The \fIclientData\fR field is ignored.
|
||||
.TP
|
||||
\fBTCL_ARGV_END\fR
|
||||
.
|
||||
|
||||
@@ -64,6 +64,9 @@ the event of an error it should set the interpreter's result to point to an
|
||||
error message. The result or error from the initialization procedure will
|
||||
be returned as the result of the \fBload\fR command that caused the
|
||||
initialization procedure to be invoked.
|
||||
.PP
|
||||
This function can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH KEYWORDS
|
||||
initialization procedure, package, static linking
|
||||
.SH "SEE ALSO"
|
||||
|
||||
@@ -189,6 +189,8 @@ procedure (if any) returns. In non-interactive mode, after
|
||||
\fBTcl_Main\fR evaluates the startup script, and the main loop
|
||||
procedure (if any) returns, \fBTcl_Main\fR will also evaluate
|
||||
the \fBexit\fR command.
|
||||
.PP
|
||||
This function can not be used in stub-enabled extensions.
|
||||
.SH "SEE ALSO"
|
||||
tclsh(1), Tcl_GetStdChannel(3), Tcl_StandardChannels(3), Tcl_AppInit(3),
|
||||
exit(n), encoding(n)
|
||||
|
||||
@@ -132,7 +132,7 @@ represent one Unicode character in the UTF-8 representation.
|
||||
.PP
|
||||
\fBTcl_UniCharToUtf\fR stores the character \fIch\fR as a UTF-8 string
|
||||
in starting at \fIbuf\fR. The return value is the number of bytes stored
|
||||
in \fIbuf\fR. If ch is an upper surrogate (range U+D800 - U+DBFF), then
|
||||
in \fIbuf\fR. If ch is a high surrogate (range U+D800 - U+DBFF), then
|
||||
the return value will be 0 and nothing will be stored. If you still
|
||||
want to produce UTF-8 output for it (even though knowing it's an illegal
|
||||
code-point on its own), just call \fBTcl_UniCharToUtf\fR again using ch = -1.
|
||||
|
||||
+16
-10
@@ -886,40 +886,46 @@ The \fIinputString\fR argument consists of zero or more specifications of the
|
||||
following form:
|
||||
.TP
|
||||
\fItime\fR
|
||||
A time of day, which is of the form: \fBhh?:mm?:ss?? ?meridian? ?zone?\fR
|
||||
or \fBhhmm ?meridian? ?zone?\fR
|
||||
If no meridian is specified, \fBhh\fR is interpreted on
|
||||
.
|
||||
A time of day, which is of the form:
|
||||
.QW "\fIhh\fR?\fB:\fImm\fR?\fB:\fIss\fR?? ?\fImeridian\fR? ?\fIzone\fR?"
|
||||
or
|
||||
.QW "\fBhhmm \fR?\fBmeridian\fR? ?\fBzone\fR?" .
|
||||
If no \fImeridian\fR is specified, \fIhh\fR is interpreted on
|
||||
a 24-hour clock.
|
||||
.TP
|
||||
\fIdate\fR
|
||||
.
|
||||
A specific month and day with optional year. The
|
||||
acceptable formats are
|
||||
.QW "\fBmm/dd\fR?\fB/yy\fR?" ,
|
||||
.QW "\fBmonthname dd\fR?\fB, yy\fR?" ,
|
||||
.QW "\fBday, dd monthname \fR?\fByy\fR?" ,
|
||||
.QW "\fBdd monthname yy\fR" ,
|
||||
.QW "?\fBCC\fR?\fByymmdd\fR" ,
|
||||
.QW "\fImm\fB/\fIdd\fR?\fB/\fIyy\fR?" ,
|
||||
.QW "\fImonthname dd\fR?\fB, \fIyy\fR?" ,
|
||||
.QW "\fIday\fB, \fIdd monthname \fR?\fIyy\fR?" ,
|
||||
.QW "\fIdd monthname yy\fR" ,
|
||||
.QW "?\fICC\fR?\fIyymmdd\fR" ,
|
||||
and
|
||||
.QW "\fBdd-monthname-\fR?\fBCC\fR?\fByy\fR" .
|
||||
.QW "\fIdd\fB-\fImonthname\fB-\fR?\fICC\fR?\fIyy\fR" .
|
||||
The default year is the current year. If the year is less
|
||||
than 100, we treat the years 00-68 as 2000-2068 and the years 69-99
|
||||
as 1969-1999. Not all platforms can represent the years 38-70, so
|
||||
an error may result if these years are used.
|
||||
.TP
|
||||
\fIISO 8601 point-in-time\fR
|
||||
.
|
||||
An ISO 8601 point-in-time specification, such as
|
||||
.QW \fICCyymmdd\fBT\fIhhmmss\fR,
|
||||
where \fBT\fR is the literal
|
||||
.QW T ,
|
||||
.QW "\fICCyymmdd hhmmss\fR" ,
|
||||
or
|
||||
.QW \fICCyymmdd\fBT\fIhh:mm:ss\fR .
|
||||
.QW \fICCyymmdd\fBT\fIhh\fB:\fImm\fB:\fIss\fR .
|
||||
Note that only these three formats are accepted.
|
||||
The command does \fInot\fR accept the full range of point-in-time
|
||||
specifications specified in ISO8601. Other formats can be recognized by
|
||||
giving an explicit \fB\-format\fR option to the \fBclock scan\fR command.
|
||||
.TP
|
||||
\fIrelative time\fR
|
||||
.
|
||||
A specification relative to the current time. The format is \fBnumber
|
||||
unit\fR. Acceptable units are \fByear\fR, \fBfortnight\fR,
|
||||
\fBmonth\fR, \fBweek\fR, \fBday\fR,
|
||||
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2014-2018 Donal K. Fellows.
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH "cookiejar" n 0.1 http "Tcl Bundled Packages"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
cookiejar \- Implementation of the Tcl http package cookie jar protocol
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require\fR \fBcookiejar\fR ?\fB0.1\fR?
|
||||
|
||||
\fB::http::cookiejar configure\fR ?\fIoptionName\fR? ?\fIoptionValue\fR?
|
||||
\fB::http::cookiejar create\fR \fIname\fR ?\fIfilename\fR?
|
||||
\fB::http::cookiejar new\fR ?\fIfilename\fR?
|
||||
|
||||
\fIcookiejar\fR \fBdestroy\fR
|
||||
\fIcookiejar\fR \fBforceLoadDomainData\fR
|
||||
\fIcookiejar\fR \fBgetCookies\fR \fIprotocol host path\fR
|
||||
\fIcookiejar\fR \fBstoreCookie\fR \fIoptions\fR
|
||||
\fIcookiejar\fR \fBlookup\fR ?\fIhost\fR? ?\fIkey\fR?
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The cookiejar package provides an implementation of the http package's cookie
|
||||
jar protocol using an SQLite database. It provides one main command,
|
||||
\fB::http::cookiejar\fR, which is a TclOO class that should be instantiated to
|
||||
create a cookie jar that manages a particular HTTP session.
|
||||
.PP
|
||||
The database management policy can be controlled at the package level by the
|
||||
\fBconfigure\fR method on the \fB::http::cookiejar\fR class object:
|
||||
.TP
|
||||
\fB::http::cookiejar configure\fR ?\fIoptionName\fR? ?\fIoptionValue\fR?
|
||||
.
|
||||
If neither \fIoptionName\fR nor \fIoptionValue\fR are supplied, this returns a
|
||||
copy of the configuration as a Tcl dictionary. If just \fIoptionName\fR is
|
||||
supplied, just the value of the named option is returned. If both
|
||||
\fIoptionName\fR and \fIoptionValue\fR are given, the named option is changed
|
||||
to be the given value.
|
||||
.RS
|
||||
.PP
|
||||
Supported options are:
|
||||
.TP
|
||||
\fB\-domainfile \fIfilename\fR
|
||||
.
|
||||
A file (defaulting to within the cookiejar package) with a description of the
|
||||
list of top-level domains (e.g., \fB.com\fR or \fB.co.jp\fR). Such domains
|
||||
\fImust not\fR accept cookies set upon them. Note that the list of such
|
||||
domains is both security-sensitive and \fInot\fR constant and should be
|
||||
periodically refetched. Cookie jars maintain their own cache of the domain
|
||||
list.
|
||||
.TP
|
||||
\fB\-domainlist \fIurl\fR
|
||||
.
|
||||
A URL to fetch the list of top-level domains (e.g., \fB.com\fR or
|
||||
\fB.co.jp\fR) from. Such domains \fImust not\fR accept cookies set upon
|
||||
them. Note that the list of such domains is both security-sensitive and
|
||||
\fInot\fR constant and should be periodically refetched. Cookie jars maintain
|
||||
their own cache of the domain list.
|
||||
.TP
|
||||
\fB\-domainrefresh \fIintervalMilliseconds\fR
|
||||
.
|
||||
The number of milliseconds between checks of the \fI\-domainlist\fR for new
|
||||
domains.
|
||||
.TP
|
||||
\fB\-loglevel \fIlevel\fR
|
||||
.
|
||||
The logging level of this package. The logging level must be (in order of
|
||||
decreasing verbosity) one of \fBdebug\fR, \fBinfo\fR, \fBwarn\fR, or
|
||||
\fBerror\fR.
|
||||
.TP
|
||||
\fB\-offline \fIflag\fR
|
||||
.
|
||||
Allows the cookie managment engine to be placed into offline mode. In offline
|
||||
mode, the list of domains is read immediately from the file configured in the
|
||||
\fB\-domainfile\fR option, and the \fB\-domainlist\fR option is not used; it
|
||||
also makes the \fB\-domainrefresh\fR option be effectively ignored.
|
||||
.TP
|
||||
\fB\-purgeold \fIintervalMilliseconds\fR
|
||||
.
|
||||
The number of milliseconds between checks of the database for expired
|
||||
cookies; expired cookies are deleted.
|
||||
.TP
|
||||
\fB\-retain \fIcookieCount\fR
|
||||
.
|
||||
The maximum number of cookies to retain in the database.
|
||||
.TP
|
||||
\fB\-vacuumtrigger \fIdeletionCount\fR
|
||||
.
|
||||
A count of the number of persistent cookie deletions to go between vacuuming
|
||||
the database.
|
||||
.RE
|
||||
.PP
|
||||
Cookie jar instances may be made with any of the standard TclOO instance
|
||||
creation methods (\fBcreate\fR or \fRnew\fR).
|
||||
.TP
|
||||
\fB::http::cookiejar new\fR ?\fIfilename\fR?
|
||||
.
|
||||
If a \fIfilename\fR argument is provided, it is the name of a file containing
|
||||
an SQLite database that will contain the persistent cookies maintained by the
|
||||
cookie jar; the database will be created if the file does not already
|
||||
exist. If \fIfilename\fR is not supplied, the database will be held entirely within
|
||||
memory, which effectively forces all cookies within it to be session cookies.
|
||||
.SS "INSTANCE METHODS"
|
||||
.PP
|
||||
The following methods are supported on the instances:
|
||||
.TP
|
||||
\fIcookiejar\fR \fBdestroy\fR
|
||||
.
|
||||
This is the standard TclOO destruction method. It does \fInot\fR delete the
|
||||
SQLite database if it is written to disk. Callers are responsible for ensuring
|
||||
that the cookie jar is not in use by the http package at the time of
|
||||
destruction.
|
||||
.TP
|
||||
\fIcookiejar\fR \fBforceLoadDomainData\fR
|
||||
.
|
||||
This method causes the cookie jar to immediately load (and cache) the domain
|
||||
list data. The domain list will be loaded from the \fB\-domainlist\fR
|
||||
configured a the package level if that is enabled, and otherwise will be
|
||||
obtained from the \fB\-domainfile\fR configured at the package level.
|
||||
.TP
|
||||
\fIcookiejar\fR \fBgetCookies\fR \fIprotocol host path\fR
|
||||
.
|
||||
This method obtains the cookies for a particular HTTP request. \fIThis
|
||||
implements the http cookie jar protocol.\fR
|
||||
.TP
|
||||
\fIcookiejar\fR \fBpolicyAllow\fR \fIoperation domain path\fR
|
||||
.
|
||||
This method is called by the \fBstoreCookie\fR method to get a decision on
|
||||
whether to allow \fIoperation\fR to be performed for the \fIdomain\fR and
|
||||
\fIpath\fR. This is checked immediately before the database is updated but
|
||||
after the built-in security checks are done, and should return a boolean
|
||||
value; if the value is false, the operation is rejected and the database is
|
||||
not modified. The supported \fIoperation\fRs are:
|
||||
.RS
|
||||
.TP
|
||||
\fBdelete\fR
|
||||
.
|
||||
The \fIdomain\fR is seeking to delete a cookie.
|
||||
.TP
|
||||
\fBsession\fR
|
||||
.
|
||||
The \fIdomain\fR is seeking to create or update a session cookie.
|
||||
.TP
|
||||
\fBset\fR
|
||||
.
|
||||
The \fIdomain\fR is seeking to create or update a persistent cookie (with a
|
||||
defined lifetime).
|
||||
.PP
|
||||
The default implementation of this method just returns true, but subclasses of
|
||||
this class may impose their own rules.
|
||||
.RE
|
||||
.TP
|
||||
\fIcookiejar\fR \fBstoreCookie\fR \fIoptions\fR
|
||||
.
|
||||
This method stores a single cookie from a particular HTTP response. Cookies
|
||||
that fail security checks are ignored. \fIThis implements the http cookie jar
|
||||
protocol.\fR
|
||||
.TP
|
||||
\fIcookiejar\fR \fBlookup\fR ?\fIhost\fR? ?\fIkey\fR?
|
||||
.
|
||||
This method looks a cookie by exact host (or domain) matching. If neither
|
||||
\fIhost\fR nor \fIkey\fR are supplied, the list of hosts for which a cookie is
|
||||
stored is returned. If just \fIhost\fR (which may be a hostname or a domain
|
||||
name) is supplied, the list of cookie keys stored for that host is returned.
|
||||
If both \fIhost\fR and \fIkey\fR are supplied, the value for that key is
|
||||
returned; it is an error if no such host or key match exactly.
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
The simplest way of using a cookie jar is to just permanently configure it at
|
||||
the start of the application.
|
||||
.PP
|
||||
.CS
|
||||
package require http
|
||||
\fBpackage require cookiejar\fR
|
||||
|
||||
set cookiedb ~/.tclcookies.db
|
||||
http::configure -cookiejar [\fBhttp::cookiejar new\fR $cookiedb]
|
||||
|
||||
# No further explicit steps are required to use cookies
|
||||
set tok [http::geturl http://core.tcl.tk/]
|
||||
.CE
|
||||
.PP
|
||||
To only allow a particular domain to use cookies, perhaps because you only
|
||||
want to enable a particular host to create and manipulate sessions, create a
|
||||
subclass that imposes that policy.
|
||||
.PP
|
||||
.CS
|
||||
package require http
|
||||
\fBpackage require cookiejar\fR
|
||||
|
||||
oo::class create MyCookieJar {
|
||||
superclass \fBhttp::cookiejar\fR
|
||||
|
||||
method \fBpolicyAllow\fR {operation domain path} {
|
||||
return [expr {$domain eq "my.example.com"}]
|
||||
}
|
||||
}
|
||||
|
||||
set cookiedb ~/.tclcookies.db
|
||||
http::configure -cookiejar [MyCookieJar new $cookiedb]
|
||||
|
||||
# No further explicit steps are required to use cookies
|
||||
set tok [http::geturl http://core.tcl.tk/]
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
http(n), oo::class(n), sqlite3(n)
|
||||
.SH KEYWORDS
|
||||
cookie, internet, security policy, www
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
+187
-79
@@ -34,7 +34,11 @@ either the \fIdefScript\fR argument or by the \fIsubcommand\fR and following
|
||||
\fIarg\fR arguments; when the second is present, it is exactly as if all the
|
||||
arguments from \fIsubcommand\fR onwards are made into a list and that list is
|
||||
used as the \fIdefScript\fR argument.
|
||||
.SS "CONFIGURING CLASSES"
|
||||
.PP
|
||||
Note that the constructor for \fBoo::class\fR will call \fBoo::define\fR on
|
||||
the script argument that it is provided. This is a convenient way to create
|
||||
and define a class in one step.
|
||||
.SH "CONFIGURING CLASSES"
|
||||
.PP
|
||||
The following commands are supported in the \fIdefScript\fR for
|
||||
\fBoo::define\fR, each of which may also be used in the \fIsubcommand\fR form:
|
||||
@@ -70,13 +74,11 @@ namespace of the constructor will be a namespace that is unique to the object
|
||||
being constructed. Within the constructor, the \fBnext\fR command should be
|
||||
used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
|
||||
string, the constructor will be deleted.
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR?
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from a class. The methods
|
||||
must have previously existed in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified).
|
||||
.RS
|
||||
.PP
|
||||
Classes do not need to have a constructor defined. If none is specified, the
|
||||
superclass's constructor will be used instead.
|
||||
.RE
|
||||
.TP
|
||||
\fBdestructor\fI bodyScript\fR
|
||||
.
|
||||
@@ -102,16 +104,6 @@ class being defined. Note that the methods themselves may be actually defined
|
||||
by a superclass; subclass exports override superclass visibility, and may in
|
||||
turn be overridden by instances.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether
|
||||
method call to instances of the class may be called and what the method's
|
||||
results are. Each \fImethodName\fR names a single filtering method (which may
|
||||
be exposed or not exposed); it is not an error for a non-existent method to be
|
||||
named since they may be defined by subclasses.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBforward\fI name cmdName \fR?\fIarg ...\fR?
|
||||
.
|
||||
This creates or updates a forwarded method called \fIname\fR. The method is
|
||||
@@ -140,7 +132,7 @@ where the current namespace is the instance namespace of the class object
|
||||
itself. This is useful for setting up, e.g., class-scoped variables.
|
||||
.VE TIP478
|
||||
.TP
|
||||
\fBmethod\fI name argList bodyScript\fR
|
||||
\fBmethod\fI name \fR?\fIoption\fR? \fIargList bodyScript\fR
|
||||
.
|
||||
This creates or updates a method that is implemented as a procedure-like
|
||||
script. The name of the method is \fIname\fR, the formal arguments to the
|
||||
@@ -150,23 +142,20 @@ the body of the method is evaluated, the current namespace of the method will
|
||||
be a namespace that is unique to the current object. The method will be
|
||||
exported if \fIname\fR starts with a lower-case letter, and non-exported
|
||||
otherwise; this behavior can be overridden via \fBexport\fR and
|
||||
\fBunexport\fR.
|
||||
\fBunexport\fR
|
||||
.VS TIP519
|
||||
or by specifying \fB\-export\fR, \fB\-private\fR or \fB\-unexport\fR in the
|
||||
optional parameter \fIoption\fR.
|
||||
.VE TIP519
|
||||
.RS
|
||||
.PP
|
||||
.VS TIP500
|
||||
If in a private definition context (see the \fBprivate\fR definition command,
|
||||
below), this command creates private procedure-like methods.
|
||||
below) or if the \fB\-private\fR flag is given for \fIoption\fR, this command
|
||||
creates private procedure-like methods.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.TP
|
||||
\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of additional classes that are to be mixed into
|
||||
all the instances of the class being defined. Each \fIclassName\fR argument
|
||||
names a single class that is to be mixed in.
|
||||
By default, this slot works by replacement.
|
||||
.TP
|
||||
\fBprivate \fIcmd arg...\fR
|
||||
.TP
|
||||
\fBprivate \fIscript\fR
|
||||
@@ -186,16 +175,6 @@ context.
|
||||
.RE
|
||||
.VE TIP500
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
|
||||
method must have previously existed in the class, and \fItoName\fR must not
|
||||
previously refer to a method in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified). Does
|
||||
not change the export status of the method; if it was exported before, it will
|
||||
be afterwards.
|
||||
.TP
|
||||
\fBself\fI subcommand arg ...\fR
|
||||
.TP
|
||||
\fBself\fI script\fR
|
||||
@@ -269,24 +248,77 @@ namespace has a unique prefix that makes accidental use from other classes
|
||||
extremely unlikely.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.SS "CONFIGURING OBJECTS"
|
||||
.SS "ADVANCED CLASS CONFIGURATION OPTIONS"
|
||||
.PP
|
||||
The following definitions are also supported, but are not required in simple
|
||||
programs:
|
||||
.TP
|
||||
\fBdefinitionnamespace\fR ?\fIkind\fR? \fInamespaceName\fR
|
||||
.VS TIP524
|
||||
This allows control over what namespace will be used by the \fBoo::define\fR
|
||||
and \fBoo::objdefine\fR commands to look up the definition commands they
|
||||
use. When any object has a definition operation applied to it, \fIthe class that
|
||||
it is an instance of\fR (and its superclasses and mixins) is consulted for
|
||||
what definition namespace to use. \fBoo::define\fR gets the class definition
|
||||
namespace, and \fB::oo::objdefine\fR gets the instance definition namespace,
|
||||
but both otherwise use the identical lookup operation.
|
||||
.RS
|
||||
.PP
|
||||
This sets the definition namespace of kind \fIkind\fR provided by the current
|
||||
class to \fInamespaceName\fR. The \fInamespaceName\fR must refer to a
|
||||
currently existing namespace, or must be the empty string (to stop the current
|
||||
class from having such a namespace connected). The \fIkind\fR, if supplied,
|
||||
must be either \fB\-class\fR (the default) or \fB\-instance\fR to specify the
|
||||
whether the namespace for use with \fBoo::define\fR or \fBoo::objdefine\fR
|
||||
respectively is being set.
|
||||
.PP
|
||||
The class \fBoo::object\fR has its instance namespace locked to
|
||||
\fB::oo::objdefine\fR, and the class \fBoo::class\fR has its class namespace
|
||||
locked to \fB::oo::define\fR. A consequence of this is that effective use of
|
||||
this feature for classes requires the definition of a metaclass.
|
||||
.RE
|
||||
.VE TIP524
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR?
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from a class. The methods
|
||||
must have previously existed in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified).
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether
|
||||
method call to instances of the class may be called and what the method's
|
||||
results are. Each \fImethodName\fR names a single filtering method (which may
|
||||
be exposed or not exposed); it is not an error for a non-existent method to be
|
||||
named since they may be defined by subclasses.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of additional classes that are to be mixed into
|
||||
all the instances of the class being defined. Each \fIclassName\fR argument
|
||||
names a single class that is to be mixed in.
|
||||
By default, this slot works by replacement.
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
|
||||
method must have previously existed in the class, and \fItoName\fR must not
|
||||
previously refer to a method in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified). Does
|
||||
not change the export status of the method; if it was exported before, it will
|
||||
be afterwards.
|
||||
.SH "CONFIGURING OBJECTS"
|
||||
.PP
|
||||
The following commands are supported in the \fIdefScript\fR for
|
||||
\fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR
|
||||
form:
|
||||
.TP
|
||||
\fBclass\fI className\fR
|
||||
.
|
||||
This allows the class of an object to be changed after creation. Note that the
|
||||
class's constructors are not called when this is done, and so the object may
|
||||
well be in an inconsistent state unless additional configuration work is done.
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from an object. The methods
|
||||
must have previously existed in that object. Does not affect the classes that
|
||||
the object is an instance of.
|
||||
.TP
|
||||
\fBexport\fI name \fR?\fIname ...\fR?
|
||||
.
|
||||
This arranges for each of the named methods, \fIname\fR, to be exported
|
||||
@@ -294,17 +326,6 @@ This arranges for each of the named methods, \fIname\fR, to be exported
|
||||
being defined. Note that the methods themselves may be actually defined by a
|
||||
class or superclass; object exports override class visibility.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether a
|
||||
method call to the object may be called and what the method's results are.
|
||||
Each \fImethodName\fR names a single filtering method (which may be exposed or
|
||||
not exposed); it is not an error for a non-existent method to be named. Note
|
||||
that the actual list of filters also depends on the filters set upon any
|
||||
classes that the object is an instance of.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBforward\fI name cmdName \fR?\fIarg ...\fR?
|
||||
.
|
||||
This creates or updates a forwarded object method called \fIname\fR. The
|
||||
@@ -321,7 +342,7 @@ below), this command creates private forwarded methods.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.TP
|
||||
\fBmethod\fI name argList bodyScript\fR
|
||||
\fBmethod\fI name \fR?\fIoption\fR? \fIargList bodyScript\fR
|
||||
.
|
||||
This creates, updates or deletes an object method. The name of the method is
|
||||
\fIname\fR, the formal arguments to the method (defined using the same format
|
||||
@@ -329,12 +350,18 @@ as for the Tcl \fBproc\fR command) will be \fIargList\fR, and the body of the
|
||||
method will be \fIbodyScript\fR. When the body of the method is evaluated, the
|
||||
current namespace of the method will be a namespace that is unique to the
|
||||
object. The method will be exported if \fIname\fR starts with a lower-case
|
||||
letter, and non-exported otherwise.
|
||||
letter, and non-exported otherwise;
|
||||
.VS TIP519
|
||||
this can be overridden by specifying \fB\-export\fR, \fB\-private\fR or
|
||||
\fB\-unexport\fR in the optional parameter \fIoption\fR, or via the
|
||||
\fBexport\fR and \fBunexport\fR definitions.
|
||||
.VE TIP519
|
||||
.RS
|
||||
.PP
|
||||
.VS TIP500
|
||||
If in a private definition context (see the \fBprivate\fR definition command,
|
||||
below), this command creates private procedure-like methods.
|
||||
below) or if the \fB\-private\fR flag is given for \fIoption\fR, this command
|
||||
creates private procedure-like methods.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.TP
|
||||
@@ -363,19 +390,6 @@ difference in behavior when used in a private definition context.
|
||||
.RE
|
||||
.VE TIP500
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in an object to \fItoName\fR.
|
||||
The method must have previously existed in the object, and \fItoName\fR must
|
||||
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
|
||||
@@ -408,6 +422,46 @@ instance namespace has a unique prefix that makes accidental use from
|
||||
superclass methods extremely unlikely.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.SS "ADVANCED OBJECT CONFIGURATION OPTIONS"
|
||||
.PP
|
||||
The following definitions are also supported, but are not required in simple
|
||||
programs:
|
||||
.TP
|
||||
\fBclass\fI className\fR
|
||||
.
|
||||
This allows the class of an object to be changed after creation. Note that the
|
||||
class's constructors are not called when this is done, and so the object may
|
||||
well be in an inconsistent state unless additional configuration work is done.
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from an object. The methods
|
||||
must have previously existed in that object. Does not affect the classes that
|
||||
the object is an instance of.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether a
|
||||
method call to the object may be called and what the method's results are.
|
||||
Each \fImethodName\fR names a single filtering method (which may be exposed or
|
||||
not exposed); it is not an error for a non-existent method to be named. Note
|
||||
that the actual list of filters also depends on the filters set upon any
|
||||
classes that the object is an instance of.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in an object to \fItoName\fR.
|
||||
The method must have previously existed in the object, and \fItoName\fR must
|
||||
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
|
||||
.SH "PRIVATE METHODS"
|
||||
.VS TIP500
|
||||
When a class or instance has a private method, that private method can only be
|
||||
@@ -659,6 +713,60 @@ $g update "emailaddress=admins"
|
||||
\fI\(-> DB: update row ::oo::Obj125 with emailaddress=admins\fR
|
||||
.CE
|
||||
.VE TIP478
|
||||
.PP
|
||||
.VS TIP524
|
||||
This example shows how to make a custom definition for a class. Note that it
|
||||
explicitly includes delegation to the existing definition commands via
|
||||
\fBnamespace path\fR.
|
||||
.PP
|
||||
.CS
|
||||
namespace eval myDefinitions {
|
||||
# Delegate to existing definitions where not overridden
|
||||
namespace path \fB::oo::define\fR
|
||||
|
||||
# A custom type of method
|
||||
proc exprmethod {name arguments body} {
|
||||
tailcall \fBmethod\fR $name $arguments [list expr $body]
|
||||
}
|
||||
|
||||
# A custom way of building a constructor
|
||||
proc parameters args {
|
||||
uplevel 1 [list \fBvariable\fR {*}$args]
|
||||
set body [join [lmap a $args {
|
||||
string map [list VAR $a] {
|
||||
set [my varname VAR] [expr {double($VAR)}]
|
||||
}
|
||||
}] ";"]
|
||||
tailcall \fBconstructor\fR $args $body
|
||||
}
|
||||
}
|
||||
|
||||
# Bind the namespace into a (very simple) metaclass for use
|
||||
oo::class create exprclass {
|
||||
\fBsuperclass\fR oo::class
|
||||
\fBdefinitionnamespace\fR myDefinitions
|
||||
}
|
||||
|
||||
# Use the custom definitions
|
||||
exprclass create quadratic {
|
||||
parameters a b c
|
||||
exprmethod evaluate {x} {
|
||||
($a * $x**2) + ($b * $x) + $c
|
||||
}
|
||||
}
|
||||
|
||||
# Showing the resulting class and object in action
|
||||
quadratic create quad 1 2 3
|
||||
for {set x 0} {$x <= 4} {incr x} {
|
||||
puts [format "quad(%d) = %.2f" $x [quad evaluate $x]]
|
||||
}
|
||||
\fI\(-> quad(0) = 3.00\fR
|
||||
\fI\(-> quad(1) = 6.00\fR
|
||||
\fI\(-> quad(2) = 11.00\fR
|
||||
\fI\(-> quad(3) = 18.00\fR
|
||||
\fI\(-> quad(4) = 27.00\fR
|
||||
.CE
|
||||
.VE TIP524
|
||||
.SH "SEE ALSO"
|
||||
next(n), oo::class(n), oo::object(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+113
-2
@@ -13,10 +13,10 @@
|
||||
.SH NAME
|
||||
http \- Client-side implementation of the HTTP/1.1 protocol
|
||||
.SH SYNOPSIS
|
||||
\fBpackage require http ?2.8?\fR
|
||||
\fBpackage require http\fI ?\fB2.8\fR?
|
||||
.\" See Also -useragent option documentation in body!
|
||||
.sp
|
||||
\fB::http::config ?\fI\-option value\fR ...?
|
||||
\fB::http::config\fR ?\fI\-option value\fR ...?
|
||||
.sp
|
||||
\fB::http::geturl \fIurl\fR ?\fI\-option value\fR ...?
|
||||
.sp
|
||||
@@ -99,6 +99,15 @@ comma-separated list of mime type patterns that you are
|
||||
willing to receive. For example,
|
||||
.QW "image/gif, image/jpeg, text/*" .
|
||||
.TP
|
||||
\fB\-cookiejar\fR \fIcommand\fR
|
||||
.VS TIP406
|
||||
The cookie store for the package to use to manage HTTP cookies.
|
||||
\fIcommand\fR is a command prefix list; if the empty list (the
|
||||
default value) is used, no cookies will be sent by requests or stored
|
||||
from responses. The command indicated by \fIcommand\fR, if supplied,
|
||||
must obey the \fBCOOKIE JAR PROTOCOL\fR described below.
|
||||
.VE TIP406
|
||||
.TP
|
||||
\fB\-pipeline\fR \fIboolean\fR
|
||||
.
|
||||
Specifies whether HTTP/1.1 transactions on a persistent socket will be
|
||||
@@ -770,6 +779,108 @@ Subsequent GET and HEAD requests in a failed pipeline will also be retried.
|
||||
that the retry is appropriate\fR - specifically, the application must know
|
||||
that if the failed POST successfully modified the state of the server, a repeat POST
|
||||
would have no adverse effect.
|
||||
.VS TIP406
|
||||
.SH "COOKIE JAR PROTOCOL"
|
||||
.PP
|
||||
Cookies are short key-value pairs used to implement sessions within the
|
||||
otherwise-stateless HTTP protocol. (See RFC 6265 for details; Tcl does not
|
||||
implement the Cookie2 protocol as that is rarely seen in the wild.)
|
||||
.PP
|
||||
Cookie storage managment commands \(em
|
||||
.QW "cookie jars"
|
||||
\(em must support these subcommands which form the HTTP cookie storage
|
||||
management protocol. Note that \fIcookieJar\fR below does not have to be a
|
||||
command name; it is properly a command prefix (a Tcl list of words that will
|
||||
be expanded in place) and admits many possible implementations.
|
||||
.PP
|
||||
Though not formally part of the protocol, it is expected that particular
|
||||
values of \fIcookieJar\fR will correspond to sessions; it is up to the caller
|
||||
of \fB::http::config\fR to decide what session applies and to manage the
|
||||
deletion of said sessions when they are no longer desired (which should be
|
||||
when they not configured as the current cookie jar).
|
||||
.TP
|
||||
\fIcookieJar \fBgetCookies \fIprotocol host requestPath\fR
|
||||
.
|
||||
This command asks the cookie jar what cookies should be supplied for a
|
||||
particular request. It should take the \fIprotocol\fR (typically \fBhttp\fR or
|
||||
\fBhttps\fR), \fIhost\fR name and \fIrequestPath\fR (parsed from the \fIurl\fR
|
||||
argument to \fB::http::geturl\fR) and return a list of cookie keys and values
|
||||
that describe the cookies to supply to the remote host. The list must have an
|
||||
even number of elements.
|
||||
.RS
|
||||
.PP
|
||||
There should only ever be at most one cookie with a particular key for any
|
||||
request (typically the one with the most specific \fIhost\fR/domain match and
|
||||
most specific \fIrequestPath\fR/path match), but there may be many cookies
|
||||
with different names in any request.
|
||||
.RE
|
||||
.TP
|
||||
\fIcookieJar \fBstoreCookie \fIcookieDictionary\fR
|
||||
.
|
||||
This command asks the cookie jar to store a particular cookie that was
|
||||
returned by a request; the result of this command is ignored. The cookie
|
||||
(which will have been parsed by the http package) is described by a
|
||||
dictionary, \fIcookieDictionary\fR, that may have the following keys:
|
||||
.RS
|
||||
.TP
|
||||
\fBdomain\fR
|
||||
.
|
||||
This is always present. Its value describes the domain hostname \fIor
|
||||
prefix\fR that the cookie should be returned for. The checking of the domain
|
||||
against the origin (below) should be careful since sites that issue cookies
|
||||
should only do so for domains related to themselves. Cookies that do not obey
|
||||
a relevant origin matching rule should be ignored.
|
||||
.TP
|
||||
\fBexpires\fR
|
||||
.
|
||||
This is optional. If present, the cookie is intended to be a persistent cookie
|
||||
and the value of the option is the Tcl timestamp (in seconds from the same
|
||||
base as \fBclock seconds\fR) of when the cookie expires (which may be in the
|
||||
past, which should result in the cookie being deleted immediately). If absent,
|
||||
the cookie is intended to be a session cookie that should be not persisted
|
||||
beyond the lifetime of the cookie jar.
|
||||
.TP
|
||||
\fBhostonly\fR
|
||||
.
|
||||
This is always present. Its value is a boolean that describes whether the
|
||||
cookie is a single host cookie (true) or a domain-level cookie (false).
|
||||
.TP
|
||||
\fBhttponly\fR
|
||||
.
|
||||
This is always present. Its value is a boolean that is true when the site
|
||||
wishes the cookie to only ever be used with HTTP (or HTTPS) traffic.
|
||||
.TP
|
||||
\fBkey\fR
|
||||
.
|
||||
This is always present. Its value is the \fIkey\fR of the cookie, which is
|
||||
part of the information that must be return when sending this cookie back in a
|
||||
future request.
|
||||
.TP
|
||||
\fBorigin\fR
|
||||
.
|
||||
This is always present. Its value describes where the http package believes it
|
||||
received the cookie from, which may be useful for checking whether the
|
||||
cookie's domain is valid.
|
||||
.TP
|
||||
\fBpath\fR
|
||||
.
|
||||
This is always present. Its value describes the path prefix of requests to the
|
||||
cookie domain where the cookie should be returned.
|
||||
.TP
|
||||
\fBsecure\fR
|
||||
.
|
||||
This is always present. Its value is a boolean that is true when the cookie
|
||||
should only used on requests sent over secure channels (typically HTTPS).
|
||||
.TP
|
||||
\fBvalue\fR
|
||||
.
|
||||
This is always present. Its value is the value of the cookie, which is part of
|
||||
the information that must be return when sending this cookie back in a future
|
||||
request.
|
||||
.PP
|
||||
Other keys may always be ignored; they have no meaning in this protocol.
|
||||
.RE
|
||||
.VE TIP406
|
||||
.SH EXAMPLE
|
||||
.PP
|
||||
This example creates a procedure to copy a URL to a file while printing a
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2014-2018 Donal K. Fellows.
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH "idna" n 0.1 http "Tcl Bundled Packages"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
tcl::idna \- Support for normalization of Internationalized Domain Names
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
package require tcl::idna 1.0
|
||||
|
||||
\fBtcl::idna decode\fR \fIhostname\fR
|
||||
\fBtcl::idna encode\fR \fIhostname\fR
|
||||
\fBtcl::idna puny decode\fR \fIstring\fR ?\fIcase\fR?
|
||||
\fBtcl::idna puny encode\fR \fIstring\fR ?\fIcase\fR?
|
||||
\fBtcl::idna version\fR
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
This package provides an implementation of the punycode scheme used in
|
||||
Internationalised Domain Names, and some access commands. (See RFC 3492 for a
|
||||
description of punycode.)
|
||||
.TP
|
||||
\fBtcl::idna decode\fR \fIhostname\fR
|
||||
.
|
||||
This command takes the name of a host that potentially contains
|
||||
punycode-encoded character sequences, \fIhostname\fR, and returns the hostname
|
||||
as might be displayed to the user. Note that there are often UNICODE
|
||||
characters that have extremely similar glyphs, so care should be taken with
|
||||
displaying hostnames to users.
|
||||
.TP
|
||||
\fBtcl::idna encode\fR \fIhostname\fR
|
||||
.
|
||||
This command takes the name of a host as might be displayed to the user,
|
||||
\fIhostname\fR, and returns the version of the hostname with characters not
|
||||
permitted in basic hostnames encoded with punycode.
|
||||
.TP
|
||||
\fBtcl::idna puny\fR \fIsubcommand ...\fR
|
||||
.
|
||||
This command provides direct access to the basic punycode encoder and
|
||||
decoder. It supports two \fIsubcommand\fRs:
|
||||
.RS
|
||||
.TP
|
||||
\fBtcl::idna puny decode\fR \fIstring\fR ?\fIcase\fR?
|
||||
.
|
||||
This command decodes the punycode-encoded string, \fIstring\fR, and returns
|
||||
the result. If \fIcase\fR is provided, it is a boolean to make the case be
|
||||
folded to upper case (if \fIcase\fR is true) or lower case (if \fIcase\fR is
|
||||
false) during the decoding process; if omitted, no case transformation is
|
||||
applied.
|
||||
.TP
|
||||
\fBtcl::idna puny encode\fR \fIstring\fR ?\fIcase\fR?
|
||||
.
|
||||
This command encodes the string, \fIstring\fR, and returns the
|
||||
punycode-encoded version of the string. If \fIcase\fR is provided, it is a
|
||||
boolean to make the case be folded to upper case (if \fIcase\fR is true) or
|
||||
lower case (if \fIcase\fR is false) during the encoding process; if omitted,
|
||||
no case transformation is applied.
|
||||
.RE
|
||||
.TP
|
||||
\fBtcl::idna version\fR
|
||||
.
|
||||
This returns the version of the \fBtcl::idna\fR package.
|
||||
.SH "EXAMPLE"
|
||||
.PP
|
||||
This is an example of how punycoding of a string works:
|
||||
.PP
|
||||
.CS
|
||||
package require tcl::idna
|
||||
|
||||
puts [\fBtcl::idna puny encode\fR "abc\(->def"]
|
||||
# prints: \fIabcdef-kn2c\fR
|
||||
puts [\fBtcl::idna puny decode\fR "abcdef-kn2c"]
|
||||
# prints: \fIabc\(->def\fR
|
||||
.CE
|
||||
'\" TODO: show how it handles a real domain name
|
||||
.SH "SEE ALSO"
|
||||
http(n), cookiejar(n)
|
||||
.SH KEYWORDS
|
||||
internet, www
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
+18
@@ -481,6 +481,24 @@ list; the first element is the list of arguments to the method in a form
|
||||
suitable for passing to another call to \fBproc\fR or a method definition, and
|
||||
the second element is the body of the method.
|
||||
.TP
|
||||
\fBinfo class definitionnamespace\fI class\fR ?\fIkind\fR?
|
||||
.VS TIP524
|
||||
This subcommand returns the definition namespace for \fIkind\fR definitions of
|
||||
the class \fIclass\fR; the definition namespace only affects the instances of
|
||||
\fIclass\fR, not \fIclass\fR itself. The \fIkind\fR can be either
|
||||
\fB\-class\fR to return the definition namespace used for \fBoo::define\fR, or
|
||||
\fB\-instance\fR to return the definition namespace used for
|
||||
\fBoo::objdefine\fR; the \fB\-class\fR kind is default (though this is only
|
||||
actually useful on classes that are subclasses of \fBoo::class\fR).
|
||||
.RS
|
||||
.PP
|
||||
If \fIclass\fR does not provide a definition namespace of the specified kind,
|
||||
this command returns the empty string. In those circumstances, the
|
||||
\fBoo::define\fR and \fBoo::objdefine\fR commands look up which definition
|
||||
namespace to use using the class inheritance hierarchy.
|
||||
.RE
|
||||
.VE TIP524
|
||||
.TP
|
||||
\fBinfo class destructor\fI class\fR
|
||||
.
|
||||
This subcommand returns the body of the destructor of class \fIclass\fR. If no
|
||||
|
||||
+1
-1
@@ -236,7 +236,7 @@ attempts are silently ignored. This is needed to maintain the
|
||||
consistency of the underlying interpreter's state.
|
||||
.RE
|
||||
.TP
|
||||
\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
|
||||
\fBinterp\fR \fBdelete \fR?\fIpath ...\fR?
|
||||
.
|
||||
Deletes zero or more interpreters given by the optional \fIpath\fR
|
||||
arguments, and for each interpreter, it also deletes its slaves. The
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
.SH NAME
|
||||
lindex \- Retrieve an element from a list
|
||||
.SH SYNOPSIS
|
||||
\fBlindex \fIlist ?index ...?\fR
|
||||
\fBlindex \fIlist\fR ?\fIindex ...\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2018 by Peter Spjuth. All rights reserved.
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH lpop n 8.7 Tcl "Tcl Built-In Commands"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
lpop \- Get and remove an element in a list
|
||||
.SH SYNOPSIS
|
||||
\fBlpop \fIvarName ?index ...?\fR
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBlpop\fR command accepts a parameter, \fIvarName\fR, which
|
||||
it interprets as the name of a variable containing a Tcl list.
|
||||
It also accepts one or more \fIindices\fR into
|
||||
the list. If no indices are presented, it defaults to "end".
|
||||
.PP
|
||||
When presented with a single index, the \fBlpop\fR command
|
||||
addresses the \fIindex\fR'th element in it, removes if from the list
|
||||
and returns the element.
|
||||
.PP
|
||||
If \fIindex\fR is negative or greater or equal than the number
|
||||
of elements in \fI$varName\fR, then an error occurs.
|
||||
.PP
|
||||
The interpretation of each simple \fIindex\fR value is the same as
|
||||
for the command \fBstring index\fR, supporting simple index
|
||||
arithmetic and indices relative to the end of the list.
|
||||
.PP
|
||||
If additional \fIindex\fR arguments are supplied, then each argument is
|
||||
used in turn to address an element within a sublist designated
|
||||
by the previous indexing operation,
|
||||
allowing the script to remove elements in sublists.
|
||||
The command,
|
||||
.PP
|
||||
.CS
|
||||
\fBlpop\fR a 1 2
|
||||
.CE
|
||||
.PP
|
||||
gets and removes element 2 of sublist 1.
|
||||
.PP
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
In each of these examples, the initial value of \fIx\fR is:
|
||||
.PP
|
||||
.CS
|
||||
set x [list [list a b c] [list d e f] [list g h i]]
|
||||
\fI\(-> {a b c} {d e f} {g h i}\fR
|
||||
.CE
|
||||
.PP
|
||||
The indicated value becomes the new value of \fIx\fR
|
||||
(except in the last case, which is an error which leaves the value of
|
||||
\fIx\fR unchanged.)
|
||||
.PP
|
||||
.CS
|
||||
\fBlpop\fR x 0
|
||||
\fI\(-> {d e f} {g h i}\fR
|
||||
\fBlpop\fR x 2
|
||||
\fI\(-> {a b c} {d e f}\fR
|
||||
\fBlpop\fR x end
|
||||
\fI\(-> {a b c} {d e f}\fR
|
||||
\fBlpop\fR x end-1
|
||||
\fI\(-> {a b c} {g h i}\fR
|
||||
\fBlpop\fR x 2 1
|
||||
\fI\(-> {a b c} {d e f} {g i}\fR
|
||||
\fBlpop\fR x 2 3 j
|
||||
\fI\(-> list index out of range\fR
|
||||
.CE
|
||||
.PP
|
||||
In the following examples, the initial value of \fIx\fR is:
|
||||
.PP
|
||||
.CS
|
||||
set x [list [list [list a b] [list c d]] \e
|
||||
[list [list e f] [list g h]]]
|
||||
\fI\(-> {{a b} {c d}} {{e f} {g h}}\fR
|
||||
.CE
|
||||
.PP
|
||||
The indicated value becomes the new value of \fIx\fR.
|
||||
.PP
|
||||
.CS
|
||||
\fBlpop\fR x 1 1 0
|
||||
\fI\(-> {{a b} {c d}} {{e f} h}\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
|
||||
lsort(n), lrange(n), lreplace(n), lset(n)
|
||||
string(n)
|
||||
.SH KEYWORDS
|
||||
element, index, list, remove, pop, stack, queue
|
||||
'\"Local Variables:
|
||||
'\"mode: nroff
|
||||
'\"End:
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
platform \- System identification support code and utilities
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require platform ?1.0.10?\fR
|
||||
\fBpackage require platform\fR ?\fB1.0.10\fR?
|
||||
.sp
|
||||
\fBplatform::generic\fR
|
||||
\fBplatform::identify\fR
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
platform::shell \- System identification support code and utilities
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require platform::shell ?1.1.4?\fR
|
||||
\fBpackage require platform::shell\fR ?\fB1.1.4\fR?
|
||||
.sp
|
||||
\fBplatform::shell::generic \fIshell\fR
|
||||
\fBplatform::shell::identify \fIshell\fR
|
||||
|
||||
+6
-6
@@ -12,9 +12,9 @@
|
||||
tcl::prefix \- facilities for prefix matching
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix match\fR \fI?option ...?\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix all\fR \fItable string\fR
|
||||
\fB::tcl::prefix longest\fR \fItable string\fR
|
||||
\fB::tcl::prefix match\fR ?\fIoption ...\fR? \fItable string\fR
|
||||
.fi
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
@@ -22,17 +22,17 @@ tcl::prefix \- facilities for prefix matching
|
||||
This document describes commands looking up a prefix in a list of strings.
|
||||
The following commands are supported:
|
||||
.TP
|
||||
\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix all\fR \fItable string\fR
|
||||
.
|
||||
Returns a list of all elements in \fItable\fR that begin with the prefix
|
||||
\fIstring\fR.
|
||||
.TP
|
||||
\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix longest\fR \fItable string\fR
|
||||
.
|
||||
Returns the longest common prefix of all elements in \fItable\fR that
|
||||
begin with the prefix \fIstring\fR.
|
||||
.TP
|
||||
\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable string\fR
|
||||
.
|
||||
If \fIstring\fR equals one element in \fItable\fR or is a prefix to exactly
|
||||
one element, the matched element is returned. If not, the result depends
|
||||
|
||||
+54
-35
@@ -16,11 +16,31 @@ tcl::process \- Subprocess management
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This command provides a way to manage subprocesses created by the \fBopen\fR
|
||||
and \fBexec\fR commands. The legal \fIoptions\fR (which may be abbreviated) are:
|
||||
and \fBexec\fR commands, as identified by the process identifiers (PIDs) of
|
||||
those subprocesses. The legal \fIoptions\fR (which may be abbreviated) are:
|
||||
.TP
|
||||
\fB::tcl::process autopurge\fR ?\fIflag\fR?
|
||||
.
|
||||
Automatic purge facility. If \fIflag\fR is specified as a boolean value then
|
||||
it activates or deactivate autopurge. In all cases it returns the current
|
||||
status as a boolean value. When autopurge is active,
|
||||
\fBTcl_ReapDetachedProcs\fR is called each time the \fBexec\fR command is
|
||||
executed or a pipe channel created by \fBopen\fR is closed. When autopurge is
|
||||
inactive, \fB::tcl::process\fR purge must be called explicitly. By default
|
||||
autopurge is active.
|
||||
.TP
|
||||
\fB::tcl::process list\fR
|
||||
.
|
||||
Returns the list of subprocess PIDs.
|
||||
Returns the list of subprocess PIDs. This includes all currently executing
|
||||
subprocesses and all terminated subprocesses that have not yet had their
|
||||
corresponding process table entries purged.
|
||||
.TP
|
||||
\fB::tcl::process purge\fR ?\fIpids\fR?
|
||||
.
|
||||
Cleans up all data associated with terminated subprocesses. If \fIpids\fR is
|
||||
specified as a list of PIDs then the command only cleanup data for the matching
|
||||
subprocesses if they exist, and raises an error otherwise. If a process listed is
|
||||
still active, this command does nothing to that process.
|
||||
.TP
|
||||
\fB::tcl::process status\fR ?\fIswitches\fR? ?\fIpids\fR?
|
||||
.
|
||||
@@ -29,62 +49,48 @@ Returns a dictionary mapping subprocess PIDs to their respective status. If
|
||||
status of the matching subprocesses if they exist, and raises an error
|
||||
otherwise. For active processes, the status is an empty value. For terminated
|
||||
processes, the status is a list with the following format:
|
||||
.QW "{code ?\fImsg errorCode\fR?}" ,
|
||||
.QW "\fB{\fIcode\fR ?\fImsg errorCode\fR?\fB}\fR" ,
|
||||
where:
|
||||
.RS
|
||||
.TP
|
||||
\fBcode\fR\0
|
||||
\fIcode\fR\0
|
||||
.
|
||||
is a standard Tcl return code,
|
||||
is a standard Tcl return code, i.e., \fB0\fR for TCL_OK and \fB1\fR
|
||||
for TCL_ERROR,
|
||||
.TP
|
||||
\fBmsg\fR\0
|
||||
\fImsg\fR\0
|
||||
.
|
||||
is the human-readable error message,
|
||||
.TP
|
||||
\fBerrorCode\fR\0
|
||||
\fIerrorCode\fR\0
|
||||
.
|
||||
uses the same format as the \fBerrorCode\fR global variable
|
||||
.RE
|
||||
.PP
|
||||
Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally
|
||||
terminated processes (i.e. those where \fBcode\fR is nonzero). Under the hood
|
||||
this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for
|
||||
terminated processes (i.e. those where the \fIcode\fR is nonzero). Under the
|
||||
hood this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for
|
||||
non-blocking behavior, unless the \fB\-wait\fR switch is set (see below).
|
||||
.RS
|
||||
.PP
|
||||
Additionally, \fB::tcl::process status\fR accepts the following switches:
|
||||
.TP
|
||||
\fB\-wait\fR\0
|
||||
.
|
||||
By default the command returns immediately (the underlying \fBTcl_WaitPid\fR is
|
||||
called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fBpids\fR
|
||||
called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fIpids\fR
|
||||
is specified as a list of PIDs then the command waits until the status of the
|
||||
matching subprocesses are available. If \fBpids\fR is not specified then it
|
||||
waits for all known subprocesses.
|
||||
matching subprocesses are available. If \fIpids\fR was not specified, this
|
||||
command will wait for all known subprocesses.
|
||||
.TP
|
||||
\fB\-\|\-\fR
|
||||
.
|
||||
Marks the end of switches. The argument following this one will
|
||||
be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
|
||||
.RE
|
||||
.TP
|
||||
\fB::tcl::process purge ?\fIpids\fR?
|
||||
.
|
||||
Cleans up all data associated with terminated subprocesses. If \fBpids\fR is
|
||||
specified as a list of PIDs then the command only cleanup data for the matching
|
||||
subprocesses if they exist, and raises an error otherwise. If the process is
|
||||
still active then it does nothing.
|
||||
.TP
|
||||
\fB::tcl::process autopurge ?\fIflag\fR?
|
||||
.
|
||||
Automatic purge facility. If \fBflag\fR is specified as a boolean value then it
|
||||
activates or deactivate autopurge. In all cases it returns the current status as
|
||||
a boolean value. When autopurge is active, \fBTcl_ReapDetachedProcs\fR is called
|
||||
each time the exec command is executed or a pipe channel created by open is
|
||||
closed. When autopurge is inactive, \fB::tcl::process\fR purge must be called
|
||||
explicitly. By default autopurge is active.
|
||||
.RE
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
These show the use of \fB::tcl::process\fR. Some of the results from
|
||||
\fB::tcl::process status\fR are split over multiple lines for readability.
|
||||
.PP
|
||||
.CS
|
||||
\fB::tcl::process autopurge\fR
|
||||
\fI\(-> true\fR
|
||||
@@ -102,7 +108,12 @@ set pid2 [pid $chan]
|
||||
\fI\(-> 123 456 789 1011\fR
|
||||
|
||||
\fB::tcl::process status\fR
|
||||
\fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {}\fR
|
||||
\fI\(-> 123 0
|
||||
456 {1 "child killed: write on pipe with no readers" {
|
||||
CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}}
|
||||
789 {1 "child suspended: background tty read" {
|
||||
CHILDSUSP 789 SIGTTIN "background tty read"}}
|
||||
1011 {}\fR
|
||||
|
||||
\fB::tcl::process status\fR 123
|
||||
\fI\(-> 123 0\fR
|
||||
@@ -111,10 +122,17 @@ set pid2 [pid $chan]
|
||||
\fI\(-> 1011 {}\fR
|
||||
|
||||
\fB::tcl::process status\fR -wait
|
||||
\fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR
|
||||
\fI\(-> 123 0
|
||||
456 {1 "child killed: write on pipe with no readers" {
|
||||
CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}}
|
||||
789 {1 "child suspended: background tty read" {
|
||||
CHILDSUSP 789 SIGTTIN "background tty read"}}
|
||||
1011 {1 "child process exited abnormally" {
|
||||
CHILDSTATUS 1011 -1}}\fR
|
||||
|
||||
\fB::tcl::process status\fR 1011
|
||||
\fI\(-> 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR
|
||||
\fI\(-> 1011 {1 "child process exited abnormally" {
|
||||
CHILDSTATUS 1011 -1}}\fR
|
||||
|
||||
\fB::tcl::process purge\fR
|
||||
exec command1 1 2 3 &
|
||||
@@ -123,7 +141,8 @@ exec command1 1 2 3 &
|
||||
\fI\(-> 1213\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
exec(n), open(n), Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3)
|
||||
exec(n), open(n), pid(n),
|
||||
Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3)
|
||||
.SH "KEYWORDS"
|
||||
background, child, detach, process, wait
|
||||
'\" Local Variables:
|
||||
|
||||
+11
-5
@@ -12,7 +12,7 @@
|
||||
.SH NAME
|
||||
string \- Manipulate strings
|
||||
.SH SYNOPSIS
|
||||
\fBstring \fIoption arg \fR?\fIarg ...?\fR
|
||||
\fBstring \fIoption arg \fR?\fIarg ...\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -20,7 +20,7 @@ Performs one of several string operations, depending on \fIoption\fR.
|
||||
The legal \fIoption\fRs (which may be abbreviated) are:
|
||||
.TP
|
||||
\fBstring cat\fR ?\fIstring1\fR? ?\fIstring2...\fR?
|
||||
.VS 8.6.2
|
||||
.
|
||||
Concatenate the given \fIstring\fRs just like placing them directly
|
||||
next to each other and return the resulting compound string. If no
|
||||
\fIstring\fRs are present, the result is an empty string.
|
||||
@@ -32,7 +32,6 @@ of a concatenation without resorting to \fBreturn\fR \fB\-level 0\fR,
|
||||
and is more efficient than building a list of arguments and using
|
||||
\fBjoin\fR with an empty join string.
|
||||
.RE
|
||||
.VE
|
||||
.TP
|
||||
\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR
|
||||
.
|
||||
@@ -111,17 +110,24 @@ Any character with a value less than \eu0080 (those that are in the
|
||||
Any of the forms allowed to \fBTcl_GetBoolean\fR.
|
||||
.IP \fBcontrol\fR 12
|
||||
Any Unicode control character.
|
||||
.IP \fBdict\fR 12
|
||||
.VS TIP501
|
||||
Any proper dict structure, with optional surrounding whitespace. In
|
||||
case of improper dict structure, 0 is returned and the \fIvarname\fR
|
||||
will contain the index of the
|
||||
.QW element
|
||||
where the dict parsing fails, or \-1 if this cannot be determined.
|
||||
.VE TIP501
|
||||
.IP \fBdigit\fR 12
|
||||
Any Unicode digit character. Note that this includes characters
|
||||
outside of the [0\-9] range.
|
||||
.IP \fBdouble\fR 12
|
||||
Any of the forms allowed to \fBTcl_GetDoubleFromObj\fR.
|
||||
.IP \fBentier\fR 12
|
||||
.VS 8.6
|
||||
.
|
||||
Any of the valid string formats for an integer value of arbitrary size
|
||||
in Tcl, with optional surrounding whitespace. The formats accepted are
|
||||
exactly those accepted by the C routine \fBTcl_GetBignumFromObj\fR.
|
||||
.VE
|
||||
.IP \fBfalse\fR 12
|
||||
Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
|
||||
false.
|
||||
|
||||
+12
-2
@@ -8,7 +8,7 @@
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH "tcltest" n 2.3 tcltest "Tcl Bundled Packages"
|
||||
.TH "tcltest" n 2.5 tcltest "Tcl Bundled Packages"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
@@ -16,7 +16,7 @@
|
||||
tcltest \- Test harness support code and utilities
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require tcltest\fR ?\fB2.3\fR?
|
||||
\fBpackage require tcltest\fR ?\fB2.5\fR?
|
||||
|
||||
\fBtcltest::test \fIname description\fR ?\fI\-option value ...\fR?
|
||||
\fBtcltest::test \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
|
||||
@@ -454,6 +454,7 @@ The valid options for \fBtest\fR are summarized:
|
||||
?\fB\-output \fIexpectedOutput\fR?
|
||||
?\fB\-errorOutput \fIexpectedError\fR?
|
||||
?\fB\-returnCodes \fIcodeList\fR?
|
||||
?\fB\-errorCode \fIexpectedErrorCode\fR?
|
||||
?\fB\-match \fImode\fR?
|
||||
.CE
|
||||
.PP
|
||||
@@ -577,6 +578,15 @@ return codes known to \fBreturn\fR, in both numeric and symbolic
|
||||
form, including extended return codes, are acceptable elements in
|
||||
the \fIexpectedCodeList\fR. Default value is
|
||||
.QW "\fBok return\fR" .
|
||||
.TP
|
||||
\fB\-errorCode \fIexpectedErrorCode\fR
|
||||
.
|
||||
The optional \fB\-errorCode\fR attribute supplies \fIexpectedErrorCode\fR,
|
||||
a glob pattern that should match the error code reported from evaluation of the
|
||||
\fB\-body\fR script. If evaluation of the \fB\-body\fR script returns
|
||||
a code not matching \fIexpectedErrorCode\fR, the test fails. Default value is
|
||||
.QW "\fB*\fR" .
|
||||
If \fB\-returnCodes\fR does not include \fBerror\fR it is set to \fBerror\fR.
|
||||
.PP
|
||||
To pass, a test must successfully evaluate its \fB\-setup\fR, \fB\-body\fR,
|
||||
and \fB\-cleanup\fR scripts. The return code of the \fB\-body\fR script and
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2005 Sergey Brester aka sebres.
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH timerate n "" Tcl "Tcl Built-In Commands"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
timerate \- Time-related execution resp. performance measurement of a script
|
||||
.SH SYNOPSIS
|
||||
\fBtimerate \fIscript\fR \fI?time ?max-count??\fR
|
||||
.sp
|
||||
\fBtimerate \fI?-direct?\fR \fI?-overhead double?\fR \fIscript\fR \fI?time ?max-count??\fR
|
||||
.sp
|
||||
\fBtimerate \fI?-calibrate?\fR \fI?-direct?\fR \fIscript\fR \fI?time ?max-count??\fR
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The first and second form will evaluate \fIscript\fR until the interval
|
||||
\fItime\fR given in milliseconds elapses, or for 1000 milliseconds (1 second)
|
||||
if \fItime\fR is not specified.
|
||||
.sp
|
||||
The parameter \fImax-count\fR could additionally impose a further restriction
|
||||
by the maximal number of iterations to evaluate the script.
|
||||
If \fImax-count\fR is specified, the evalution will stop either this count of
|
||||
iterations is reached or the time is exceeded.
|
||||
.sp
|
||||
It will then return a canonical tcl-list of the form
|
||||
.PP
|
||||
.CS
|
||||
\fB0.095977 \(mcs/# 52095836 # 10419167 #/sec 5000.000 nett-ms\fR
|
||||
.CE
|
||||
.PP
|
||||
which indicates:
|
||||
.IP \(bu
|
||||
the average amount of time required per iteration, in microseconds ([\fBlindex\fR $result 0])
|
||||
.IP \(bu
|
||||
the count how many times it was executed ([\fBlindex\fR $result 2])
|
||||
.IP \(bu
|
||||
the estimated rate per second ([\fBlindex\fR $result 4])
|
||||
.IP \(bu
|
||||
the estimated real execution time without measurement overhead ([\fBlindex\fR $result 6])
|
||||
.PP
|
||||
Time is measured in elapsed time using the finest timer resolution as possible,
|
||||
not CPU time.
|
||||
This command may be used to provide information as to how well the script or a
|
||||
tcl-command is performing and can help determine bottlenecks and fine-tune
|
||||
application performance.
|
||||
.TP
|
||||
\fI-calibrate\fR
|
||||
.
|
||||
To measure very fast scripts as exact as posible the calibration process
|
||||
may be required.
|
||||
|
||||
The \fI-calibrate\fR option is used to calibrate timerate, calculating the
|
||||
estimated overhead of the given script as the default overhead for future
|
||||
invocations of the \fBtimerate\fR command. If the \fItime\fR parameter is not
|
||||
specified, the calibrate procedure runs for up to 10 seconds.
|
||||
.TP
|
||||
\fI-overhead double\fR
|
||||
.
|
||||
The \fI-overhead\fR parameter supplies an estimate (in microseconds) of the
|
||||
measurement overhead of each iteration of the tested script. This quantity
|
||||
will be subtracted from the measured time prior to reporting results.
|
||||
.TP
|
||||
\fI-direct\fR
|
||||
.
|
||||
The \fI-direct\fR option causes direct execution of the supplied script,
|
||||
without compilation, in a manner similar to the \fBtime\fR command. It can be
|
||||
used to measure the cost of \fBTcl_EvalObjEx\fR, of the invocation of canonical
|
||||
lists, and of the uncompiled versions of bytecoded commands.
|
||||
.PP
|
||||
As opposed to the \fBtime\fR commmand, which runs the tested script for a fixed
|
||||
number of iterations, the timerate command runs it for a fixed time.
|
||||
Additionally, the compiled variant of the script will be used during the entire
|
||||
measurement, as if the script were part of a compiled procedure, if the \fI-direct\fR
|
||||
option is not specified. The fixed time period and possibility of compilation allow
|
||||
for more precise results and prevent very long execution times by slow scripts, making
|
||||
it practical for measuring scripts with highly uncertain execution times.
|
||||
|
||||
.SH EXAMPLE
|
||||
Estimate how fast it takes for a simple Tcl \fBfor\fR loop (including
|
||||
operations on variable \fIi\fR) to count to a ten:
|
||||
.PP
|
||||
.CS
|
||||
# calibrate:
|
||||
timerate -calibrate {}
|
||||
# measure:
|
||||
timerate { for {set i 0} {$i<10} {incr i} {} } 5000
|
||||
.CE
|
||||
.PP
|
||||
Estimate how fast it takes for a simple Tcl \fBfor\fR loop, ignoring the
|
||||
overhead for to perform ten iterations, ignoring the overhead of the management
|
||||
of the variable that controls the loop:
|
||||
.PP
|
||||
.CS
|
||||
# calibrate for overhead of variable operations:
|
||||
set i 0; timerate -calibrate {expr {$i<10}; incr i} 1000
|
||||
# measure:
|
||||
timerate { for {set i 0} {$i<10} {incr i} {} } 5000
|
||||
.CE
|
||||
.PP
|
||||
Estimate the speed of calculating the hour of the day using \fBclock format\fR only,
|
||||
ignoring overhead of the portion of the script that prepares the time for it to
|
||||
calculate:
|
||||
.PP
|
||||
.CS
|
||||
# calibrate:
|
||||
timerate -calibrate {}
|
||||
# estimate overhead:
|
||||
set tm 0
|
||||
set ovh [lindex [timerate { incr tm [expr {24*60*60}] }] 0]
|
||||
# measure using esimated overhead:
|
||||
set tm 0
|
||||
timerate -overhead $ovh {
|
||||
clock format $tm -format %H
|
||||
incr tm [expr {24*60*60}]; # overhead for this is ignored
|
||||
} 5000
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
time(n)
|
||||
.SH KEYWORDS
|
||||
script, timerate, time
|
||||
.\" Local Variables:
|
||||
.\" mode: nroff
|
||||
.\" End:
|
||||
+2
-1
@@ -20,7 +20,8 @@ trace \- Monitor variable accesses, command usages and command executions
|
||||
This command causes Tcl commands to be executed whenever certain operations are
|
||||
invoked. The legal \fIoption\fRs (which may be abbreviated) are:
|
||||
.TP
|
||||
\fBtrace add \fItype name ops ?args?\fR
|
||||
\fBtrace add \fItype name ops\fR ?\fIargs\fR?
|
||||
.
|
||||
Where \fItype\fR is \fBcommand\fR, \fBexecution\fR, or \fBvariable\fR.
|
||||
.RS
|
||||
.TP
|
||||
|
||||
@@ -112,6 +112,8 @@ call is a standard Tcl result code.
|
||||
unmounts the mounted ZIP file system that was mounted from \fIzipname\fR (at
|
||||
\fImountpoint\fR). Errors are reported in the interpreter \fIinterp\fR. The
|
||||
result of this call is a standard Tcl result code.
|
||||
.PP
|
||||
\fBTclZipfs_AppHook\fR can not be used in stub-enabled extensions.
|
||||
.SH "SEE ALSO"
|
||||
zipfs(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+147
-30
@@ -16,10 +16,13 @@ zipfs \- Mount and work with ZIP files within Tcl
|
||||
.nf
|
||||
\fBpackage require zipfs \fR?\fB1.0\fR?
|
||||
.sp
|
||||
\fBzipfs canonical\fR ?\fImntpnt\fR? \fIfilename\fR ?\fIZIPFS\fR?
|
||||
\fBzipfs exists\fR \fIfilename\fR
|
||||
\fBzipfs find\fR \fIdir\fR
|
||||
\fBzipfs find\fR \fIdirectoryName\fR
|
||||
\fBzipfs info\fR \fIfilename\fR
|
||||
\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR?
|
||||
\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR?
|
||||
\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR?
|
||||
\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR?
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR?
|
||||
@@ -27,21 +30,33 @@ zipfs \- Mount and work with ZIP files within Tcl
|
||||
\fBzipfs root\fR
|
||||
\fBzipfs unmount\fR \fImountpoint\fR
|
||||
.fi
|
||||
'\" The following subcommand is *UNDOCUMENTED*
|
||||
'\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBzipfs\fR command (the sole public command provided by the built-in
|
||||
package with the same name) provides Tcl with the ability to mount the
|
||||
contents of a ZIP file as a virtual file system.
|
||||
contents of a ZIP archive file as a virtual file system. ZIP archives support
|
||||
simple encryption, sufficient to prevent casual inspection of their contents
|
||||
but not able to prevent access by even a moderately determined attacker.
|
||||
.TP
|
||||
\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR ?\fIinZipfs\fR?
|
||||
.
|
||||
This takes the name of a file, \fIfilename\fR, and produces where it would be
|
||||
mapped into a zipfs mount as its result. If specified, \fImountpoint\fR says
|
||||
within which mount the mapping will be done; if omitted, the main root of the
|
||||
zipfs system is used. The \fIinZipfs\fR argument is a an optional boolean
|
||||
which controls whether to fully canonicalise the name; it defaults to true.
|
||||
.TP
|
||||
\fBzipfs exists\fR \fIfilename\fR
|
||||
.
|
||||
Return 1 if the given filename exists in the mounted zipfs and 0 if it does not.
|
||||
.TP
|
||||
\fBzipfs find\fR \fIdir\fR
|
||||
\fBzipfs find\fR \fIdirectoryName\fR
|
||||
.
|
||||
Recursively lists files including and below the directory \fIdir\fR. The
|
||||
result list consists of relative path names starting from the given
|
||||
Recursively lists files including and below the directory \fIdirectoryName\fR.
|
||||
The result list consists of relative path names starting from the given
|
||||
directory. This command is also used by the \fBzipfs mkzip\fR and \fBzipfs
|
||||
mkimg\fR commands.
|
||||
.TP
|
||||
@@ -63,7 +78,7 @@ Note: querying the mount point gives the start of the zip data as the offset
|
||||
in (4), which can be used to truncate the zip information from an executable.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? \fI?pattern?\fR
|
||||
\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR?
|
||||
.
|
||||
Return a list of all files in the mounted zipfs, or just those matching
|
||||
\fIpattern\fR (optionally controlled by the option parameters). The order of
|
||||
@@ -79,6 +94,13 @@ in \fIzipfile\fR will appear to Tcl to be regular files at the mount point.
|
||||
With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. With
|
||||
no \fImountpoint\fR, return all zipfile/mount pairs. If \fImountpoint\fR is
|
||||
specified as an empty string, mount on file path.
|
||||
.PP
|
||||
\fBNB:\fR because the current working directory is a concept maintained by the
|
||||
operating system, using \fBcd\fR into a mounted archive will only work in the
|
||||
current process, and then not entirely consistently (e.g., if a shared library
|
||||
uses direct access to the OS rather than through Tcl's filesystem API, it will
|
||||
not see the current directory as being inside the mount and will not be able
|
||||
to access the files inside the mount).
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs root\fR
|
||||
@@ -97,40 +119,135 @@ Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR.
|
||||
This package also provides several commands to aid the creation of ZIP
|
||||
archives as Tcl applications.
|
||||
.TP
|
||||
\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR?
|
||||
.
|
||||
Creates an image (potentially a new executable file) similar to \fBzipfs
|
||||
mkzip\fR. If the \fIinfile\fR parameter is specified, this file is prepended
|
||||
in front of the ZIP archive, otherwise the file returned by
|
||||
\fBinfo nameofexecutable\fR (i.e., the executable file of the running process)
|
||||
is used. If the \fIpassword\fR parameter is not empty, an obfuscated version
|
||||
of that password is placed between the image and ZIP chunks of the output file
|
||||
and the contents of the ZIP chunk are protected with that password.
|
||||
.RS
|
||||
.PP
|
||||
Caution: highly experimental, not usable on Android, only partially tested on
|
||||
Linux and Windows.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
.
|
||||
For the clear text \fIpassword\fR argument, an obfuscated string version is
|
||||
returned with the same format used in the \fBzipfs mkimg\fR command.
|
||||
.TP
|
||||
\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR?
|
||||
.
|
||||
Creates a ZIP archive file named \fIoutfile\fR from the contents of the input
|
||||
directory \fIindir\fR (contained regular files only) with optional ZIP
|
||||
password \fIpassword\fR. While processing the files below \fIindir\fR the
|
||||
optional file name prefix given in \fIstrip\fR is stripped off the beginning
|
||||
of the respective file name.
|
||||
of the respective file name. When stripping, it is common to remove either
|
||||
the whole source directory name or the name of its parent directory.
|
||||
.RS
|
||||
.PP
|
||||
Caution: the choice of the \fIindir\fR parameter (less the optional stripped
|
||||
prefix) determines the later root name of the archive's content.
|
||||
\fBCaution:\fR the choice of the \fIindir\fR parameter (less the optional
|
||||
stripped prefix) determines the later root name of the archive's content.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR?
|
||||
.
|
||||
Creates an image (potentially a new executable file) similar to \fBzipfs
|
||||
mkzip\fR; see that command for a description of most parameters to this
|
||||
command, as they behave identically here.
|
||||
.RS
|
||||
.PP
|
||||
If the \fIinfile\fR parameter is specified, this file is prepended in front of
|
||||
the ZIP archive, otherwise the file returned by \fBinfo nameofexecutable\fR
|
||||
(i.e., the executable file of the running process) is used. If the
|
||||
\fIpassword\fR parameter is not empty, an obfuscated version of that password
|
||||
(see \fBzipfs mkkey\fR) is placed between the image and ZIP chunks of the
|
||||
output file and the contents of the ZIP chunk are protected with that
|
||||
password.
|
||||
.PP
|
||||
If there is a file, \fBmain.tcl\fR, in the root directory of the resulting
|
||||
archive and the image file that the archive is attached to is a \fBtclsh\fR
|
||||
(or \fBwish\fR) instance (true by default, but depends on your configuration),
|
||||
then the resulting image is an executable that will \fBsource\fR the script in
|
||||
that \fBmain.tcl\fR after mounting the ZIP archive, and will \fBexit\fR once
|
||||
that script has been executed.
|
||||
.PP
|
||||
\fBCaution:\fR highly experimental, not usable on Android, only partially
|
||||
tested on Linux and Windows.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
.
|
||||
Given the clear text \fIpassword\fR argument, an obfuscated string version is
|
||||
returned with the same format used in the \fBzipfs mkimg\fR command.
|
||||
.TP
|
||||
\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR?
|
||||
.
|
||||
This command is like \fBzipfs mkimg\fR, but instead of an input directory,
|
||||
\fIinlist\fR must be a Tcl list where the odd elements are the names of files
|
||||
to be copied into the archive in the image, and the even elements are their
|
||||
respective names within that archive.
|
||||
.TP
|
||||
\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR?
|
||||
.
|
||||
This command is like \fBzipfs mkzip\fR, but instead of an input directory,
|
||||
\fIinlist\fR must be a Tcl list where the odd elements are the names of files
|
||||
to be copied into the archive, and the even elements are their respective
|
||||
names within that archive.
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
Mounting an ZIP archive as an application directory and running code out of it
|
||||
before unmounting it again:
|
||||
.PP
|
||||
.CS
|
||||
set zip myApp.zip
|
||||
set base [file join [\fbzipfs root\fR] myApp]
|
||||
|
||||
\fBzipfs mount\fR $base $zip
|
||||
# $base now has the contents of myApp.zip
|
||||
|
||||
source [file join $base app.tcl]
|
||||
# use the contents, load libraries from it, etc...
|
||||
|
||||
\fBzipfs unmount\fR $zip
|
||||
.CE
|
||||
.PP
|
||||
Creating a ZIP archive, given that a directory exists containing the content
|
||||
to put in the archive. Note that the source directory is given twice, in order
|
||||
to strip the exterior directory name from each filename in the archive.
|
||||
.PP
|
||||
.CS
|
||||
set sourceDirectory [file normalize myApp]
|
||||
set targetZip myApp.zip
|
||||
|
||||
\fBzipfs mkzip\fR $targetZip $sourceDirectory $sourceDirectory
|
||||
.CE
|
||||
.PP
|
||||
Encryption can be applied to ZIP archives by providing a password when
|
||||
building the ZIP and when mounting it.
|
||||
.PP
|
||||
.CS
|
||||
set zip myApp.zip
|
||||
set sourceDir [file normalize myApp]
|
||||
set password "hunter2"
|
||||
set base [file join [\fbzipfs root\fR] myApp]
|
||||
|
||||
# Create with password
|
||||
\fBzipfs mkzip\fR $targetZip $sourceDir $sourceDir $password
|
||||
|
||||
# Mount with password
|
||||
\fBzipfs mount\fR $base $zip $password
|
||||
.CE
|
||||
.PP
|
||||
When creating an executable image with a password, the password is placed
|
||||
within the executable in a shrouded form so that the application can read
|
||||
files inside the embedded ZIP archive yet casual inspection cannot read it.
|
||||
.PP
|
||||
.CS
|
||||
set appDir [file normalize myApp]
|
||||
set img "myApp.bin"
|
||||
set password "hunter2"
|
||||
|
||||
# Create some simple content to define a basic application
|
||||
file mkdir $appDir
|
||||
set f [open $appDir/main.tcl]
|
||||
puts $f {
|
||||
puts "Hi. This is [info script]"
|
||||
}
|
||||
close $f
|
||||
|
||||
# Create the executable
|
||||
\fBzipfs mkimg\fR $img $appDir $appDir $password
|
||||
|
||||
# Launch the executable, printing its output to stdout
|
||||
exec $img >@stdout
|
||||
# prints: \fIHi. This is //zipfs:/app/main.tcl\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
tclsh(1), file(n), zlib(n)
|
||||
tclsh(1), file(n), zipfs(3), zlib(n)
|
||||
.SH "KEYWORDS"
|
||||
compress, filesystem, zip
|
||||
'\" Local Variables:
|
||||
|
||||
+177
-172
@@ -153,46 +153,46 @@ static const crange alphaRangeTable[] = {
|
||||
{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, 0x1878}, {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5},
|
||||
{0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
|
||||
{0x19b0, 0x19c9}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33},
|
||||
{0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23},
|
||||
{0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba},
|
||||
{0x1cbd, 0x1cbf}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf},
|
||||
{0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
|
||||
{0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc},
|
||||
{0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb},
|
||||
{0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c},
|
||||
{0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139},
|
||||
{0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e},
|
||||
{0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67},
|
||||
{0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6},
|
||||
{0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6},
|
||||
{0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f},
|
||||
{0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e},
|
||||
{0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef},
|
||||
{0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f},
|
||||
{0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f},
|
||||
{0xa722, 0xa788}, {0xa78b, 0xa7b9}, {0xa7f7, 0xa801}, {0xa803, 0xa805},
|
||||
{0xdc0, 0xdc6}, {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe86, 0xe8a},
|
||||
{0xe8c, 0xea3}, {0xea7, 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, 0x1878},
|
||||
{0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e},
|
||||
{0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
|
||||
{0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b},
|
||||
{0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f},
|
||||
{0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cbf},
|
||||
{0x1ce9, 0x1cec}, {0x1cee, 0x1cf3}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15},
|
||||
{0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
|
||||
{0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4},
|
||||
{0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec},
|
||||
{0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113},
|
||||
{0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f},
|
||||
{0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4},
|
||||
{0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96},
|
||||
{0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe},
|
||||
{0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde},
|
||||
{0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa},
|
||||
{0x30fc, 0x30ff}, {0x3105, 0x312f}, {0x3131, 0x318e}, {0x31a0, 0x31ba},
|
||||
{0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fef}, {0xa000, 0xa48c},
|
||||
{0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e},
|
||||
{0xa67f, 0xa69d}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788},
|
||||
{0xa78b, 0xa7bf}, {0xa7c2, 0xa7c6}, {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},
|
||||
{0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab5a}, {0xab5c, 0xab67},
|
||||
{0xab70, 0xabe2}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
|
||||
{0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
|
||||
{0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1},
|
||||
@@ -213,21 +213,22 @@ static const crange alphaRangeTable[] = {
|
||||
{0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
|
||||
{0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10d00, 0x10d23}, {0x10f00, 0x10f1c},
|
||||
{0x10f30, 0x10f45}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8},
|
||||
{0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
|
||||
{0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de}, {0x11305, 0x1130c},
|
||||
{0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361},
|
||||
{0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af}, {0x11580, 0x115ae},
|
||||
{0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa}, {0x11700, 0x1171a},
|
||||
{0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a83},
|
||||
{0x11a86, 0x11a89}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c2e},
|
||||
{0x11c72, 0x11c8f}, {0x11d00, 0x11d06}, {0x11d0b, 0x11d30}, {0x11d60, 0x11d65},
|
||||
{0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2}, {0x12000, 0x12399}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
|
||||
{0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
|
||||
{0x16b7d, 0x16b8f}, {0x16e40, 0x16e7f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f},
|
||||
{0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
|
||||
{0x10f30, 0x10f45}, {0x10fe0, 0x10ff6}, {0x11003, 0x11037}, {0x11083, 0x110af},
|
||||
{0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
|
||||
{0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
|
||||
{0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
|
||||
{0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
|
||||
{0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
|
||||
{0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
|
||||
{0x11700, 0x1171a}, {0x11800, 0x1182b}, {0x118a0, 0x118df}, {0x119a0, 0x119a7},
|
||||
{0x119aa, 0x119d0}, {0x11a0b, 0x11a32}, {0x11a5c, 0x11a89}, {0x11ac0, 0x11af8},
|
||||
{0x11c00, 0x11c08}, {0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {0x11d00, 0x11d06},
|
||||
{0x11d0b, 0x11d30}, {0x11d60, 0x11d65}, {0x11d6a, 0x11d89}, {0x11ee0, 0x11ef2},
|
||||
{0x12000, 0x12399}, {0x12480, 0x12543}, {0x13000, 0x1342e}, {0x14400, 0x14646},
|
||||
{0x16800, 0x16a38}, {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f},
|
||||
{0x16b40, 0x16b43}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16e40, 0x16e7f},
|
||||
{0x16f00, 0x16f4a}, {0x16f93, 0x16f9f}, {0x17000, 0x187f7}, {0x18800, 0x18af2},
|
||||
{0x1b000, 0x1b11e}, {0x1b150, 0x1b152}, {0x1b164, 0x1b167}, {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},
|
||||
@@ -235,12 +236,13 @@ static const crange alphaRangeTable[] = {
|
||||
{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}
|
||||
{0x1d7c4, 0x1d7cb}, {0x1e100, 0x1e12c}, {0x1e137, 0x1e13d}, {0x1e2c0, 0x1e2eb},
|
||||
{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
|
||||
};
|
||||
|
||||
@@ -257,24 +259,24 @@ static const chr alphaCharTable[] = {
|
||||
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, 0xa8fe, 0xa9cf, 0xaa7a, 0xaab1,
|
||||
0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43,
|
||||
0xfb44
|
||||
0xea5, 0xeb2, 0xeb3, 0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065,
|
||||
0x1066, 0x108e, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa,
|
||||
0x1aa7, 0x1bae, 0x1baf, 0x1cf5, 0x1cf6, 0x1cfa, 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, 0xa8fe,
|
||||
0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e,
|
||||
0xfb40, 0xfb41, 0xfb43, 0xfb44
|
||||
#if CHRBITS > 16
|
||||
,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
|
||||
0x109bf, 0x10a00, 0x10f27, 0x11144, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f,
|
||||
0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644,
|
||||
0x118ff, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d, 0x11c40, 0x11d08, 0x11d09, 0x11d46,
|
||||
0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2,
|
||||
0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39,
|
||||
0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57,
|
||||
0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
|
||||
0x11310, 0x11332, 0x11333, 0x1133d, 0x11350, 0x1145f, 0x114c4, 0x114c5, 0x114c7,
|
||||
0x11644, 0x116b8, 0x118ff, 0x119e1, 0x119e3, 0x11a00, 0x11a3a, 0x11a50, 0x11a9d,
|
||||
0x11c40, 0x11d08, 0x11d09, 0x11d46, 0x11d67, 0x11d68, 0x11d98, 0x16f50, 0x16fe0,
|
||||
0x16fe1, 0x16fe3, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546,
|
||||
0x1e14e, 0x1e94b, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
|
||||
0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
|
||||
0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -289,8 +291,8 @@ static const crange controlRangeTable[] = {
|
||||
{0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
|
||||
{0xfff9, 0xfffb}
|
||||
#if CHRBITS > 16
|
||||
,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd},
|
||||
{0x100000, 0x10fffd}
|
||||
,{0x13430, 0x13438}, {0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f},
|
||||
{0xf0000, 0xffffd}, {0x100000, 0x10fffd}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -325,7 +327,8 @@ static const crange digitRangeTable[] = {
|
||||
{0x11136, 0x1113f}, {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459},
|
||||
{0x114d0, 0x114d9}, {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739},
|
||||
{0x118e0, 0x118e9}, {0x11c50, 0x11c59}, {0x11d50, 0x11d59}, {0x11da0, 0x11da9},
|
||||
{0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e950, 0x1e959}
|
||||
{0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff}, {0x1e140, 0x1e149},
|
||||
{0x1e2f0, 0x1e2f9}, {0x1e950, 0x1e959}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -348,7 +351,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, 0x2e4e},
|
||||
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e4f},
|
||||
{0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
|
||||
{0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
|
||||
{0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
|
||||
@@ -372,8 +375,8 @@ static const chr punctCharTable[] = {
|
||||
0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
|
||||
0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
|
||||
0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970,
|
||||
0x9fd, 0xa76, 0xaf0, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14,
|
||||
0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c,
|
||||
0x9fd, 0xa76, 0xaf0, 0xc77, 0xc84, 0xdf4, 0xe4f, 0xe5a, 0xe5b,
|
||||
0xf14, 0xf85, 0xfd9, 0xfda, 0x10fb, 0x1400, 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,
|
||||
@@ -384,8 +387,8 @@ static const chr punctCharTable[] = {
|
||||
#if CHRBITS > 16
|
||||
,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
|
||||
0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x1183b,
|
||||
0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f,
|
||||
0x1e95e, 0x1e95f
|
||||
0x119e2, 0x11c70, 0x11c71, 0x11ef7, 0x11ef8, 0x11fff, 0x16a6e, 0x16a6f, 0x16af5,
|
||||
0x16b44, 0x16fe2, 0x1bc9f, 0x1e95e, 0x1e95f
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -424,7 +427,7 @@ static const crange lowerRangeTable[] = {
|
||||
{0x1f90, 0x1f97}, {0x1fa0, 0x1fa7}, {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4},
|
||||
{0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7}, {0x1ff2, 0x1ff4}, {0x2146, 0x2149},
|
||||
{0x2c30, 0x2c5e}, {0x2c76, 0x2c7b}, {0x2d00, 0x2d25}, {0xa72f, 0xa731},
|
||||
{0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xab60, 0xab65},
|
||||
{0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xab60, 0xab67},
|
||||
{0xab70, 0xabbf}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
|
||||
#if CHRBITS > 16
|
||||
,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df},
|
||||
@@ -504,7 +507,7 @@ static const chr lowerCharTable[] = {
|
||||
0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c,
|
||||
0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e, 0xa791, 0xa797,
|
||||
0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9,
|
||||
0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7fa
|
||||
0xa7af, 0xa7b5, 0xa7b7, 0xa7b9, 0xa7bb, 0xa7bd, 0xa7bf, 0xa7c3, 0xa7fa
|
||||
#if CHRBITS > 16
|
||||
,0x1d4bb, 0x1d7cb
|
||||
#endif
|
||||
@@ -527,7 +530,7 @@ static const crange upperRangeTable[] = {
|
||||
{0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d}, {0x2110, 0x2112},
|
||||
{0x2119, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2133}, {0x2c00, 0x2c2e},
|
||||
{0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae},
|
||||
{0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
|
||||
{0xa7b0, 0xa7b4}, {0xa7c4, 0xa7c6}, {0xff21, 0xff3a}
|
||||
#if CHRBITS > 16
|
||||
,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf},
|
||||
{0x16e40, 0x16e5f}, {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481},
|
||||
@@ -606,7 +609,7 @@ static const chr upperCharTable[] = {
|
||||
0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780,
|
||||
0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798,
|
||||
0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6,
|
||||
0xa7b8
|
||||
0xa7b8, 0xa7ba, 0xa7bc, 0xa7be, 0xa7c2
|
||||
#if CHRBITS > 16
|
||||
,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
|
||||
0x1d539, 0x1d546, 0x1d7ca
|
||||
@@ -640,61 +643,60 @@ static const crange graphRangeTable[] = {
|
||||
{0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd},
|
||||
{0xbe6, 0xbfa}, {0xc00, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
|
||||
{0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
|
||||
{0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc8c},
|
||||
{0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc77, 0xc8c},
|
||||
{0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
|
||||
{0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3},
|
||||
{0xce6, 0xcef}, {0xd00, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
|
||||
{0xd12, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4f}, {0xd54, 0xd63},
|
||||
{0xd66, 0xd7f}, {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb},
|
||||
{0xdc0, 0xdc6}, {0xdcf, 0xdd4}, {0xdd8, 0xddf}, {0xde6, 0xdef},
|
||||
{0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe94, 0xe97},
|
||||
{0xe99, 0xe9f}, {0xea1, 0xea3}, {0xead, 0xeb9}, {0xebb, 0xebd},
|
||||
{0xec0, 0xec4}, {0xec8, 0xecd}, {0xed0, 0xed9}, {0xedc, 0xedf},
|
||||
{0xf00, 0xf47}, {0xf49, 0xf6c}, {0xf71, 0xf97}, {0xf99, 0xfbc},
|
||||
{0xfbe, 0xfcc}, {0xfce, 0xfda}, {0x1000, 0x10c5}, {0x10d0, 0x1248},
|
||||
{0x124a, 0x124d}, {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288},
|
||||
{0x128a, 0x128d}, {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be},
|
||||
{0x12c2, 0x12c5}, {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315},
|
||||
{0x1318, 0x135a}, {0x135d, 0x137c}, {0x1380, 0x1399}, {0x13a0, 0x13f5},
|
||||
{0x13f8, 0x13fd}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8},
|
||||
{0x1700, 0x170c}, {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753},
|
||||
{0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9},
|
||||
{0x17f0, 0x17f9}, {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1878},
|
||||
{0x1880, 0x18aa}, {0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1920, 0x192b},
|
||||
{0x1930, 0x193b}, {0x1944, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab},
|
||||
{0x19b0, 0x19c9}, {0x19d0, 0x19da}, {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e},
|
||||
{0x1a60, 0x1a7c}, {0x1a7f, 0x1a89}, {0x1a90, 0x1a99}, {0x1aa0, 0x1aad},
|
||||
{0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3},
|
||||
{0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c88}, {0x1c90, 0x1cba},
|
||||
{0x1cbd, 0x1cc7}, {0x1cd0, 0x1cf9}, {0x1d00, 0x1df9}, {0x1dfb, 0x1f15},
|
||||
{0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
|
||||
{0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4}, {0x1fc6, 0x1fd3},
|
||||
{0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffe},
|
||||
{0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e}, {0x2090, 0x209c},
|
||||
{0x20a0, 0x20bf}, {0x20d0, 0x20f0}, {0x2100, 0x218b}, {0x2190, 0x2426},
|
||||
{0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bc8},
|
||||
{0x2bca, 0x2bfe}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
|
||||
{0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b}, {0xe86, 0xe8a},
|
||||
{0xe8c, 0xea3}, {0xea7, 0xebd}, {0xec0, 0xec4}, {0xec8, 0xecd},
|
||||
{0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47}, {0xf49, 0xf6c},
|
||||
{0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc}, {0xfce, 0xfda},
|
||||
{0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256},
|
||||
{0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0},
|
||||
{0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6},
|
||||
{0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, {0x135d, 0x137c},
|
||||
{0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1400, 0x167f},
|
||||
{0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1714},
|
||||
{0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, {0x176e, 0x1770},
|
||||
{0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, {0x1800, 0x180d},
|
||||
{0x1810, 0x1819}, {0x1820, 0x1878}, {0x1880, 0x18aa}, {0x18b0, 0x18f5},
|
||||
{0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b}, {0x1944, 0x196d},
|
||||
{0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, {0x19d0, 0x19da},
|
||||
{0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89},
|
||||
{0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b},
|
||||
{0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49},
|
||||
{0x1c4d, 0x1c88}, {0x1c90, 0x1cba}, {0x1cbd, 0x1cc7}, {0x1cd0, 0x1cfa},
|
||||
{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, 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, 0x2e4e},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e4f},
|
||||
{0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
|
||||
{0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312f},
|
||||
{0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
|
||||
{0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fef}, {0xa000, 0xa48c},
|
||||
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7b9},
|
||||
{0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c5},
|
||||
{0xa8ce, 0xa8d9}, {0xa8e0, 0xa953}, {0xa95f, 0xa97c}, {0xa980, 0xa9cd},
|
||||
{0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, {0xaa00, 0xaa36}, {0xaa40, 0xaa4d},
|
||||
{0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, {0xaadb, 0xaaf6}, {0xab01, 0xab06},
|
||||
{0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
|
||||
{0xab30, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3},
|
||||
{0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
|
||||
{0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c},
|
||||
{0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7},
|
||||
{0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52}, {0xfe54, 0xfe66},
|
||||
{0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe},
|
||||
{0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc},
|
||||
{0xffe0, 0xffe6}, {0xffe8, 0xffee}
|
||||
{0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7bf},
|
||||
{0xa7c2, 0xa7c6}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
|
||||
{0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa953}, {0xa95f, 0xa97c},
|
||||
{0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe}, {0xaa00, 0xaa36},
|
||||
{0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2}, {0xaadb, 0xaaf6},
|
||||
{0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26},
|
||||
{0xab28, 0xab2e}, {0xab30, 0xab67}, {0xab70, 0xabed}, {0xabf0, 0xabf9},
|
||||
{0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d},
|
||||
{0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36},
|
||||
{0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f},
|
||||
{0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe52},
|
||||
{0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc},
|
||||
{0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7},
|
||||
{0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
|
||||
#if CHRBITS > 16
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
|
||||
@@ -711,29 +713,31 @@ static const crange graphRangeTable[] = {
|
||||
{0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
|
||||
{0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
|
||||
{0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10d27}, {0x10d30, 0x10d39},
|
||||
{0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x11000, 0x1104d},
|
||||
{0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8},
|
||||
{0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146}, {0x11150, 0x11176},
|
||||
{0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4}, {0x11200, 0x11211},
|
||||
{0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d}, {0x1128f, 0x1129d},
|
||||
{0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9}, {0x11300, 0x11303},
|
||||
{0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
|
||||
{0x1133b, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363}, {0x11366, 0x1136c},
|
||||
{0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7}, {0x114d0, 0x114d9},
|
||||
{0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644}, {0x11650, 0x11659},
|
||||
{0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x11700, 0x1171a},
|
||||
{0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x11800, 0x1183b}, {0x118a0, 0x118f2},
|
||||
{0x11a00, 0x11a47}, {0x11a50, 0x11a83}, {0x11a86, 0x11aa2}, {0x11ac0, 0x11af8},
|
||||
{0x10e60, 0x10e7e}, {0x10f00, 0x10f27}, {0x10f30, 0x10f59}, {0x10fe0, 0x10ff6},
|
||||
{0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1},
|
||||
{0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11146},
|
||||
{0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
|
||||
{0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
|
||||
{0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
|
||||
{0x11335, 0x11339}, {0x1133b, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
|
||||
{0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x1145d, 0x1145f},
|
||||
{0x11480, 0x114c7}, {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd},
|
||||
{0x11600, 0x11644}, {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b8},
|
||||
{0x116c0, 0x116c9}, {0x11700, 0x1171a}, {0x1171d, 0x1172b}, {0x11730, 0x1173f},
|
||||
{0x11800, 0x1183b}, {0x118a0, 0x118f2}, {0x119a0, 0x119a7}, {0x119aa, 0x119d7},
|
||||
{0x119da, 0x119e4}, {0x11a00, 0x11a47}, {0x11a50, 0x11aa2}, {0x11ac0, 0x11af8},
|
||||
{0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45}, {0x11c50, 0x11c6c},
|
||||
{0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6}, {0x11d00, 0x11d06},
|
||||
{0x11d0b, 0x11d36}, {0x11d3f, 0x11d47}, {0x11d50, 0x11d59}, {0x11d60, 0x11d65},
|
||||
{0x11d6a, 0x11d8e}, {0x11d93, 0x11d98}, {0x11da0, 0x11da9}, {0x11ee0, 0x11ef8},
|
||||
{0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
|
||||
{0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
|
||||
{0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
|
||||
{0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
|
||||
{0x16e40, 0x16e9a}, {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f},
|
||||
{0x17000, 0x187f1}, {0x18800, 0x18af2}, {0x1b000, 0x1b11e}, {0x1b170, 0x1b2fb},
|
||||
{0x11fc0, 0x11ff1}, {0x11fff, 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}, {0x16e40, 0x16e9a}, {0x16f00, 0x16f4a}, {0x16f4f, 0x16f87},
|
||||
{0x16f8f, 0x16f9f}, {0x16fe0, 0x16fe3}, {0x17000, 0x187f7}, {0x18800, 0x18af2},
|
||||
{0x1b000, 0x1b11e}, {0x1b150, 0x1b152}, {0x1b164, 0x1b167}, {0x1b170, 0x1b2fb},
|
||||
{0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99},
|
||||
{0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126}, {0x1d129, 0x1d172},
|
||||
{0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d2e0, 0x1d2f3}, {0x1d300, 0x1d356},
|
||||
@@ -742,22 +746,24 @@ static const crange graphRangeTable[] = {
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
|
||||
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
|
||||
{0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
|
||||
{0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
|
||||
{0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ec71, 0x1ecb4},
|
||||
{0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
|
||||
{0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
|
||||
{0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
|
||||
{0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093},
|
||||
{0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5},
|
||||
{0x1f100, 0x1f10c}, {0x1f110, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
|
||||
{0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265}, {0x1f300, 0x1f6d4},
|
||||
{0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f9}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d8},
|
||||
{0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887},
|
||||
{0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b}, {0x1f910, 0x1f93e}, {0x1f940, 0x1f970},
|
||||
{0x1f973, 0x1f976}, {0x1f97c, 0x1f9a2}, {0x1f9b0, 0x1f9b9}, {0x1f9c0, 0x1f9c2},
|
||||
{0x1f9d0, 0x1f9ff}, {0x1fa60, 0x1fa6d}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
|
||||
{0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0}, {0x2f800, 0x2fa1d},
|
||||
{0xe0100, 0xe01ef}
|
||||
{0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e100, 0x1e12c},
|
||||
{0x1e130, 0x1e13d}, {0x1e140, 0x1e149}, {0x1e2c0, 0x1e2f9}, {0x1e800, 0x1e8c4},
|
||||
{0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94b}, {0x1e950, 0x1e959}, {0x1ec71, 0x1ecb4},
|
||||
{0x1ed01, 0x1ed3d}, {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, 0x1f16c}, {0x1f170, 0x1f1ac},
|
||||
{0x1f1e6, 0x1f202}, {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f260, 0x1f265},
|
||||
{0x1f300, 0x1f6d5}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6fa}, {0x1f700, 0x1f773},
|
||||
{0x1f780, 0x1f7d8}, {0x1f7e0, 0x1f7eb}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847},
|
||||
{0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x1f900, 0x1f90b},
|
||||
{0x1f90d, 0x1f971}, {0x1f973, 0x1f976}, {0x1f97a, 0x1f9a2}, {0x1f9a5, 0x1f9aa},
|
||||
{0x1f9ae, 0x1f9ca}, {0x1f9cd, 0x1fa53}, {0x1fa60, 0x1fa6d}, {0x1fa70, 0x1fa73},
|
||||
{0x1fa78, 0x1fa7a}, {0x1fa80, 0x1fa82}, {0x1fa90, 0x1fa95}, {0x20000, 0x2a6d6},
|
||||
{0x2a700, 0x2b734}, {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2ceb0, 0x2ebe0},
|
||||
{0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -770,21 +776,20 @@ static const chr graphCharTable[] = {
|
||||
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
|
||||
0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81, 0xe82, 0xe84, 0xea5,
|
||||
0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940, 0x1f59,
|
||||
0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xfb3e,
|
||||
0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
|
||||
#if CHRBITS > 16
|
||||
,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
|
||||
0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
|
||||
0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x1145e, 0x118ff, 0x11d08,
|
||||
0x11d09, 0x11d3a, 0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e,
|
||||
0x16a6f, 0x16fe0, 0x16fe1, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
|
||||
0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
|
||||
0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
|
||||
0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
|
||||
0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f97a
|
||||
0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x118ff, 0x11d08, 0x11d09, 0x11d3a,
|
||||
0x11d3c, 0x11d3d, 0x11d67, 0x11d68, 0x11d90, 0x11d91, 0x16a6e, 0x16a6f, 0x1d49e,
|
||||
0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1e023, 0x1e024, 0x1e14e,
|
||||
0x1e14f, 0x1e2ff, 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
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+9
-10
@@ -206,11 +206,11 @@ struct vars {
|
||||
int cflags; /* copy of compile flags */
|
||||
int lasttype; /* type of previous token */
|
||||
int nexttype; /* type of next token */
|
||||
chr nextvalue; /* value (if any) of next token */
|
||||
int nextvalue; /* value (if any) of next token */
|
||||
int lexcon; /* lexical context type (see lex.c) */
|
||||
int nsubexp; /* subexpression count */
|
||||
struct subre **subs; /* subRE pointer vector */
|
||||
size_t nsubs; /* length of vector */
|
||||
int nsubs; /* length of vector */
|
||||
struct subre *sub10[10]; /* initial vector, enough for most */
|
||||
struct nfa *nfa; /* the NFA */
|
||||
struct colormap *cm; /* character color map */
|
||||
@@ -287,8 +287,7 @@ compile(
|
||||
{
|
||||
AllocVars(v);
|
||||
struct guts *g;
|
||||
int i;
|
||||
size_t j;
|
||||
int i, j;
|
||||
FILE *debug = (flags®_PROGRESS) ? stdout : NULL;
|
||||
#define CNOERR() { if (ISERR()) return freev(v, v->err); }
|
||||
|
||||
@@ -477,10 +476,10 @@ moresubs(
|
||||
int wanted) /* want enough room for this one */
|
||||
{
|
||||
struct subre **p;
|
||||
size_t n;
|
||||
int n;
|
||||
|
||||
assert(wanted > 0 && (size_t)wanted >= v->nsubs);
|
||||
n = (size_t)wanted * 3 / 2 + 1;
|
||||
assert(wanted > 0 && wanted >= v->nsubs);
|
||||
n = wanted * 3 / 2 + 1;
|
||||
if (v->subs == v->sub10) {
|
||||
p = (struct subre **) MALLOC(n * sizeof(struct subre *));
|
||||
if (p != NULL) {
|
||||
@@ -499,7 +498,7 @@ moresubs(
|
||||
*p = NULL;
|
||||
}
|
||||
assert(v->nsubs == n);
|
||||
assert((size_t)wanted < v->nsubs);
|
||||
assert(wanted < v->nsubs);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -954,10 +953,10 @@ parseqatom(
|
||||
if (cap) {
|
||||
v->nsubexp++;
|
||||
subno = v->nsubexp;
|
||||
if ((size_t)subno >= v->nsubs) {
|
||||
if (subno >= v->nsubs) {
|
||||
moresubs(v, subno);
|
||||
}
|
||||
assert((size_t)subno < v->nsubs);
|
||||
assert(subno < v->nsubs);
|
||||
} else {
|
||||
atomtype = PLAIN; /* something that's not '(' */
|
||||
}
|
||||
|
||||
+4
-4
@@ -172,8 +172,8 @@ exec(
|
||||
{
|
||||
AllocVars(v);
|
||||
int st, backref;
|
||||
size_t n;
|
||||
size_t i;
|
||||
int n;
|
||||
int i;
|
||||
#define LOCALMAT 20
|
||||
regmatch_t mat[LOCALMAT];
|
||||
#define LOCALDFAS 40
|
||||
@@ -236,7 +236,7 @@ exec(
|
||||
v->stop = (chr *)string + len;
|
||||
v->err = 0;
|
||||
assert(v->g->ntree >= 0);
|
||||
n = (size_t) v->g->ntree;
|
||||
n = v->g->ntree;
|
||||
if (n <= LOCALDFAS)
|
||||
v->subdfas = subdfas;
|
||||
else
|
||||
@@ -278,7 +278,7 @@ exec(
|
||||
if (v->pmatch != pmatch && v->pmatch != mat) {
|
||||
FREE(v->pmatch);
|
||||
}
|
||||
n = (size_t) v->g->ntree;
|
||||
n = v->g->ntree;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (v->subdfas[i] != NULL)
|
||||
freeDFA(v->subdfas[i]);
|
||||
|
||||
+52
-6
@@ -132,8 +132,9 @@ declare 28 {
|
||||
declare 29 {
|
||||
Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *objPtr)
|
||||
}
|
||||
# Only available as stub-entry, for backwards-compatible stub-enabled extensions
|
||||
declare 30 {
|
||||
void TclFreeObj(Tcl_Obj *objPtr)
|
||||
void TclOldFreeObj(Tcl_Obj *objPtr)
|
||||
}
|
||||
declare 31 {
|
||||
int Tcl_GetBoolean(Tcl_Interp *interp, const char *src, int *boolPtr)
|
||||
@@ -282,7 +283,7 @@ declare 74 {
|
||||
declare 75 {
|
||||
int Tcl_AsyncReady(void)
|
||||
}
|
||||
declare 76 {
|
||||
declare 76 {deprecated {No longer in use, changed to macro}} {
|
||||
void Tcl_BackgroundError(Tcl_Interp *interp)
|
||||
}
|
||||
declare 77 {deprecated {Use Tcl_UtfBackslash}} {
|
||||
@@ -513,7 +514,7 @@ declare 142 {
|
||||
declare 143 {
|
||||
void Tcl_Finalize(void)
|
||||
}
|
||||
declare 144 {
|
||||
declare 144 {nostub {Don't use this function in a stub-enabled extension}} {
|
||||
void Tcl_FindExecutable(const char *argv0)
|
||||
}
|
||||
declare 145 {
|
||||
@@ -812,7 +813,7 @@ declare 228 {
|
||||
declare 229 {
|
||||
void Tcl_SetMaxBlockTime(const Tcl_Time *timePtr)
|
||||
}
|
||||
declare 230 {
|
||||
declare 230 {nostub {Don't use this function in a stub-enabled extension}} {
|
||||
void Tcl_SetPanicProc(TCL_NORETURN1 Tcl_PanicProc *panicProc)
|
||||
}
|
||||
declare 231 {
|
||||
@@ -859,7 +860,7 @@ declare 242 {
|
||||
declare 243 {
|
||||
void Tcl_SplitPath(const char *path, int *argcPtr, const char ***argvPtr)
|
||||
}
|
||||
declare 244 {
|
||||
declare 244 {nostub {Don't use this function in a stub-enabled extension}} {
|
||||
void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName,
|
||||
Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc)
|
||||
}
|
||||
@@ -1868,7 +1869,7 @@ declare 518 {
|
||||
}
|
||||
|
||||
# TIP#121 (exit handler) dkf for Joe Mistachkin
|
||||
declare 519 {
|
||||
declare 519 {nostub {Don't use this function in a stub-enabled extension}} {
|
||||
Tcl_ExitProc *Tcl_SetExitProc(TCL_NORETURN1 Tcl_ExitProc *proc)
|
||||
}
|
||||
|
||||
@@ -2346,6 +2347,38 @@ declare 635 {
|
||||
unsigned char *data, size_t datalen, int copy)
|
||||
}
|
||||
|
||||
# TIP #445
|
||||
declare 636 {
|
||||
void Tcl_FreeIntRep(Tcl_Obj *objPtr)
|
||||
}
|
||||
declare 637 {
|
||||
char *Tcl_InitStringRep(Tcl_Obj *objPtr, const char *bytes,
|
||||
unsigned int numBytes)
|
||||
}
|
||||
declare 638 {
|
||||
Tcl_ObjIntRep *Tcl_FetchIntRep(Tcl_Obj *objPtr, const Tcl_ObjType *typePtr)
|
||||
}
|
||||
declare 639 {
|
||||
void Tcl_StoreIntRep(Tcl_Obj *objPtr, const Tcl_ObjType *typePtr,
|
||||
const Tcl_ObjIntRep *irPtr)
|
||||
}
|
||||
declare 640 {
|
||||
int Tcl_HasStringRep(Tcl_Obj *objPtr)
|
||||
}
|
||||
|
||||
# TIP #506
|
||||
declare 641 {
|
||||
void Tcl_IncrRefCount(Tcl_Obj *objPtr)
|
||||
}
|
||||
|
||||
declare 642 {
|
||||
void Tcl_DecrRefCount(Tcl_Obj *objPtr)
|
||||
}
|
||||
|
||||
declare 643 {
|
||||
int Tcl_IsShared(Tcl_Obj *objPtr)
|
||||
}
|
||||
|
||||
# ----- BASELINE -- FOR -- 8.7.0 ----- #
|
||||
|
||||
##############################################################################
|
||||
@@ -2396,6 +2429,19 @@ export {
|
||||
void Tcl_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
|
||||
Tcl_Interp *interp)
|
||||
}
|
||||
export {
|
||||
void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName,
|
||||
Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc)
|
||||
}
|
||||
export {
|
||||
void Tcl_SetPanicProc(TCL_NORETURN1 Tcl_PanicProc *panicProc)
|
||||
}
|
||||
export {
|
||||
Tcl_ExitProc *Tcl_SetExitProc(TCL_NORETURN1 Tcl_ExitProc *proc)
|
||||
}
|
||||
export {
|
||||
void Tcl_FindExecutable(const char *argv0)
|
||||
}
|
||||
export {
|
||||
const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version,
|
||||
int exact)
|
||||
|
||||
+41
-40
@@ -42,10 +42,6 @@ extern "C" {
|
||||
* win/configure.ac (as above)
|
||||
* win/tcl.m4 (not patchlevel)
|
||||
* 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
|
||||
* macosx/Tcl.xcode/project.pbxproj (not patchlevel) 2 LOC
|
||||
* macosx/Tcl.xcode/default.pbxuser (not patchlevel) 1 LOC
|
||||
* macosx/Tcl-Common.xcconfig (not patchlevel) 1 LOC
|
||||
* win/README (not patchlevel) (sections 0 and 2)
|
||||
* unix/tcl.spec (1 LOC patch)
|
||||
@@ -750,6 +746,29 @@ typedef struct Tcl_ObjType {
|
||||
* old type. Returns TCL_ERROR on failure. */
|
||||
} Tcl_ObjType;
|
||||
|
||||
/*
|
||||
* The following structure stores an internal representation (intrep) for
|
||||
* a Tcl value. An intrep is associated with an Tcl_ObjType when both
|
||||
* are stored in the same Tcl_Obj. The routines of the Tcl_ObjType govern
|
||||
* the handling of the intrep.
|
||||
*/
|
||||
|
||||
typedef union Tcl_ObjIntRep { /* The internal representation: */
|
||||
long longValue; /* - an long integer value. */
|
||||
double doubleValue; /* - a double-precision floating value. */
|
||||
void *otherValuePtr; /* - another, type-specific value, */
|
||||
/* not used internally any more. */
|
||||
Tcl_WideInt wideValue; /* - an integer value >= 64bits */
|
||||
struct { /* - internal rep as two pointers. */
|
||||
void *ptr1;
|
||||
void *ptr2;
|
||||
} twoPtrValue;
|
||||
struct { /* - internal rep as a pointer and a long, */
|
||||
void *ptr; /* not used internally any more. */
|
||||
unsigned long value;
|
||||
} ptrAndLongRep;
|
||||
} Tcl_ObjIntRep;
|
||||
|
||||
/*
|
||||
* One of the following structures exists for each object in the Tcl system.
|
||||
* An object stores a value as either a string, some internal representation,
|
||||
@@ -775,40 +794,9 @@ typedef struct Tcl_Obj {
|
||||
* corresponds to the type of the object's
|
||||
* internal rep. NULL indicates the object has
|
||||
* no internal rep (has no type). */
|
||||
union { /* The internal representation: */
|
||||
long longValue; /* - an long integer value. */
|
||||
double doubleValue; /* - a double-precision floating value. */
|
||||
void *otherValuePtr; /* - another, type-specific value, not used
|
||||
* internally any more. */
|
||||
Tcl_WideInt wideValue; /* - a long long value. */
|
||||
struct { /* - internal rep as two pointers.
|
||||
* Many uses in Tcl, including a bignum's
|
||||
* tightly packed fields, where the alloc,
|
||||
* used and signum flags are packed into
|
||||
* ptr2 with everything else hung off
|
||||
* ptr1. */
|
||||
void *ptr1;
|
||||
void *ptr2;
|
||||
} twoPtrValue;
|
||||
struct { /* - internal rep as a pointer and a long,
|
||||
* not used internally any more. */
|
||||
void *ptr;
|
||||
unsigned long value;
|
||||
} ptrAndLongRep;
|
||||
} internalRep;
|
||||
Tcl_ObjIntRep internalRep; /* The internal representation: */
|
||||
} Tcl_Obj;
|
||||
|
||||
/*
|
||||
* Macros to increment and decrement a Tcl_Obj's reference count, and to test
|
||||
* whether an object is shared (i.e. has reference count > 1). Note: clients
|
||||
* should use Tcl_DecrRefCount() when they are finished using an object, and
|
||||
* should never call TclFreeObj() directly. TclFreeObj() is only defined and
|
||||
* made public in tcl.h to support Tcl_DecrRefCount's macro definition.
|
||||
*/
|
||||
|
||||
void Tcl_IncrRefCount(Tcl_Obj *objPtr);
|
||||
void Tcl_DecrRefCount(Tcl_Obj *objPtr);
|
||||
int Tcl_IsShared(Tcl_Obj *objPtr);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -2403,7 +2391,7 @@ const char * TclTomMathInitializeStubs(Tcl_Interp *interp,
|
||||
*/
|
||||
|
||||
#define Tcl_Main(argc, argv, proc) Tcl_MainEx(argc, argv, proc, \
|
||||
(((Tcl_SetPanicProc)(Tcl_ConsolePanic), Tcl_CreateInterp)()))
|
||||
((Tcl_SetPanicProc(Tcl_ConsolePanic), Tcl_CreateInterp)()))
|
||||
EXTERN void Tcl_MainEx(int argc, char **argv,
|
||||
Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
|
||||
EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp,
|
||||
@@ -2482,26 +2470,39 @@ EXTERN int TclZipfs_AppHook(int *argc, char ***argv);
|
||||
#endif /* !TCL_MEM_DEBUG */
|
||||
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
# undef Tcl_IncrRefCount
|
||||
# define Tcl_IncrRefCount(objPtr) \
|
||||
Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__)
|
||||
# undef Tcl_DecrRefCount
|
||||
# define Tcl_DecrRefCount(objPtr) \
|
||||
Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__)
|
||||
# undef Tcl_IsShared
|
||||
# define Tcl_IsShared(objPtr) \
|
||||
Tcl_DbIsShared(objPtr, __FILE__, __LINE__)
|
||||
#else
|
||||
#elif (!defined(TCL_NO_DEPRECATED) && defined(USE_TCL_STUBS))
|
||||
/*
|
||||
* When compiling stub-enabled extensions without -DTCL_NO_DEPRECATED,
|
||||
* those extensions are expected to run fine with Tcl 8.6 as well.
|
||||
* This means we must continue to use macro's for the above 3 functions,
|
||||
* and the old stub entry for TclFreeObj. All other usage of TclFreeObj()
|
||||
* is forbidden now, therefore it is changed to be MODULE_SCOPE internal.
|
||||
*/
|
||||
# undef Tcl_IncrRefCount
|
||||
# define Tcl_IncrRefCount(objPtr) \
|
||||
++(objPtr)->refCount
|
||||
/*
|
||||
* Use do/while0 idiom for optimum correctness without compiler warnings.
|
||||
* http://c2.com/cgi/wiki?TrivialDoWhileLoop
|
||||
*/
|
||||
# undef Tcl_DecrRefCount
|
||||
# define Tcl_DecrRefCount(objPtr) \
|
||||
do { \
|
||||
Tcl_Obj *_objPtr = (objPtr); \
|
||||
if ((_objPtr)->refCount-- <= 1) { \
|
||||
TclFreeObj(_objPtr); \
|
||||
TclOldFreeObj(_objPtr); \
|
||||
} \
|
||||
} while(0)
|
||||
# undef Tcl_IsShared
|
||||
# define Tcl_IsShared(objPtr) \
|
||||
((objPtr)->refCount > 1)
|
||||
#endif
|
||||
@@ -2518,7 +2519,7 @@ EXTERN int TclZipfs_AppHook(int *argc, char ***argv);
|
||||
Tcl_DbNewBignumObj(val, __FILE__, __LINE__)
|
||||
# undef Tcl_NewBooleanObj
|
||||
# define Tcl_NewBooleanObj(val) \
|
||||
Tcl_DbNewLongObj((val)!=0, __FILE__, __LINE__)
|
||||
Tcl_DbNewWideIntObj((val)!=0, __FILE__, __LINE__)
|
||||
# undef Tcl_NewByteArrayObj
|
||||
# define Tcl_NewByteArrayObj(bytes, len) \
|
||||
Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
|
||||
|
||||
+3
-3
@@ -274,8 +274,8 @@ TclpAlloc(
|
||||
|
||||
if (numBytes >= MAXMALLOC - OVERHEAD) {
|
||||
if (numBytes <= UINT_MAX - OVERHEAD -sizeof(struct block)) {
|
||||
bigBlockPtr = (struct block *) TclpSysAlloc((unsigned)
|
||||
(sizeof(struct block) + OVERHEAD + numBytes), 0);
|
||||
bigBlockPtr = (struct block *) TclpSysAlloc(
|
||||
sizeof(struct block) + OVERHEAD + numBytes, 0);
|
||||
}
|
||||
if (bigBlockPtr == NULL) {
|
||||
Tcl_MutexUnlock(allocMutexPtr);
|
||||
@@ -604,7 +604,7 @@ TclpRealloc(
|
||||
if (maxSize < numBytes) {
|
||||
numBytes = maxSize;
|
||||
}
|
||||
memcpy(newPtr, oldPtr, (size_t) numBytes);
|
||||
memcpy(newPtr, oldPtr, numBytes);
|
||||
TclpFree(oldPtr);
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
+15
-11
@@ -32,6 +32,7 @@
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclOOInt.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Structure that represents a range of instructions in the bytecode.
|
||||
@@ -271,15 +272,12 @@ static void CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*,
|
||||
const TalInstDesc*);
|
||||
static int DefineLabel(AssemblyEnv* envPtr, const char* label);
|
||||
static void DeleteMirrorJumpTable(JumptableInfo* jtPtr);
|
||||
static void DupAssembleCodeInternalRep(Tcl_Obj* src,
|
||||
Tcl_Obj* dest);
|
||||
static void FillInJumpOffsets(AssemblyEnv*);
|
||||
static int CreateMirrorJumpTable(AssemblyEnv* assemEnvPtr,
|
||||
Tcl_Obj* jumpTable);
|
||||
static int FindLocalVar(AssemblyEnv* envPtr,
|
||||
Tcl_Token** tokenPtrPtr);
|
||||
static int FinishAssembly(AssemblyEnv*);
|
||||
static void FreeAssembleCodeInternalRep(Tcl_Obj *objPtr);
|
||||
static void FreeAssemblyEnv(AssemblyEnv*);
|
||||
static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*);
|
||||
static int GetListIndexOperand(AssemblyEnv*, Tcl_Token**, int*);
|
||||
@@ -318,6 +316,9 @@ static void UnstackExpiredCatches(CompileEnv*, BasicBlock*, int,
|
||||
* Tcl_ObjType that describes bytecode emitted by the assembler.
|
||||
*/
|
||||
|
||||
static Tcl_FreeInternalRepProc FreeAssembleCodeInternalRep;
|
||||
static Tcl_DupInternalRepProc DupAssembleCodeInternalRep;
|
||||
|
||||
static const Tcl_ObjType assembleCodeType = {
|
||||
"assemblecode",
|
||||
FreeAssembleCodeInternalRep, /* freeIntRepProc */
|
||||
@@ -802,7 +803,7 @@ TclNRAssembleObjCmd(
|
||||
Tcl_AddErrorInfo(interp, "\n (\"");
|
||||
Tcl_AppendObjToErrorInfo(interp, objv[0]);
|
||||
Tcl_AddErrorInfo(interp, "\" body, line ");
|
||||
backtrace = Tcl_NewIntObj(Tcl_GetErrorLine(interp));
|
||||
backtrace = Tcl_NewWideIntObj(Tcl_GetErrorLine(interp));
|
||||
Tcl_AppendObjToErrorInfo(interp, backtrace);
|
||||
Tcl_AddErrorInfo(interp, ")");
|
||||
return TCL_ERROR;
|
||||
@@ -847,15 +848,15 @@ CompileAssembleObj(
|
||||
const char* source; /* String representation of the source code */
|
||||
int sourceLen; /* Length of the source code in bytes */
|
||||
|
||||
|
||||
/*
|
||||
* Get the expression ByteCode from the object. If it exists, make sure it
|
||||
* is valid in the current context.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &assembleCodeType) {
|
||||
ByteCodeGetIntRep(objPtr, &assembleCodeType, codePtr);
|
||||
|
||||
if (codePtr) {
|
||||
namespacePtr = iPtr->varFramePtr->nsPtr;
|
||||
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (((Interp *) *codePtr->interpHandle == iPtr)
|
||||
&& (codePtr->compileEpoch == iPtr->compileEpoch)
|
||||
&& (codePtr->nsPtr == namespacePtr)
|
||||
@@ -869,7 +870,7 @@ CompileAssembleObj(
|
||||
* Not valid, so free it and regenerate.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
Tcl_StoreIntRep(objPtr, &assembleCodeType, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2261,7 +2262,7 @@ GetListIndexOperand(
|
||||
* when list size limits grow.
|
||||
*/
|
||||
status = TclIndexEncode(interp, value,
|
||||
TCL_INDEX_BEFORE,TCL_INDEX_BEFORE, result);
|
||||
TCL_INDEX_NONE,TCL_INDEX_NONE, result);
|
||||
|
||||
Tcl_DecrRefCount(value);
|
||||
*tokenPtrPtr = TokenAfter(tokenPtr);
|
||||
@@ -4262,7 +4263,7 @@ AddBasicBlockRangeToErrorInfo(
|
||||
Tcl_Obj* lineNo; /* Line number in the source */
|
||||
|
||||
Tcl_AddErrorInfo(interp, "\n in assembly code between lines ");
|
||||
lineNo = Tcl_NewIntObj(bbPtr->startLine);
|
||||
lineNo = Tcl_NewWideIntObj(bbPtr->startLine);
|
||||
Tcl_IncrRefCount(lineNo);
|
||||
Tcl_AppendObjToErrorInfo(interp, lineNo);
|
||||
Tcl_AddErrorInfo(interp, " and ");
|
||||
@@ -4332,7 +4333,10 @@ static void
|
||||
FreeAssembleCodeInternalRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ByteCode *codePtr;
|
||||
|
||||
ByteCodeGetIntRep(objPtr, &assembleCodeType, codePtr);
|
||||
assert(codePtr != NULL);
|
||||
|
||||
TclReleaseByteCode(codePtr);
|
||||
}
|
||||
|
||||
+255
-82
@@ -105,6 +105,7 @@ TCL_DECLARE_MUTEX(commandTypeLock);
|
||||
* Static functions in this file:
|
||||
*/
|
||||
|
||||
static Tcl_ObjCmdProc BadEnsembleSubcommand;
|
||||
static char * CallCommandTraces(Interp *iPtr, Command *cmdPtr,
|
||||
const char *oldName, const char *newName,
|
||||
int flags);
|
||||
@@ -125,7 +126,6 @@ static Tcl_ObjCmdProc ExprBinaryFunc;
|
||||
static Tcl_ObjCmdProc ExprBoolFunc;
|
||||
static Tcl_ObjCmdProc ExprCeilFunc;
|
||||
static Tcl_ObjCmdProc ExprDoubleFunc;
|
||||
static Tcl_ObjCmdProc ExprEntierFunc;
|
||||
static Tcl_ObjCmdProc ExprFloorFunc;
|
||||
static Tcl_ObjCmdProc ExprIntFunc;
|
||||
static Tcl_ObjCmdProc ExprIsqrtFunc;
|
||||
@@ -206,6 +206,24 @@ typedef struct {
|
||||
* expansion for itself rather than needing the generic layer to take care of
|
||||
* it for it. Defined in tclInt.h. */
|
||||
|
||||
/*
|
||||
* The following struct states that the command it talks about (a subcommand
|
||||
* of one of Tcl's built-in ensembles) is unsafe and must be hidden when an
|
||||
* interpreter is made safe. (TclHideUnsafeCommands accesses an array of these
|
||||
* structs.) Alas, we can't sensibly just store the information directly in
|
||||
* the commands.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const char *ensembleNsName; /* The ensemble's name within ::tcl. NULL for
|
||||
* the end of the list of commands to hide. */
|
||||
const char *commandName; /* The name of the command within the
|
||||
* ensemble. If this is NULL, we want to also
|
||||
* make the overall command be hidden, an ugly
|
||||
* hack because it is expected by security
|
||||
* policies in the wild. */
|
||||
} UnsafeEnsembleInfo;
|
||||
|
||||
/*
|
||||
* The built-in commands, and the functions that implement them:
|
||||
*/
|
||||
@@ -242,6 +260,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"list", Tcl_ListObjCmd, TclCompileListCmd, NULL, CMD_IS_SAFE|CMD_COMPILES_EXPANDED},
|
||||
{"llength", Tcl_LlengthObjCmd, TclCompileLlengthCmd, NULL, CMD_IS_SAFE},
|
||||
{"lmap", Tcl_LmapObjCmd, TclCompileLmapCmd, TclNRLmapCmd, CMD_IS_SAFE},
|
||||
{"lpop", Tcl_LpopObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"lrange", Tcl_LrangeObjCmd, TclCompileLrangeCmd, NULL, CMD_IS_SAFE},
|
||||
{"lrepeat", Tcl_LrepeatObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"lreplace", Tcl_LreplaceObjCmd, TclCompileLreplaceCmd, NULL, CMD_IS_SAFE},
|
||||
@@ -300,12 +319,75 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"source", Tcl_SourceObjCmd, NULL, TclNRSourceObjCmd, 0},
|
||||
{"tell", Tcl_TellObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"time", Tcl_TimeObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"timerate", Tcl_TimeRateObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"unload", Tcl_UnloadObjCmd, NULL, NULL, 0},
|
||||
{"update", Tcl_UpdateObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"vwait", Tcl_VwaitObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Information about which pieces of ensembles to hide when making an
|
||||
* interpreter safe:
|
||||
*/
|
||||
|
||||
static const UnsafeEnsembleInfo unsafeEnsembleCommands[] = {
|
||||
/* [encoding] has two unsafe commands. Assumed by older security policies
|
||||
* to be overall unsafe; it isn't but... */
|
||||
{"encoding", NULL},
|
||||
{"encoding", "dirs"},
|
||||
{"encoding", "system"},
|
||||
/* [file] has MANY unsafe commands! Assumed by older security policies to
|
||||
* be overall unsafe; it isn't but... */
|
||||
{"file", NULL},
|
||||
{"file", "atime"},
|
||||
{"file", "attributes"},
|
||||
{"file", "copy"},
|
||||
{"file", "delete"},
|
||||
{"file", "dirname"},
|
||||
{"file", "executable"},
|
||||
{"file", "exists"},
|
||||
{"file", "extension"},
|
||||
{"file", "isdirectory"},
|
||||
{"file", "isfile"},
|
||||
{"file", "link"},
|
||||
{"file", "lstat"},
|
||||
{"file", "mtime"},
|
||||
{"file", "mkdir"},
|
||||
{"file", "nativename"},
|
||||
{"file", "normalize"},
|
||||
{"file", "owned"},
|
||||
{"file", "readable"},
|
||||
{"file", "readlink"},
|
||||
{"file", "rename"},
|
||||
{"file", "rootname"},
|
||||
{"file", "size"},
|
||||
{"file", "stat"},
|
||||
{"file", "tail"},
|
||||
{"file", "tempfile"},
|
||||
{"file", "type"},
|
||||
{"file", "volumes"},
|
||||
{"file", "writable"},
|
||||
/* [info] has two unsafe commands */
|
||||
{"info", "cmdtype"},
|
||||
{"info", "nameofexecutable"},
|
||||
/* [tcl::process] has ONLY unsafe commands! */
|
||||
{"process", "list"},
|
||||
{"process", "status"},
|
||||
{"process", "purge"},
|
||||
{"process", "autopurge"},
|
||||
/* [zipfs] has MANY unsafe commands! */
|
||||
{"zipfs", "lmkimg"},
|
||||
{"zipfs", "lmkzip"},
|
||||
{"zipfs", "mkimg"},
|
||||
{"zipfs", "mkkey"},
|
||||
{"zipfs", "mkzip"},
|
||||
{"zipfs", "mount"},
|
||||
{"zipfs", "mount_data"},
|
||||
{"zipfs", "unmount"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* Math functions. All are safe.
|
||||
*/
|
||||
@@ -327,7 +409,7 @@ static const BuiltinFuncDef BuiltinFuncTable[] = {
|
||||
{ "cos", ExprUnaryFunc, (ClientData) cos },
|
||||
{ "cosh", ExprUnaryFunc, (ClientData) cosh },
|
||||
{ "double", ExprDoubleFunc, NULL },
|
||||
{ "entier", ExprEntierFunc, NULL },
|
||||
{ "entier", ExprIntFunc, NULL },
|
||||
{ "exp", ExprUnaryFunc, (ClientData) exp },
|
||||
{ "floor", ExprFloorFunc, NULL },
|
||||
{ "fmod", ExprBinaryFunc, (ClientData) fmod },
|
||||
@@ -478,7 +560,7 @@ Tcl_CreateInterp(void)
|
||||
const BuiltinFuncDef *builtinFuncPtr;
|
||||
const OpCmdInfo *opcmdInfoPtr;
|
||||
const CmdInfo *cmdInfoPtr;
|
||||
Tcl_Namespace *mathfuncNSPtr, *mathopNSPtr;
|
||||
Tcl_Namespace *nsPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
int isNew;
|
||||
CancelInfo *cancelInfo;
|
||||
@@ -893,6 +975,13 @@ Tcl_CreateInterp(void)
|
||||
Tcl_NRCreateCommand(interp, "::tcl::unsupported::inject", NULL,
|
||||
NRCoroInjectObjCmd, NULL, NULL);
|
||||
|
||||
/* Export unsupported commands */
|
||||
nsPtr = Tcl_FindNamespace(interp, "::tcl::unsupported", NULL, 0);
|
||||
if (nsPtr) {
|
||||
Tcl_Export(interp, nsPtr, "*", 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_DTRACE
|
||||
/*
|
||||
* Register the tcl::dtrace command.
|
||||
@@ -905,8 +994,8 @@ Tcl_CreateInterp(void)
|
||||
* Register the builtin math functions.
|
||||
*/
|
||||
|
||||
mathfuncNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathfunc", NULL,NULL);
|
||||
if (mathfuncNSPtr == NULL) {
|
||||
nsPtr = Tcl_CreateNamespace(interp, "::tcl::mathfunc", NULL,NULL);
|
||||
if (nsPtr == NULL) {
|
||||
Tcl_Panic("Can't create math function namespace");
|
||||
}
|
||||
#define MATH_FUNC_PREFIX_LEN 17 /* == strlen("::tcl::mathfunc::") */
|
||||
@@ -916,18 +1005,18 @@ Tcl_CreateInterp(void)
|
||||
strcpy(mathFuncName+MATH_FUNC_PREFIX_LEN, builtinFuncPtr->name);
|
||||
Tcl_CreateObjCommand(interp, mathFuncName,
|
||||
builtinFuncPtr->objCmdProc, builtinFuncPtr->clientData, NULL);
|
||||
Tcl_Export(interp, mathfuncNSPtr, builtinFuncPtr->name, 0);
|
||||
Tcl_Export(interp, nsPtr, builtinFuncPtr->name, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the mathematical "operator" commands. [TIP #174]
|
||||
*/
|
||||
|
||||
mathopNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathop", NULL, NULL);
|
||||
if (mathopNSPtr == NULL) {
|
||||
nsPtr = Tcl_CreateNamespace(interp, "::tcl::mathop", NULL, NULL);
|
||||
if (nsPtr == NULL) {
|
||||
Tcl_Panic("can't create math operator namespace");
|
||||
}
|
||||
Tcl_Export(interp, mathopNSPtr, "*", 1);
|
||||
Tcl_Export(interp, nsPtr, "*", 1);
|
||||
#define MATH_OP_PREFIX_LEN 15 /* == strlen("::tcl::mathop::") */
|
||||
memcpy(mathFuncName, "::tcl::mathop::", MATH_OP_PREFIX_LEN);
|
||||
for (opcmdInfoPtr=mathOpCmds ; opcmdInfoPtr->name!=NULL ; opcmdInfoPtr++){
|
||||
@@ -977,11 +1066,11 @@ Tcl_CreateInterp(void)
|
||||
TCL_GLOBAL_ONLY);
|
||||
|
||||
Tcl_SetVar2Ex(interp, "tcl_platform", "wordSize",
|
||||
Tcl_NewLongObj((long) sizeof(long)), TCL_GLOBAL_ONLY);
|
||||
Tcl_NewWideIntObj(sizeof(long)), TCL_GLOBAL_ONLY);
|
||||
|
||||
/* TIP #291 */
|
||||
Tcl_SetVar2Ex(interp, "tcl_platform", "pointerSize",
|
||||
Tcl_NewLongObj((long) sizeof(void *)), TCL_GLOBAL_ONLY);
|
||||
Tcl_NewWideIntObj(sizeof(void *)), TCL_GLOBAL_ONLY);
|
||||
|
||||
/*
|
||||
* Set up other variables such as tcl_version and tcl_library
|
||||
@@ -1135,6 +1224,7 @@ TclHideUnsafeCommands(
|
||||
Tcl_Interp *interp) /* Hide commands in this interpreter. */
|
||||
{
|
||||
register const CmdInfo *cmdInfoPtr;
|
||||
register const UnsafeEnsembleInfo *unsafePtr;
|
||||
|
||||
if (interp == NULL) {
|
||||
return TCL_ERROR;
|
||||
@@ -1144,11 +1234,82 @@ TclHideUnsafeCommands(
|
||||
Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
|
||||
}
|
||||
}
|
||||
TclMakeEncodingCommandSafe(interp); /* Ugh! */
|
||||
TclMakeFileCommandSafe(interp); /* Ugh! */
|
||||
|
||||
for (unsafePtr = unsafeEnsembleCommands;
|
||||
unsafePtr->ensembleNsName; unsafePtr++) {
|
||||
if (unsafePtr->commandName) {
|
||||
/*
|
||||
* Hide an ensemble subcommand.
|
||||
*/
|
||||
|
||||
Tcl_Obj *cmdName = Tcl_ObjPrintf("::tcl::%s::%s",
|
||||
unsafePtr->ensembleNsName, unsafePtr->commandName);
|
||||
Tcl_Obj *hideName = Tcl_ObjPrintf("tcl:%s:%s",
|
||||
unsafePtr->ensembleNsName, unsafePtr->commandName);
|
||||
|
||||
if (TclRenameCommand(interp, TclGetString(cmdName),
|
||||
"___tmp") != TCL_OK
|
||||
|| Tcl_HideCommand(interp, "___tmp",
|
||||
TclGetString(hideName)) != TCL_OK) {
|
||||
Tcl_Panic("problem making '%s %s' safe: %s",
|
||||
unsafePtr->ensembleNsName, unsafePtr->commandName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
Tcl_CreateObjCommand(interp, TclGetString(cmdName),
|
||||
BadEnsembleSubcommand, (ClientData) unsafePtr, NULL);
|
||||
TclDecrRefCount(cmdName);
|
||||
TclDecrRefCount(hideName);
|
||||
} else {
|
||||
/*
|
||||
* Hide an ensemble main command (for compatibility).
|
||||
*/
|
||||
|
||||
if (Tcl_HideCommand(interp, unsafePtr->ensembleNsName,
|
||||
unsafePtr->ensembleNsName) != TCL_OK) {
|
||||
Tcl_Panic("problem making '%s' safe: %s",
|
||||
unsafePtr->ensembleNsName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* BadEnsembleSubcommand --
|
||||
*
|
||||
* Command used to act as a backstop implementation when subcommands of
|
||||
* ensembles are unsafe (the real implementations of the subcommands are
|
||||
* hidden). The clientData is description of what was hidden.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result (always a TCL_ERROR).
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
BadEnsembleSubcommand(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
const UnsafeEnsembleInfo *infoPtr = clientData;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"not allowed to invoke subcommand %s of %s",
|
||||
infoPtr->commandName, infoPtr->ensembleNsName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
@@ -2594,7 +2755,7 @@ TclInvokeStringCommand(
|
||||
Command *cmdPtr = clientData;
|
||||
int i, result;
|
||||
const char **argv =
|
||||
TclStackAlloc(interp, (unsigned)(objc + 1) * sizeof(char *));
|
||||
TclStackAlloc(interp, (objc + 1) * sizeof(char *));
|
||||
|
||||
for (i = 0; i < objc; i++) {
|
||||
argv[i] = TclGetString(objv[i]);
|
||||
@@ -2623,7 +2784,7 @@ TclInvokeStringCommand(
|
||||
* in the Command structure.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl string result value.
|
||||
* A standard Tcl result value.
|
||||
*
|
||||
* Side effects:
|
||||
* Besides those side effects of the called Tcl_ObjCmdProc,
|
||||
@@ -2643,7 +2804,7 @@ TclInvokeObjectCommand(
|
||||
Tcl_Obj *objPtr;
|
||||
int i, length, result;
|
||||
Tcl_Obj **objv =
|
||||
TclStackAlloc(interp, (unsigned)(argc * sizeof(Tcl_Obj *)));
|
||||
TclStackAlloc(interp, (argc * sizeof(Tcl_Obj *)));
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
length = strlen(argv[i]);
|
||||
@@ -3715,9 +3876,14 @@ OldMathFuncProc(
|
||||
valuePtr = objv[j];
|
||||
result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((result != TCL_OK) && (valuePtr->typePtr == &tclDoubleType)) {
|
||||
d = valuePtr->internalRep.doubleValue;
|
||||
result = TCL_OK;
|
||||
if (result != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr
|
||||
= TclFetchIntRep(valuePtr, &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d = irPtr->doubleValue;
|
||||
result = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (result != TCL_OK) {
|
||||
@@ -4250,7 +4416,7 @@ Tcl_CancelEval(
|
||||
if (resultObjPtr != NULL) {
|
||||
result = TclGetStringFromObj(resultObjPtr, &cancelInfo->length);
|
||||
cancelInfo->result = ckrealloc(cancelInfo->result,cancelInfo->length);
|
||||
memcpy(cancelInfo->result, result, (size_t) cancelInfo->length);
|
||||
memcpy(cancelInfo->result, result, cancelInfo->length);
|
||||
TclDecrRefCount(resultObjPtr); /* Discard their result object. */
|
||||
} else {
|
||||
cancelInfo->result = NULL;
|
||||
@@ -4818,7 +4984,7 @@ TEOV_NotFound(
|
||||
Tcl_ListObjGetElements(NULL, currNsPtr->unknownHandlerPtr,
|
||||
&handlerObjc, &handlerObjv);
|
||||
newObjc = objc + handlerObjc;
|
||||
newObjv = TclStackAlloc(interp, (int) sizeof(Tcl_Obj *) * newObjc);
|
||||
newObjv = TclStackAlloc(interp, sizeof(Tcl_Obj *) * newObjc);
|
||||
|
||||
/*
|
||||
* Copy command prefix from unknown handler and add on the real command's
|
||||
@@ -4830,7 +4996,7 @@ TEOV_NotFound(
|
||||
newObjv[i] = handlerObjv[i];
|
||||
Tcl_IncrRefCount(newObjv[i]);
|
||||
}
|
||||
memcpy(newObjv+handlerObjc, objv, sizeof(Tcl_Obj *) * (unsigned)objc);
|
||||
memcpy(newObjv+handlerObjc, objv, sizeof(Tcl_Obj *) * objc);
|
||||
|
||||
/*
|
||||
* Look up and invoke the handler (by recursive call to this function). If
|
||||
@@ -5999,7 +6165,7 @@ TclArgumentGet(
|
||||
* up by the caller. It knows better than us.
|
||||
*/
|
||||
|
||||
if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) {
|
||||
if (!TclHasStringRep(obj) || TclListObjIsCanonical(obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6620,7 +6786,7 @@ Tcl_ExprLongObj(
|
||||
resultPtr = Tcl_NewBignumObj(&big);
|
||||
/* FALLTHROUGH */
|
||||
}
|
||||
case TCL_NUMBER_WIDE:
|
||||
case TCL_NUMBER_INT:
|
||||
case TCL_NUMBER_BIG:
|
||||
result = TclGetLongFromObj(interp, resultPtr, ptr);
|
||||
break;
|
||||
@@ -6863,7 +7029,7 @@ Tcl_ExprString(
|
||||
* An empty string. Just set the interpreter's result to 0.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
} else {
|
||||
Tcl_Obj *resultPtr, *exprObj = Tcl_NewStringObj(expr, -1);
|
||||
|
||||
@@ -7276,9 +7442,13 @@ ExprCeilFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7312,9 +7482,13 @@ ExprFloorFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7386,7 +7560,7 @@ ExprIsqrtFunc(
|
||||
if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (SIGN(&big) == MP_NEG) {
|
||||
if (big.sign != MP_ZPOS) {
|
||||
mp_clear(&big);
|
||||
goto negarg;
|
||||
}
|
||||
@@ -7448,9 +7622,13 @@ ExprSqrtFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7491,10 +7669,14 @@ ExprUnaryFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
d = objv[1]->internalRep.doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d = irPtr->doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7551,10 +7733,14 @@ ExprBinaryFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d1);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
d1 = objv[1]->internalRep.doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d1 = irPtr->doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7562,10 +7748,14 @@ ExprBinaryFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[2], &d2);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[2]->typePtr == &tclDoubleType)) {
|
||||
d2 = objv[2]->internalRep.doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d2 = irPtr->doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7596,20 +7786,22 @@ ExprAbsFunc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (type == TCL_NUMBER_WIDE) {
|
||||
if (type == TCL_NUMBER_INT) {
|
||||
Tcl_WideInt l = *((const Tcl_WideInt *) ptr);
|
||||
|
||||
if (l > (Tcl_WideInt)0) {
|
||||
if (l > 0) {
|
||||
goto unChanged;
|
||||
} else if (l == (Tcl_WideInt)0) {
|
||||
const char *string = objv[1]->bytes;
|
||||
if (string) {
|
||||
while (*string != '0') {
|
||||
if (*string == '-') {
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
|
||||
} else if (l == 0) {
|
||||
if (TclHasStringRep(objv[1])) {
|
||||
int numBytes;
|
||||
const char *bytes = TclGetStringFromObj(objv[1], &numBytes);
|
||||
|
||||
while (numBytes) {
|
||||
if (*bytes == '-') {
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
return TCL_OK;
|
||||
}
|
||||
string++;
|
||||
bytes++; numBytes--;
|
||||
}
|
||||
}
|
||||
goto unChanged;
|
||||
@@ -7642,7 +7834,7 @@ ExprAbsFunc(
|
||||
}
|
||||
|
||||
if (type == TCL_NUMBER_BIG) {
|
||||
if (mp_isneg((const mp_int *) ptr)) {
|
||||
if (((const mp_int *) ptr)->sign != MP_ZPOS) {
|
||||
Tcl_GetBignumFromObj(NULL, objv[1], &big);
|
||||
tooLarge:
|
||||
mp_neg(&big, &big);
|
||||
@@ -7705,7 +7897,7 @@ ExprDoubleFunc(
|
||||
}
|
||||
if (Tcl_GetDoubleFromObj(interp, objv[1], &dResult) != TCL_OK) {
|
||||
#ifdef ACCEPT_NAN
|
||||
if (objv[1]->typePtr == &tclDoubleType) {
|
||||
if (TclHasIntRep(objv[1], &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -7717,7 +7909,7 @@ ExprDoubleFunc(
|
||||
}
|
||||
|
||||
static int
|
||||
ExprEntierFunc(
|
||||
ExprIntFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
Tcl_Interp *interp, /* The interpreter in which to execute the
|
||||
* function. */
|
||||
@@ -7772,25 +7964,6 @@ ExprEntierFunc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
ExprIntFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
Tcl_Interp *interp, /* The interpreter in which to execute the
|
||||
* function. */
|
||||
int objc, /* Actual parameter count. */
|
||||
Tcl_Obj *const *objv) /* Actual parameter vector. */
|
||||
{
|
||||
Tcl_WideInt wResult;
|
||||
Tcl_Obj *objPtr;
|
||||
if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objPtr = Tcl_GetObjResult(interp);
|
||||
TclGetWideBitsFromObj(NULL, objPtr, &wResult);
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj((long)wResult));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
ExprWideFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
@@ -7801,7 +7974,7 @@ ExprWideFunc(
|
||||
{
|
||||
Tcl_WideInt wResult;
|
||||
|
||||
if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
|
||||
if (ExprIntFunc(NULL, interp, objc, objv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclGetWideBitsFromObj(NULL, Tcl_GetObjResult(interp), &wResult);
|
||||
@@ -7990,7 +8163,7 @@ ExprRoundFunc(
|
||||
|
||||
if (type == TCL_NUMBER_DOUBLE) {
|
||||
double fractPart, intPart;
|
||||
long max = LONG_MAX, min = LONG_MIN;
|
||||
Tcl_WideInt max = WIDE_MAX, min = WIDE_MIN;
|
||||
|
||||
fractPart = modf(*((const double *) ptr), &intPart);
|
||||
if (fractPart <= -0.5) {
|
||||
@@ -8013,14 +8186,14 @@ ExprRoundFunc(
|
||||
Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
|
||||
return TCL_OK;
|
||||
} else {
|
||||
long result = (long)intPart;
|
||||
Tcl_WideInt result = (Tcl_WideInt)intPart;
|
||||
|
||||
if (fractPart <= -0.5) {
|
||||
result--;
|
||||
} else if (fractPart >= 0.5) {
|
||||
result++;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
+164
-102
@@ -15,6 +15,7 @@
|
||||
#include "tommath.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* The following constants are used by GetFormatSpec to indicate various
|
||||
@@ -56,9 +57,12 @@
|
||||
|
||||
static void DupByteArrayInternalRep(Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *copyPtr);
|
||||
static void DupProperByteArrayInternalRep(Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *copyPtr);
|
||||
static int FormatNumber(Tcl_Interp *interp, int type,
|
||||
Tcl_Obj *src, unsigned char **cursorPtr);
|
||||
static void FreeByteArrayInternalRep(Tcl_Obj *objPtr);
|
||||
static void FreeProperByteArrayInternalRep(Tcl_Obj *objPtr);
|
||||
static int GetFormatSpec(const char **formatPtr, char *cmdPtr,
|
||||
int *countPtr, int *flagsPtr);
|
||||
static Tcl_Obj * ScanNumber(unsigned char *buffer, int type,
|
||||
@@ -246,8 +250,8 @@ static const EnsembleImplMap decodeMap[] = {
|
||||
|
||||
static const Tcl_ObjType properByteArrayType = {
|
||||
"bytearray",
|
||||
FreeByteArrayInternalRep,
|
||||
DupByteArrayInternalRep,
|
||||
FreeProperByteArrayInternalRep,
|
||||
DupProperByteArrayInternalRep,
|
||||
UpdateStringOfByteArray,
|
||||
NULL
|
||||
};
|
||||
@@ -268,9 +272,9 @@ const Tcl_ObjType tclByteArrayType = {
|
||||
*/
|
||||
|
||||
typedef struct ByteArray {
|
||||
int used; /* The number of bytes used in the byte
|
||||
unsigned int used; /* The number of bytes used in the byte
|
||||
* array. */
|
||||
int allocated; /* The amount of space actually allocated
|
||||
unsigned int allocated; /* The amount of space actually allocated
|
||||
* minus 1 byte. */
|
||||
unsigned char bytes[1]; /* The array of bytes. The actual size of this
|
||||
* field depends on the 'allocated' field
|
||||
@@ -279,16 +283,15 @@ typedef struct ByteArray {
|
||||
|
||||
#define BYTEARRAY_SIZE(len) \
|
||||
((unsigned) (TclOffset(ByteArray, bytes) + (len)))
|
||||
#define GET_BYTEARRAY(objPtr) \
|
||||
((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1)
|
||||
#define SET_BYTEARRAY(objPtr, baPtr) \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr)
|
||||
#define GET_BYTEARRAY(irPtr) ((ByteArray *) (irPtr)->twoPtrValue.ptr1)
|
||||
#define SET_BYTEARRAY(irPtr, baPtr) \
|
||||
(irPtr)->twoPtrValue.ptr1 = (void *) (baPtr)
|
||||
|
||||
int
|
||||
TclIsPureByteArray(
|
||||
Tcl_Obj * objPtr)
|
||||
{
|
||||
return (objPtr->typePtr == &properByteArrayType);
|
||||
return TclHasIntRep(objPtr, &properByteArrayType);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -403,11 +406,11 @@ Tcl_SetByteArrayObj(
|
||||
be >= 0. */
|
||||
{
|
||||
ByteArray *byteArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayObj");
|
||||
}
|
||||
TclFreeIntRep(objPtr);
|
||||
TclInvalidateStringRep(objPtr);
|
||||
|
||||
if (length < 0) {
|
||||
@@ -418,10 +421,11 @@ Tcl_SetByteArrayObj(
|
||||
byteArrayPtr->allocated = length;
|
||||
|
||||
if ((bytes != NULL) && (length > 0)) {
|
||||
memcpy(byteArrayPtr->bytes, bytes, (size_t) length);
|
||||
memcpy(byteArrayPtr->bytes, bytes, length);
|
||||
}
|
||||
objPtr->typePtr = &properByteArrayType;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
SET_BYTEARRAY(&ir, byteArrayPtr);
|
||||
|
||||
Tcl_StoreIntRep(objPtr, &properByteArrayType, &ir);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -449,17 +453,24 @@ Tcl_GetByteArrayFromObj(
|
||||
* array of bytes in the ByteArray object. */
|
||||
{
|
||||
ByteArray *baPtr;
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
|
||||
if ((objPtr->typePtr != &properByteArrayType)
|
||||
&& (objPtr->typePtr != &tclByteArrayType)) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
}
|
||||
}
|
||||
}
|
||||
baPtr = GET_BYTEARRAY(objPtr);
|
||||
baPtr = GET_BYTEARRAY(irPtr);
|
||||
|
||||
if (lengthPtr != NULL) {
|
||||
*lengthPtr = baPtr->used;
|
||||
}
|
||||
return (unsigned char *) baPtr->bytes;
|
||||
return baPtr->bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -490,23 +501,36 @@ Tcl_SetByteArrayLength(
|
||||
int length) /* New length for internal byte array. */
|
||||
{
|
||||
ByteArray *byteArrayPtr;
|
||||
unsigned newLength;
|
||||
Tcl_ObjIntRep *irPtr;
|
||||
|
||||
assert(length >= 0);
|
||||
newLength = (unsigned int)length;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayLength");
|
||||
}
|
||||
if ((objPtr->typePtr != &properByteArrayType)
|
||||
&& (objPtr->typePtr != &tclByteArrayType)) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byteArrayPtr = GET_BYTEARRAY(objPtr);
|
||||
if (length > byteArrayPtr->allocated) {
|
||||
byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(length));
|
||||
byteArrayPtr->allocated = length;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
byteArrayPtr = GET_BYTEARRAY(irPtr);
|
||||
if (newLength > byteArrayPtr->allocated) {
|
||||
byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(newLength));
|
||||
byteArrayPtr->allocated = newLength;
|
||||
SET_BYTEARRAY(irPtr, byteArrayPtr);
|
||||
}
|
||||
TclInvalidateStringRep(objPtr);
|
||||
byteArrayPtr->used = length;
|
||||
byteArrayPtr->used = newLength;
|
||||
return byteArrayPtr->bytes;
|
||||
}
|
||||
|
||||
@@ -535,13 +559,14 @@ SetByteArrayFromAny(
|
||||
int improper = 0;
|
||||
const char *src, *srcEnd;
|
||||
unsigned char *dst;
|
||||
ByteArray *byteArrayPtr;
|
||||
Tcl_UniChar ch = 0;
|
||||
ByteArray *byteArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
if (objPtr->typePtr == &properByteArrayType) {
|
||||
if (TclHasIntRep(objPtr, &properByteArrayType)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclByteArrayType) {
|
||||
if (TclHasIntRep(objPtr, &tclByteArrayType)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -559,9 +584,9 @@ SetByteArrayFromAny(
|
||||
byteArrayPtr->used = dst - byteArrayPtr->bytes;
|
||||
byteArrayPtr->allocated = length;
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->typePtr = improper ? &tclByteArrayType : &properByteArrayType;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
SET_BYTEARRAY(&ir, byteArrayPtr);
|
||||
Tcl_StoreIntRep(objPtr,
|
||||
improper ? &tclByteArrayType : &properByteArrayType, &ir);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -586,8 +611,14 @@ static void
|
||||
FreeByteArrayInternalRep(
|
||||
Tcl_Obj *objPtr) /* Object with internal rep to free. */
|
||||
{
|
||||
ckfree(GET_BYTEARRAY(objPtr));
|
||||
objPtr->typePtr = NULL;
|
||||
ckfree(GET_BYTEARRAY(TclFetchIntRep(objPtr, &tclByteArrayType)));
|
||||
}
|
||||
|
||||
static void
|
||||
FreeProperByteArrayInternalRep(
|
||||
Tcl_Obj *objPtr) /* Object with internal rep to free. */
|
||||
{
|
||||
ckfree(GET_BYTEARRAY(TclFetchIntRep(objPtr, &properByteArrayType)));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -612,19 +643,41 @@ DupByteArrayInternalRep(
|
||||
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
|
||||
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
{
|
||||
int length;
|
||||
unsigned int length;
|
||||
ByteArray *srcArrayPtr, *copyArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
srcArrayPtr = GET_BYTEARRAY(srcPtr);
|
||||
srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &tclByteArrayType));
|
||||
length = srcArrayPtr->used;
|
||||
|
||||
copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
|
||||
copyArrayPtr->used = length;
|
||||
copyArrayPtr->allocated = length;
|
||||
memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, (size_t) length);
|
||||
SET_BYTEARRAY(copyPtr, copyArrayPtr);
|
||||
memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length);
|
||||
|
||||
copyPtr->typePtr = srcPtr->typePtr;
|
||||
SET_BYTEARRAY(&ir, copyArrayPtr);
|
||||
Tcl_StoreIntRep(copyPtr, &tclByteArrayType, &ir);
|
||||
}
|
||||
|
||||
static void
|
||||
DupProperByteArrayInternalRep(
|
||||
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
|
||||
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
{
|
||||
unsigned int length;
|
||||
ByteArray *srcArrayPtr, *copyArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &properByteArrayType));
|
||||
length = srcArrayPtr->used;
|
||||
|
||||
copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
|
||||
copyArrayPtr->used = length;
|
||||
copyArrayPtr->allocated = length;
|
||||
memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length);
|
||||
|
||||
SET_BYTEARRAY(&ir, copyArrayPtr);
|
||||
Tcl_StoreIntRep(copyPtr, &properByteArrayType, &ir);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -632,9 +685,7 @@ DupByteArrayInternalRep(
|
||||
*
|
||||
* UpdateStringOfByteArray --
|
||||
*
|
||||
* Update the string representation for a ByteArray data object. Note:
|
||||
* This procedure does not invalidate an existing old string rep so
|
||||
* storage will be lost if this has not already been done.
|
||||
* Update the string representation for a ByteArray data object.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -643,9 +694,6 @@ DupByteArrayInternalRep(
|
||||
* The object's string is set to a valid string that results from the
|
||||
* ByteArray-to-string conversion.
|
||||
*
|
||||
* The object becomes a string object -- the internal rep is discarded
|
||||
* and the typePtr becomes NULL.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -654,41 +702,35 @@ UpdateStringOfByteArray(
|
||||
Tcl_Obj *objPtr) /* ByteArray object whose string rep to
|
||||
* update. */
|
||||
{
|
||||
int i, length, size;
|
||||
unsigned char *src;
|
||||
char *dst;
|
||||
ByteArray *byteArrayPtr;
|
||||
|
||||
byteArrayPtr = GET_BYTEARRAY(objPtr);
|
||||
src = byteArrayPtr->bytes;
|
||||
length = byteArrayPtr->used;
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
ByteArray *byteArrayPtr = GET_BYTEARRAY(irPtr);
|
||||
unsigned char *src = byteArrayPtr->bytes;
|
||||
unsigned int i, length = byteArrayPtr->used;
|
||||
unsigned int size = length;
|
||||
|
||||
/*
|
||||
* How much space will string rep need?
|
||||
*/
|
||||
|
||||
size = length;
|
||||
for (i = 0; i < length && size >= 0; i++) {
|
||||
for (i = 0; i < length && size <= INT_MAX; i++) {
|
||||
if ((src[i] == 0) || (src[i] > 127)) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
if (size < 0) {
|
||||
if (size > INT_MAX) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
|
||||
dst = ckalloc(size + 1);
|
||||
objPtr->bytes = dst;
|
||||
objPtr->length = size;
|
||||
|
||||
if (size == length) {
|
||||
memcpy(dst, src, (size_t) size);
|
||||
dst[size] = '\0';
|
||||
char *dst = Tcl_InitStringRep(objPtr, (char *)src, size);
|
||||
TclOOM(dst, size);
|
||||
} else {
|
||||
char *dst = Tcl_InitStringRep(objPtr, NULL, size);
|
||||
TclOOM(dst, size);
|
||||
for (i = 0; i < length; i++) {
|
||||
dst += Tcl_UniCharToUtf(src[i], dst);
|
||||
}
|
||||
*dst = '\0';
|
||||
(void)Tcl_InitStringRep(objPtr, NULL, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,7 +760,8 @@ TclAppendBytesToByteArray(
|
||||
int len)
|
||||
{
|
||||
ByteArray *byteArrayPtr;
|
||||
int needed;
|
||||
unsigned int length, needed;
|
||||
Tcl_ObjIntRep *irPtr;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
|
||||
@@ -731,24 +774,34 @@ TclAppendBytesToByteArray(
|
||||
/* Append zero bytes is a no-op. */
|
||||
return;
|
||||
}
|
||||
if ((objPtr->typePtr != &properByteArrayType)
|
||||
&& (objPtr->typePtr != &tclByteArrayType)) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
}
|
||||
byteArrayPtr = GET_BYTEARRAY(objPtr);
|
||||
|
||||
if (len > INT_MAX - byteArrayPtr->used) {
|
||||
length = (unsigned int)len;
|
||||
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
}
|
||||
}
|
||||
}
|
||||
byteArrayPtr = GET_BYTEARRAY(irPtr);
|
||||
|
||||
if (length > INT_MAX - byteArrayPtr->used) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
|
||||
needed = byteArrayPtr->used + len;
|
||||
needed = byteArrayPtr->used + length;
|
||||
/*
|
||||
* If we need to, resize the allocated space in the byte array.
|
||||
*/
|
||||
|
||||
if (needed > byteArrayPtr->allocated) {
|
||||
ByteArray *ptr = NULL;
|
||||
int attempt;
|
||||
unsigned int attempt;
|
||||
|
||||
if (needed <= INT_MAX/2) {
|
||||
/* Try to allocate double the total space that is needed. */
|
||||
@@ -758,7 +811,7 @@ TclAppendBytesToByteArray(
|
||||
if (ptr == NULL) {
|
||||
/* Try to allocate double the increment that is needed (plus). */
|
||||
unsigned int limit = INT_MAX - needed;
|
||||
unsigned int extra = len + TCL_MIN_GROWTH;
|
||||
unsigned int extra = length + TCL_MIN_GROWTH;
|
||||
int growth = (int) ((extra > limit) ? limit : extra);
|
||||
|
||||
attempt = needed + growth;
|
||||
@@ -771,13 +824,13 @@ TclAppendBytesToByteArray(
|
||||
}
|
||||
byteArrayPtr = ptr;
|
||||
byteArrayPtr->allocated = attempt;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
SET_BYTEARRAY(irPtr, byteArrayPtr);
|
||||
}
|
||||
|
||||
if (bytes) {
|
||||
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
|
||||
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, length);
|
||||
}
|
||||
byteArrayPtr->used += len;
|
||||
byteArrayPtr->used += length;
|
||||
TclInvalidateStringRep(objPtr);
|
||||
}
|
||||
|
||||
@@ -1023,7 +1076,7 @@ BinaryFormatCmd(
|
||||
|
||||
resultPtr = Tcl_NewObj();
|
||||
buffer = Tcl_SetByteArrayLength(resultPtr, length);
|
||||
memset(buffer, 0, (size_t) length);
|
||||
memset(buffer, 0, length);
|
||||
|
||||
/*
|
||||
* Pack the data into the result object. Note that we can skip the
|
||||
@@ -1060,10 +1113,10 @@ BinaryFormatCmd(
|
||||
count = 1;
|
||||
}
|
||||
if (length >= count) {
|
||||
memcpy(cursor, bytes, (size_t) count);
|
||||
memcpy(cursor, bytes, count);
|
||||
} else {
|
||||
memcpy(cursor, bytes, (size_t) length);
|
||||
memset(cursor + length, pad, (size_t) (count - length));
|
||||
memcpy(cursor, bytes, length);
|
||||
memset(cursor + length, pad, count - length);
|
||||
}
|
||||
cursor += count;
|
||||
break;
|
||||
@@ -1252,7 +1305,7 @@ BinaryFormatCmd(
|
||||
if (count == BINARY_NOCOUNT) {
|
||||
count = 1;
|
||||
}
|
||||
memset(cursor, 0, (size_t) count);
|
||||
memset(cursor, 0, count);
|
||||
cursor += count;
|
||||
break;
|
||||
case 'X':
|
||||
@@ -1301,7 +1354,7 @@ BinaryFormatCmd(
|
||||
badField:
|
||||
{
|
||||
Tcl_UniChar ch = 0;
|
||||
char buf[TCL_UTF_MAX + 1];
|
||||
char buf[TCL_UTF_MAX + 1] = "";
|
||||
|
||||
TclUtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
@@ -1655,7 +1708,7 @@ BinaryScanCmd(
|
||||
*/
|
||||
|
||||
done:
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(arg - 3));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(arg - 3));
|
||||
DeleteScanNumberCache(numberCachePtr);
|
||||
|
||||
return TCL_OK;
|
||||
@@ -1671,7 +1724,7 @@ BinaryScanCmd(
|
||||
badField:
|
||||
{
|
||||
Tcl_UniChar ch = 0;
|
||||
char buf[TCL_UTF_MAX + 1];
|
||||
char buf[TCL_UTF_MAX + 1] = "";
|
||||
|
||||
TclUtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
@@ -1978,10 +2031,11 @@ FormatNumber(
|
||||
*/
|
||||
|
||||
if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
|
||||
if (src->typePtr != &tclDoubleType) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(src, &tclDoubleType);
|
||||
if (irPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dvalue = src->internalRep.doubleValue;
|
||||
dvalue = irPtr->doubleValue;
|
||||
}
|
||||
CopyNumber(&dvalue, *cursorPtr, sizeof(double), type);
|
||||
*cursorPtr += sizeof(double);
|
||||
@@ -1997,10 +2051,11 @@ FormatNumber(
|
||||
*/
|
||||
|
||||
if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
|
||||
if (src->typePtr != &tclDoubleType) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(src, &tclDoubleType);
|
||||
if (irPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dvalue = src->internalRep.doubleValue;
|
||||
dvalue = irPtr->doubleValue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2220,7 +2275,7 @@ ScanNumber(
|
||||
|
||||
returnNumericObject:
|
||||
if (*numberCachePtrPtr == NULL) {
|
||||
return Tcl_NewLongObj(value);
|
||||
return Tcl_NewWideIntObj(value);
|
||||
} else {
|
||||
register Tcl_HashTable *tablePtr = *numberCachePtrPtr;
|
||||
register Tcl_HashEntry *hPtr;
|
||||
@@ -2231,7 +2286,7 @@ ScanNumber(
|
||||
return Tcl_GetHashValue(hPtr);
|
||||
}
|
||||
if (tablePtr->numEntries <= BINARY_SCAN_MAX_CACHE) {
|
||||
register Tcl_Obj *objPtr = Tcl_NewLongObj(value);
|
||||
register Tcl_Obj *objPtr = Tcl_NewWideIntObj(value);
|
||||
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
Tcl_SetHashValue(hPtr, objPtr);
|
||||
@@ -2249,7 +2304,7 @@ ScanNumber(
|
||||
|
||||
DeleteScanNumberCache(tablePtr);
|
||||
*numberCachePtrPtr = NULL;
|
||||
return Tcl_NewLongObj(value);
|
||||
return Tcl_NewWideIntObj(value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2483,8 +2538,8 @@ BinaryDecodeHex(
|
||||
}
|
||||
|
||||
c = *data++;
|
||||
if (!isxdigit((int) c)) {
|
||||
if (strict || !isspace(c)) {
|
||||
if (!isxdigit(UCHAR(c))) {
|
||||
if (strict || !TclIsSpaceProc(c)) {
|
||||
goto badChar;
|
||||
}
|
||||
i--;
|
||||
@@ -2831,7 +2886,7 @@ BinaryDecodeUu(
|
||||
if (lineLen < 0) {
|
||||
c = *data++;
|
||||
if (c < 32 || c > 96) {
|
||||
if (strict || !isspace(c)) {
|
||||
if (strict || !TclIsSpaceProc(c)) {
|
||||
goto badUu;
|
||||
}
|
||||
i--;
|
||||
@@ -2849,7 +2904,7 @@ BinaryDecodeUu(
|
||||
d[i] = c = *data++;
|
||||
if (c < 32 || c > 96) {
|
||||
if (strict) {
|
||||
if (!isspace(c)) {
|
||||
if (!TclIsSpaceProc(c)) {
|
||||
goto badUu;
|
||||
} else if (c == '\n') {
|
||||
goto shortUu;
|
||||
@@ -2893,7 +2948,7 @@ BinaryDecodeUu(
|
||||
} else if (c >= 32 && c <= 96) {
|
||||
data--;
|
||||
break;
|
||||
} else if (strict || !isspace(c)) {
|
||||
} else if (strict || !TclIsSpaceProc(c)) {
|
||||
goto badUu;
|
||||
}
|
||||
} while (data < dataend);
|
||||
@@ -3003,6 +3058,11 @@ BinaryDecode64(
|
||||
} else if (i > 1) {
|
||||
c = '=';
|
||||
} else {
|
||||
if (strict && i <= 1) {
|
||||
/* single resp. unfulfilled char (each 4th next single char)
|
||||
* is rather bad64 error case in strict mode */
|
||||
goto bad64;
|
||||
}
|
||||
cut += 3;
|
||||
break;
|
||||
}
|
||||
@@ -3018,7 +3078,7 @@ BinaryDecode64(
|
||||
if (c == '=' && i > 1) {
|
||||
value <<= 6;
|
||||
cut++;
|
||||
} else if (!strict && isspace(c)) {
|
||||
} else if (!strict && TclIsSpaceProc(c)) {
|
||||
i--;
|
||||
} else {
|
||||
goto bad64;
|
||||
@@ -3033,10 +3093,12 @@ BinaryDecode64(
|
||||
value = (value << 6) | 0x3e;
|
||||
} else if (c == '/') {
|
||||
value = (value << 6) | 0x3f;
|
||||
} else if (c == '=') {
|
||||
} else if (c == '=' && (
|
||||
!strict || i > 1) /* "=" and "a=" is rather bad64 error case in strict mode */
|
||||
) {
|
||||
value <<= 6;
|
||||
cut++;
|
||||
} else if (strict || !isspace(c)) {
|
||||
if (i) cut++;
|
||||
} else if (strict || !TclIsSpaceProc(c)) {
|
||||
goto bad64;
|
||||
} else {
|
||||
i--;
|
||||
@@ -3057,7 +3119,7 @@ BinaryDecode64(
|
||||
goto bad64;
|
||||
}
|
||||
for (; data < dataend; data++) {
|
||||
if (!isspace(*data)) {
|
||||
if (!TclIsSpaceProc(*data)) {
|
||||
goto bad64;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ Tcl_DbCkalloc(
|
||||
|
||||
/* Don't let size argument to TclpAlloc overflow */
|
||||
if (size <= UINT_MAX - HIGH_GUARD_SIZE -sizeof(struct mem_header)) {
|
||||
result = (struct mem_header *) TclpAlloc((unsigned)size +
|
||||
result = (struct mem_header *) TclpAlloc(size +
|
||||
sizeof(struct mem_header) + HIGH_GUARD_SIZE);
|
||||
}
|
||||
if (result == NULL) {
|
||||
@@ -495,7 +495,7 @@ Tcl_AttemptDbCkalloc(
|
||||
|
||||
/* Don't let size argument to TclpAlloc overflow */
|
||||
if (size <= UINT_MAX - HIGH_GUARD_SIZE - sizeof(struct mem_header)) {
|
||||
result = (struct mem_header *) TclpAlloc((unsigned)size +
|
||||
result = (struct mem_header *) TclpAlloc(size +
|
||||
sizeof(struct mem_header) + HIGH_GUARD_SIZE);
|
||||
}
|
||||
if (result == NULL) {
|
||||
@@ -691,7 +691,7 @@ Tcl_DbCkrealloc(
|
||||
copySize = memp->length;
|
||||
}
|
||||
newPtr = Tcl_DbCkalloc(size, file, line);
|
||||
memcpy(newPtr, ptr, (size_t) copySize);
|
||||
memcpy(newPtr, ptr, copySize);
|
||||
Tcl_DbCkfree(ptr, file, line);
|
||||
return newPtr;
|
||||
}
|
||||
@@ -725,7 +725,7 @@ Tcl_AttemptDbCkrealloc(
|
||||
if (newPtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(newPtr, ptr, (size_t) copySize);
|
||||
memcpy(newPtr, ptr, copySize);
|
||||
Tcl_DbCkfree(ptr, file, line);
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
+15
-20
@@ -452,7 +452,7 @@ ClockGetdatefieldsObjCmd(
|
||||
* that it isn't.
|
||||
*/
|
||||
|
||||
if (objv[1]->typePtr == &tclBignumType) {
|
||||
if (TclHasIntRep(objv[1], &tclBignumType)) {
|
||||
Tcl_SetObjResult(interp, literals[LIT_INTEGER_VALUE_TOO_LARGE]);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -488,27 +488,27 @@ ClockGetdatefieldsObjCmd(
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_TZNAME], fields.tzName);
|
||||
Tcl_DecrRefCount(fields.tzName);
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_TZOFFSET],
|
||||
Tcl_NewIntObj(fields.tzOffset));
|
||||
Tcl_NewWideIntObj(fields.tzOffset));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_JULIANDAY],
|
||||
Tcl_NewIntObj(fields.julianDay));
|
||||
Tcl_NewWideIntObj(fields.julianDay));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_GREGORIAN],
|
||||
Tcl_NewIntObj(fields.gregorian));
|
||||
Tcl_NewWideIntObj(fields.gregorian));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_ERA],
|
||||
literals[fields.era ? LIT_BCE : LIT_CE]);
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_YEAR],
|
||||
Tcl_NewIntObj(fields.year));
|
||||
Tcl_NewWideIntObj(fields.year));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFYEAR],
|
||||
Tcl_NewIntObj(fields.dayOfYear));
|
||||
Tcl_NewWideIntObj(fields.dayOfYear));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_MONTH],
|
||||
Tcl_NewIntObj(fields.month));
|
||||
Tcl_NewWideIntObj(fields.month));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFMONTH],
|
||||
Tcl_NewIntObj(fields.dayOfMonth));
|
||||
Tcl_NewWideIntObj(fields.dayOfMonth));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601YEAR],
|
||||
Tcl_NewIntObj(fields.iso8601Year));
|
||||
Tcl_NewWideIntObj(fields.iso8601Year));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601WEEK],
|
||||
Tcl_NewIntObj(fields.iso8601Week));
|
||||
Tcl_NewWideIntObj(fields.iso8601Week));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFWEEK],
|
||||
Tcl_NewIntObj(fields.dayOfWeek));
|
||||
Tcl_NewWideIntObj(fields.dayOfWeek));
|
||||
Tcl_SetObjResult(interp, dict);
|
||||
|
||||
return TCL_OK;
|
||||
@@ -628,7 +628,7 @@ ClockGetjuliandayfromerayearmonthdayObjCmd(
|
||||
copied = 1;
|
||||
}
|
||||
status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
|
||||
Tcl_NewIntObj(fields.julianDay));
|
||||
Tcl_NewWideIntObj(fields.julianDay));
|
||||
if (status == TCL_OK) {
|
||||
Tcl_SetObjResult(interp, dict);
|
||||
}
|
||||
@@ -712,7 +712,7 @@ ClockGetjuliandayfromerayearweekdayObjCmd(
|
||||
copied = 1;
|
||||
}
|
||||
status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
|
||||
Tcl_NewIntObj(fields.julianDay));
|
||||
Tcl_NewWideIntObj(fields.julianDay));
|
||||
if (status == TCL_OK) {
|
||||
Tcl_SetObjResult(interp, dict);
|
||||
}
|
||||
@@ -1772,8 +1772,7 @@ ClockClicksObjCmd(
|
||||
#endif
|
||||
break;
|
||||
case CLICKS_MICROS:
|
||||
Tcl_GetTime(&now);
|
||||
clicks = ((Tcl_WideInt) now.sec * 1000000) + now.usec;
|
||||
clicks = TclpGetMicroseconds();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1843,15 +1842,11 @@ ClockMicrosecondsObjCmd(
|
||||
int objc, /* Parameter count */
|
||||
Tcl_Obj *const *objv) /* Parameter values */
|
||||
{
|
||||
Tcl_Time now;
|
||||
|
||||
if (objc != 1) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_GetTime(&now);
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
|
||||
((Tcl_WideInt) now.sec * 1000000) + now.usec));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclpGetMicroseconds()));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
+43
-289
@@ -46,9 +46,6 @@ 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[]);
|
||||
@@ -84,7 +81,6 @@ static Tcl_NRPostProc ForPostNextCallback;
|
||||
static Tcl_NRPostProc ForeachLoopStep;
|
||||
static Tcl_NRPostProc EvalCmdErrMsg;
|
||||
|
||||
static Tcl_ObjCmdProc BadFileSubcommand;
|
||||
static Tcl_ObjCmdProc FileAttrAccessTimeCmd;
|
||||
static Tcl_ObjCmdProc FileAttrIsDirectoryCmd;
|
||||
static Tcl_ObjCmdProc FileAttrIsExecutableCmd;
|
||||
@@ -386,7 +382,7 @@ CatchObjCmdCallback(
|
||||
}
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -536,122 +532,15 @@ TclInitEncodingCmd(
|
||||
static const EnsembleImplMap encodingImplMap[] = {
|
||||
{"convertfrom", EncodingConvertfromObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"convertto", EncodingConverttoObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
|
||||
{"names", EncodingNamesObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
|
||||
{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;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1174,180 +1063,45 @@ TclInitFileCmd(
|
||||
*/
|
||||
|
||||
static const EnsembleImplMap initMap[] = {
|
||||
{"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
|
||||
{"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 1},
|
||||
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 1},
|
||||
{"channels", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
|
||||
{"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 1},
|
||||
{"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1},
|
||||
{"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"join", PathJoinCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
|
||||
{"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
|
||||
{"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 1},
|
||||
{"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1},
|
||||
{"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 1},
|
||||
{"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1},
|
||||
{"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"pathtype", PathTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
|
||||
{"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 1},
|
||||
{"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1},
|
||||
{"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
|
||||
{"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 1},
|
||||
{"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1},
|
||||
{"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
return TclMakeEnsemble(interp, "file", initMap);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclMakeFileCommandSafe --
|
||||
*
|
||||
* This function hides the unsafe subcommands of the "file" Tcl command
|
||||
* ensemble. It must only be called from TclHideUnsafeCommands.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Adds commands to the table of hidden commands.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclMakeFileCommandSafe(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
static const struct {
|
||||
const char *cmdName;
|
||||
int unsafe;
|
||||
} unsafeInfo[] = {
|
||||
{"atime", 1},
|
||||
{"attributes", 1},
|
||||
{"channels", 0},
|
||||
{"copy", 1},
|
||||
{"delete", 1},
|
||||
{"dirname", 1},
|
||||
{"executable", 1},
|
||||
{"exists", 1},
|
||||
{"extension", 1},
|
||||
{"isdirectory", 1},
|
||||
{"isfile", 1},
|
||||
{"join", 0},
|
||||
{"link", 1},
|
||||
{"lstat", 1},
|
||||
{"mtime", 1},
|
||||
{"mkdir", 1},
|
||||
{"nativename", 1},
|
||||
{"normalize", 1},
|
||||
{"owned", 1},
|
||||
{"pathtype", 0},
|
||||
{"readable", 1},
|
||||
{"readlink", 1},
|
||||
{"rename", 1},
|
||||
{"rootname", 1},
|
||||
{"separator", 0},
|
||||
{"size", 1},
|
||||
{"split", 0},
|
||||
{"stat", 1},
|
||||
{"system", 0},
|
||||
{"tail", 1},
|
||||
{"tempfile", 1},
|
||||
{"type", 1},
|
||||
{"volumes", 1},
|
||||
{"writable", 1},
|
||||
{NULL, 0}
|
||||
};
|
||||
int i;
|
||||
Tcl_DString oldBuf, newBuf;
|
||||
|
||||
Tcl_DStringInit(&oldBuf);
|
||||
TclDStringAppendLiteral(&oldBuf, "::tcl::file::");
|
||||
Tcl_DStringInit(&newBuf);
|
||||
TclDStringAppendLiteral(&newBuf, "tcl:file:");
|
||||
for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
|
||||
if (unsafeInfo[i].unsafe) {
|
||||
const char *oldName, *newName;
|
||||
|
||||
Tcl_DStringSetLength(&oldBuf, 13);
|
||||
oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1);
|
||||
Tcl_DStringSetLength(&newBuf, 9);
|
||||
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 'file %s' safe: %s",
|
||||
unsafeInfo[i].cmdName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
Tcl_CreateObjCommand(interp, oldName, BadFileSubcommand,
|
||||
(ClientData) unsafeInfo[i].cmdName, NULL);
|
||||
}
|
||||
}
|
||||
Tcl_DStringFree(&oldBuf);
|
||||
Tcl_DStringFree(&newBuf);
|
||||
|
||||
/*
|
||||
* Ugh. The [file] command is now actually safe, but it is assumed by
|
||||
* scripts that it is not, which messes up security policies. [Bug
|
||||
* 3211758]
|
||||
*/
|
||||
|
||||
if (Tcl_HideCommand(interp, "file", "file") != TCL_OK) {
|
||||
Tcl_Panic("problem making 'file' safe: %s",
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* BadFileSubcommand --
|
||||
*
|
||||
* Command used to act as a backstop implementation when subcommands of
|
||||
* "file" 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
|
||||
BadFileSubcommand(
|
||||
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 file", subcommandName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1425,7 +1179,7 @@ FileAttrAccessTimeCmd(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_atime));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((long) buf.st_atime));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1505,7 +1259,7 @@ FileAttrModifyTimeCmd(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_mtime));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((long) buf.st_mtime));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2128,7 +1882,7 @@ PathJoinCmd(
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1));
|
||||
Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1, 0));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2524,23 +2278,23 @@ StoreStatData(
|
||||
* cast might fail when there isn't a real arithmetic 'long long' type...
|
||||
*/
|
||||
|
||||
STORE_ARY("dev", Tcl_NewLongObj((long)statPtr->st_dev));
|
||||
STORE_ARY("dev", Tcl_NewWideIntObj((long)statPtr->st_dev));
|
||||
STORE_ARY("ino", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_ino));
|
||||
STORE_ARY("nlink", Tcl_NewLongObj((long)statPtr->st_nlink));
|
||||
STORE_ARY("uid", Tcl_NewLongObj((long)statPtr->st_uid));
|
||||
STORE_ARY("gid", Tcl_NewLongObj((long)statPtr->st_gid));
|
||||
STORE_ARY("nlink", Tcl_NewWideIntObj((long)statPtr->st_nlink));
|
||||
STORE_ARY("uid", Tcl_NewWideIntObj((long)statPtr->st_uid));
|
||||
STORE_ARY("gid", Tcl_NewWideIntObj((long)statPtr->st_gid));
|
||||
STORE_ARY("size", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_size));
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
||||
STORE_ARY("blocks", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_blocks));
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
STORE_ARY("blksize", Tcl_NewLongObj((long)statPtr->st_blksize));
|
||||
STORE_ARY("blksize", Tcl_NewWideIntObj((long)statPtr->st_blksize));
|
||||
#endif
|
||||
STORE_ARY("atime", Tcl_NewLongObj((long)statPtr->st_atime));
|
||||
STORE_ARY("mtime", Tcl_NewLongObj((long)statPtr->st_mtime));
|
||||
STORE_ARY("ctime", Tcl_NewLongObj((long)statPtr->st_ctime));
|
||||
STORE_ARY("atime", Tcl_NewWideIntObj((long)statPtr->st_atime));
|
||||
STORE_ARY("mtime", Tcl_NewWideIntObj((long)statPtr->st_mtime));
|
||||
STORE_ARY("ctime", Tcl_NewWideIntObj((long)statPtr->st_ctime));
|
||||
mode = (unsigned short) statPtr->st_mode;
|
||||
STORE_ARY("mode", Tcl_NewIntObj(mode));
|
||||
STORE_ARY("mode", Tcl_NewWideIntObj(mode));
|
||||
STORE_ARY("type", Tcl_NewStringObj(GetTypeFromMode(mode), -1));
|
||||
#undef STORE_ARY
|
||||
|
||||
|
||||
+133
-47
@@ -173,7 +173,7 @@ static const EnsembleImplMap defaultInfoMap[] = {
|
||||
{"library", InfoLibraryCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"loaded", InfoLoadedCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"locals", TclInfoLocalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1},
|
||||
{"patchlevel", InfoPatchLevelCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"procs", InfoProcsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
@@ -404,7 +404,7 @@ Tcl_IncrObjCmd(
|
||||
if (objc == 3) {
|
||||
incrPtr = objv[2];
|
||||
} else {
|
||||
incrPtr = Tcl_NewIntObj(1);
|
||||
incrPtr = Tcl_NewWideIntObj(1);
|
||||
}
|
||||
Tcl_IncrRefCount(incrPtr);
|
||||
newValuePtr = TclIncrObjVar2(interp, objv[1], NULL,
|
||||
@@ -539,9 +539,9 @@ InfoBodyCmd(
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
register Interp *iPtr = (Interp *) interp;
|
||||
const char *name;
|
||||
const char *name, *bytes;
|
||||
Proc *procPtr;
|
||||
Tcl_Obj *bodyPtr, *resultPtr;
|
||||
int numBytes;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "procname");
|
||||
@@ -566,18 +566,8 @@ InfoBodyCmd(
|
||||
* the object do not invalidate the internal rep.
|
||||
*/
|
||||
|
||||
bodyPtr = procPtr->bodyPtr;
|
||||
if (bodyPtr->bytes == NULL) {
|
||||
/*
|
||||
* The string rep might not be valid if the procedure has never been
|
||||
* run before. [Bug #545644]
|
||||
*/
|
||||
|
||||
TclGetString(bodyPtr);
|
||||
}
|
||||
resultPtr = Tcl_NewStringObj(bodyPtr->bytes, bodyPtr->length);
|
||||
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
bytes = Tcl_GetStringFromObj(procPtr->bodyPtr, &numBytes);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(bytes, numBytes));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -616,7 +606,7 @@ InfoCmdCountCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->cmdCount));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iPtr->cmdCount));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -998,7 +988,7 @@ InfoDefaultCmd(
|
||||
if (valueObjPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(1));
|
||||
} else {
|
||||
Tcl_Obj *nullObjPtr = Tcl_NewObj();
|
||||
|
||||
@@ -1007,7 +997,7 @@ InfoDefaultCmd(
|
||||
if (valueObjPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1181,7 +1171,7 @@ InfoFrameCmd(
|
||||
* Just "info frame".
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(topLevel));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(topLevel));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1303,9 +1293,9 @@ TclInfoFrame(
|
||||
|
||||
ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
|
||||
if (framePtr->line) {
|
||||
ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(framePtr->line[0]));
|
||||
} else {
|
||||
ADD_PAIR("line", Tcl_NewIntObj(1));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(1));
|
||||
}
|
||||
ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
|
||||
break;
|
||||
@@ -1342,7 +1332,7 @@ TclInfoFrame(
|
||||
|
||||
ADD_PAIR("type", Tcl_NewStringObj(typeString[fPtr->type], -1));
|
||||
if (fPtr->line) {
|
||||
ADD_PAIR("line", Tcl_NewIntObj(fPtr->line[0]));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(fPtr->line[0]));
|
||||
}
|
||||
|
||||
if (fPtr->type == TCL_LOCATION_SOURCE) {
|
||||
@@ -1369,7 +1359,7 @@ TclInfoFrame(
|
||||
*/
|
||||
|
||||
ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
|
||||
ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(framePtr->line[0]));
|
||||
ADD_PAIR("file", framePtr->data.eval.path);
|
||||
|
||||
/*
|
||||
@@ -1440,7 +1430,7 @@ TclInfoFrame(
|
||||
int c = framePtr->framePtr->level;
|
||||
int t = iPtr->varFramePtr->level;
|
||||
|
||||
ADD_PAIR("level", Tcl_NewIntObj(t - c));
|
||||
ADD_PAIR("level", Tcl_NewWideIntObj(t - c));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1595,7 +1585,7 @@ InfoLevelCmd(
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
|
||||
if (objc == 1) { /* Just "info level" */
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iPtr->varFramePtr->level));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2564,7 +2554,97 @@ Tcl_LlengthObjCmd(
|
||||
* length.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(listLen));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(listLen));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_LpopObjCmd --
|
||||
*
|
||||
* This procedure is invoked to process the "lpop" Tcl command. See the
|
||||
* user documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl object result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Tcl_LpopObjCmd(
|
||||
ClientData notUsed, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
register Tcl_Obj *const objv[])
|
||||
/* Argument objects. */
|
||||
{
|
||||
int listLen, result;
|
||||
Tcl_Obj *elemPtr;
|
||||
Tcl_Obj *listPtr, **elemPtrs;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "listvar ?index?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
listPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
|
||||
if (listPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
result = TclListObjGetElements(interp, listPtr, &listLen, &elemPtrs);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, extract the element to be returned.
|
||||
* TclLindexFlat adds a ref count which is handled.
|
||||
*/
|
||||
|
||||
if (objc == 2) {
|
||||
elemPtr = elemPtrs[listLen - 1];
|
||||
Tcl_IncrRefCount(elemPtr);
|
||||
} else {
|
||||
elemPtr = TclLindexFlat(interp, listPtr, objc-2, objv+2);
|
||||
|
||||
if (elemPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, elemPtr);
|
||||
Tcl_DecrRefCount(elemPtr);
|
||||
|
||||
/*
|
||||
* Second, remove the element.
|
||||
*/
|
||||
|
||||
if (objc == 2) {
|
||||
if (Tcl_IsShared(listPtr)) {
|
||||
listPtr = TclListObjCopy(NULL, listPtr);
|
||||
}
|
||||
result = Tcl_ListObjReplace(interp, listPtr, listLen - 1, 1, 0, NULL);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
listPtr = TclLsetFlat(interp, listPtr, objc-2, objv+2, NULL);
|
||||
|
||||
if (listPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
listPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG);
|
||||
if (listPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3159,12 +3239,11 @@ Tcl_LsearchObjCmd(
|
||||
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
int encoded = 0;
|
||||
if (TclIndexEncode(interp, indices[j], TCL_INDEX_BEFORE,
|
||||
TCL_INDEX_AFTER, &encoded) != TCL_OK) {
|
||||
if (TclIndexEncode(interp, indices[j], TCL_INDEX_NONE,
|
||||
TCL_INDEX_NONE, &encoded) != TCL_OK) {
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if ((encoded == TCL_INDEX_BEFORE)
|
||||
|| (encoded == TCL_INDEX_AFTER)) {
|
||||
if (encoded == TCL_INDEX_NONE) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"index \"%s\" cannot select an element "
|
||||
"from any list", Tcl_GetString(indices[j])));
|
||||
@@ -3310,7 +3389,7 @@ Tcl_LsearchObjCmd(
|
||||
if (allMatches || inlineReturn) {
|
||||
Tcl_ResetResult(interp);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-1));
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
@@ -3599,14 +3678,14 @@ Tcl_LsearchObjCmd(
|
||||
} else if (returnSubindices) {
|
||||
int j;
|
||||
|
||||
itemPtr = Tcl_NewIntObj(i+groupOffset);
|
||||
itemPtr = Tcl_NewWideIntObj(i+groupOffset);
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewWideIntObj(
|
||||
TclIndexDecode(sortInfo.indexv[j], listc)));
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
|
||||
} else {
|
||||
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i));
|
||||
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewWideIntObj(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3621,14 +3700,14 @@ Tcl_LsearchObjCmd(
|
||||
if (returnSubindices) {
|
||||
int j;
|
||||
|
||||
itemPtr = Tcl_NewIntObj(index+groupOffset);
|
||||
itemPtr = Tcl_NewWideIntObj(index+groupOffset);
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewWideIntObj(
|
||||
TclIndexDecode(sortInfo.indexv[j], listc)));
|
||||
}
|
||||
Tcl_SetObjResult(interp, itemPtr);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
|
||||
}
|
||||
} else if (index < 0) {
|
||||
/*
|
||||
@@ -3879,10 +3958,9 @@ Tcl_LsortObjCmd(
|
||||
for (j=0 ; j<indexc ; j++) {
|
||||
int encoded = 0;
|
||||
int result = TclIndexEncode(interp, indexv[j],
|
||||
TCL_INDEX_BEFORE, TCL_INDEX_AFTER, &encoded);
|
||||
TCL_INDEX_NONE, TCL_INDEX_NONE, &encoded);
|
||||
|
||||
if ((result == TCL_OK) && ((encoded == TCL_INDEX_BEFORE)
|
||||
|| (encoded == TCL_INDEX_AFTER))) {
|
||||
if ((result == TCL_OK) && (encoded == TCL_INDEX_NONE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"index \"%s\" cannot select an element "
|
||||
"from any list", Tcl_GetString(indexv[j])));
|
||||
@@ -3971,7 +4049,8 @@ Tcl_LsortObjCmd(
|
||||
}
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
/* Prescreened values, no errors or out of range possible */
|
||||
TclIndexEncode(NULL, indexv[j], 0, 0, &sortInfo.indexv[j]);
|
||||
TclIndexEncode(NULL, indexv[j], TCL_INDEX_NONE,
|
||||
TCL_INDEX_NONE, &sortInfo.indexv[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4197,7 +4276,7 @@ Tcl_LsortObjCmd(
|
||||
idx = elementPtr->payload.index;
|
||||
for (j = 0; j < groupSize; j++) {
|
||||
if (indices) {
|
||||
objPtr = Tcl_NewIntObj(idx + j - groupOffset);
|
||||
objPtr = Tcl_NewWideIntObj(idx + j - groupOffset);
|
||||
newArray[i++] = objPtr;
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
} else {
|
||||
@@ -4209,7 +4288,7 @@ Tcl_LsortObjCmd(
|
||||
}
|
||||
} else if (indices) {
|
||||
for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) {
|
||||
objPtr = Tcl_NewIntObj(elementPtr->payload.index);
|
||||
objPtr = Tcl_NewWideIntObj(elementPtr->payload.index);
|
||||
newArray[i++] = objPtr;
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
}
|
||||
@@ -4641,9 +4720,16 @@ SelectObjFromSublist(
|
||||
return NULL;
|
||||
}
|
||||
if (currentObj == NULL) {
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element %d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
if (index == TCL_INDEX_NONE) {
|
||||
index = TCL_INDEX_END - infoPtr->indexv[i];
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element end-%d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
} else {
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element %d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
}
|
||||
Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
|
||||
"INDEXFAILED", NULL);
|
||||
infoPtr->resultCode = TCL_ERROR;
|
||||
|
||||
+488
-61
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclRegexp.h"
|
||||
#include "tclStringTrim.h"
|
||||
|
||||
@@ -258,7 +259,7 @@ Tcl_RegexpObjCmd(
|
||||
stringLength = Tcl_GetCharLength(objPtr);
|
||||
|
||||
if (startIndex) {
|
||||
TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
|
||||
TclGetIntForIndexM(interp, startIndex, stringLength, &offset);
|
||||
Tcl_DecrRefCount(startIndex);
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
@@ -335,7 +336,7 @@ Tcl_RegexpObjCmd(
|
||||
*/
|
||||
|
||||
if (!doinline) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -388,8 +389,8 @@ Tcl_RegexpObjCmd(
|
||||
end = -1;
|
||||
}
|
||||
|
||||
objs[0] = Tcl_NewLongObj(start);
|
||||
objs[1] = Tcl_NewLongObj(end);
|
||||
objs[0] = Tcl_NewWideIntObj(start);
|
||||
objs[1] = Tcl_NewWideIntObj(end);
|
||||
|
||||
newPtr = Tcl_NewListObj(2, objs);
|
||||
} else {
|
||||
@@ -457,7 +458,7 @@ Tcl_RegexpObjCmd(
|
||||
if (doinline) {
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(all ? all-1 : 1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(all ? all-1 : 1));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -582,7 +583,7 @@ Tcl_RegsubObjCmd(
|
||||
if (startIndex) {
|
||||
int stringLength = Tcl_GetCharLength(objv[1]);
|
||||
|
||||
TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
|
||||
TclGetIntForIndexM(interp, startIndex, stringLength, &offset);
|
||||
Tcl_DecrRefCount(startIndex);
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
@@ -959,7 +960,7 @@ Tcl_RegsubObjCmd(
|
||||
* holding the number of matches.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(numMatches));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(numMatches));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -1216,13 +1217,13 @@ Tcl_SplitObjCmd(
|
||||
Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
|
||||
|
||||
for ( ; stringPtr < end; stringPtr += len) {
|
||||
int fullchar;
|
||||
int fullchar;
|
||||
len = TclUtfToUniChar(stringPtr, &ch);
|
||||
fullchar = ch;
|
||||
|
||||
#if TCL_UTF_MAX <= 4
|
||||
if (!len) {
|
||||
len += TclUtfToUniChar(stringPtr, &ch);
|
||||
if ((ch >= 0xD800) && (len < 3)) {
|
||||
len += TclUtfToUniChar(stringPtr + len, &ch);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
@@ -1336,7 +1337,7 @@ StringFirstCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFirst(objv[1],
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclStringFirst(objv[1],
|
||||
objv[2], start)));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1381,7 +1382,7 @@ StringLastCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringLast(objv[1],
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclStringLast(objv[1],
|
||||
objv[2], last)));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1444,11 +1445,11 @@ StringIndexCmd(
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1));
|
||||
} else {
|
||||
char buf[4];
|
||||
char buf[TCL_UTF_MAX] = "";
|
||||
|
||||
length = Tcl_UniCharToUtf(ch, buf);
|
||||
if (!length) {
|
||||
length = Tcl_UniCharToUtf(-1, buf);
|
||||
if ((ch >= 0xD800) && (length < 3)) {
|
||||
length += Tcl_UniCharToUtf(-1, buf + length);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length));
|
||||
}
|
||||
@@ -1490,19 +1491,19 @@ StringIsCmd(
|
||||
|
||||
static const char *const isClasses[] = {
|
||||
"alnum", "alpha", "ascii", "control",
|
||||
"boolean", "digit", "double", "entier",
|
||||
"false", "graph", "integer", "list",
|
||||
"lower", "print", "punct", "space",
|
||||
"true", "upper", "wideinteger", "wordchar",
|
||||
"xdigit", NULL
|
||||
"boolean", "dict", "digit", "double",
|
||||
"entier", "false", "graph", "integer",
|
||||
"list", "lower", "print", "punct",
|
||||
"space", "true", "upper", "wideinteger",
|
||||
"wordchar", "xdigit", NULL
|
||||
};
|
||||
enum isClasses {
|
||||
STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
|
||||
STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
|
||||
STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST,
|
||||
STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE,
|
||||
STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD,
|
||||
STR_IS_XDIGIT
|
||||
STR_IS_BOOL, STR_IS_DICT, STR_IS_DIGIT, STR_IS_DOUBLE,
|
||||
STR_IS_ENTIER, STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT,
|
||||
STR_IS_LIST, STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT,
|
||||
STR_IS_SPACE, STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE,
|
||||
STR_IS_WORD, STR_IS_XDIGIT
|
||||
};
|
||||
static const char *const isOptions[] = {
|
||||
"-strict", "-failindex", NULL
|
||||
@@ -1571,7 +1572,7 @@ StringIsCmd(
|
||||
case STR_IS_BOOL:
|
||||
case STR_IS_TRUE:
|
||||
case STR_IS_FALSE:
|
||||
if ((objPtr->typePtr != &tclBooleanType)
|
||||
if (!TclHasIntRep(objPtr, &tclBooleanType)
|
||||
&& (TCL_OK != TclSetBooleanFromAny(NULL, objPtr))) {
|
||||
if (strict) {
|
||||
result = 0;
|
||||
@@ -1589,13 +1590,61 @@ StringIsCmd(
|
||||
case STR_IS_CONTROL:
|
||||
chcomp = Tcl_UniCharIsControl;
|
||||
break;
|
||||
case STR_IS_DICT: {
|
||||
int dresult, dsize;
|
||||
|
||||
dresult = Tcl_DictObjSize(interp, objPtr, &dsize);
|
||||
Tcl_ResetResult(interp);
|
||||
result = (dresult == TCL_OK) ? 1 : 0;
|
||||
if (dresult != TCL_OK && failVarObj != NULL) {
|
||||
/*
|
||||
* Need to figure out where the list parsing failed, which is
|
||||
* fairly expensive. This is adapted from the core of
|
||||
* SetDictFromAny().
|
||||
*/
|
||||
|
||||
const char *elemStart, *nextElem;
|
||||
int lenRemain, elemSize;
|
||||
register const char *p;
|
||||
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
end = string1 + length1;
|
||||
failat = -1;
|
||||
for (p=string1, lenRemain=length1; lenRemain > 0;
|
||||
p=nextElem, lenRemain=end-nextElem) {
|
||||
if (TCL_ERROR == TclFindElement(NULL, p, lenRemain,
|
||||
&elemStart, &nextElem, &elemSize, NULL)) {
|
||||
Tcl_Obj *tmpStr;
|
||||
|
||||
/*
|
||||
* This is the simplest way of getting the number of
|
||||
* characters parsed. Note that this is not the same as
|
||||
* the number of bytes when parsing strings with non-ASCII
|
||||
* characters in them.
|
||||
*
|
||||
* Skip leading spaces first. This is only really an issue
|
||||
* if it is the first "element" that has the failure.
|
||||
*/
|
||||
|
||||
while (TclIsSpaceProc(*p)) {
|
||||
p++;
|
||||
}
|
||||
TclNewStringObj(tmpStr, string1, p-string1);
|
||||
failat = Tcl_GetCharLength(tmpStr);
|
||||
TclDecrRefCount(tmpStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STR_IS_DIGIT:
|
||||
chcomp = Tcl_UniCharIsDigit;
|
||||
break;
|
||||
case STR_IS_DOUBLE: {
|
||||
if ((objPtr->typePtr == &tclDoubleType) ||
|
||||
(objPtr->typePtr == &tclIntType) ||
|
||||
(objPtr->typePtr == &tclBignumType)) {
|
||||
if (TclHasIntRep(objPtr, &tclDoubleType) ||
|
||||
TclHasIntRep(objPtr, &tclIntType) ||
|
||||
TclHasIntRep(objPtr, &tclBignumType)) {
|
||||
break;
|
||||
}
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
@@ -1623,13 +1672,9 @@ StringIsCmd(
|
||||
chcomp = Tcl_UniCharIsGraph;
|
||||
break;
|
||||
case STR_IS_INT:
|
||||
if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) {
|
||||
break;
|
||||
}
|
||||
goto failedIntParse;
|
||||
case STR_IS_ENTIER:
|
||||
if ((objPtr->typePtr == &tclIntType) ||
|
||||
(objPtr->typePtr == &tclBignumType)) {
|
||||
if (TclHasIntRep(objPtr, &tclIntType) ||
|
||||
TclHasIntRep(objPtr, &tclBignumType)) {
|
||||
break;
|
||||
}
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
@@ -1674,7 +1719,6 @@ StringIsCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
failedIntParse:
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
if (length1 == 0) {
|
||||
if (strict) {
|
||||
@@ -1811,8 +1855,8 @@ StringIsCmd(
|
||||
length2 = TclUtfToUniChar(string1, &ch);
|
||||
fullchar = ch;
|
||||
#if TCL_UTF_MAX <= 4
|
||||
if (!length2) {
|
||||
length2 = TclUtfToUniChar(string1, &ch);
|
||||
if ((ch >= 0xD800) && (length2 < 3)) {
|
||||
length2 += TclUtfToUniChar(string1 + length2, &ch);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
@@ -1830,7 +1874,7 @@ StringIsCmd(
|
||||
|
||||
str_is_done:
|
||||
if ((result == 0) && (failVarObj != NULL) &&
|
||||
Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewIntObj(failat),
|
||||
Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewWideIntObj(failat),
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1849,7 +1893,7 @@ static int
|
||||
UniCharIsHexDigit(
|
||||
int character)
|
||||
{
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(character);
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(UCHAR(character));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1892,7 +1936,7 @@ StringMapCmd(
|
||||
const char *string = TclGetStringFromObj(objv[1], &length2);
|
||||
|
||||
if ((length2 > 1) &&
|
||||
strncmp(string, "-nocase", (size_t) length2) == 0) {
|
||||
strncmp(string, "-nocase", length2) == 0) {
|
||||
nocase = 1;
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
@@ -1908,7 +1952,8 @@ StringMapCmd(
|
||||
* inconsistencies (see test string-10.20.1 for illustration why!)
|
||||
*/
|
||||
|
||||
if (objv[objc-2]->typePtr == &tclDictType && objv[objc-2]->bytes == NULL){
|
||||
if (!TclHasStringRep(objv[objc-2])
|
||||
&& TclHasIntRep(objv[objc-2], &tclDictType)){
|
||||
int i, done;
|
||||
Tcl_DictSearch search;
|
||||
|
||||
@@ -2070,7 +2115,7 @@ StringMapCmd(
|
||||
(Tcl_UniCharToLower(*ustring1) == u2lc[index/2]))) &&
|
||||
/* Restrict max compare length. */
|
||||
(end-ustring1 >= length2) && ((length2 == 1) ||
|
||||
!strCmpFn(ustring2, ustring1, (unsigned) length2))) {
|
||||
!strCmpFn(ustring2, ustring1, length2))) {
|
||||
if (p != ustring1) {
|
||||
/*
|
||||
* Put the skipped chars onto the result first.
|
||||
@@ -2159,7 +2204,7 @@ StringMatchCmd(
|
||||
const char *string = TclGetStringFromObj(objv[1], &length);
|
||||
|
||||
if ((length > 1) &&
|
||||
strncmp(string, "-nocase", (size_t) length) == 0) {
|
||||
strncmp(string, "-nocase", length) == 0) {
|
||||
nocase = TCL_MATCH_NOCASE;
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
@@ -2452,7 +2497,7 @@ StringStartCmd(
|
||||
cur += 1;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2514,7 +2559,7 @@ StringEndCmd(
|
||||
} else {
|
||||
cur = numChars;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2561,10 +2606,10 @@ StringEqualCmd(
|
||||
|
||||
for (i = 1; i < objc-2; i++) {
|
||||
string2 = TclGetStringFromObj(objv[i], &length);
|
||||
if ((length > 1) && !strncmp(string2, "-nocase", (size_t)length)) {
|
||||
if ((length > 1) && !strncmp(string2, "-nocase", length)) {
|
||||
nocase = 1;
|
||||
} else if ((length > 1)
|
||||
&& !strncmp(string2, "-length", (size_t)length)) {
|
||||
&& !strncmp(string2, "-length", length)) {
|
||||
if (i+1 >= objc-2) {
|
||||
goto str_cmp_args;
|
||||
}
|
||||
@@ -2588,9 +2633,7 @@ StringEqualCmd(
|
||||
*/
|
||||
|
||||
objv += objc-2;
|
||||
|
||||
match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -2635,11 +2678,12 @@ StringCmpCmd(
|
||||
|
||||
objv += objc-2;
|
||||
match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(match));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int TclStringCmpOpts(
|
||||
int
|
||||
TclStringCmpOpts(
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[], /* Argument objects. */
|
||||
@@ -2660,10 +2704,10 @@ int TclStringCmpOpts(
|
||||
|
||||
for (i = 1; i < objc-2; i++) {
|
||||
string = TclGetStringFromObj(objv[i], &length);
|
||||
if ((length > 1) && !strncmp(string, "-nocase", (size_t)length)) {
|
||||
if ((length > 1) && !strncmp(string, "-nocase", length)) {
|
||||
*nocase = 1;
|
||||
} else if ((length > 1)
|
||||
&& !strncmp(string, "-length", (size_t)length)) {
|
||||
&& !strncmp(string, "-length", length)) {
|
||||
if (i+1 >= objc-2) {
|
||||
goto str_cmp_args;
|
||||
}
|
||||
@@ -2760,7 +2804,7 @@ StringBytesCmd(
|
||||
}
|
||||
|
||||
(void) TclGetStringFromObj(objv[1], &length);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(length));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(length));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2794,7 +2838,7 @@ StringLenCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_GetCharLength(objv[1])));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tcl_GetCharLength(objv[1])));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3683,10 +3727,10 @@ TclNRSwitchObjCmd(
|
||||
Tcl_Obj *rangeObjAry[2];
|
||||
|
||||
if (info.matches[j].end > 0) {
|
||||
rangeObjAry[0] = Tcl_NewLongObj(info.matches[j].start);
|
||||
rangeObjAry[1] = Tcl_NewLongObj(info.matches[j].end-1);
|
||||
rangeObjAry[0] = Tcl_NewWideIntObj(info.matches[j].start);
|
||||
rangeObjAry[1] = Tcl_NewWideIntObj(info.matches[j].end-1);
|
||||
} else {
|
||||
rangeObjAry[0] = rangeObjAry[1] = Tcl_NewIntObj(-1);
|
||||
rangeObjAry[0] = rangeObjAry[1] = Tcl_NewWideIntObj(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3987,7 +4031,7 @@ Tcl_TimeObjCmd(
|
||||
start = TclpGetWideClicks();
|
||||
#endif
|
||||
while (i-- > 0) {
|
||||
result = Tcl_EvalObjEx(interp, objPtr, 0);
|
||||
result = TclEvalObjEx(interp, objPtr, 0, NULL, 0);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -4006,7 +4050,7 @@ Tcl_TimeObjCmd(
|
||||
* Use int obj since we know time is not fractional. [Bug 1202178]
|
||||
*/
|
||||
|
||||
objs[0] = Tcl_NewIntObj((count <= 0) ? 0 : (int) totalMicroSec);
|
||||
objs[0] = Tcl_NewWideIntObj((count <= 0) ? 0 : (Tcl_WideInt)totalMicroSec);
|
||||
} else {
|
||||
objs[0] = Tcl_NewDoubleObj(totalMicroSec/count);
|
||||
}
|
||||
@@ -4024,6 +4068,389 @@ Tcl_TimeObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_TimeRateObjCmd --
|
||||
*
|
||||
* This object-based procedure is invoked to process the "timerate" Tcl
|
||||
* command.
|
||||
* This is similar to command "time", except the execution limited by
|
||||
* given time (in milliseconds) instead of repetition count.
|
||||
*
|
||||
* Example:
|
||||
* timerate {after 5} 1000 ; # equivalent for `time {after 5} [expr 1000/5]`
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl object result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Tcl_TimeRateObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
static double measureOverhead = 0; /* global measure-overhead */
|
||||
double overhead = -1; /* given measure-overhead */
|
||||
register Tcl_Obj *objPtr;
|
||||
register int result, i;
|
||||
Tcl_Obj *calibrate = NULL, *direct = NULL;
|
||||
Tcl_WideUInt count = 0; /* Holds repetition count */
|
||||
Tcl_WideInt maxms = WIDE_MIN;
|
||||
/* Maximal running time (in milliseconds) */
|
||||
Tcl_WideUInt maxcnt = WIDE_MAX;
|
||||
/* Maximal count of iterations. */
|
||||
Tcl_WideUInt threshold = 1; /* Current threshold for check time (faster
|
||||
* repeat count without time check) */
|
||||
Tcl_WideUInt maxIterTm = 1; /* Max time of some iteration as max threshold
|
||||
* additionally avoid divide to zero (never < 1) */
|
||||
unsigned short factor = 50; /* Factor (4..50) limiting threshold to avoid
|
||||
* growth of execution time. */
|
||||
register Tcl_WideInt start, middle, stop;
|
||||
#ifndef TCL_WIDE_CLICKS
|
||||
Tcl_Time now;
|
||||
#endif
|
||||
|
||||
static const char *const options[] = {
|
||||
"-direct", "-overhead", "-calibrate", "--", NULL
|
||||
};
|
||||
enum options {
|
||||
TMRT_EV_DIRECT, TMRT_OVERHEAD, TMRT_CALIBRATE, TMRT_LAST
|
||||
};
|
||||
|
||||
NRE_callback *rootPtr;
|
||||
ByteCode *codePtr = NULL;
|
||||
|
||||
for (i = 1; i < objc - 1; i++) {
|
||||
int index;
|
||||
if (Tcl_GetIndexFromObj(NULL, objv[i], options, "option", TCL_EXACT,
|
||||
&index) != TCL_OK) {
|
||||
break;
|
||||
}
|
||||
if (index == TMRT_LAST) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
switch (index) {
|
||||
case TMRT_EV_DIRECT:
|
||||
direct = objv[i];
|
||||
break;
|
||||
case TMRT_OVERHEAD:
|
||||
if (++i >= objc - 1) {
|
||||
goto usage;
|
||||
}
|
||||
if (Tcl_GetDoubleFromObj(interp, objv[i], &overhead) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
break;
|
||||
case TMRT_CALIBRATE:
|
||||
calibrate = objv[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= objc || i < objc-3) {
|
||||
usage:
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?-direct? ?-calibrate? ?-overhead double? command ?time ?max-count??");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objPtr = objv[i++];
|
||||
if (i < objc) { /* max-time */
|
||||
result = Tcl_GetWideIntFromObj(interp, objv[i++], &maxms);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
if (i < objc) { /* max-count*/
|
||||
Tcl_WideInt v;
|
||||
result = Tcl_GetWideIntFromObj(interp, objv[i], &v);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
maxcnt = (v > 0) ? v : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* if calibrate */
|
||||
if (calibrate) {
|
||||
|
||||
/* if no time specified for the calibration */
|
||||
if (maxms == WIDE_MIN) {
|
||||
Tcl_Obj *clobjv[6];
|
||||
Tcl_WideInt maxCalTime = 5000;
|
||||
double lastMeasureOverhead = measureOverhead;
|
||||
|
||||
clobjv[0] = objv[0];
|
||||
i = 1;
|
||||
if (direct) {
|
||||
clobjv[i++] = direct;
|
||||
}
|
||||
clobjv[i++] = objPtr;
|
||||
|
||||
/* reset last measurement overhead */
|
||||
measureOverhead = (double)0;
|
||||
|
||||
/* self-call with 100 milliseconds to warm-up,
|
||||
* before entering the calibration cycle */
|
||||
TclNewIntObj(clobjv[i], 100);
|
||||
Tcl_IncrRefCount(clobjv[i]);
|
||||
result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv);
|
||||
Tcl_DecrRefCount(clobjv[i]);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
i--;
|
||||
clobjv[i++] = calibrate;
|
||||
clobjv[i++] = objPtr;
|
||||
|
||||
/* set last measurement overhead to max */
|
||||
measureOverhead = (double)UWIDE_MAX;
|
||||
|
||||
/* calibration cycle until it'll be preciser */
|
||||
maxms = -1000;
|
||||
do {
|
||||
lastMeasureOverhead = measureOverhead;
|
||||
TclNewIntObj(clobjv[i], (int)maxms);
|
||||
Tcl_IncrRefCount(clobjv[i]);
|
||||
result = Tcl_TimeRateObjCmd(dummy, interp, i+1, clobjv);
|
||||
Tcl_DecrRefCount(clobjv[i]);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
maxCalTime += maxms;
|
||||
/* increase maxms for preciser calibration */
|
||||
maxms -= (-maxms / 4);
|
||||
/* as long as new value more as 0.05% better */
|
||||
} while ( (measureOverhead >= lastMeasureOverhead
|
||||
|| measureOverhead / lastMeasureOverhead <= 0.9995)
|
||||
&& maxCalTime > 0
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
if (maxms == 0) {
|
||||
/* reset last measurement overhead */
|
||||
measureOverhead = 0;
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* if time is negative - make current overhead more precise */
|
||||
if (maxms > 0) {
|
||||
/* set last measurement overhead to max */
|
||||
measureOverhead = (double)UWIDE_MAX;
|
||||
} else {
|
||||
maxms = -maxms;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (maxms == WIDE_MIN) {
|
||||
maxms = 1000;
|
||||
}
|
||||
if (overhead == -1) {
|
||||
overhead = measureOverhead;
|
||||
}
|
||||
|
||||
/* be sure that resetting of result will not smudge the further measurement */
|
||||
Tcl_ResetResult(interp);
|
||||
|
||||
/* compile object */
|
||||
if (!direct) {
|
||||
if (TclInterpReady(interp) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
codePtr = TclCompileObj(interp, objPtr, NULL, 0);
|
||||
TclPreserveByteCode(codePtr);
|
||||
}
|
||||
|
||||
/* get start and stop time */
|
||||
#ifdef TCL_WIDE_CLICKS
|
||||
start = middle = TclpGetWideClicks();
|
||||
/* time to stop execution (in wide clicks) */
|
||||
stop = start + (maxms * 1000 / TclpWideClickInMicrosec());
|
||||
#else
|
||||
Tcl_GetTime(&now);
|
||||
start = now.sec; start *= 1000000; start += now.usec;
|
||||
middle = start;
|
||||
/* time to stop execution (in microsecs) */
|
||||
stop = start + maxms * 1000;
|
||||
#endif
|
||||
|
||||
/* start measurement */
|
||||
if (maxcnt > 0)
|
||||
while (1) {
|
||||
/* eval single iteration */
|
||||
count++;
|
||||
|
||||
if (!direct) {
|
||||
/* precompiled */
|
||||
rootPtr = TOP_CB(interp);
|
||||
result = TclNRExecuteByteCode(interp, codePtr);
|
||||
result = TclNRRunCallbacks(interp, result, rootPtr);
|
||||
} else {
|
||||
/* eval */
|
||||
result = TclEvalObjEx(interp, objPtr, 0, NULL, 0);
|
||||
}
|
||||
if (result != TCL_OK) {
|
||||
/* allow break from measurement cycle (used for conditional stop) */
|
||||
if (result != TCL_BREAK) {
|
||||
goto done;
|
||||
}
|
||||
/* force stop immediately */
|
||||
threshold = 1;
|
||||
maxcnt = 0;
|
||||
result = TCL_OK;
|
||||
}
|
||||
|
||||
/* don't check time up to threshold */
|
||||
if (--threshold > 0) continue;
|
||||
|
||||
/* check stop time reached, estimate new threshold */
|
||||
#ifdef TCL_WIDE_CLICKS
|
||||
middle = TclpGetWideClicks();
|
||||
#else
|
||||
Tcl_GetTime(&now);
|
||||
middle = now.sec; middle *= 1000000; middle += now.usec;
|
||||
#endif
|
||||
if (middle >= stop || count >= maxcnt) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* don't calculate threshold by few iterations, because sometimes first
|
||||
* iteration(s) can be too fast or slow (cached, delayed clean up, etc) */
|
||||
if (count < 10) {
|
||||
threshold = 1; continue;
|
||||
}
|
||||
|
||||
/* average iteration time in microsecs */
|
||||
threshold = (middle - start) / count;
|
||||
if (threshold > maxIterTm) {
|
||||
maxIterTm = threshold;
|
||||
/* interations seems to be longer */
|
||||
if (threshold > (maxIterTm * 2)) {
|
||||
if ((factor *= 2) > 50) factor = 50;
|
||||
} else {
|
||||
if (factor < 50) factor++;
|
||||
}
|
||||
} else if (factor > 4) {
|
||||
/* interations seems to be shorter */
|
||||
if (threshold < (maxIterTm / 2)) {
|
||||
if ((factor /= 2) < 4) factor = 4;
|
||||
} else {
|
||||
factor--;
|
||||
}
|
||||
}
|
||||
/* as relation between remaining time and time since last check,
|
||||
* maximal some % of time (by factor), so avoid growing of the execution time
|
||||
* if iterations are not consistent, e. g. wax continuously on time) */
|
||||
threshold = ((stop - middle) / maxIterTm) / factor + 1;
|
||||
if (threshold > 100000) { /* fix for too large threshold */
|
||||
threshold = 100000;
|
||||
}
|
||||
/* consider max-count */
|
||||
if (threshold > maxcnt - count) {
|
||||
threshold = maxcnt - count;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Tcl_Obj *objarr[8], **objs = objarr;
|
||||
Tcl_WideInt val;
|
||||
const char *fmt;
|
||||
|
||||
middle -= start; /* execution time in microsecs */
|
||||
|
||||
#ifdef TCL_WIDE_CLICKS
|
||||
/* convert execution time in wide clicks to microsecs */
|
||||
middle *= TclpWideClickInMicrosec();
|
||||
#endif
|
||||
|
||||
/* if not calibrate */
|
||||
if (!calibrate) {
|
||||
/* minimize influence of measurement overhead */
|
||||
if (overhead > 0) {
|
||||
/* estimate the time of overhead (microsecs) */
|
||||
Tcl_WideUInt curOverhead = overhead * count;
|
||||
if (middle > (Tcl_WideInt)curOverhead) {
|
||||
middle -= curOverhead;
|
||||
} else {
|
||||
middle = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* calibration - obtaining new measurement overhead */
|
||||
if (measureOverhead > (double)middle / count) {
|
||||
measureOverhead = (double)middle / count;
|
||||
}
|
||||
objs[0] = Tcl_NewDoubleObj(measureOverhead);
|
||||
TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#-overhead"); /* mics */
|
||||
objs += 2;
|
||||
}
|
||||
|
||||
val = middle / count; /* microsecs per iteration */
|
||||
if (val >= 1000000) {
|
||||
objs[0] = Tcl_NewWideIntObj(val);
|
||||
} else {
|
||||
if (val < 10) { fmt = "%.6f"; } else
|
||||
if (val < 100) { fmt = "%.4f"; } else
|
||||
if (val < 1000) { fmt = "%.3f"; } else
|
||||
if (val < 10000) { fmt = "%.2f"; } else
|
||||
{ fmt = "%.1f"; };
|
||||
objs[0] = Tcl_ObjPrintf(fmt, ((double)middle)/count);
|
||||
}
|
||||
|
||||
objs[2] = Tcl_NewWideIntObj(count); /* iterations */
|
||||
|
||||
/* calculate speed as rate (count) per sec */
|
||||
if (!middle) middle++; /* +1 ms, just to avoid divide by zero */
|
||||
if (count < (WIDE_MAX / 1000000)) {
|
||||
val = (count * 1000000) / middle;
|
||||
if (val < 100000) {
|
||||
if (val < 100) { fmt = "%.3f"; } else
|
||||
if (val < 1000) { fmt = "%.2f"; } else
|
||||
{ fmt = "%.1f"; };
|
||||
objs[4] = Tcl_ObjPrintf(fmt, ((double)(count * 1000000)) / middle);
|
||||
} else {
|
||||
objs[4] = Tcl_NewWideIntObj(val);
|
||||
}
|
||||
} else {
|
||||
objs[4] = Tcl_NewWideIntObj((count / middle) * 1000000);
|
||||
}
|
||||
|
||||
/* estimated net execution time (in millisecs) */
|
||||
if (!calibrate) {
|
||||
objs[6] = Tcl_ObjPrintf("%.3f", (double)middle / 1000);
|
||||
TclNewLiteralStringObj(objs[7], "nett-ms");
|
||||
}
|
||||
|
||||
/*
|
||||
* Construct the result as a list because many programs have always parsed
|
||||
* as such (extracting the first element, typically).
|
||||
*/
|
||||
|
||||
TclNewLiteralStringObj(objs[1], "\xC2\xB5s/#"); /* mics/# */
|
||||
TclNewLiteralStringObj(objs[3], "#");
|
||||
TclNewLiteralStringObj(objs[5], "#/sec");
|
||||
Tcl_SetObjResult(interp, Tcl_NewListObj(8, objarr));
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (codePtr != NULL) {
|
||||
TclReleaseByteCode(codePtr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+32
-28
@@ -3408,10 +3408,10 @@ TclPushVarName(
|
||||
int *isScalarPtr) /* Must not be NULL. */
|
||||
{
|
||||
register const char *p;
|
||||
const char *name, *elName;
|
||||
register int i, n;
|
||||
const char *last, *name, *elName;
|
||||
register int n;
|
||||
Tcl_Token *elemTokenPtr = NULL;
|
||||
int nameChars, elNameChars, simpleVarName, localIndex;
|
||||
int nameLen, elNameLen, simpleVarName, localIndex;
|
||||
int elemTokenCount = 0, allocedTokens = 0, removedParen = 0;
|
||||
|
||||
/*
|
||||
@@ -3424,7 +3424,7 @@ TclPushVarName(
|
||||
|
||||
simpleVarName = 0;
|
||||
name = elName = NULL;
|
||||
nameChars = elNameChars = 0;
|
||||
nameLen = elNameLen = 0;
|
||||
localIndex = -1;
|
||||
|
||||
if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
|
||||
@@ -3436,22 +3436,25 @@ TclPushVarName(
|
||||
simpleVarName = 1;
|
||||
|
||||
name = varTokenPtr[1].start;
|
||||
nameChars = varTokenPtr[1].size;
|
||||
if (name[nameChars-1] == ')') {
|
||||
nameLen = varTokenPtr[1].size;
|
||||
if (name[nameLen-1] == ')') {
|
||||
/*
|
||||
* last char is ')' => potential array reference.
|
||||
*/
|
||||
last = Tcl_UtfPrev(name + nameLen, name);
|
||||
|
||||
for (i=0,p=name ; i<nameChars ; i++,p++) {
|
||||
if (*p == '(') {
|
||||
elName = p + 1;
|
||||
elNameChars = nameChars - i - 2;
|
||||
nameChars = i;
|
||||
break;
|
||||
if (*last == ')') {
|
||||
for (p = name; p < last; p = Tcl_UtfNext(p)) {
|
||||
if (*p == '(') {
|
||||
elName = p + 1;
|
||||
elNameLen = last - elName;
|
||||
nameLen = p - name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(flags & TCL_NO_ELEMENT) && (elName != NULL) && elNameChars) {
|
||||
if (!(flags & TCL_NO_ELEMENT) && elNameLen) {
|
||||
/*
|
||||
* An array element, the element name is a simple string:
|
||||
* assemble the corresponding token.
|
||||
@@ -3461,7 +3464,7 @@ TclPushVarName(
|
||||
allocedTokens = 1;
|
||||
elemTokenPtr->type = TCL_TOKEN_TEXT;
|
||||
elemTokenPtr->start = elName;
|
||||
elemTokenPtr->size = elNameChars;
|
||||
elemTokenPtr->size = elNameLen;
|
||||
elemTokenPtr->numComponents = 0;
|
||||
elemTokenCount = 1;
|
||||
}
|
||||
@@ -3469,21 +3472,22 @@ TclPushVarName(
|
||||
} else if (interp && ((n = varTokenPtr->numComponents) > 1)
|
||||
&& (varTokenPtr[1].type == TCL_TOKEN_TEXT)
|
||||
&& (varTokenPtr[n].type == TCL_TOKEN_TEXT)
|
||||
&& (varTokenPtr[n].start[varTokenPtr[n].size - 1] == ')')) {
|
||||
&& (*((p = varTokenPtr[n].start + varTokenPtr[n].size)-1) == ')')
|
||||
&& (*Tcl_UtfPrev(p, varTokenPtr[n].start) == ')')) {
|
||||
/*
|
||||
* Check for parentheses inside first token.
|
||||
*/
|
||||
|
||||
simpleVarName = 0;
|
||||
for (i = 0, p = varTokenPtr[1].start;
|
||||
i < varTokenPtr[1].size; i++, p++) {
|
||||
for (p = varTokenPtr[1].start,
|
||||
last = p + varTokenPtr[1].size; p < last; p = Tcl_UtfNext(p)) {
|
||||
if (*p == '(') {
|
||||
simpleVarName = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (simpleVarName) {
|
||||
int remainingChars;
|
||||
int remainingLen;
|
||||
|
||||
/*
|
||||
* Check the last token: if it is just ')', do not count it.
|
||||
@@ -3499,13 +3503,13 @@ TclPushVarName(
|
||||
}
|
||||
|
||||
name = varTokenPtr[1].start;
|
||||
nameChars = p - varTokenPtr[1].start;
|
||||
nameLen = p - varTokenPtr[1].start;
|
||||
elName = p + 1;
|
||||
remainingChars = (varTokenPtr[2].start - p) - 1;
|
||||
elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1;
|
||||
remainingLen = (varTokenPtr[2].start - p) - 1;
|
||||
elNameLen = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1;
|
||||
|
||||
if (!(flags & TCL_NO_ELEMENT)) {
|
||||
if (remainingChars) {
|
||||
if (remainingLen) {
|
||||
/*
|
||||
* Make a first token with the extra characters in the first
|
||||
* token.
|
||||
@@ -3515,7 +3519,7 @@ TclPushVarName(
|
||||
allocedTokens = 1;
|
||||
elemTokenPtr->type = TCL_TOKEN_TEXT;
|
||||
elemTokenPtr->start = elName;
|
||||
elemTokenPtr->size = remainingChars;
|
||||
elemTokenPtr->size = remainingLen;
|
||||
elemTokenPtr->numComponents = 0;
|
||||
elemTokenCount = n;
|
||||
|
||||
@@ -3544,8 +3548,8 @@ TclPushVarName(
|
||||
|
||||
int hasNsQualifiers = 0;
|
||||
|
||||
for (i = 0, p = name; i < nameChars; i++, p++) {
|
||||
if ((*p == ':') && ((i+1) < nameChars) && (*(p+1) == ':')) {
|
||||
for (p = name, last = p + nameLen-1; p < last; p = Tcl_UtfNext(p)) {
|
||||
if ((*p == ':') && (*(p+1) == ':')) {
|
||||
hasNsQualifiers = 1;
|
||||
break;
|
||||
}
|
||||
@@ -3558,7 +3562,7 @@ TclPushVarName(
|
||||
*/
|
||||
|
||||
if (!hasNsQualifiers) {
|
||||
localIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
|
||||
localIndex = TclFindCompiledLocal(name, nameLen, 1, envPtr);
|
||||
if ((flags & TCL_NO_LARGE_INDEX) && (localIndex > 255)) {
|
||||
/*
|
||||
* We'll push the name.
|
||||
@@ -3568,7 +3572,7 @@ TclPushVarName(
|
||||
}
|
||||
}
|
||||
if (interp && localIndex < 0) {
|
||||
PushLiteral(envPtr, name, nameChars);
|
||||
PushLiteral(envPtr, name, nameLen);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3577,7 +3581,7 @@ TclPushVarName(
|
||||
*/
|
||||
|
||||
if (elName != NULL && !(flags & TCL_NO_ELEMENT)) {
|
||||
if (elNameChars) {
|
||||
if (elNameLen) {
|
||||
TclCompileTokens(interp, elemTokenPtr, elemTokenCount,
|
||||
envPtr);
|
||||
} else {
|
||||
|
||||
+13
-13
@@ -1089,8 +1089,8 @@ TclCompileLindexCmd(
|
||||
}
|
||||
|
||||
idxTokenPtr = TokenAfter(valTokenPtr);
|
||||
if (TclGetIndexFromToken(idxTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_BEFORE,
|
||||
&idx) == TCL_OK) {
|
||||
if (TclGetIndexFromToken(idxTokenPtr, TCL_INDEX_NONE,
|
||||
TCL_INDEX_NONE, &idx) == TCL_OK) {
|
||||
/*
|
||||
* The idxTokenPtr parsed as a valid index value and was
|
||||
* encoded as expected by INST_LIST_INDEX_IMM.
|
||||
@@ -1318,8 +1318,8 @@ TclCompileLrangeCmd(
|
||||
listTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
tokenPtr = TokenAfter(listTokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
&idx1) != TCL_OK) {
|
||||
if ((TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_NONE,
|
||||
&idx1) != TCL_OK) || (idx1 == TCL_INDEX_NONE)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
/*
|
||||
@@ -1328,7 +1328,7 @@ TclCompileLrangeCmd(
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_NONE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1483,13 +1483,13 @@ TclCompileLreplaceCmd(
|
||||
listTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
tokenPtr = TokenAfter(listTokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_NONE,
|
||||
&idx1) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_NONE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1505,12 +1505,12 @@ TclCompileLreplaceCmd(
|
||||
* we must defer to direct evaluation.
|
||||
*/
|
||||
|
||||
if (idx1 == TCL_INDEX_AFTER) {
|
||||
suffixStart = idx1;
|
||||
} else if (idx2 == TCL_INDEX_BEFORE) {
|
||||
if (idx1 == TCL_INDEX_NONE) {
|
||||
suffixStart = TCL_INDEX_NONE;
|
||||
} else if (idx2 == TCL_INDEX_NONE) {
|
||||
suffixStart = idx1;
|
||||
} else if (idx2 == TCL_INDEX_END) {
|
||||
suffixStart = TCL_INDEX_AFTER;
|
||||
suffixStart = TCL_INDEX_NONE;
|
||||
} else if (((idx2 < TCL_INDEX_END) && (idx1 <= TCL_INDEX_END))
|
||||
|| ((idx2 >= TCL_INDEX_START) && (idx1 >= TCL_INDEX_START))) {
|
||||
suffixStart = (idx1 > idx2 + 1) ? idx1 : idx2 + 1;
|
||||
@@ -1570,7 +1570,7 @@ TclCompileLreplaceCmd(
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
}
|
||||
|
||||
if (suffixStart == TCL_INDEX_AFTER) {
|
||||
if (suffixStart == TCL_INDEX_NONE) {
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
if (emptyPrefix) {
|
||||
PushStringLiteral(envPtr, "");
|
||||
@@ -2121,7 +2121,7 @@ TclCompileRegexpCmd(
|
||||
sawLast++;
|
||||
i++;
|
||||
break;
|
||||
} else if ((len > 1) && (strncmp(str,"-nocase",(unsigned)len) == 0)) {
|
||||
} else if ((len > 1) && (strncmp(str, "-nocase", len) == 0)) {
|
||||
nocase = 1;
|
||||
} else {
|
||||
/*
|
||||
|
||||
+41
-35
@@ -461,7 +461,7 @@ TclCompileStringIsCmd(
|
||||
Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
static const char *const isClasses[] = {
|
||||
"alnum", "alpha", "ascii", "control",
|
||||
"boolean", "digit", "double", "entier",
|
||||
"boolean", "dict", "digit", "double", "entier",
|
||||
"false", "graph", "integer", "list",
|
||||
"lower", "print", "punct", "space",
|
||||
"true", "upper", "wideinteger", "wordchar",
|
||||
@@ -469,7 +469,7 @@ TclCompileStringIsCmd(
|
||||
};
|
||||
enum isClasses {
|
||||
STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
|
||||
STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
|
||||
STR_IS_BOOL, STR_IS_DICT, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
|
||||
STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST,
|
||||
STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE,
|
||||
STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD,
|
||||
@@ -691,14 +691,11 @@ TclCompileStringIsCmd(
|
||||
}
|
||||
|
||||
switch (t) {
|
||||
case STR_IS_INT:
|
||||
PUSH( "1");
|
||||
OP( EQ);
|
||||
break;
|
||||
case STR_IS_WIDE:
|
||||
PUSH( "2");
|
||||
OP( LE);
|
||||
break;
|
||||
case STR_IS_INT:
|
||||
case STR_IS_ENTIER:
|
||||
PUSH( "3");
|
||||
OP( LE);
|
||||
@@ -706,7 +703,19 @@ TclCompileStringIsCmd(
|
||||
}
|
||||
FIXJUMP1( end);
|
||||
return TCL_OK;
|
||||
|
||||
case STR_IS_DICT:
|
||||
range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
|
||||
OP4( BEGIN_CATCH4, range);
|
||||
ExceptionRangeStarts(envPtr, range);
|
||||
OP( DUP);
|
||||
OP( DICT_VERIFY);
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
OP( POP);
|
||||
OP( PUSH_RETURN_CODE);
|
||||
OP( END_CATCH);
|
||||
OP( LNOT);
|
||||
return TCL_OK;
|
||||
case STR_IS_LIST:
|
||||
range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
|
||||
OP4( BEGIN_CATCH4, range);
|
||||
@@ -937,7 +946,7 @@ TclCompileStringRangeCmd(
|
||||
* Parse the two indices.
|
||||
*/
|
||||
|
||||
if (TclGetIndexFromToken(fromTokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
if (TclGetIndexFromToken(fromTokenPtr, TCL_INDEX_START, TCL_INDEX_NONE,
|
||||
&idx1) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
@@ -946,14 +955,14 @@ TclCompileStringRangeCmd(
|
||||
* the string the same as the start of the string.
|
||||
*/
|
||||
|
||||
if (idx1 == TCL_INDEX_AFTER) {
|
||||
if (idx1 == TCL_INDEX_NONE) {
|
||||
/* [string range $s end+1 $last] must be empty string */
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (TclGetIndexFromToken(toTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
if (TclGetIndexFromToken(toTokenPtr, TCL_INDEX_NONE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
@@ -961,7 +970,7 @@ TclCompileStringRangeCmd(
|
||||
* Token parsed as an index expression. We treat all indices after
|
||||
* the string the same as the end of the string.
|
||||
*/
|
||||
if (idx2 == TCL_INDEX_BEFORE) {
|
||||
if (idx2 == TCL_INDEX_NONE) {
|
||||
/* [string range $s $first -1] must be empty string */
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
@@ -1011,7 +1020,7 @@ TclCompileStringReplaceCmd(
|
||||
* Check for first index known and useful at compile time.
|
||||
*/
|
||||
tokenPtr = TokenAfter(valueTokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_NONE,
|
||||
&first) != TCL_OK) {
|
||||
goto genericReplace;
|
||||
}
|
||||
@@ -1020,7 +1029,7 @@ TclCompileStringReplaceCmd(
|
||||
* Check for last index known and useful at compile time.
|
||||
*/
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_NONE, TCL_INDEX_END,
|
||||
&last) != TCL_OK) {
|
||||
goto genericReplace;
|
||||
}
|
||||
@@ -1039,8 +1048,8 @@ TclCompileStringReplaceCmd(
|
||||
* compile direct to bytecode implementing the no-op.
|
||||
*/
|
||||
|
||||
if ((last == TCL_INDEX_BEFORE) /* Know (last < 0) */
|
||||
|| (first == TCL_INDEX_AFTER) /* Know (first > end) */
|
||||
if ((last == TCL_INDEX_NONE) /* Know (last < 0) */
|
||||
|| (first == TCL_INDEX_NONE) /* Know (first > end) */
|
||||
|
||||
/*
|
||||
* Tricky to determine when runtime (last < first) can be
|
||||
@@ -1048,20 +1057,17 @@ TclCompileStringReplaceCmd(
|
||||
* cases...
|
||||
*
|
||||
* (first <= TCL_INDEX_END) &&
|
||||
* (last == TCL_INDEX_AFTER) => cannot tell REJECT
|
||||
* (last <= TCL_INDEX END) && (last < first) => ACCEPT
|
||||
* else => cannot tell REJECT
|
||||
*/
|
||||
|| ((first <= TCL_INDEX_END) && (last <= TCL_INDEX_END)
|
||||
&& (last < first)) /* Know (last < first) */
|
||||
/*
|
||||
* (first == TCL_INDEX_BEFORE) &&
|
||||
* (last == TCL_INDEX_AFTER) => (first < last) REJECT
|
||||
* (first == TCL_INDEX_NONE) &&
|
||||
* (last <= TCL_INDEX_END) => cannot tell REJECT
|
||||
* else => (first < last) REJECT
|
||||
*
|
||||
* else [[first >= TCL_INDEX_START]] &&
|
||||
* (last == TCL_INDEX_AFTER) => cannot tell REJECT
|
||||
* (last <= TCL_INDEX_END) => cannot tell REJECT
|
||||
* else [[last >= TCL_INDEX START]] && (last < first) => ACCEPT
|
||||
*/
|
||||
@@ -1094,34 +1100,34 @@ TclCompileStringReplaceCmd(
|
||||
* (first <= end)
|
||||
*
|
||||
* The encoded indices (first <= TCL_INDEX END) and
|
||||
* (first == TCL_INDEX_BEFORE) always meets this condition, but
|
||||
* (first == TCL_INDEX_NONE) always meets this condition, but
|
||||
* any other encoded first index has some list for which it fails.
|
||||
*
|
||||
* We also need, second:
|
||||
*
|
||||
* (last >= 0)
|
||||
*
|
||||
* The encoded indices (last >= TCL_INDEX_START) and
|
||||
* (last == TCL_INDEX_AFTER) always meet this condition but any
|
||||
* other encoded last index has some list for which it fails.
|
||||
* The encoded index (last >= TCL_INDEX_START) always meet this
|
||||
* condition but any other encoded last index has some list for
|
||||
* which it fails.
|
||||
*
|
||||
* Finally we need, third:
|
||||
*
|
||||
* (first <= last)
|
||||
*
|
||||
* Considered in combination with the constraints we already have,
|
||||
* we see that we can proceed when (first == TCL_INDEX_BEFORE)
|
||||
* or (last == TCL_INDEX_AFTER). These also permit simplification
|
||||
* of the prefix|replace|suffix construction. The other constraints,
|
||||
* though, interfere with getting a guarantee that first <= last.
|
||||
* we see that we can proceed when (first == TCL_INDEX_NONE).
|
||||
* These also permit simplification of the prefix|replace|suffix
|
||||
* construction. The other constraints, though, interfere with
|
||||
* getting a guarantee that first <= last.
|
||||
*/
|
||||
|
||||
if ((first == TCL_INDEX_BEFORE) && (last >= TCL_INDEX_START)) {
|
||||
if ((first == TCL_INDEX_START) && (last >= TCL_INDEX_START)) {
|
||||
/* empty prefix */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
OP4( REVERSE, 2);
|
||||
if (last == TCL_INDEX_AFTER) {
|
||||
if (last == INT_MAX) {
|
||||
OP( POP); /* Pop original */
|
||||
} else {
|
||||
OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END);
|
||||
@@ -1130,7 +1136,7 @@ TclCompileStringReplaceCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((last == TCL_INDEX_AFTER) && (first <= TCL_INDEX_END)) {
|
||||
if ((last == TCL_INDEX_NONE) && (first <= TCL_INDEX_END)) {
|
||||
OP44( STR_RANGE_IMM, 0, first-1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
@@ -1147,10 +1153,10 @@ TclCompileStringReplaceCmd(
|
||||
* are harmless when they are replaced by another empty string.
|
||||
*/
|
||||
|
||||
if ((first == TCL_INDEX_BEFORE) || (first == TCL_INDEX_START)) {
|
||||
if (first == TCL_INDEX_START) {
|
||||
/* empty prefix - build suffix only */
|
||||
|
||||
if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) {
|
||||
if (last == TCL_INDEX_END) {
|
||||
/* empty suffix too => empty result */
|
||||
OP( POP); /* Pop original */
|
||||
PUSH ( "");
|
||||
@@ -1159,7 +1165,7 @@ TclCompileStringReplaceCmd(
|
||||
OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END);
|
||||
return TCL_OK;
|
||||
} else {
|
||||
if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) {
|
||||
if (last == TCL_INDEX_END) {
|
||||
/* empty suffix - build prefix only */
|
||||
OP44( STR_RANGE_IMM, 0, first-1);
|
||||
return TCL_OK;
|
||||
@@ -1353,7 +1359,7 @@ static int
|
||||
UniCharIsHexDigit(
|
||||
int character)
|
||||
{
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(character);
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(UCHAR(character));
|
||||
}
|
||||
|
||||
StringClassDesc const tclStringClassTable[] = {
|
||||
@@ -1496,7 +1502,7 @@ TclSubstCompile(
|
||||
for (endTokenPtr = tokenPtr + parse.numTokens;
|
||||
tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
|
||||
int length, literal, catchRange, breakJump;
|
||||
char buf[TCL_UTF_MAX];
|
||||
char buf[TCL_UTF_MAX] = "";
|
||||
JumpFixup startFixup, okFixup, returnFixup, breakFixup;
|
||||
JumpFixup continueFixup, otherFixup, endFixup;
|
||||
|
||||
|
||||
@@ -1759,7 +1759,7 @@ ConvertTreeToTokens(
|
||||
|
||||
/*
|
||||
* All the Tcl_Tokens allocated and filled belong to
|
||||
* this subexpresion. The first token is the leading
|
||||
* this subexpression. The first token is the leading
|
||||
* TCL_TOKEN_SUB_EXPR token, and all the rest (one fewer)
|
||||
* are its components.
|
||||
*/
|
||||
@@ -2027,7 +2027,7 @@ ParseLexeme(
|
||||
* Example: Inf + luence + () becomes a valid function call.
|
||||
* [Bug 3401704]
|
||||
*/
|
||||
if (literal->typePtr == &tclDoubleType) {
|
||||
if (TclHasIntRep(literal, &tclDoubleType)) {
|
||||
const char *p = start;
|
||||
|
||||
while (p < end) {
|
||||
@@ -2068,7 +2068,7 @@ ParseLexeme(
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
|
||||
memcpy(utfBytes, start, (size_t) numBytes);
|
||||
memcpy(utfBytes, start, numBytes);
|
||||
utfBytes[numBytes] = '\0';
|
||||
scanned = TclUtfToUniChar(utfBytes, &ch);
|
||||
}
|
||||
@@ -2476,11 +2476,13 @@ CompileExprTree(
|
||||
* already, then use it to share via the literal table.
|
||||
*/
|
||||
|
||||
if (objPtr->bytes) {
|
||||
if (TclHasStringRep(objPtr)) {
|
||||
Tcl_Obj *tableValue;
|
||||
int numBytes;
|
||||
const char *bytes
|
||||
= Tcl_GetStringFromObj(objPtr, &numBytes);
|
||||
|
||||
index = TclRegisterLiteral(envPtr, objPtr->bytes,
|
||||
objPtr->length, 0);
|
||||
index = TclRegisterLiteral(envPtr, bytes, numBytes, 0);
|
||||
tableValue = TclFetchLiteral(envPtr, index);
|
||||
if ((tableValue->typePtr == NULL) &&
|
||||
(objPtr->typePtr != NULL)) {
|
||||
|
||||
+26
-20
@@ -725,13 +725,14 @@ static const Tcl_ObjType substCodeType = {
|
||||
NULL, /* updateStringProc */
|
||||
NULL, /* setFromAnyProc */
|
||||
};
|
||||
#define SubstFlags(objPtr) (objPtr)->internalRep.twoPtrValue.ptr2
|
||||
|
||||
/*
|
||||
* Helper macros.
|
||||
*/
|
||||
|
||||
#define TclIncrUInt4AtPtr(ptr, delta) \
|
||||
TclStoreInt4AtPtr(TclGetUInt4AtPtr(ptr)+(delta), (ptr));
|
||||
TclStoreInt4AtPtr(TclGetUInt4AtPtr(ptr)+(delta), (ptr))
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -974,7 +975,10 @@ static void
|
||||
FreeByteCodeInternalRep(
|
||||
register Tcl_Obj *objPtr) /* Object whose internal rep to free. */
|
||||
{
|
||||
register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ByteCode *codePtr;
|
||||
|
||||
ByteCodeGetIntRep(objPtr, &tclByteCodeType, codePtr);
|
||||
assert(codePtr != NULL);
|
||||
|
||||
TclReleaseByteCode(codePtr);
|
||||
}
|
||||
@@ -1304,21 +1308,23 @@ CompileSubstObj(
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ByteCode *codePtr = NULL;
|
||||
|
||||
if (objPtr->typePtr == &substCodeType) {
|
||||
ByteCodeGetIntRep(objPtr, &substCodeType, codePtr);
|
||||
|
||||
if (codePtr != NULL) {
|
||||
Namespace *nsPtr = iPtr->varFramePtr->nsPtr;
|
||||
|
||||
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (flags != PTR2INT(objPtr->internalRep.twoPtrValue.ptr2)
|
||||
if (flags != PTR2INT(SubstFlags(objPtr))
|
||||
|| ((Interp *) *codePtr->interpHandle != iPtr)
|
||||
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|
||||
|| (codePtr->nsPtr != nsPtr)
|
||||
|| (codePtr->nsEpoch != nsPtr->resolverEpoch)
|
||||
|| (codePtr->localCachePtr !=
|
||||
iPtr->varFramePtr->localCachePtr)) {
|
||||
TclFreeIntRep(objPtr);
|
||||
Tcl_StoreIntRep(objPtr, &substCodeType, NULL);
|
||||
codePtr = NULL;
|
||||
}
|
||||
}
|
||||
if (objPtr->typePtr != &substCodeType) {
|
||||
if (codePtr == NULL) {
|
||||
CompileEnv compEnv;
|
||||
int numBytes;
|
||||
const char *bytes = TclGetStringFromObj(objPtr, &numBytes);
|
||||
@@ -1332,8 +1338,7 @@ CompileSubstObj(
|
||||
codePtr = TclInitByteCodeObj(objPtr, &substCodeType, &compEnv);
|
||||
TclFreeCompileEnv(&compEnv);
|
||||
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(flags);
|
||||
SubstFlags(objPtr) = INT2PTR(flags);
|
||||
if (iPtr->varFramePtr->localCachePtr) {
|
||||
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
|
||||
codePtr->localCachePtr->refCount++;
|
||||
@@ -1372,7 +1377,10 @@ static void
|
||||
FreeSubstCodeInternalRep(
|
||||
register Tcl_Obj *objPtr) /* Object whose internal rep to free. */
|
||||
{
|
||||
register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
register ByteCode *codePtr;
|
||||
|
||||
ByteCodeGetIntRep(objPtr, &substCodeType, codePtr);
|
||||
assert(codePtr != NULL);
|
||||
|
||||
TclReleaseByteCode(codePtr);
|
||||
}
|
||||
@@ -1736,7 +1744,7 @@ TclWordKnownAtCompileTime(
|
||||
|
||||
case TCL_TOKEN_BS:
|
||||
if (tempPtr != NULL) {
|
||||
char utfBuf[TCL_UTF_MAX];
|
||||
char utfBuf[TCL_UTF_MAX] = "";
|
||||
int length = TclParseBackslash(tokenPtr->start,
|
||||
tokenPtr->size, NULL, utfBuf);
|
||||
|
||||
@@ -2350,7 +2358,7 @@ TclCompileTokens(
|
||||
{
|
||||
Tcl_DString textBuffer; /* Holds concatenated chars from adjacent
|
||||
* TCL_TOKEN_TEXT, TCL_TOKEN_BS tokens. */
|
||||
char buffer[TCL_UTF_MAX];
|
||||
char buffer[TCL_UTF_MAX] = "";
|
||||
int i, numObjsToConcat, length, adjust;
|
||||
unsigned char *entryCodeNext = envPtr->codeNext;
|
||||
#define NUM_STATIC_POS 20
|
||||
@@ -2829,7 +2837,7 @@ TclInitByteCode(
|
||||
|
||||
p += sizeof(ByteCode);
|
||||
codePtr->codeStart = p;
|
||||
memcpy(p, envPtr->codeStart, (size_t) codeBytes);
|
||||
memcpy(p, envPtr->codeStart, codeBytes);
|
||||
|
||||
p += TCL_ALIGN(codeBytes); /* align object array */
|
||||
codePtr->objArrayPtr = (Tcl_Obj **) p;
|
||||
@@ -2840,7 +2848,7 @@ TclInitByteCode(
|
||||
p += TCL_ALIGN(objArrayBytes); /* align exception range array */
|
||||
if (exceptArrayBytes > 0) {
|
||||
codePtr->exceptArrayPtr = (ExceptionRange *) p;
|
||||
memcpy(p, envPtr->exceptArrayPtr, (size_t) exceptArrayBytes);
|
||||
memcpy(p, envPtr->exceptArrayPtr, exceptArrayBytes);
|
||||
} else {
|
||||
codePtr->exceptArrayPtr = NULL;
|
||||
}
|
||||
@@ -2848,7 +2856,7 @@ TclInitByteCode(
|
||||
p += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
|
||||
if (auxDataArrayBytes > 0) {
|
||||
codePtr->auxDataArrayPtr = (AuxData *) p;
|
||||
memcpy(p, envPtr->auxDataArrayPtr, (size_t) auxDataArrayBytes);
|
||||
memcpy(p, envPtr->auxDataArrayPtr, auxDataArrayBytes);
|
||||
} else {
|
||||
codePtr->auxDataArrayPtr = NULL;
|
||||
}
|
||||
@@ -2912,9 +2920,7 @@ TclInitByteCodeObj(
|
||||
* by making its internal rep point to the just compiled ByteCode.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
|
||||
objPtr->typePtr = typePtr;
|
||||
ByteCodeSetIntRep(objPtr, typePtr, codePtr);
|
||||
return codePtr;
|
||||
}
|
||||
|
||||
@@ -3002,7 +3008,7 @@ TclFindCompiledLocal(
|
||||
char *localName = localPtr->name;
|
||||
|
||||
if ((nameBytes == localPtr->nameLength) &&
|
||||
(strncmp(name,localName,(unsigned)nameBytes) == 0)) {
|
||||
(strncmp(name, localName, nameBytes) == 0)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -3034,7 +3040,7 @@ TclFindCompiledLocal(
|
||||
localPtr->resolveInfo = NULL;
|
||||
|
||||
if (name != NULL) {
|
||||
memcpy(localPtr->name, name, (size_t) nameBytes);
|
||||
memcpy(localPtr->name, name, nameBytes);
|
||||
}
|
||||
localPtr->name[nameBytes] = '\0';
|
||||
procPtr->numCompiledLocals++;
|
||||
|
||||
+18
-1
@@ -266,7 +266,7 @@ typedef struct AuxDataType {
|
||||
typedef struct AuxData {
|
||||
const AuxDataType *type; /* Pointer to the AuxData type associated with
|
||||
* this ClientData. */
|
||||
ClientData clientData; /* The compilation data itself. */
|
||||
void *clientData; /* The compilation data itself. */
|
||||
} AuxData;
|
||||
|
||||
/*
|
||||
@@ -514,6 +514,23 @@ typedef struct ByteCode {
|
||||
* created. */
|
||||
#endif /* TCL_COMPILE_STATS */
|
||||
} ByteCode;
|
||||
|
||||
#define ByteCodeSetIntRep(objPtr, typePtr, codePtr) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (codePtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((objPtr), (typePtr), &ir); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
#define ByteCodeGetIntRep(objPtr, typePtr, codePtr) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), (typePtr)); \
|
||||
(codePtr) = irPtr ? irPtr->twoPtrValue.ptr1 : NULL; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Opcodes for the Tcl bytecode instructions. These must correspond to the
|
||||
|
||||
+954
-954
File diff suppressed because it is too large
Load Diff
+61
-14
@@ -143,7 +143,7 @@ EXTERN Tcl_Obj * Tcl_DbNewStringObj(const char *bytes, int length,
|
||||
/* 29 */
|
||||
EXTERN Tcl_Obj * Tcl_DuplicateObj(Tcl_Obj *objPtr);
|
||||
/* 30 */
|
||||
EXTERN void TclFreeObj(Tcl_Obj *objPtr);
|
||||
EXTERN void TclOldFreeObj(Tcl_Obj *objPtr);
|
||||
/* 31 */
|
||||
EXTERN int Tcl_GetBoolean(Tcl_Interp *interp, const char *src,
|
||||
int *boolPtr);
|
||||
@@ -271,7 +271,8 @@ EXTERN void Tcl_AsyncMark(Tcl_AsyncHandler async);
|
||||
/* 75 */
|
||||
EXTERN int Tcl_AsyncReady(void);
|
||||
/* 76 */
|
||||
EXTERN void Tcl_BackgroundError(Tcl_Interp *interp);
|
||||
TCL_DEPRECATED("No longer in use, changed to macro")
|
||||
void Tcl_BackgroundError(Tcl_Interp *interp);
|
||||
/* 77 */
|
||||
TCL_DEPRECATED("Use Tcl_UtfBackslash")
|
||||
char Tcl_Backslash(const char *src, int *readPtr);
|
||||
@@ -1875,6 +1876,26 @@ EXTERN Tcl_Obj * TclZipfs_TclLibrary(void);
|
||||
EXTERN int TclZipfs_MountBuffer(Tcl_Interp *interp,
|
||||
const char *mountPoint, unsigned char *data,
|
||||
size_t datalen, int copy);
|
||||
/* 636 */
|
||||
EXTERN void Tcl_FreeIntRep(Tcl_Obj *objPtr);
|
||||
/* 637 */
|
||||
EXTERN char * Tcl_InitStringRep(Tcl_Obj *objPtr, const char *bytes,
|
||||
unsigned int numBytes);
|
||||
/* 638 */
|
||||
EXTERN Tcl_ObjIntRep * Tcl_FetchIntRep(Tcl_Obj *objPtr,
|
||||
const Tcl_ObjType *typePtr);
|
||||
/* 639 */
|
||||
EXTERN void Tcl_StoreIntRep(Tcl_Obj *objPtr,
|
||||
const Tcl_ObjType *typePtr,
|
||||
const Tcl_ObjIntRep *irPtr);
|
||||
/* 640 */
|
||||
EXTERN int Tcl_HasStringRep(Tcl_Obj *objPtr);
|
||||
/* 641 */
|
||||
EXTERN void Tcl_IncrRefCount(Tcl_Obj *objPtr);
|
||||
/* 642 */
|
||||
EXTERN void Tcl_DecrRefCount(Tcl_Obj *objPtr);
|
||||
/* 643 */
|
||||
EXTERN int Tcl_IsShared(Tcl_Obj *objPtr);
|
||||
|
||||
typedef struct {
|
||||
const struct TclPlatStubs *tclPlatStubs;
|
||||
@@ -1932,7 +1953,7 @@ typedef struct TclStubs {
|
||||
Tcl_Obj * (*tcl_DbNewObj) (const char *file, int line); /* 27 */
|
||||
Tcl_Obj * (*tcl_DbNewStringObj) (const char *bytes, int length, const char *file, int line); /* 28 */
|
||||
Tcl_Obj * (*tcl_DuplicateObj) (Tcl_Obj *objPtr); /* 29 */
|
||||
void (*tclFreeObj) (Tcl_Obj *objPtr); /* 30 */
|
||||
void (*tclOldFreeObj) (Tcl_Obj *objPtr); /* 30 */
|
||||
int (*tcl_GetBoolean) (Tcl_Interp *interp, const char *src, int *boolPtr); /* 31 */
|
||||
int (*tcl_GetBooleanFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *boolPtr); /* 32 */
|
||||
unsigned char * (*tcl_GetByteArrayFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 33 */
|
||||
@@ -1978,7 +1999,7 @@ typedef struct TclStubs {
|
||||
int (*tcl_AsyncInvoke) (Tcl_Interp *interp, int code); /* 73 */
|
||||
void (*tcl_AsyncMark) (Tcl_AsyncHandler async); /* 74 */
|
||||
int (*tcl_AsyncReady) (void); /* 75 */
|
||||
void (*tcl_BackgroundError) (Tcl_Interp *interp); /* 76 */
|
||||
TCL_DEPRECATED_API("No longer in use, changed to macro") void (*tcl_BackgroundError) (Tcl_Interp *interp); /* 76 */
|
||||
TCL_DEPRECATED_API("Use Tcl_UtfBackslash") char (*tcl_Backslash) (const char *src, int *readPtr); /* 77 */
|
||||
int (*tcl_BadChannelOption) (Tcl_Interp *interp, const char *optionName, const char *optionList); /* 78 */
|
||||
void (*tcl_CallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 79 */
|
||||
@@ -2046,7 +2067,7 @@ typedef struct TclStubs {
|
||||
int (*tcl_ExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **resultPtrPtr); /* 141 */
|
||||
int (*tcl_ExprString) (Tcl_Interp *interp, const char *expr); /* 142 */
|
||||
void (*tcl_Finalize) (void); /* 143 */
|
||||
void (*tcl_FindExecutable) (const char *argv0); /* 144 */
|
||||
TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tcl_FindExecutable) (const char *argv0); /* 144 */
|
||||
Tcl_HashEntry * (*tcl_FirstHashEntry) (Tcl_HashTable *tablePtr, Tcl_HashSearch *searchPtr); /* 145 */
|
||||
int (*tcl_Flush) (Tcl_Channel chan); /* 146 */
|
||||
void (*tcl_FreeResult) (Tcl_Interp *interp); /* 147 */
|
||||
@@ -2140,7 +2161,7 @@ typedef struct TclStubs {
|
||||
void (*tcl_SetErrno) (int err); /* 227 */
|
||||
void (*tcl_SetErrorCode) (Tcl_Interp *interp, ...); /* 228 */
|
||||
void (*tcl_SetMaxBlockTime) (const Tcl_Time *timePtr); /* 229 */
|
||||
void (*tcl_SetPanicProc) (TCL_NORETURN1 Tcl_PanicProc *panicProc); /* 230 */
|
||||
TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tcl_SetPanicProc) (TCL_NORETURN1 Tcl_PanicProc *panicProc); /* 230 */
|
||||
int (*tcl_SetRecursionLimit) (Tcl_Interp *interp, int depth); /* 231 */
|
||||
void (*tcl_SetResult) (Tcl_Interp *interp, char *result, Tcl_FreeProc *freeProc); /* 232 */
|
||||
int (*tcl_SetServiceMode) (int mode); /* 233 */
|
||||
@@ -2154,7 +2175,7 @@ typedef struct TclStubs {
|
||||
void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */
|
||||
int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, int *argcPtr, const char ***argvPtr); /* 242 */
|
||||
void (*tcl_SplitPath) (const char *path, int *argcPtr, const char ***argvPtr); /* 243 */
|
||||
void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */
|
||||
TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */
|
||||
int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */
|
||||
TCL_DEPRECATED_API("") int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */
|
||||
TCL_DEPRECATED_API("No longer in use, changed to macro") int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */
|
||||
@@ -2429,7 +2450,7 @@ typedef struct TclStubs {
|
||||
Tcl_Command (*tcl_GetCommandFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 516 */
|
||||
void (*tcl_GetCommandFullName) (Tcl_Interp *interp, Tcl_Command command, Tcl_Obj *objPtr); /* 517 */
|
||||
int (*tcl_FSEvalFileEx) (Tcl_Interp *interp, Tcl_Obj *fileName, const char *encodingName); /* 518 */
|
||||
Tcl_ExitProc * (*tcl_SetExitProc) (TCL_NORETURN1 Tcl_ExitProc *proc); /* 519 */
|
||||
TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") Tcl_ExitProc * (*tcl_SetExitProc) (TCL_NORETURN1 Tcl_ExitProc *proc); /* 519 */
|
||||
void (*tcl_LimitAddHandler) (Tcl_Interp *interp, int type, Tcl_LimitHandlerProc *handlerProc, ClientData clientData, Tcl_LimitHandlerDeleteProc *deleteProc); /* 520 */
|
||||
void (*tcl_LimitRemoveHandler) (Tcl_Interp *interp, int type, Tcl_LimitHandlerProc *handlerProc, ClientData clientData); /* 521 */
|
||||
int (*tcl_LimitReady) (Tcl_Interp *interp); /* 522 */
|
||||
@@ -2546,6 +2567,14 @@ typedef struct TclStubs {
|
||||
int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *mountPoint); /* 633 */
|
||||
Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */
|
||||
int (*tclZipfs_MountBuffer) (Tcl_Interp *interp, const char *mountPoint, unsigned char *data, size_t datalen, int copy); /* 635 */
|
||||
void (*tcl_FreeIntRep) (Tcl_Obj *objPtr); /* 636 */
|
||||
char * (*tcl_InitStringRep) (Tcl_Obj *objPtr, const char *bytes, unsigned int numBytes); /* 637 */
|
||||
Tcl_ObjIntRep * (*tcl_FetchIntRep) (Tcl_Obj *objPtr, const Tcl_ObjType *typePtr); /* 638 */
|
||||
void (*tcl_StoreIntRep) (Tcl_Obj *objPtr, const Tcl_ObjType *typePtr, const Tcl_ObjIntRep *irPtr); /* 639 */
|
||||
int (*tcl_HasStringRep) (Tcl_Obj *objPtr); /* 640 */
|
||||
void (*tcl_IncrRefCount) (Tcl_Obj *objPtr); /* 641 */
|
||||
void (*tcl_DecrRefCount) (Tcl_Obj *objPtr); /* 642 */
|
||||
int (*tcl_IsShared) (Tcl_Obj *objPtr); /* 643 */
|
||||
} TclStubs;
|
||||
|
||||
extern const TclStubs *tclStubsPtr;
|
||||
@@ -2632,8 +2661,8 @@ extern const TclStubs *tclStubsPtr;
|
||||
(tclStubsPtr->tcl_DbNewStringObj) /* 28 */
|
||||
#define Tcl_DuplicateObj \
|
||||
(tclStubsPtr->tcl_DuplicateObj) /* 29 */
|
||||
#define TclFreeObj \
|
||||
(tclStubsPtr->tclFreeObj) /* 30 */
|
||||
#define TclOldFreeObj \
|
||||
(tclStubsPtr->tclOldFreeObj) /* 30 */
|
||||
#define Tcl_GetBoolean \
|
||||
(tclStubsPtr->tcl_GetBoolean) /* 31 */
|
||||
#define Tcl_GetBooleanFromObj \
|
||||
@@ -3848,6 +3877,22 @@ extern const TclStubs *tclStubsPtr;
|
||||
(tclStubsPtr->tclZipfs_TclLibrary) /* 634 */
|
||||
#define TclZipfs_MountBuffer \
|
||||
(tclStubsPtr->tclZipfs_MountBuffer) /* 635 */
|
||||
#define Tcl_FreeIntRep \
|
||||
(tclStubsPtr->tcl_FreeIntRep) /* 636 */
|
||||
#define Tcl_InitStringRep \
|
||||
(tclStubsPtr->tcl_InitStringRep) /* 637 */
|
||||
#define Tcl_FetchIntRep \
|
||||
(tclStubsPtr->tcl_FetchIntRep) /* 638 */
|
||||
#define Tcl_StoreIntRep \
|
||||
(tclStubsPtr->tcl_StoreIntRep) /* 639 */
|
||||
#define Tcl_HasStringRep \
|
||||
(tclStubsPtr->tcl_HasStringRep) /* 640 */
|
||||
#define Tcl_IncrRefCount \
|
||||
(tclStubsPtr->tcl_IncrRefCount) /* 641 */
|
||||
#define Tcl_DecrRefCount \
|
||||
(tclStubsPtr->tcl_DecrRefCount) /* 642 */
|
||||
#define Tcl_IsShared \
|
||||
(tclStubsPtr->tcl_IsShared) /* 643 */
|
||||
|
||||
#endif /* defined(USE_TCL_STUBS) */
|
||||
|
||||
@@ -3859,12 +3904,12 @@ extern const TclStubs *tclStubsPtr;
|
||||
# undef Tcl_GetStringResult
|
||||
# undef Tcl_Init
|
||||
# undef Tcl_SetPanicProc
|
||||
# undef Tcl_SetExitProc
|
||||
# undef Tcl_ObjSetVar2
|
||||
# undef Tcl_StaticPackage
|
||||
# define Tcl_CreateInterp() (tclStubsPtr->tcl_CreateInterp())
|
||||
# define Tcl_GetStringResult(interp) (tclStubsPtr->tcl_GetStringResult(interp))
|
||||
# define Tcl_Init(interp) (tclStubsPtr->tcl_Init(interp))
|
||||
# define Tcl_SetPanicProc(proc) (tclStubsPtr->tcl_SetPanicProc(proc))
|
||||
# define Tcl_ObjSetVar2(interp, part1, part2, newValue, flags) \
|
||||
(tclStubsPtr->tcl_ObjSetVar2(interp, part1, part2, newValue, flags))
|
||||
#endif
|
||||
@@ -3898,13 +3943,13 @@ extern const TclStubs *tclStubsPtr;
|
||||
sizeof(char *), msg, flags, indexPtr)
|
||||
#undef Tcl_NewBooleanObj
|
||||
#define Tcl_NewBooleanObj(boolValue) \
|
||||
Tcl_NewLongObj((boolValue)!=0)
|
||||
Tcl_NewWideIntObj((boolValue)!=0)
|
||||
#undef Tcl_DbNewBooleanObj
|
||||
#define Tcl_DbNewBooleanObj(boolValue, file, line) \
|
||||
Tcl_DbNewLongObj((boolValue)!=0, file, line)
|
||||
Tcl_DbNewWideIntObj((boolValue)!=0, file, line)
|
||||
#undef Tcl_SetBooleanObj
|
||||
#define Tcl_SetBooleanObj(objPtr, boolValue) \
|
||||
Tcl_SetLongObj(objPtr, (boolValue)!=0)
|
||||
Tcl_SetWideIntObj(objPtr, (boolValue)!=0)
|
||||
#undef Tcl_SetVar
|
||||
#define Tcl_SetVar(interp, varName, newValue, flags) \
|
||||
Tcl_SetVar2(interp, varName, NULL, newValue, flags)
|
||||
@@ -4026,6 +4071,8 @@ extern const TclStubs *tclStubsPtr;
|
||||
#define Tcl_SetLongObj(objPtr, value) Tcl_SetWideIntObj((objPtr), (long)(value))
|
||||
#undef Tcl_GetUnicode
|
||||
#define Tcl_GetUnicode(objPtr) Tcl_GetUnicodeFromObj((objPtr), NULL)
|
||||
#undef Tcl_BackgroundError
|
||||
#define Tcl_BackgroundError(interp) Tcl_BackgroundException((interp), TCL_ERROR)
|
||||
|
||||
/*
|
||||
* Deprecated Tcl procedures:
|
||||
|
||||
+125
-97
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tommath.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Forward declaration.
|
||||
@@ -148,13 +149,6 @@ typedef struct Dict {
|
||||
* dictionaries. */
|
||||
} Dict;
|
||||
|
||||
/*
|
||||
* Accessor macro for converting between a Tcl_Obj* and a Dict. Note that this
|
||||
* must be assignable as well as readable.
|
||||
*/
|
||||
|
||||
#define DICT(dictObj) ((dictObj)->internalRep.twoPtrValue.ptr1)
|
||||
|
||||
/*
|
||||
* The structure below defines the dictionary object type by means of
|
||||
* functions that can be invoked by generic object code.
|
||||
@@ -168,6 +162,21 @@ const Tcl_ObjType tclDictType = {
|
||||
SetDictFromAny /* setFromAnyProc */
|
||||
};
|
||||
|
||||
#define DictSetIntRep(objPtr, dictRepPtr) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (dictRepPtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((objPtr), &tclDictType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define DictGetIntRep(objPtr, dictRepPtr) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), &tclDictType); \
|
||||
(dictRepPtr) = irPtr ? irPtr->twoPtrValue.ptr1 : NULL; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* The type of the specially adapted version of the Tcl_Obj*-containing hash
|
||||
* table defined in the tclObj.c code. This version differs in that it
|
||||
@@ -363,10 +372,11 @@ DupDictInternalRep(
|
||||
Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *copyPtr)
|
||||
{
|
||||
Dict *oldDict = DICT(srcPtr);
|
||||
Dict *newDict = ckalloc(sizeof(Dict));
|
||||
Dict *oldDict, *newDict = ckalloc(sizeof(Dict));
|
||||
ChainEntry *cPtr;
|
||||
|
||||
DictGetIntRep(srcPtr, oldDict);
|
||||
|
||||
/*
|
||||
* Copy values across from the old hash table.
|
||||
*/
|
||||
@@ -398,9 +408,7 @@ DupDictInternalRep(
|
||||
* Store in the object.
|
||||
*/
|
||||
|
||||
DICT(copyPtr) = newDict;
|
||||
copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
copyPtr->typePtr = &tclDictType;
|
||||
DictSetIntRep(copyPtr, newDict);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -425,12 +433,13 @@ static void
|
||||
FreeDictInternalRep(
|
||||
Tcl_Obj *dictPtr)
|
||||
{
|
||||
Dict *dict = DICT(dictPtr);
|
||||
Dict *dict;
|
||||
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
|
||||
if (dict->refCount-- <= 1) {
|
||||
DeleteDict(dict);
|
||||
}
|
||||
dictPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -489,7 +498,7 @@ UpdateStringOfDict(
|
||||
{
|
||||
#define LOCAL_SIZE 64
|
||||
char localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
Dict *dict = DICT(dictPtr);
|
||||
Dict *dict;
|
||||
ChainEntry *cPtr;
|
||||
Tcl_Obj *keyPtr, *valuePtr;
|
||||
int i, length, bytesNeeded = 0;
|
||||
@@ -501,12 +510,17 @@ UpdateStringOfDict(
|
||||
* is not exposed by any API function...
|
||||
*/
|
||||
|
||||
int numElems = dict->table.numEntries * 2;
|
||||
int numElems;
|
||||
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
|
||||
assert (dict != NULL);
|
||||
|
||||
numElems = dict->table.numEntries * 2;
|
||||
|
||||
/* Handle empty list case first, simplifies what follows */
|
||||
if (numElems == 0) {
|
||||
dictPtr->bytes = &tclEmptyString;
|
||||
dictPtr->length = 0;
|
||||
Tcl_InitStringRep(dictPtr, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -550,9 +564,8 @@ UpdateStringOfDict(
|
||||
* Pass 2: copy into string rep buffer.
|
||||
*/
|
||||
|
||||
dictPtr->length = bytesNeeded - 1;
|
||||
dictPtr->bytes = ckalloc(bytesNeeded);
|
||||
dst = dictPtr->bytes;
|
||||
dst = Tcl_InitStringRep(dictPtr, NULL, bytesNeeded - 1);
|
||||
TclOOM(dst, bytesNeeded);
|
||||
for (i=0,cPtr=dict->entryChainHead; i<numElems; i+=2,cPtr=cPtr->nextPtr) {
|
||||
flagPtr[i] |= ( i ? TCL_DONT_QUOTE_HASH : 0 );
|
||||
keyPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry);
|
||||
@@ -566,7 +579,7 @@ UpdateStringOfDict(
|
||||
dst += TclConvertElement(elem, length, dst, flagPtr[i+1]);
|
||||
*dst++ = ' ';
|
||||
}
|
||||
dictPtr->bytes[dictPtr->length] = '\0';
|
||||
(void)Tcl_InitStringRep(dictPtr, NULL, bytesNeeded - 1);
|
||||
|
||||
if (flagPtr != localFlags) {
|
||||
ckfree(flagPtr);
|
||||
@@ -610,7 +623,7 @@ SetDictFromAny(
|
||||
* the conversion from lists to dictionaries.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &tclListType) {
|
||||
if (TclHasIntRep(objPtr, &tclListType)) {
|
||||
int objc, i;
|
||||
Tcl_Obj **objv;
|
||||
|
||||
@@ -665,10 +678,14 @@ SetDictFromAny(
|
||||
TclNewStringObj(keyPtr, elemStart, elemSize);
|
||||
} else {
|
||||
/* Avoid double copy */
|
||||
char *dst;
|
||||
|
||||
TclNewObj(keyPtr);
|
||||
keyPtr->bytes = ckalloc((unsigned) elemSize + 1);
|
||||
keyPtr->length = TclCopyAndCollapse(elemSize, elemStart,
|
||||
keyPtr->bytes);
|
||||
Tcl_InvalidateStringRep(keyPtr);
|
||||
dst = Tcl_InitStringRep(keyPtr, NULL, elemSize);
|
||||
TclOOM(dst, elemSize); /* Consider error */
|
||||
(void)Tcl_InitStringRep(keyPtr, NULL,
|
||||
TclCopyAndCollapse(elemSize, elemStart, dst));
|
||||
}
|
||||
|
||||
if (TclFindDictElement(interp, nextElem, (limit - nextElem),
|
||||
@@ -681,10 +698,14 @@ SetDictFromAny(
|
||||
TclNewStringObj(valuePtr, elemStart, elemSize);
|
||||
} else {
|
||||
/* Avoid double copy */
|
||||
char *dst;
|
||||
|
||||
TclNewObj(valuePtr);
|
||||
valuePtr->bytes = ckalloc((unsigned) elemSize + 1);
|
||||
valuePtr->length = TclCopyAndCollapse(elemSize, elemStart,
|
||||
valuePtr->bytes);
|
||||
Tcl_InvalidateStringRep(valuePtr);
|
||||
dst = Tcl_InitStringRep(valuePtr, NULL, elemSize);
|
||||
TclOOM(dst, elemSize); /* Consider error */
|
||||
(void)Tcl_InitStringRep(valuePtr, NULL,
|
||||
TclCopyAndCollapse(elemSize, elemStart, dst));
|
||||
}
|
||||
|
||||
/* Store key and value in the hash table we're building. */
|
||||
@@ -706,13 +727,10 @@ SetDictFromAny(
|
||||
* Tcl_GetStringFromObj, to use that old internalRep.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
dict->epoch = 1;
|
||||
dict->chain = NULL;
|
||||
dict->refCount = 1;
|
||||
DICT(objPtr) = dict;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = &tclDictType;
|
||||
DictSetIntRep(objPtr, dict);
|
||||
return TCL_OK;
|
||||
|
||||
missingValue:
|
||||
@@ -726,6 +744,23 @@ SetDictFromAny(
|
||||
ckfree(dict);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
static Dict *
|
||||
GetDictFromObj(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *dictPtr)
|
||||
{
|
||||
Dict *dict;
|
||||
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
if (dict == NULL) {
|
||||
if (SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
}
|
||||
return dict;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -770,11 +805,13 @@ TclTraceDictPath(
|
||||
Dict *dict, *newDict;
|
||||
int i;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
if (dict == NULL) {
|
||||
if (SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
}
|
||||
dict = DICT(dictPtr);
|
||||
if (flags & DICT_PATH_UPDATE) {
|
||||
dict->chain = NULL;
|
||||
}
|
||||
@@ -810,13 +847,17 @@ TclTraceDictPath(
|
||||
Tcl_SetHashValue(hPtr, tmpObj);
|
||||
} else {
|
||||
tmpObj = Tcl_GetHashValue(hPtr);
|
||||
if (tmpObj->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, tmpObj) != TCL_OK) {
|
||||
return NULL;
|
||||
|
||||
DictGetIntRep(tmpObj, newDict);
|
||||
|
||||
if (newDict == NULL) {
|
||||
if (SetDictFromAny(interp, tmpObj) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newDict = DICT(tmpObj);
|
||||
DictGetIntRep(tmpObj, newDict);
|
||||
if (flags & DICT_PATH_UPDATE) {
|
||||
if (Tcl_IsShared(tmpObj)) {
|
||||
TclDecrRefCount(tmpObj);
|
||||
@@ -824,7 +865,7 @@ TclTraceDictPath(
|
||||
Tcl_IncrRefCount(tmpObj);
|
||||
Tcl_SetHashValue(hPtr, tmpObj);
|
||||
dict->epoch++;
|
||||
newDict = DICT(tmpObj);
|
||||
DictGetIntRep(tmpObj, newDict);
|
||||
}
|
||||
|
||||
newDict->chain = dictPtr;
|
||||
@@ -859,17 +900,24 @@ static void
|
||||
InvalidateDictChain(
|
||||
Tcl_Obj *dictObj)
|
||||
{
|
||||
Dict *dict = DICT(dictObj);
|
||||
Dict *dict;
|
||||
|
||||
DictGetIntRep(dictObj, dict);
|
||||
assert( dict != NULL);
|
||||
|
||||
do {
|
||||
dict->refCount++;
|
||||
TclInvalidateStringRep(dictObj);
|
||||
TclFreeIntRep(dictObj);
|
||||
DictSetIntRep(dictObj, dict);
|
||||
|
||||
dict->epoch++;
|
||||
dictObj = dict->chain;
|
||||
if (dictObj == NULL) {
|
||||
break;
|
||||
}
|
||||
dict->chain = NULL;
|
||||
dict = DICT(dictObj);
|
||||
DictGetIntRep(dictObj, dict);
|
||||
} while (dict != NULL);
|
||||
}
|
||||
|
||||
@@ -907,16 +955,16 @@ Tcl_DictObjPut(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_DictObjPut");
|
||||
}
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
dict = GetDictFromObj(interp, dictPtr);
|
||||
if (dict == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
dict = DICT(dictPtr);
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
hPtr = CreateChainEntry(dict, keyPtr, &isNew);
|
||||
dict->refCount++;
|
||||
TclFreeIntRep(dictPtr)
|
||||
DictSetIntRep(dictPtr, dict);
|
||||
Tcl_IncrRefCount(valuePtr);
|
||||
if (!isNew) {
|
||||
Tcl_Obj *oldValuePtr = Tcl_GetHashValue(hPtr);
|
||||
@@ -958,13 +1006,12 @@ Tcl_DictObjGet(
|
||||
Dict *dict;
|
||||
Tcl_HashEntry *hPtr;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
dict = GetDictFromObj(interp, dictPtr);
|
||||
if (dict == NULL) {
|
||||
*valuePtrPtr = NULL;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = DICT(dictPtr);
|
||||
hPtr = Tcl_FindHashEntry(&dict->table, keyPtr);
|
||||
if (hPtr == NULL) {
|
||||
*valuePtrPtr = NULL;
|
||||
@@ -1005,16 +1052,13 @@ Tcl_DictObjRemove(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_DictObjRemove");
|
||||
}
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
dict = GetDictFromObj(interp, dictPtr);
|
||||
if (dict == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = DICT(dictPtr);
|
||||
if (DeleteChainEntry(dict, keyPtr)) {
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
dict->epoch++;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -1046,12 +1090,11 @@ Tcl_DictObjSize(
|
||||
{
|
||||
Dict *dict;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
dict = GetDictFromObj(interp, dictPtr);
|
||||
if (dict == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = DICT(dictPtr);
|
||||
*sizePtr = dict->table.numEntries;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1098,12 +1141,11 @@ Tcl_DictObjFirst(
|
||||
Dict *dict;
|
||||
ChainEntry *cPtr;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
dict = GetDictFromObj(interp, dictPtr);
|
||||
if (dict == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = DICT(dictPtr);
|
||||
cPtr = dict->entryChainHead;
|
||||
if (cPtr == NULL) {
|
||||
searchPtr->epoch = 0;
|
||||
@@ -1277,7 +1319,8 @@ Tcl_DictObjPutKeyList(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = DICT(dictPtr);
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
assert(dict != NULL);
|
||||
hPtr = CreateChainEntry(dict, keyv[keyc-1], &isNew);
|
||||
Tcl_IncrRefCount(valuePtr);
|
||||
if (!isNew) {
|
||||
@@ -1334,7 +1377,8 @@ Tcl_DictObjRemoveKeyList(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = DICT(dictPtr);
|
||||
DictGetIntRep(dictPtr, dict);
|
||||
assert(dict != NULL);
|
||||
DeleteChainEntry(dict, keyv[keyc-1]);
|
||||
InvalidateDictChain(dictPtr);
|
||||
return TCL_OK;
|
||||
@@ -1380,9 +1424,7 @@ Tcl_NewDictObj(void)
|
||||
dict->epoch = 1;
|
||||
dict->chain = NULL;
|
||||
dict->refCount = 1;
|
||||
DICT(dictPtr) = dict;
|
||||
dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
dictPtr->typePtr = &tclDictType;
|
||||
DictSetIntRep(dictPtr, dict);
|
||||
return dictPtr;
|
||||
#endif
|
||||
}
|
||||
@@ -1430,9 +1472,7 @@ Tcl_DbNewDictObj(
|
||||
dict->epoch = 1;
|
||||
dict->chain = NULL;
|
||||
dict->refCount = 1;
|
||||
DICT(dictPtr) = dict;
|
||||
dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
dictPtr->typePtr = &tclDictType;
|
||||
DictSetIntRep(dictPtr, dict);
|
||||
return dictPtr;
|
||||
#else /* !TCL_MEM_DEBUG */
|
||||
return Tcl_NewDictObj();
|
||||
@@ -1618,16 +1658,13 @@ DictReplaceCmd(
|
||||
}
|
||||
|
||||
dictPtr = objv[1];
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
if (GetDictFromObj(interp, dictPtr) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_IsShared(dictPtr)) {
|
||||
dictPtr = Tcl_DuplicateObj(dictPtr);
|
||||
}
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
for (i=2 ; i<objc ; i+=2) {
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[i], objv[i+1]);
|
||||
}
|
||||
@@ -1669,16 +1706,13 @@ DictRemoveCmd(
|
||||
}
|
||||
|
||||
dictPtr = objv[1];
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
if (GetDictFromObj(interp, dictPtr) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_IsShared(dictPtr)) {
|
||||
dictPtr = Tcl_DuplicateObj(dictPtr);
|
||||
}
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
for (i=2 ; i<objc ; i++) {
|
||||
Tcl_DictObjRemove(NULL, dictPtr, objv[i]);
|
||||
}
|
||||
@@ -1729,8 +1763,7 @@ DictMergeCmd(
|
||||
*/
|
||||
|
||||
targetObj = objv[1];
|
||||
if (targetObj->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, targetObj) != TCL_OK) {
|
||||
if (GetDictFromObj(interp, targetObj) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1813,8 +1846,7 @@ DictKeysCmd(
|
||||
* need. [Bug 1705778, leak K04]
|
||||
*/
|
||||
|
||||
if (objv[1]->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, objv[1]) != TCL_OK) {
|
||||
if (GetDictFromObj(interp, objv[1]) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2021,7 +2053,6 @@ DictInfoCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Tcl_Obj *dictPtr;
|
||||
Dict *dict;
|
||||
char *statsStr;
|
||||
|
||||
@@ -2030,12 +2061,10 @@ DictInfoCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dictPtr = objv[1];
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
dict = GetDictFromObj(interp, objv[1]);
|
||||
if (dict == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dict = DICT(dictPtr);
|
||||
|
||||
statsStr = Tcl_HashStats(&dict->table);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1));
|
||||
@@ -2096,12 +2125,11 @@ DictIncrCmd(
|
||||
* soon be no good.
|
||||
*/
|
||||
|
||||
char *saved = dictPtr->bytes;
|
||||
Tcl_Obj *oldPtr = dictPtr;
|
||||
|
||||
dictPtr->bytes = NULL;
|
||||
dictPtr = Tcl_DuplicateObj(dictPtr);
|
||||
oldPtr->bytes = saved;
|
||||
TclNewObj(dictPtr);
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
DupDictInternalRep(oldPtr, dictPtr);
|
||||
}
|
||||
if (valuePtr == NULL) {
|
||||
/*
|
||||
@@ -2238,7 +2266,7 @@ DictLappendCmd(
|
||||
|
||||
if (allocatedValue) {
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
|
||||
} else if (dictPtr->bytes != NULL) {
|
||||
} else {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
|
||||
|
||||
+53
-41
@@ -38,7 +38,7 @@ static void UpdateStringOfInstName(Tcl_Obj *objPtr);
|
||||
* reporting of inner contexts in errorstack without string allocation.
|
||||
*/
|
||||
|
||||
static const Tcl_ObjType tclInstNameType = {
|
||||
static const Tcl_ObjType instNameType = {
|
||||
"instname", /* name */
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
@@ -46,12 +46,21 @@ static const Tcl_ObjType tclInstNameType = {
|
||||
NULL, /* setFromAnyProc */
|
||||
};
|
||||
|
||||
/*
|
||||
* How to get the bytecode out of a Tcl_Obj.
|
||||
*/
|
||||
#define InstNameSetIntRep(objPtr, inst) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.wideValue = (inst); \
|
||||
Tcl_StoreIntRep((objPtr), &instNameType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define InstNameGetIntRep(objPtr, inst) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), &instNameType); \
|
||||
assert(irPtr != NULL); \
|
||||
(inst) = (size_t)irPtr->wideValue; \
|
||||
} while (0)
|
||||
|
||||
#define BYTECODE(objPtr) \
|
||||
((ByteCode *) (objPtr)->internalRep.twoPtrValue.ptr1)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -245,14 +254,18 @@ DisassembleByteCodeObj(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr) /* The bytecode object to disassemble. */
|
||||
{
|
||||
ByteCode *codePtr = BYTECODE(objPtr);
|
||||
ByteCode *codePtr;
|
||||
unsigned char *codeStart, *codeLimit, *pc;
|
||||
unsigned char *codeDeltaNext, *codeLengthNext;
|
||||
unsigned char *srcDeltaNext, *srcLengthNext;
|
||||
int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
|
||||
Interp *iPtr = (Interp *) *codePtr->interpHandle;
|
||||
Interp *iPtr;
|
||||
Tcl_Obj *bufferObj, *fileObj;
|
||||
|
||||
ByteCodeGetIntRep(objPtr, &tclByteCodeType, codePtr);
|
||||
|
||||
iPtr = (Interp *) *codePtr->interpHandle;
|
||||
|
||||
TclNewObj(bufferObj);
|
||||
if (!codePtr->refCount) {
|
||||
return bufferObj; /* Already freed. */
|
||||
@@ -796,9 +809,8 @@ TclNewInstNameObj(
|
||||
{
|
||||
Tcl_Obj *objPtr = Tcl_NewObj();
|
||||
|
||||
objPtr->typePtr = &tclInstNameType;
|
||||
objPtr->internalRep.wideValue = (long) inst;
|
||||
objPtr->bytes = NULL;
|
||||
TclInvalidateStringRep(objPtr);
|
||||
InstNameSetIntRep(objPtr, (long) inst);
|
||||
|
||||
return objPtr;
|
||||
}
|
||||
@@ -817,20 +829,22 @@ static void
|
||||
UpdateStringOfInstName(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
size_t len, inst = (size_t)objPtr->internalRep.wideValue;
|
||||
char *s, buf[TCL_INTEGER_SPACE + 5];
|
||||
size_t inst; /* NOTE: We know this is really an unsigned char */
|
||||
char *dst;
|
||||
|
||||
InstNameGetIntRep(objPtr, inst);
|
||||
|
||||
if (inst > LAST_INST_OPCODE) {
|
||||
sprintf(buf, "inst_%" TCL_Z_MODIFIER "d", inst);
|
||||
s = buf;
|
||||
dst = Tcl_InitStringRep(objPtr, NULL, TCL_INTEGER_SPACE + 5);
|
||||
TclOOM(dst, TCL_INTEGER_SPACE + 5);
|
||||
sprintf(dst, "inst_%" TCL_Z_MODIFIER "d", inst);
|
||||
(void) Tcl_InitStringRep(objPtr, NULL, strlen(dst));
|
||||
} else {
|
||||
s = (char *) tclInstructionTable[inst].name;
|
||||
const char *s = tclInstructionTable[inst].name;
|
||||
unsigned int len = strlen(s);
|
||||
dst = Tcl_InitStringRep(objPtr, s, len);
|
||||
TclOOM(dst, len);
|
||||
}
|
||||
len = strlen(s);
|
||||
/* assert (len < UINT_MAX) */
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, s, len + 1);
|
||||
objPtr->length = len;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -942,13 +956,15 @@ DisassembleByteCodeAsDicts(
|
||||
* procedure, if one exists. */
|
||||
Tcl_Obj *objPtr) /* The bytecode-holding value to take apart */
|
||||
{
|
||||
ByteCode *codePtr = BYTECODE(objPtr);
|
||||
ByteCode *codePtr;
|
||||
Tcl_Obj *description, *literals, *variables, *instructions, *inst;
|
||||
Tcl_Obj *aux, *exn, *commands, *file;
|
||||
unsigned char *pc, *opnd, *codeOffPtr, *codeLenPtr, *srcOffPtr, *srcLenPtr;
|
||||
int codeOffset, codeLength, sourceOffset, sourceLength;
|
||||
int i, val, line;
|
||||
|
||||
ByteCodeGetIntRep(objPtr, &tclByteCodeType, codePtr);
|
||||
|
||||
/*
|
||||
* Get the literals from the bytecode.
|
||||
*/
|
||||
@@ -1286,6 +1302,7 @@ Tcl_DisassembleObjCmd(
|
||||
Proc *procPtr = NULL;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Object *oPtr;
|
||||
ByteCode *codePtr;
|
||||
Method *methodPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
@@ -1304,27 +1321,19 @@ Tcl_DisassembleObjCmd(
|
||||
|
||||
/*
|
||||
* Compile (if uncompiled) and disassemble a lambda term.
|
||||
*
|
||||
* WARNING! Pokes inside the lambda objtype.
|
||||
*/
|
||||
|
||||
if (objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "lambdaTerm");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objv[2]->typePtr == &tclLambdaType) {
|
||||
procPtr = objv[2]->internalRep.twoPtrValue.ptr1;
|
||||
}
|
||||
if (procPtr == NULL || procPtr->iPtr != (Interp *) interp) {
|
||||
result = tclLambdaType.setFromAnyProc(interp, objv[2]);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
procPtr = objv[2]->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
procPtr = TclGetLambdaFromObj(interp, objv[2], &nsObjPtr);
|
||||
if (procPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
memset(&cmd, 0, sizeof(Command));
|
||||
nsObjPtr = objv[2]->internalRep.twoPtrValue.ptr2;
|
||||
result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
@@ -1374,8 +1383,9 @@ Tcl_DisassembleObjCmd(
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "script");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((objv[2]->typePtr != &tclByteCodeType)
|
||||
&& (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK)) {
|
||||
|
||||
if (!TclHasIntRep(objv[2], &tclByteCodeType) && (TCL_OK
|
||||
!= TclSetByteCodeFromAny(interp, objv[2], NULL, NULL))) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
codeObjPtr = objv[2];
|
||||
@@ -1425,7 +1435,7 @@ Tcl_DisassembleObjCmd(
|
||||
* Compile if necessary.
|
||||
*/
|
||||
|
||||
if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
|
||||
if (!TclHasIntRep(procPtr->bodyPtr, &tclByteCodeType)) {
|
||||
Command cmd;
|
||||
|
||||
/*
|
||||
@@ -1490,7 +1500,7 @@ Tcl_DisassembleObjCmd(
|
||||
* Compile if necessary.
|
||||
*/
|
||||
|
||||
if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
|
||||
if (!TclHasIntRep(procPtr->bodyPtr, &tclByteCodeType)) {
|
||||
Command cmd;
|
||||
|
||||
/*
|
||||
@@ -1575,7 +1585,7 @@ Tcl_DisassembleObjCmd(
|
||||
"METHODTYPE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
|
||||
if (!TclHasIntRep(procPtr->bodyPtr, &tclByteCodeType)) {
|
||||
Command cmd;
|
||||
|
||||
/*
|
||||
@@ -1603,14 +1613,16 @@ Tcl_DisassembleObjCmd(
|
||||
* Do the actual disassembly.
|
||||
*/
|
||||
|
||||
if (BYTECODE(codeObjPtr)->flags & TCL_BYTECODE_PRECOMPILED) {
|
||||
ByteCodeGetIntRep(codeObjPtr, &tclByteCodeType, codePtr);
|
||||
|
||||
if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"may not disassemble prebuilt bytecode", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
|
||||
"BYTECODE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (PTR2INT(clientData)) {
|
||||
if (clientData) {
|
||||
Tcl_SetObjResult(interp,
|
||||
DisassembleByteCodeAsDicts(interp, codeObjPtr));
|
||||
} else {
|
||||
|
||||
+80
-52
@@ -234,12 +234,12 @@ static int TableToUtfProc(ClientData clientData, const char *src,
|
||||
char *dst, int dstLen, int *srcReadPtr,
|
||||
int *dstWrotePtr, int *dstCharsPtr);
|
||||
static size_t unilen(const char *src);
|
||||
static int UnicodeToUtfProc(ClientData clientData,
|
||||
static int UniCharToUtfProc(ClientData clientData,
|
||||
const char *src, int srcLen, int flags,
|
||||
Tcl_EncodingState *statePtr, char *dst, int dstLen,
|
||||
int *srcReadPtr, int *dstWrotePtr,
|
||||
int *dstCharsPtr);
|
||||
static int UtfToUnicodeProc(ClientData clientData,
|
||||
static int UtfToUniCharProc(ClientData clientData,
|
||||
const char *src, int srcLen, int flags,
|
||||
Tcl_EncodingState *statePtr, char *dst, int dstLen,
|
||||
int *srcReadPtr, int *dstWrotePtr,
|
||||
@@ -279,6 +279,21 @@ static int Iso88591ToUtfProc(ClientData clientData,
|
||||
static const Tcl_ObjType encodingType = {
|
||||
"encoding", FreeEncodingIntRep, DupEncodingIntRep, NULL, NULL
|
||||
};
|
||||
#define EncodingSetIntRep(objPtr, encoding) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (encoding); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((objPtr), &encodingType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define EncodingGetIntRep(objPtr, encoding) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep ((objPtr), &encodingType); \
|
||||
(encoding) = irPtr ? irPtr->twoPtrValue.ptr1 : NULL; \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -305,17 +320,16 @@ Tcl_GetEncodingFromObj(
|
||||
Tcl_Obj *objPtr,
|
||||
Tcl_Encoding *encodingPtr)
|
||||
{
|
||||
Tcl_Encoding encoding;
|
||||
const char *name = TclGetString(objPtr);
|
||||
|
||||
if (objPtr->typePtr != &encodingType) {
|
||||
Tcl_Encoding encoding = Tcl_GetEncoding(interp, name);
|
||||
|
||||
EncodingGetIntRep(objPtr, encoding);
|
||||
if (encoding == NULL) {
|
||||
encoding = Tcl_GetEncoding(interp, name);
|
||||
if (encoding == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = encoding;
|
||||
objPtr->typePtr = &encodingType;
|
||||
EncodingSetIntRep(objPtr, encoding);
|
||||
}
|
||||
*encodingPtr = Tcl_GetEncoding(NULL, name);
|
||||
return TCL_OK;
|
||||
@@ -335,8 +349,10 @@ static void
|
||||
FreeEncodingIntRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
Tcl_FreeEncoding(objPtr->internalRep.twoPtrValue.ptr1);
|
||||
objPtr->typePtr = NULL;
|
||||
Tcl_Encoding encoding;
|
||||
|
||||
EncodingGetIntRep(objPtr, encoding);
|
||||
Tcl_FreeEncoding(encoding);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -354,8 +370,8 @@ DupEncodingIntRep(
|
||||
Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *dupPtr)
|
||||
{
|
||||
dupPtr->internalRep.twoPtrValue.ptr1 = Tcl_GetEncoding(NULL, srcPtr->bytes);
|
||||
dupPtr->typePtr = &encodingType;
|
||||
Tcl_Encoding encoding = Tcl_GetEncoding(NULL, TclGetString(srcPtr));
|
||||
EncodingSetIntRep(dupPtr, encoding);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -580,8 +596,8 @@ TclInitEncodingSubsystem(void)
|
||||
Tcl_CreateEncoding(&type);
|
||||
|
||||
type.encodingName = "unicode";
|
||||
type.toUtfProc = UnicodeToUtfProc;
|
||||
type.fromUtfProc = UtfToUnicodeProc;
|
||||
type.toUtfProc = UniCharToUtfProc;
|
||||
type.fromUtfProc = UtfToUniCharProc;
|
||||
type.freeProc = NULL;
|
||||
type.nullSize = 2;
|
||||
type.clientData = NULL;
|
||||
@@ -1723,7 +1739,9 @@ LoadTableEncoding(
|
||||
};
|
||||
|
||||
Tcl_DStringInit(&lineString);
|
||||
Tcl_Gets(chan, &lineString);
|
||||
if (Tcl_Gets(chan, &lineString) == TCL_IO_FAILURE) {
|
||||
return NULL;
|
||||
}
|
||||
line = Tcl_DStringValue(&lineString);
|
||||
|
||||
fallback = (int) strtol(line, &line, 16);
|
||||
@@ -1763,8 +1781,11 @@ LoadTableEncoding(
|
||||
for (i = 0; i < numPages; i++) {
|
||||
int ch;
|
||||
const char *p;
|
||||
int expected = 3 + 16 * (16 * 4 + 1);
|
||||
|
||||
Tcl_ReadChars(chan, objPtr, 3 + 16 * (16 * 4 + 1), 0);
|
||||
if (Tcl_ReadChars(chan, objPtr, expected, 0) != expected) {
|
||||
return NULL;
|
||||
}
|
||||
p = TclGetString(objPtr);
|
||||
hi = (staticHex[UCHAR(p[0])] << 4) + staticHex[UCHAR(p[1])];
|
||||
dataPtr->toUnicode[hi] = pageMemPtr;
|
||||
@@ -2052,13 +2073,13 @@ LoadEscapeEncoding(
|
||||
+ Tcl_DStringLength(&escapeData);
|
||||
dataPtr = ckalloc(size);
|
||||
dataPtr->initLen = strlen(init);
|
||||
memcpy(dataPtr->init, init, (unsigned) dataPtr->initLen + 1);
|
||||
memcpy(dataPtr->init, init, dataPtr->initLen + 1);
|
||||
dataPtr->finalLen = strlen(final);
|
||||
memcpy(dataPtr->final, final, (unsigned) dataPtr->finalLen + 1);
|
||||
memcpy(dataPtr->final, final, dataPtr->finalLen + 1);
|
||||
dataPtr->numSubTables =
|
||||
Tcl_DStringLength(&escapeData) / sizeof(EscapeSubTable);
|
||||
memcpy(dataPtr->subTables, Tcl_DStringValue(&escapeData),
|
||||
(size_t) Tcl_DStringLength(&escapeData));
|
||||
Tcl_DStringLength(&escapeData));
|
||||
Tcl_DStringFree(&escapeData);
|
||||
|
||||
memset(dataPtr->prefixBytes, 0, sizeof(dataPtr->prefixBytes));
|
||||
@@ -2146,7 +2167,7 @@ BinaryProc(
|
||||
*srcReadPtr = srcLen;
|
||||
*dstWrotePtr = srcLen;
|
||||
*dstCharsPtr = srcLen;
|
||||
memcpy(dst, src, (size_t) srcLen);
|
||||
memcpy(dst, src, srcLen);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -2363,8 +2384,8 @@ UtfToUtfProc(
|
||||
src += len;
|
||||
dst += Tcl_UniCharToUtf(*chPtr, dst);
|
||||
#if TCL_UTF_MAX <= 4
|
||||
if (!len) {
|
||||
src += TclUtfToUniChar(src, chPtr);
|
||||
if ((*chPtr >= 0xD800) && (len < 3)) {
|
||||
src += TclUtfToUniChar(src + len, chPtr);
|
||||
dst += Tcl_UniCharToUtf(*chPtr, dst);
|
||||
}
|
||||
#endif
|
||||
@@ -2380,7 +2401,7 @@ UtfToUtfProc(
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* UnicodeToUtfProc --
|
||||
* UniCharToUtfProc --
|
||||
*
|
||||
* Convert from Unicode to UTF-8.
|
||||
*
|
||||
@@ -2394,7 +2415,7 @@ UtfToUtfProc(
|
||||
*/
|
||||
|
||||
static int
|
||||
UnicodeToUtfProc(
|
||||
UniCharToUtfProc(
|
||||
ClientData clientData, /* Not used. */
|
||||
const char *src, /* Source string in Unicode. */
|
||||
int srcLen, /* Source string length in bytes. */
|
||||
@@ -2423,19 +2444,16 @@ UnicodeToUtfProc(
|
||||
const char *srcStart, *srcEnd;
|
||||
const char *dstEnd, *dstStart;
|
||||
int result, numChars, charLimit = INT_MAX;
|
||||
Tcl_UniChar *chPtr = (Tcl_UniChar *) statePtr;
|
||||
unsigned short ch;
|
||||
|
||||
if (flags & TCL_ENCODING_START) {
|
||||
*statePtr = 0;
|
||||
}
|
||||
if (flags & TCL_ENCODING_CHAR_LIMIT) {
|
||||
charLimit = *dstCharsPtr;
|
||||
}
|
||||
result = TCL_OK;
|
||||
if ((srcLen % sizeof(Tcl_UniChar)) != 0) {
|
||||
if ((srcLen % sizeof(unsigned short)) != 0) {
|
||||
result = TCL_CONVERT_MULTIBYTE;
|
||||
srcLen /= sizeof(Tcl_UniChar);
|
||||
srcLen *= sizeof(Tcl_UniChar);
|
||||
srcLen /= sizeof(unsigned short);
|
||||
srcLen *= sizeof(unsigned short);
|
||||
}
|
||||
|
||||
srcStart = src;
|
||||
@@ -2452,16 +2470,16 @@ UnicodeToUtfProc(
|
||||
|
||||
/*
|
||||
* Special case for 1-byte utf chars for speed. Make sure we work with
|
||||
* Tcl_UniChar-size data.
|
||||
* unsigned short-size data.
|
||||
*/
|
||||
|
||||
*chPtr = *(Tcl_UniChar *)src;
|
||||
if (*chPtr && *chPtr < 0x80) {
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
ch = *(unsigned short *)src;
|
||||
if (ch && ch < 0x80) {
|
||||
*dst++ = (ch & 0xFF);
|
||||
} else {
|
||||
dst += Tcl_UniCharToUtf(*chPtr, dst);
|
||||
dst += Tcl_UniCharToUtf(ch, dst);
|
||||
}
|
||||
src += sizeof(Tcl_UniChar);
|
||||
src += sizeof(unsigned short);
|
||||
}
|
||||
|
||||
*srcReadPtr = src - srcStart;
|
||||
@@ -2473,7 +2491,7 @@ UnicodeToUtfProc(
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
*
|
||||
* UtfToUnicodeProc --
|
||||
* UtfToUniCharProc --
|
||||
*
|
||||
* Convert from UTF-8 to Unicode.
|
||||
*
|
||||
@@ -2487,7 +2505,7 @@ UnicodeToUtfProc(
|
||||
*/
|
||||
|
||||
static int
|
||||
UtfToUnicodeProc(
|
||||
UtfToUniCharProc(
|
||||
ClientData clientData, /* TableEncodingData that specifies
|
||||
* encoding. */
|
||||
const char *src, /* Source string in UTF-8. */
|
||||
@@ -2555,20 +2573,30 @@ UtfToUnicodeProc(
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#if TCL_UTF_MAX > 4
|
||||
*dst++ = (*chPtr >> 24);
|
||||
*dst++ = ((*chPtr >> 16) & 0xFF);
|
||||
*dst++ = ((*chPtr >> 8) & 0xFF);
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
if (*chPtr <= 0xFFFF) {
|
||||
*dst++ = (*chPtr >> 8);
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
} else {
|
||||
*dst++ = ((*chPtr & 0x3) >> 8) | 0xDC;
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
*dst++ = (((*chPtr - 0x10000) >> 18) & 0x3) | 0xD8;
|
||||
*dst++ = (((*chPtr - 0x10000) >> 10) & 0xFF);
|
||||
}
|
||||
#else
|
||||
*dst++ = (*chPtr >> 8);
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
#endif
|
||||
#else
|
||||
#if TCL_UTF_MAX > 4
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
*dst++ = ((*chPtr >> 8) & 0xFF);
|
||||
*dst++ = ((*chPtr >> 16) & 0xFF);
|
||||
*dst++ = (*chPtr >> 24);
|
||||
if (*chPtr <= 0xFFFF) {
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
*dst++ = (*chPtr >> 8);
|
||||
} else {
|
||||
*dst++ = (((*chPtr - 0x10000) >> 10) & 0xFF);
|
||||
*dst++ = (((*chPtr - 0x10000) >> 18) & 0x3) | 0xD8;
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
*dst++ = ((*chPtr & 0x3) >> 8) | 0xDC;
|
||||
}
|
||||
#else
|
||||
*dst++ = (*chPtr & 0xFF);
|
||||
*dst++ = (*chPtr >> 8);
|
||||
@@ -2985,7 +3013,7 @@ Iso88591FromUtfProc(
|
||||
|
||||
if (ch > 0xff
|
||||
#if TCL_UTF_MAX <= 4
|
||||
|| !len
|
||||
|| ((ch >= 0xD800) && (len < 3))
|
||||
#endif
|
||||
) {
|
||||
if (flags & TCL_ENCODING_STOPONERROR) {
|
||||
@@ -2993,7 +3021,7 @@ Iso88591FromUtfProc(
|
||||
break;
|
||||
}
|
||||
#if TCL_UTF_MAX <= 4
|
||||
if (!len) len = 4;
|
||||
if ((ch >= 0xD800) && (len < 3)) len = 4;
|
||||
#endif
|
||||
/*
|
||||
* Plunge on, using '?' as a fallback character.
|
||||
@@ -3343,7 +3371,7 @@ EscapeFromUtfProc(
|
||||
*dstWrotePtr = 0;
|
||||
return TCL_CONVERT_NOSPACE;
|
||||
}
|
||||
memcpy(dst, dataPtr->init, (size_t)dataPtr->initLen);
|
||||
memcpy(dst, dataPtr->init, dataPtr->initLen);
|
||||
dst += dataPtr->initLen;
|
||||
} else {
|
||||
state = PTR2INT(*statePtr);
|
||||
@@ -3422,7 +3450,7 @@ EscapeFromUtfProc(
|
||||
break;
|
||||
}
|
||||
memcpy(dst, subTablePtr->sequence,
|
||||
(size_t) subTablePtr->sequenceLen);
|
||||
subTablePtr->sequenceLen);
|
||||
dst += subTablePtr->sequenceLen;
|
||||
}
|
||||
}
|
||||
@@ -3465,7 +3493,7 @@ EscapeFromUtfProc(
|
||||
memcpy(dst, dataPtr->subTables[0].sequence, len);
|
||||
dst += len;
|
||||
}
|
||||
memcpy(dst, dataPtr->final, (size_t) dataPtr->finalLen);
|
||||
memcpy(dst, dataPtr->final, dataPtr->finalLen);
|
||||
dst += dataPtr->finalLen;
|
||||
state &= ~TCL_ENCODING_END;
|
||||
}
|
||||
|
||||
+54
-27
@@ -84,6 +84,21 @@ static const Tcl_ObjType ensembleCmdType = {
|
||||
NULL /* setFromAnyProc */
|
||||
};
|
||||
|
||||
#define ECRSetIntRep(objPtr, ecRepPtr) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (ecRepPtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((objPtr), &ensembleCmdType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define ECRGetIntRep(objPtr, ecRepPtr) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), &ensembleCmdType); \
|
||||
(ecRepPtr) = irPtr ? irPtr->twoPtrValue.ptr1 : NULL; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* The internal rep for caching ensemble subcommand lookups and spelling
|
||||
* corrections.
|
||||
@@ -1742,10 +1757,10 @@ NsEnsembleImplementationCmdNR(
|
||||
* check here, and if we're still valid, we can jump straight to the
|
||||
* part where we do the invocation of the subcommand.
|
||||
*/
|
||||
EnsembleCmdRep *ensembleCmd;
|
||||
|
||||
if (subObj->typePtr==&ensembleCmdType){
|
||||
EnsembleCmdRep *ensembleCmd = subObj->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
ECRGetIntRep(subObj, ensembleCmd);
|
||||
if (ensembleCmd) {
|
||||
if (ensembleCmd->epoch == ensemblePtr->epoch &&
|
||||
ensembleCmd->token == (Command *)ensemblePtr->token) {
|
||||
prefixObj = Tcl_GetHashValue(ensembleCmd->hPtr);
|
||||
@@ -1800,7 +1815,7 @@ NsEnsembleImplementationCmdNR(
|
||||
for (i=0 ; i<tableLength ; i++) {
|
||||
register int cmp = strncmp(subcmdName,
|
||||
ensemblePtr->subcommandArrayPtr[i],
|
||||
(unsigned) stringLength);
|
||||
stringLength);
|
||||
|
||||
if (cmp == 0) {
|
||||
if (fullName != NULL) {
|
||||
@@ -2064,8 +2079,8 @@ TclResetRewriteEnsemble(
|
||||
*
|
||||
* TclSpellFix --
|
||||
*
|
||||
* Record a spelling correction that needs making in the
|
||||
* generation of the WrongNumArgs usage message.
|
||||
* Record a spelling correction that needs making in the generation of
|
||||
* the WrongNumArgs usage message.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -2082,9 +2097,10 @@ FreeER(
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
Tcl_Obj **tmp = (Tcl_Obj **)data[0];
|
||||
Tcl_Obj **tmp = (Tcl_Obj **) data[0];
|
||||
Tcl_Obj **store = (Tcl_Obj **) data[1];
|
||||
|
||||
ckfree(tmp[2]);
|
||||
ckfree(store);
|
||||
ckfree(tmp);
|
||||
return result;
|
||||
}
|
||||
@@ -2120,8 +2136,9 @@ TclSpellFix(
|
||||
search = iPtr->ensembleRewrite.sourceObjs;
|
||||
if (search[0] == NULL) {
|
||||
/*
|
||||
* Awful casting abuse here...
|
||||
* Awful casting abuse here!
|
||||
*/
|
||||
|
||||
search = (Tcl_Obj *const *) search[1];
|
||||
}
|
||||
|
||||
@@ -2142,7 +2159,10 @@ TclSpellFix(
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
/* Jump to the misspelled value. */
|
||||
/*
|
||||
* Jump to the misspelled value.
|
||||
*/
|
||||
|
||||
idx = iPtr->ensembleRewrite.numRemovedObjs + badIdx
|
||||
- iPtr->ensembleRewrite.numInsertedObjs;
|
||||
|
||||
@@ -2155,17 +2175,25 @@ TclSpellFix(
|
||||
search = iPtr->ensembleRewrite.sourceObjs;
|
||||
if (search[0] == NULL) {
|
||||
store = (Tcl_Obj **) search[2];
|
||||
} else {
|
||||
} else {
|
||||
Tcl_Obj **tmp = ckalloc(3 * sizeof(Tcl_Obj *));
|
||||
|
||||
store = ckalloc(size * sizeof(Tcl_Obj *));
|
||||
memcpy(store, iPtr->ensembleRewrite.sourceObjs,
|
||||
size * sizeof(Tcl_Obj *));
|
||||
|
||||
/*
|
||||
* Awful casting abuse here! Note that the NULL in the first element
|
||||
* indicates that the initial objects are a raw array in the second
|
||||
* element and the rewritten ones are a raw array in the third.
|
||||
*/
|
||||
|
||||
tmp[0] = NULL;
|
||||
tmp[1] = (Tcl_Obj *) iPtr->ensembleRewrite.sourceObjs;
|
||||
tmp[2] = (Tcl_Obj *) ckalloc(size * sizeof(Tcl_Obj *));
|
||||
memcpy(tmp[2], tmp[1], size * sizeof(Tcl_Obj *));
|
||||
|
||||
tmp[2] = (Tcl_Obj *) store;
|
||||
iPtr->ensembleRewrite.sourceObjs = (Tcl_Obj *const *) tmp;
|
||||
TclNRAddCallback(interp, FreeER, tmp, NULL, NULL, NULL);
|
||||
store = (Tcl_Obj **)tmp[2];
|
||||
|
||||
TclNRAddCallback(interp, FreeER, tmp, store, NULL, NULL);
|
||||
}
|
||||
|
||||
store[idx] = fix;
|
||||
@@ -2378,8 +2406,8 @@ MakeCachedEnsembleCommand(
|
||||
{
|
||||
register EnsembleCmdRep *ensembleCmd;
|
||||
|
||||
if (objPtr->typePtr == &ensembleCmdType) {
|
||||
ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ECRGetIntRep(objPtr, ensembleCmd);
|
||||
if (ensembleCmd) {
|
||||
TclCleanupCommandMacro(ensembleCmd->token);
|
||||
if (ensembleCmd->fix) {
|
||||
Tcl_DecrRefCount(ensembleCmd->fix);
|
||||
@@ -2390,10 +2418,8 @@ MakeCachedEnsembleCommand(
|
||||
* our own.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
ensembleCmd = ckalloc(sizeof(EnsembleCmdRep));
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = ensembleCmd;
|
||||
objPtr->typePtr = &ensembleCmdType;
|
||||
ECRSetIntRep(objPtr, ensembleCmd);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2743,7 +2769,7 @@ BuildEnsembleConfig(
|
||||
hPtr = Tcl_NextHashEntry(&search);
|
||||
}
|
||||
if (hash->numEntries > 1) {
|
||||
qsort(ensemblePtr->subcommandArrayPtr, (unsigned) hash->numEntries,
|
||||
qsort(ensemblePtr->subcommandArrayPtr, hash->numEntries,
|
||||
sizeof(char *), NsEnsembleStringOrder);
|
||||
}
|
||||
}
|
||||
@@ -2797,14 +2823,14 @@ static void
|
||||
FreeEnsembleCmdRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
EnsembleCmdRep *ensembleCmd;
|
||||
|
||||
ECRGetIntRep(objPtr, ensembleCmd);
|
||||
TclCleanupCommandMacro(ensembleCmd->token);
|
||||
if (ensembleCmd->fix) {
|
||||
Tcl_DecrRefCount(ensembleCmd->fix);
|
||||
}
|
||||
ckfree(ensembleCmd);
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2830,11 +2856,12 @@ DupEnsembleCmdRep(
|
||||
Tcl_Obj *objPtr,
|
||||
Tcl_Obj *copyPtr)
|
||||
{
|
||||
EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
EnsembleCmdRep *ensembleCmd;
|
||||
EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep));
|
||||
|
||||
copyPtr->typePtr = &ensembleCmdType;
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy;
|
||||
ECRGetIntRep(objPtr, ensembleCmd);
|
||||
ECRSetIntRep(copyPtr, ensembleCopy);
|
||||
|
||||
ensembleCopy->epoch = ensembleCmd->epoch;
|
||||
ensembleCopy->token = ensembleCmd->token;
|
||||
ensembleCopy->token->refCount++;
|
||||
|
||||
+19
-6
@@ -119,7 +119,8 @@ TclSetupEnv(
|
||||
Tcl_MutexLock(&envMutex);
|
||||
for (i = 0; environ[i] != NULL; i++) {
|
||||
Tcl_Obj *obj1, *obj2;
|
||||
char *p1, *p2;
|
||||
const char *p1;
|
||||
char *p2;
|
||||
|
||||
p1 = Tcl_ExternalToUtfDString(NULL, environ[i], -1, &envString);
|
||||
p2 = strchr(p1, '=');
|
||||
@@ -135,6 +136,18 @@ TclSetupEnv(
|
||||
}
|
||||
p2++;
|
||||
p2[-1] = '\0';
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
* Enforce PATH and COMSPEC to be all uppercase. This eliminates
|
||||
* additional trace logic otherwise required in init.tcl.
|
||||
*/
|
||||
|
||||
if (strcasecmp(p1, "PATH") == 0) {
|
||||
p1 = "PATH";
|
||||
} else if (strcasecmp(p1, "COMSPEC") == 0) {
|
||||
p1 = "COMSPEC";
|
||||
}
|
||||
#endif
|
||||
obj1 = Tcl_NewStringObj(p1, -1);
|
||||
obj2 = Tcl_NewStringObj(p2, -1);
|
||||
Tcl_DStringFree(&envString);
|
||||
@@ -260,7 +273,7 @@ TclSetEnv(
|
||||
Tcl_DStringFree(&envString);
|
||||
|
||||
oldValue = environ[index];
|
||||
nameLength = (unsigned) length;
|
||||
nameLength = length;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -281,7 +294,7 @@ TclSetEnv(
|
||||
*/
|
||||
|
||||
p = ckrealloc(p, Tcl_DStringLength(&envString) + 1);
|
||||
memcpy(p, p2, (unsigned) Tcl_DStringLength(&envString) + 1);
|
||||
memcpy(p, p2, Tcl_DStringLength(&envString) + 1);
|
||||
Tcl_DStringFree(&envString);
|
||||
|
||||
#ifdef USE_PUTENV
|
||||
@@ -442,19 +455,19 @@ TclUnsetEnv(
|
||||
|
||||
#if defined(_WIN32)
|
||||
string = ckalloc(length + 2);
|
||||
memcpy(string, name, (size_t) length);
|
||||
memcpy(string, name, length);
|
||||
string[length] = '=';
|
||||
string[length+1] = '\0';
|
||||
#else
|
||||
string = ckalloc(length + 1);
|
||||
memcpy(string, name, (size_t) length);
|
||||
memcpy(string, name, length);
|
||||
string[length] = '\0';
|
||||
#endif /* _WIN32 */
|
||||
|
||||
Tcl_UtfToExternalDString(NULL, string, -1, &envString);
|
||||
string = ckrealloc(string, Tcl_DStringLength(&envString) + 1);
|
||||
memcpy(string, Tcl_DStringValue(&envString),
|
||||
(unsigned) Tcl_DStringLength(&envString)+1);
|
||||
Tcl_DStringLength(&envString)+1);
|
||||
Tcl_DStringFree(&envString);
|
||||
|
||||
putenv(string);
|
||||
|
||||
@@ -139,6 +139,8 @@ static void FinalizeThread(int quick);
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
#undef Tcl_BackgroundError
|
||||
void
|
||||
Tcl_BackgroundError(
|
||||
Tcl_Interp *interp) /* Interpreter in which an error has
|
||||
@@ -146,6 +148,7 @@ Tcl_BackgroundError(
|
||||
{
|
||||
Tcl_BackgroundException(interp, TCL_ERROR);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
void
|
||||
Tcl_BackgroundException(
|
||||
|
||||
+239
-384
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -180,7 +180,7 @@ FileCopyRename(
|
||||
}
|
||||
jargv[0] = objv[objc - 1];
|
||||
jargv[1] = source;
|
||||
newFileName = TclJoinPath(2, jargv);
|
||||
newFileName = TclJoinPath(2, jargv, 1);
|
||||
Tcl_IncrRefCount(newFileName);
|
||||
result = CopyRenameOneFile(interp, objv[i], newFileName, copyFlag,
|
||||
force);
|
||||
|
||||
@@ -598,7 +598,7 @@ Tcl_SplitPath(
|
||||
for (i = 0; i < *argcPtr; i++) {
|
||||
Tcl_ListObjIndex(NULL, resultPtr, i, &eltPtr);
|
||||
str = TclGetStringFromObj(eltPtr, &len);
|
||||
memcpy(p, str, (size_t) len+1);
|
||||
memcpy(p, str, len+1);
|
||||
p += len+1;
|
||||
}
|
||||
|
||||
@@ -808,24 +808,24 @@ Tcl_FSJoinToPath(
|
||||
Tcl_Obj *const objv[]) /* Path elements to join. */
|
||||
{
|
||||
if (pathPtr == NULL) {
|
||||
return TclJoinPath(objc, objv);
|
||||
return TclJoinPath(objc, objv, 0);
|
||||
}
|
||||
if (objc == 0) {
|
||||
return TclJoinPath(1, &pathPtr);
|
||||
return TclJoinPath(1, &pathPtr, 0);
|
||||
}
|
||||
if (objc == 1) {
|
||||
Tcl_Obj *pair[2];
|
||||
|
||||
pair[0] = pathPtr;
|
||||
pair[1] = objv[0];
|
||||
return TclJoinPath(2, pair);
|
||||
return TclJoinPath(2, pair, 0);
|
||||
} else {
|
||||
int elemc = objc + 1;
|
||||
Tcl_Obj *ret, **elemv = ckalloc(elemc*sizeof(Tcl_Obj *));
|
||||
|
||||
elemv[0] = pathPtr;
|
||||
memcpy(elemv+1, objv, objc*sizeof(Tcl_Obj *));
|
||||
ret = TclJoinPath(elemc, elemv);
|
||||
ret = TclJoinPath(elemc, elemv, 0);
|
||||
ckfree(elemv);
|
||||
return ret;
|
||||
}
|
||||
@@ -2548,21 +2548,21 @@ unsigned
|
||||
Tcl_GetFSDeviceFromStat(
|
||||
const Tcl_StatBuf *statPtr)
|
||||
{
|
||||
return (unsigned) statPtr->st_dev;
|
||||
return statPtr->st_dev;
|
||||
}
|
||||
|
||||
unsigned
|
||||
Tcl_GetFSInodeFromStat(
|
||||
const Tcl_StatBuf *statPtr)
|
||||
{
|
||||
return (unsigned) statPtr->st_ino;
|
||||
return statPtr->st_ino;
|
||||
}
|
||||
|
||||
unsigned
|
||||
Tcl_GetModeFromStat(
|
||||
const Tcl_StatBuf *statPtr)
|
||||
{
|
||||
return (unsigned) statPtr->st_mode;
|
||||
return statPtr->st_mode;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -2639,7 +2639,7 @@ Tcl_GetBlockSizeFromStat(
|
||||
const Tcl_StatBuf *statPtr)
|
||||
{
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
return (unsigned) statPtr->st_blksize;
|
||||
return statPtr->st_blksize;
|
||||
#else
|
||||
/*
|
||||
* Not a great guess, but will do...
|
||||
|
||||
@@ -897,7 +897,7 @@ TclDatelex(
|
||||
|
||||
location->first_column = yyInput - info->dateStart;
|
||||
for ( ; ; ) {
|
||||
while (isspace(UCHAR(*yyInput))) {
|
||||
while (TclIsSpaceProc(UCHAR(*yyInput))) {
|
||||
yyInput++;
|
||||
}
|
||||
|
||||
@@ -960,7 +960,7 @@ TclDatelex(
|
||||
|
||||
int
|
||||
TclClockOldscanObjCmd(
|
||||
ClientData clientData, /* Unused */
|
||||
void *clientData, /* Unused */
|
||||
Tcl_Interp *interp, /* Tcl interpreter */
|
||||
int objc, /* Count of paraneters */
|
||||
Tcl_Obj *const *objv) /* Parameters */
|
||||
|
||||
+2
-2
@@ -1015,8 +1015,8 @@ RebuildTable(
|
||||
|
||||
tablePtr->numBuckets *= 4;
|
||||
if (typePtr->flags & TCL_HASH_KEY_SYSTEM_HASH) {
|
||||
tablePtr->buckets = (Tcl_HashEntry **) TclpSysAlloc((unsigned)
|
||||
(tablePtr->numBuckets * sizeof(Tcl_HashEntry *)), 0);
|
||||
tablePtr->buckets = (Tcl_HashEntry **) TclpSysAlloc(
|
||||
tablePtr->numBuckets * sizeof(Tcl_HashEntry *), 0);
|
||||
} else {
|
||||
tablePtr->buckets =
|
||||
ckalloc(tablePtr->numBuckets * sizeof(Tcl_HashEntry *));
|
||||
|
||||
+36
-23
@@ -337,6 +337,22 @@ static const Tcl_ObjType chanObjType = {
|
||||
NULL /* setFromAnyProc */
|
||||
};
|
||||
|
||||
#define ChanSetIntRep(objPtr, resPtr) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
(resPtr)->refCount++; \
|
||||
ir.twoPtrValue.ptr1 = (resPtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((objPtr), &chanObjType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define ChanGetIntRep(objPtr, resPtr) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), &chanObjType); \
|
||||
(resPtr) = irPtr ? irPtr->twoPtrValue.ptr1 : NULL; \
|
||||
} while (0)
|
||||
|
||||
#define BUSY_STATE(st, fl) \
|
||||
((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \
|
||||
(((st)->csPtrW) && ((fl) & TCL_WRITABLE)))
|
||||
@@ -1515,12 +1531,12 @@ TclGetChannelFromObj(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (objPtr->typePtr == &chanObjType) {
|
||||
ChanGetIntRep(objPtr, resPtr);
|
||||
if (resPtr) {
|
||||
/*
|
||||
* Confirm validity of saved lookup results.
|
||||
*/
|
||||
|
||||
resPtr = (ResolvedChanName *) objPtr->internalRep.twoPtrValue.ptr1;
|
||||
statePtr = resPtr->statePtr;
|
||||
if ((resPtr->interp == interp) /* Same interp context */
|
||||
/* No epoch change in channel since lookup */
|
||||
@@ -1537,7 +1553,7 @@ TclGetChannelFromObj(
|
||||
|
||||
if (chan == NULL) {
|
||||
if (resPtr) {
|
||||
FreeChannelIntRep(objPtr);
|
||||
Tcl_StoreIntRep(objPtr, &chanObjType, NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1548,14 +1564,10 @@ TclGetChannelFromObj(
|
||||
*/
|
||||
|
||||
Tcl_Release((ClientData) resPtr->statePtr);
|
||||
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
|
||||
resPtr = (ResolvedChanName *) ckalloc(sizeof(ResolvedChanName));
|
||||
resPtr->refCount = 1;
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = (ClientData) resPtr;
|
||||
objPtr->typePtr = &chanObjType;
|
||||
resPtr->refCount = 0;
|
||||
ChanSetIntRep(objPtr, resPtr); /* Overwrites, if needed */
|
||||
}
|
||||
statePtr = ((Channel *)chan)->state;
|
||||
resPtr->statePtr = statePtr;
|
||||
@@ -4308,7 +4320,7 @@ Write(
|
||||
* that we need to stick at the beginning of this buffer.
|
||||
*/
|
||||
|
||||
memcpy(InsertPoint(bufPtr), safe, (size_t) saved);
|
||||
memcpy(InsertPoint(bufPtr), safe, saved);
|
||||
bufPtr->nextAdded += saved;
|
||||
saved = 0;
|
||||
}
|
||||
@@ -4396,7 +4408,7 @@ Write(
|
||||
*/
|
||||
|
||||
saved = -SpaceLeft(bufPtr);
|
||||
memcpy(safe, dst + dstLen, (size_t) saved);
|
||||
memcpy(safe, dst + dstLen, saved);
|
||||
bufPtr->nextAdded = bufPtr->bufLength;
|
||||
}
|
||||
|
||||
@@ -5074,7 +5086,7 @@ TclGetsObjBinary(
|
||||
|
||||
rawLen = dstEnd - dst;
|
||||
byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen);
|
||||
memcpy(byteArray + byteLen, dst, (size_t) rawLen);
|
||||
memcpy(byteArray + byteLen, dst, rawLen);
|
||||
byteLen += rawLen;
|
||||
}
|
||||
|
||||
@@ -5091,7 +5103,7 @@ TclGetsObjBinary(
|
||||
|
||||
rawLen = eol - dst;
|
||||
byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen);
|
||||
memcpy(byteArray + byteLen, dst, (size_t) rawLen);
|
||||
memcpy(byteArray + byteLen, dst, rawLen);
|
||||
byteLen += rawLen;
|
||||
bufPtr->nextRemoved += rawLen + skip;
|
||||
|
||||
@@ -5642,7 +5654,7 @@ Tcl_ReadRaw(
|
||||
* Copy the current chunk into the read buffer.
|
||||
*/
|
||||
|
||||
memcpy(readBuf, RemovePoint(bufPtr), (size_t) toCopy);
|
||||
memcpy(readBuf, RemovePoint(bufPtr), toCopy);
|
||||
bufPtr->nextRemoved += toCopy;
|
||||
copied += toCopy;
|
||||
readBuf += toCopy;
|
||||
@@ -6390,7 +6402,7 @@ ReadChars(
|
||||
}
|
||||
|
||||
nextPtr->nextRemoved -= srcLen;
|
||||
memcpy(RemovePoint(nextPtr), src, (size_t) srcLen);
|
||||
memcpy(RemovePoint(nextPtr), src, srcLen);
|
||||
RecycleBuffer(statePtr, bufPtr, 0);
|
||||
statePtr->inQueueHead = nextPtr;
|
||||
Tcl_SetObjLength(objPtr, numBytes);
|
||||
@@ -6496,7 +6508,7 @@ TranslateInputEOL(
|
||||
case TCL_TRANSLATE_LF:
|
||||
case TCL_TRANSLATE_CR:
|
||||
if (dstStart != srcStart) {
|
||||
memcpy(dstStart, srcStart, (size_t) srcLen);
|
||||
memcpy(dstStart, srcStart, srcLen);
|
||||
}
|
||||
if (statePtr->inputTranslation == TCL_TRANSLATE_CR) {
|
||||
char *dst = dstStart;
|
||||
@@ -6653,7 +6665,7 @@ Tcl_Ungets(
|
||||
statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
|
||||
|
||||
bufPtr = AllocChannelBuffer(len);
|
||||
memcpy(InsertPoint(bufPtr), str, (size_t) len);
|
||||
memcpy(InsertPoint(bufPtr), str, len);
|
||||
bufPtr->nextAdded += len;
|
||||
|
||||
if (statePtr->inQueueHead == NULL) {
|
||||
@@ -11198,11 +11210,11 @@ DupChannelIntRep(
|
||||
register Tcl_Obj *copyPtr) /* Object with internal rep to set. Must not
|
||||
* currently have an internal rep.*/
|
||||
{
|
||||
ResolvedChanName *resPtr = srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
ResolvedChanName *resPtr;
|
||||
|
||||
resPtr->refCount++;
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = resPtr;
|
||||
copyPtr->typePtr = srcPtr->typePtr;
|
||||
ChanGetIntRep(srcPtr, resPtr);
|
||||
assert(resPtr);
|
||||
ChanSetIntRep(copyPtr, resPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -11225,9 +11237,10 @@ static void
|
||||
FreeChannelIntRep(
|
||||
Tcl_Obj *objPtr) /* Object with internal rep to free. */
|
||||
{
|
||||
ResolvedChanName *resPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ResolvedChanName *resPtr;
|
||||
|
||||
objPtr->typePtr = NULL;
|
||||
ChanGetIntRep(objPtr, resPtr);
|
||||
assert(resPtr);
|
||||
if (resPtr->refCount-- > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
+1
-1
@@ -96,7 +96,7 @@ typedef struct EventScriptRecord {
|
||||
|
||||
typedef struct Channel {
|
||||
struct ChannelState *state; /* Split out state information */
|
||||
ClientData instanceData; /* Instance-specific data provided by creator
|
||||
void *instanceData; /* Instance-specific data provided by creator
|
||||
* of channel. */
|
||||
const Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */
|
||||
struct Channel *downChanPtr;/* Refers to channel this one was stacked
|
||||
|
||||
+1
-1
@@ -952,7 +952,7 @@ Tcl_ExecObjCmd(
|
||||
*/
|
||||
|
||||
argc = objc - skip;
|
||||
argv = TclStackAlloc(interp, (unsigned)(argc + 1) * sizeof(char *));
|
||||
argv = TclStackAlloc(interp, (argc + 1) * sizeof(char *));
|
||||
|
||||
/*
|
||||
* Copy the string conversions of each (post option) object into the
|
||||
|
||||
@@ -1326,7 +1326,7 @@ ReflectInput(
|
||||
*errorCodePtr = EOK;
|
||||
|
||||
if (bytec > 0) {
|
||||
memcpy(buf, bytev, (size_t) bytec);
|
||||
memcpy(buf, bytev, bytec);
|
||||
}
|
||||
|
||||
stop:
|
||||
@@ -3008,7 +3008,7 @@ ForwardProc(
|
||||
paramPtr->input.toRead = -1;
|
||||
} else {
|
||||
if (bytec > 0) {
|
||||
memcpy(paramPtr->input.buf, bytev, (size_t) bytec);
|
||||
memcpy(paramPtr->input.buf, bytev, bytec);
|
||||
}
|
||||
paramPtr->input.toRead = bytec;
|
||||
}
|
||||
@@ -3298,7 +3298,7 @@ ForwardSetObjError(
|
||||
|
||||
len++;
|
||||
ForwardSetDynamicError(paramPtr, ckalloc(len));
|
||||
memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len);
|
||||
memcpy(paramPtr->base.msgStr, msgStr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -2607,7 +2607,7 @@ ForwardProc(
|
||||
|
||||
if (bytec > 0) {
|
||||
paramPtr->transform.buf = ckalloc(bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, bytec);
|
||||
} else {
|
||||
paramPtr->transform.buf = NULL;
|
||||
}
|
||||
@@ -2641,7 +2641,7 @@ ForwardProc(
|
||||
|
||||
if (bytec > 0) {
|
||||
paramPtr->transform.buf = ckalloc(bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, bytec);
|
||||
} else {
|
||||
paramPtr->transform.buf = NULL;
|
||||
}
|
||||
@@ -2670,7 +2670,7 @@ ForwardProc(
|
||||
|
||||
if (bytec > 0) {
|
||||
paramPtr->transform.buf = ckalloc(bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, bytec);
|
||||
} else {
|
||||
paramPtr->transform.buf = NULL;
|
||||
}
|
||||
@@ -2697,7 +2697,7 @@ ForwardProc(
|
||||
|
||||
if (bytec > 0) {
|
||||
paramPtr->transform.buf = ckalloc(bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
|
||||
memcpy(paramPtr->transform.buf, bytev, bytec);
|
||||
} else {
|
||||
paramPtr->transform.buf = NULL;
|
||||
}
|
||||
@@ -2810,7 +2810,7 @@ ForwardSetObjError(
|
||||
|
||||
len++;
|
||||
ForwardSetDynamicError(paramPtr, ckalloc(len));
|
||||
memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len);
|
||||
memcpy(paramPtr->base.msgStr, msgStr, len);
|
||||
}
|
||||
#endif /* TCL_THREADS */
|
||||
|
||||
|
||||
+1
-1
@@ -4699,7 +4699,7 @@ Tcl_FSGetFileSystemForPath(
|
||||
* Tcl_FSGetNativePath --
|
||||
*
|
||||
* This function is for use by the Win/Unix native filesystems, so that
|
||||
* they can easily retrieve the native (char* or TCHAR*) representation
|
||||
* they can easily retrieve the native (char* or WCHAR*) representation
|
||||
* of a path. Other filesystems will probably want to implement similar
|
||||
* functions. They basically act as a safety net around
|
||||
* Tcl_FSGetInternalRep. Normally your file-system functions will always
|
||||
|
||||
+44
-38
@@ -115,14 +115,18 @@ Tcl_GetIndexFromObj(
|
||||
int flags, /* 0 or TCL_EXACT */
|
||||
int *indexPtr) /* Place to store resulting integer index. */
|
||||
{
|
||||
if (!(flags & INDEX_TEMP_TABLE)) {
|
||||
|
||||
/*
|
||||
* See if there is a valid cached result from a previous lookup (doing the
|
||||
* check here saves the overhead of calling Tcl_GetIndexFromObjStruct in
|
||||
* the common case where the result is cached).
|
||||
*/
|
||||
|
||||
if (!(flags & INDEX_TEMP_TABLE) && objPtr->typePtr == &indexType) {
|
||||
IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &indexType);
|
||||
|
||||
if (irPtr) {
|
||||
IndexRep *indexRep = irPtr->twoPtrValue.ptr1;
|
||||
|
||||
/*
|
||||
* Here's hoping we don't get hit by unfortunate packing constraints
|
||||
@@ -135,6 +139,7 @@ Tcl_GetIndexFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, sizeof(char *),
|
||||
msg, flags, indexPtr);
|
||||
}
|
||||
@@ -266,6 +271,7 @@ Tcl_GetIndexFromObjStruct(
|
||||
const char *const *entryPtr;
|
||||
Tcl_Obj *resultPtr;
|
||||
IndexRep *indexRep;
|
||||
const Tcl_ObjIntRep *irPtr;
|
||||
|
||||
/* Protect against invalid values, like -1 or 0. */
|
||||
if (offset < (int)sizeof(char *)) {
|
||||
@@ -275,13 +281,16 @@ Tcl_GetIndexFromObjStruct(
|
||||
* See if there is a valid cached result from a previous lookup.
|
||||
*/
|
||||
|
||||
if (!(flags & INDEX_TEMP_TABLE) && objPtr->typePtr == &indexType) {
|
||||
indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (!(flags & INDEX_TEMP_TABLE)) {
|
||||
irPtr = TclFetchIntRep(objPtr, &indexType);
|
||||
if (irPtr) {
|
||||
indexRep = irPtr->twoPtrValue.ptr1;
|
||||
if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) {
|
||||
*indexPtr = indexRep->index;
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Lookup the value of the object in the table. Accept unique
|
||||
@@ -337,17 +346,19 @@ Tcl_GetIndexFromObjStruct(
|
||||
*/
|
||||
|
||||
if (!(flags & INDEX_TEMP_TABLE)) {
|
||||
if (objPtr->typePtr == &indexType) {
|
||||
indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
indexRep = ckalloc(sizeof(IndexRep));
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = indexRep;
|
||||
objPtr->typePtr = &indexType;
|
||||
}
|
||||
indexRep->tablePtr = (void *) tablePtr;
|
||||
indexRep->offset = offset;
|
||||
indexRep->index = index;
|
||||
irPtr = TclFetchIntRep(objPtr, &indexType);
|
||||
if (irPtr) {
|
||||
indexRep = irPtr->twoPtrValue.ptr1;
|
||||
} else {
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
indexRep = ckalloc(sizeof(IndexRep));
|
||||
ir.twoPtrValue.ptr1 = indexRep;
|
||||
Tcl_StoreIntRep(objPtr, &indexType, &ir);
|
||||
}
|
||||
indexRep->tablePtr = (void *) tablePtr;
|
||||
indexRep->offset = offset;
|
||||
indexRep->index = index;
|
||||
}
|
||||
|
||||
*indexPtr = index;
|
||||
@@ -446,16 +457,10 @@ static void
|
||||
UpdateStringOfIndex(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
register char *buf;
|
||||
register unsigned len;
|
||||
IndexRep *indexRep = TclFetchIntRep(objPtr, &indexType)->twoPtrValue.ptr1;
|
||||
register const char *indexStr = EXPAND_OF(indexRep);
|
||||
|
||||
len = strlen(indexStr);
|
||||
buf = ckalloc(len + 1);
|
||||
memcpy(buf, indexStr, len+1);
|
||||
objPtr->bytes = buf;
|
||||
objPtr->length = len;
|
||||
Tcl_InitStringRep(objPtr, indexStr, strlen(indexStr));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -481,12 +486,14 @@ DupIndex(
|
||||
Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *dupPtr)
|
||||
{
|
||||
IndexRep *srcIndexRep = srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
Tcl_ObjIntRep ir;
|
||||
IndexRep *dupIndexRep = ckalloc(sizeof(IndexRep));
|
||||
|
||||
memcpy(dupIndexRep, srcIndexRep, sizeof(IndexRep));
|
||||
dupPtr->internalRep.twoPtrValue.ptr1 = dupIndexRep;
|
||||
dupPtr->typePtr = &indexType;
|
||||
memcpy(dupIndexRep, TclFetchIntRep(srcPtr, &indexType)->twoPtrValue.ptr1,
|
||||
sizeof(IndexRep));
|
||||
|
||||
ir.twoPtrValue.ptr1 = dupIndexRep;
|
||||
Tcl_StoreIntRep(dupPtr, &indexType, &ir);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -510,7 +517,7 @@ static void
|
||||
FreeIndex(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
ckfree(objPtr->internalRep.twoPtrValue.ptr1);
|
||||
ckfree(TclFetchIntRep(objPtr, &indexType)->twoPtrValue.ptr1);
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
@@ -957,10 +964,10 @@ Tcl_WrongNumArgs(
|
||||
/*
|
||||
* Add the element, quoting it if necessary.
|
||||
*/
|
||||
const Tcl_ObjIntRep *irPtr;
|
||||
|
||||
if (origObjv[i]->typePtr == &indexType) {
|
||||
register IndexRep *indexRep =
|
||||
origObjv[i]->internalRep.twoPtrValue.ptr1;
|
||||
if ((irPtr = TclFetchIntRep(origObjv[i], &indexType))) {
|
||||
register IndexRep *indexRep = irPtr->twoPtrValue.ptr1;
|
||||
|
||||
elementStr = EXPAND_OF(indexRep);
|
||||
elemLen = strlen(elementStr);
|
||||
@@ -971,8 +978,7 @@ Tcl_WrongNumArgs(
|
||||
len = TclScanElement(elementStr, elemLen, &flags);
|
||||
|
||||
if (MAY_QUOTE_WORD && len != elemLen) {
|
||||
char *quotedElementStr = TclStackAlloc(interp,
|
||||
(unsigned)len + 1);
|
||||
char *quotedElementStr = TclStackAlloc(interp, len + 1);
|
||||
|
||||
len = TclConvertElement(elementStr, elemLen,
|
||||
quotedElementStr, flags);
|
||||
@@ -1007,9 +1013,10 @@ Tcl_WrongNumArgs(
|
||||
* the correct error message even if the subcommand was abbreviated.
|
||||
* Otherwise, just use the string rep.
|
||||
*/
|
||||
const Tcl_ObjIntRep *irPtr;
|
||||
|
||||
if (objv[i]->typePtr == &indexType) {
|
||||
register IndexRep *indexRep = objv[i]->internalRep.twoPtrValue.ptr1;
|
||||
if ((irPtr = TclFetchIntRep(objv[i], &indexType))) {
|
||||
register IndexRep *indexRep = irPtr->twoPtrValue.ptr1;
|
||||
|
||||
Tcl_AppendStringsToObj(objPtr, EXPAND_OF(indexRep), NULL);
|
||||
} else {
|
||||
@@ -1022,8 +1029,7 @@ Tcl_WrongNumArgs(
|
||||
len = TclScanElement(elementStr, elemLen, &flags);
|
||||
|
||||
if (MAY_QUOTE_WORD && len != elemLen) {
|
||||
char *quotedElementStr = TclStackAlloc(interp,
|
||||
(unsigned) len + 1);
|
||||
char *quotedElementStr = TclStackAlloc(interp, len + 1);
|
||||
|
||||
len = TclConvertElement(elementStr, elemLen,
|
||||
quotedElementStr, flags);
|
||||
@@ -1456,7 +1462,7 @@ TclGetCompletionCodeFromObj(
|
||||
"ok", "error", "return", "break", "continue", NULL
|
||||
};
|
||||
|
||||
if ((value->typePtr != &indexType)
|
||||
if (!TclHasIntRep(value, &indexType)
|
||||
&& TclGetIntFromObj(NULL, value, codePtr) == TCL_OK) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1024,6 +1024,10 @@ declare 256 {
|
||||
int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr, Tcl_Var arrayPtr,
|
||||
Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, const int flags)
|
||||
}
|
||||
declare 257 {
|
||||
void TclStaticPackage(Tcl_Interp *interp, const char *pkgName,
|
||||
Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc)
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
||||
+108
-72
@@ -120,19 +120,19 @@ typedef int ptrdiff_t;
|
||||
#if !defined(INT2PTR) && !defined(PTR2INT)
|
||||
# if defined(HAVE_INTPTR_T) || defined(intptr_t)
|
||||
# define INT2PTR(p) ((void *)(intptr_t)(p))
|
||||
# define PTR2INT(p) ((int)(intptr_t)(p))
|
||||
# define PTR2INT(p) ((intptr_t)(p))
|
||||
# else
|
||||
# define INT2PTR(p) ((void *)(p))
|
||||
# define PTR2INT(p) ((int)(p))
|
||||
# define PTR2INT(p) ((long)(p))
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(UINT2PTR) && !defined(PTR2UINT)
|
||||
# if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
|
||||
# define UINT2PTR(p) ((void *)(uintptr_t)(p))
|
||||
# define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
|
||||
# define PTR2UINT(p) ((uintptr_t)(p))
|
||||
# else
|
||||
# define UINT2PTR(p) ((void *)(p))
|
||||
# define PTR2UINT(p) ((unsigned int)(p))
|
||||
# define PTR2UINT(p) ((unsigned long)(p))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -272,7 +272,7 @@ typedef struct Namespace {
|
||||
* synonym. */
|
||||
char *fullName; /* The namespace's fully qualified name. This
|
||||
* starts with ::. */
|
||||
ClientData clientData; /* An arbitrary value associated with this
|
||||
void *clientData; /* An arbitrary value associated with this
|
||||
* namespace. */
|
||||
Tcl_NamespaceDeleteProc *deleteProc;
|
||||
/* Procedure invoked when deleting the
|
||||
@@ -543,7 +543,7 @@ typedef struct EnsembleConfig {
|
||||
typedef struct VarTrace {
|
||||
Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given by
|
||||
* flags are performed on variable. */
|
||||
ClientData clientData; /* Argument to pass to proc. */
|
||||
void *clientData; /* Argument to pass to proc. */
|
||||
int flags; /* What events the trace procedure is
|
||||
* interested in: OR-ed combination of
|
||||
* TCL_TRACE_READS, TCL_TRACE_WRITES,
|
||||
@@ -562,7 +562,7 @@ typedef struct CommandTrace {
|
||||
Tcl_CommandTraceProc *traceProc;
|
||||
/* Procedure to call when operations given by
|
||||
* flags are performed on command. */
|
||||
ClientData clientData; /* Argument to pass to proc. */
|
||||
void *clientData; /* Argument to pass to proc. */
|
||||
int flags; /* What events the trace procedure is
|
||||
* interested in: OR-ed combination of
|
||||
* TCL_TRACE_RENAME, TCL_TRACE_DELETE. */
|
||||
@@ -939,9 +939,8 @@ typedef struct CompiledLocal {
|
||||
/* Next compiler-recognized local variable for
|
||||
* this procedure, or NULL if this is the last
|
||||
* local. */
|
||||
int nameLength; /* The number of characters in local
|
||||
* variable's name. Used to speed up variable
|
||||
* lookups. */
|
||||
int nameLength; /* The number of bytes in local variable's name.
|
||||
* Among others used to speed up var lookups. */
|
||||
int frameIndex; /* Index in the array of compiler-assigned
|
||||
* variables in the procedure call frame. */
|
||||
int flags; /* Flag bits for the local variable. Same as
|
||||
@@ -955,7 +954,7 @@ typedef struct CompiledLocal {
|
||||
/* Customized variable resolution info
|
||||
* supplied by the Tcl_ResolveCompiledVarProc
|
||||
* associated with a namespace. Each variable
|
||||
* is marked by a unique ClientData tag during
|
||||
* is marked by a unique tag during
|
||||
* compilation, and that same tag is used to
|
||||
* find the variable at runtime. */
|
||||
char name[1]; /* Name of the local variable starts here. If
|
||||
@@ -1016,7 +1015,7 @@ typedef struct Trace {
|
||||
int level; /* Only trace commands at nesting level less
|
||||
* than or equal to this. */
|
||||
Tcl_CmdObjTraceProc *proc; /* Procedure to call to trace command. */
|
||||
ClientData clientData; /* Arbitrary value to pass to proc. */
|
||||
void *clientData; /* Arbitrary value to pass to proc. */
|
||||
struct Trace *nextPtr; /* Next in list of traces for this interp. */
|
||||
int flags; /* Flags governing the trace - see
|
||||
* Tcl_CreateObjTrace for details. */
|
||||
@@ -1068,7 +1067,7 @@ typedef struct ActiveInterpTrace {
|
||||
|
||||
typedef struct AssocData {
|
||||
Tcl_InterpDeleteProc *proc; /* Proc to call when deleting. */
|
||||
ClientData clientData; /* Value to pass to proc. */
|
||||
void *clientData; /* Value to pass to proc. */
|
||||
} AssocData;
|
||||
|
||||
/*
|
||||
@@ -1146,7 +1145,7 @@ typedef struct CallFrame {
|
||||
* recognized by the compiler. The compiler
|
||||
* emits code that refers to these variables
|
||||
* using an index into this array. */
|
||||
ClientData clientData; /* Pointer to some context that is used by
|
||||
void *clientData; /* Pointer to some context that is used by
|
||||
* object systems. The meaning of the contents
|
||||
* of this field is defined by the code that
|
||||
* sets it, and it should only ever be set by
|
||||
@@ -1334,13 +1333,13 @@ typedef struct ContLineLoc {
|
||||
* by [info frame]. Contains a sub-structure for each extra field.
|
||||
*/
|
||||
|
||||
typedef Tcl_Obj * (GetFrameInfoValueProc)(ClientData clientData);
|
||||
typedef Tcl_Obj * (GetFrameInfoValueProc)(void *clientData);
|
||||
typedef struct {
|
||||
const char *name; /* Name of this field. */
|
||||
GetFrameInfoValueProc *proc; /* Function to generate a Tcl_Obj* from the
|
||||
* clientData, or just use the clientData
|
||||
* directly (after casting) if NULL. */
|
||||
ClientData clientData; /* Context for above function, or Tcl_Obj* if
|
||||
void *clientData; /* Context for above function, or Tcl_Obj* if
|
||||
* proc field is NULL. */
|
||||
} ExtraFrameInfoField;
|
||||
typedef struct {
|
||||
@@ -1596,7 +1595,7 @@ typedef struct {
|
||||
Tcl_ObjCmdProc *proc; /* The implementation of the subcommand. */
|
||||
CompileProc *compileProc; /* The compiler for the subcommand. */
|
||||
Tcl_ObjCmdProc *nreProc; /* NRE implementation of this command. */
|
||||
ClientData clientData; /* Any clientData to give the command. */
|
||||
void *clientData; /* Any clientData to give the command. */
|
||||
int unsafe; /* Whether this command is to be hidden by
|
||||
* default in a safe interpreter. */
|
||||
} EnsembleImplMap;
|
||||
@@ -1673,13 +1672,13 @@ typedef struct Command {
|
||||
CompileProc *compileProc; /* Procedure called to compile command. NULL
|
||||
* if no compile proc exists for command. */
|
||||
Tcl_ObjCmdProc *objProc; /* Object-based command procedure. */
|
||||
ClientData objClientData; /* Arbitrary value passed to object proc. */
|
||||
void *objClientData; /* Arbitrary value passed to object proc. */
|
||||
Tcl_CmdProc *proc; /* String-based command procedure. */
|
||||
ClientData clientData; /* Arbitrary value passed to string proc. */
|
||||
void *clientData; /* Arbitrary value passed to string proc. */
|
||||
Tcl_CmdDeleteProc *deleteProc;
|
||||
/* Procedure invoked when deleting command to,
|
||||
* e.g., free all client data. */
|
||||
ClientData deleteData; /* Arbitrary value passed to deleteProc. */
|
||||
void *deleteData; /* Arbitrary value passed to deleteProc. */
|
||||
int flags; /* Miscellaneous bits of information about
|
||||
* command. See below for definitions. */
|
||||
ImportRef *importRefPtr; /* List of each imported Command created in
|
||||
@@ -1845,7 +1844,7 @@ typedef struct Interp {
|
||||
/* Hash table used by tclBasic.c to keep track
|
||||
* of hidden commands on a per-interp
|
||||
* basis. */
|
||||
ClientData interpInfo; /* Information used by tclInterp.c to keep
|
||||
void *interpInfo; /* Information used by tclInterp.c to keep
|
||||
* track of master/slave interps on a
|
||||
* per-interp basis. */
|
||||
union {
|
||||
@@ -2363,6 +2362,13 @@ typedef struct Interp {
|
||||
|
||||
#define TCL_ALIGN(x) (((int)(x) + 7) & ~7)
|
||||
|
||||
/*
|
||||
* A common panic alert when memory allocation fails.
|
||||
*/
|
||||
|
||||
#define TclOOM(ptr, size) \
|
||||
((size) && ((ptr)||(Tcl_Panic("unable to alloc %u bytes", (size)),1)))
|
||||
|
||||
/*
|
||||
* The following enum values are used to specify the runtime platform setting
|
||||
* of the tclPlatform variable.
|
||||
@@ -2437,12 +2443,6 @@ typedef struct List {
|
||||
#define ListRepPtr(listPtr) \
|
||||
((List *) (listPtr)->internalRep.twoPtrValue.ptr1)
|
||||
|
||||
#define ListSetIntRep(objPtr, listRepPtr) \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr1 = (void *)(listRepPtr), \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr2 = NULL, \
|
||||
(listRepPtr)->refCount++, \
|
||||
(objPtr)->typePtr = &tclListType
|
||||
|
||||
#define ListObjGetElements(listPtr, objc, objv) \
|
||||
((objv) = &(ListRepPtr(listPtr)->elements), \
|
||||
(objc) = ListRepPtr(listPtr)->elemCount)
|
||||
@@ -2497,23 +2497,23 @@ typedef struct List {
|
||||
#else
|
||||
#define TclGetLongFromObj(interp, objPtr, longPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(ULONG_MAX) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(ULONG_MAX)) \
|
||||
&& (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(LONG_MIN) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(LONG_MAX)) \
|
||||
? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
: Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
|
||||
#endif
|
||||
|
||||
#define TclGetIntFromObj(interp, objPtr, intPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(UINT_MAX) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(UINT_MAX)) \
|
||||
&& (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
|
||||
? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
: Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
|
||||
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.wideValue >= INT_MIN \
|
||||
&& (objPtr)->internalRep.wideValue <= INT_MAX) \
|
||||
? ((*(idxPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
|
||||
? ((*(idxPtr) = ((objPtr)->internalRep.wideValue >= 0) \
|
||||
? (int)(objPtr)->internalRep.wideValue : -1), TCL_OK) \
|
||||
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
|
||||
|
||||
/*
|
||||
@@ -2526,7 +2526,7 @@ typedef struct List {
|
||||
|
||||
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(wideIntPtr) = (Tcl_WideInt) \
|
||||
? (*(wideIntPtr) = \
|
||||
((objPtr)->internalRep.wideValue), TCL_OK) : \
|
||||
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
|
||||
|
||||
@@ -2709,8 +2709,11 @@ typedef struct ProcessGlobalValue {
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define TCL_NUMBER_LONG 1
|
||||
#define TCL_NUMBER_WIDE 2
|
||||
#define TCL_NUMBER_INT 2
|
||||
#if (TCL_MAJOR_VERSION < 9) && !defined(TCL_NO_DEPRECATED)
|
||||
# define TCL_NUMBER_LONG 1 /* deprecated, not used any more */
|
||||
# define TCL_NUMBER_WIDE TCL_NUMBER_INT /* deprecated */
|
||||
#endif
|
||||
#define TCL_NUMBER_BIG 3
|
||||
#define TCL_NUMBER_DOUBLE 4
|
||||
#define TCL_NUMBER_NAN 5
|
||||
@@ -2747,7 +2750,6 @@ MODULE_SCOPE const Tcl_ObjType tclBooleanType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclByteArrayType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclByteCodeType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclDoubleType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclEndOffsetType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclIntType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclListType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclDictType;
|
||||
@@ -2858,7 +2860,7 @@ typedef struct ForIterData {
|
||||
typedef void* TclFindSymbolProc(Tcl_Interp* interp, Tcl_LoadHandle loadHandle,
|
||||
const char* symbol);
|
||||
struct Tcl_LoadHandle_ {
|
||||
ClientData clientData; /* Client data is the load handle in the
|
||||
void *clientData; /* Client data is the load handle in the
|
||||
* native filesystem if a module was loaded
|
||||
* there, or an opaque pointer to a structure
|
||||
* for further bookkeeping on load-from-VFS
|
||||
@@ -2874,8 +2876,6 @@ struct Tcl_LoadHandle_ {
|
||||
|
||||
#define TCL_DD_SHORTEST 0x4
|
||||
/* Use the shortest possible string */
|
||||
#define TCL_DD_STEELE 0x5
|
||||
/* Use the original Steele&White algorithm */
|
||||
#define TCL_DD_E_FORMAT 0x2
|
||||
/* Use a fixed-length string of digits,
|
||||
* suitable for E format*/
|
||||
@@ -2891,10 +2891,6 @@ struct Tcl_LoadHandle_ {
|
||||
|
||||
#define TCL_DD_CONVERSION_TYPE_MASK 0x3
|
||||
/* Mask to isolate the conversion type */
|
||||
#define TCL_DD_STEELE0 0x1
|
||||
/* 'Steele&White' after masking */
|
||||
#define TCL_DD_SHORTEST0 0x0
|
||||
/* 'Shortest possible' after masking */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -3027,6 +3023,8 @@ MODULE_SCOPE int TclGetChannelFromObj(Tcl_Interp *interp,
|
||||
MODULE_SCOPE CmdFrame * TclGetCmdFrameForProcedure(Proc *procPtr);
|
||||
MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *value, int *code);
|
||||
MODULE_SCOPE Proc * TclGetLambdaFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr, Tcl_Obj **nsObjPtrPtr);
|
||||
MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr, ClientData *clientDataPtr,
|
||||
int *typePtr);
|
||||
@@ -3062,7 +3060,6 @@ 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);
|
||||
@@ -3077,9 +3074,10 @@ MODULE_SCOPE void TclInitNotifier(void);
|
||||
MODULE_SCOPE void TclInitObjSubsystem(void);
|
||||
MODULE_SCOPE void TclInitSubsystems(void);
|
||||
MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclIsSpaceProc(char byte);
|
||||
MODULE_SCOPE int TclIsBareword(char byte);
|
||||
MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]);
|
||||
MODULE_SCOPE int TclIsSpaceProc(int byte);
|
||||
MODULE_SCOPE int TclIsBareword(int byte);
|
||||
MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[],
|
||||
int forceRelative);
|
||||
MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result);
|
||||
MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp);
|
||||
MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp,
|
||||
@@ -3242,6 +3240,17 @@ MODULE_SCOPE const char*TclGetCommandTypeName(Tcl_Command command);
|
||||
MODULE_SCOPE void TclRegisterCommandTypeName(
|
||||
Tcl_ObjCmdProc *implementationProc,
|
||||
const char *nameStr);
|
||||
#if (TCL_UTF_MAX > 4) && (defined(__CYGWIN__) || defined(_WIN32))
|
||||
MODULE_SCOPE int TclUtfToWChar(const char *src, WCHAR *chPtr);
|
||||
MODULE_SCOPE char * TclWCharToUtfDString(const WCHAR *uniStr,
|
||||
int uniLength, Tcl_DString *dsPtr);
|
||||
MODULE_SCOPE WCHAR * TclUtfToWCharDString(const char *src,
|
||||
int length, Tcl_DString *dsPtr);
|
||||
#else
|
||||
# define TclUtfToWChar TclUtfToUniChar
|
||||
# define TclWCharToUtfDString Tcl_UniCharToUtfDString
|
||||
# define TclUtfToWCharDString Tcl_UtfToUniCharDString
|
||||
#endif
|
||||
MODULE_SCOPE int TclUtfCmp(const char *cs, const char *ct);
|
||||
MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct);
|
||||
MODULE_SCOPE int TclUtfCount(int ch);
|
||||
@@ -3260,15 +3269,23 @@ MODULE_SCOPE int TclpLoadMemory(Tcl_Interp *interp, void *buffer,
|
||||
MODULE_SCOPE void TclInitThreadStorage(void);
|
||||
MODULE_SCOPE void TclFinalizeThreadDataThread(void);
|
||||
MODULE_SCOPE void TclFinalizeThreadStorage(void);
|
||||
|
||||
#ifdef TCL_WIDE_CLICKS
|
||||
MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void);
|
||||
MODULE_SCOPE double TclpWideClicksToNanoseconds(Tcl_WideInt clicks);
|
||||
MODULE_SCOPE double TclpWideClickInMicrosec(void);
|
||||
#else
|
||||
# ifdef _WIN32
|
||||
# define TCL_WIDE_CLICKS 1
|
||||
MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void);
|
||||
MODULE_SCOPE double TclpWideClickInMicrosec(void);
|
||||
# define TclpWideClicksToNanoseconds(clicks) \
|
||||
((double)(clicks) * TclpWideClickInMicrosec() * 1000)
|
||||
# endif
|
||||
#endif
|
||||
MODULE_SCOPE Tcl_WideInt TclpGetMicroseconds(void);
|
||||
|
||||
MODULE_SCOPE int TclZlibInit(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclZipfsInit(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclZipfsMount(Tcl_Interp *interp, const char *zipname,
|
||||
const char *mntpt, const char *passwd);
|
||||
MODULE_SCOPE int TclZipfsUnmount(Tcl_Interp *interp, const char *zipname);
|
||||
MODULE_SCOPE void * TclpThreadCreateKey(void);
|
||||
MODULE_SCOPE void TclpThreadDeleteKey(void *keyPtr);
|
||||
MODULE_SCOPE void TclpThreadSetMasterTSD(void *tsdKeyPtr, void *ptr);
|
||||
@@ -3277,7 +3294,6 @@ MODULE_SCOPE void TclErrorStackResetIf(Tcl_Interp *interp,
|
||||
const char *msg, int length);
|
||||
/* Tip 430 */
|
||||
MODULE_SCOPE int TclZipfs_Init(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclZipfs_SafeInit(Tcl_Interp *interp);
|
||||
|
||||
|
||||
/*
|
||||
@@ -3324,7 +3340,7 @@ MODULE_SCOPE int TclChanPushObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE void TclClockInit(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclClockOldscanObjCmd(
|
||||
ClientData clientData, Tcl_Interp *interp,
|
||||
void *clientData, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE int Tcl_CloseObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
@@ -3360,7 +3376,6 @@ MODULE_SCOPE int TclNRAssembleObjCmd(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[]);
|
||||
@@ -3389,7 +3404,6 @@ MODULE_SCOPE int Tcl_FcopyObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE Tcl_Command TclInitFileCmd(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclMakeFileCommandSafe(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int Tcl_FileEventObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -3451,6 +3465,9 @@ MODULE_SCOPE int Tcl_LmapObjCmd(ClientData clientData,
|
||||
MODULE_SCOPE int Tcl_LoadObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE int Tcl_LpopObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE int Tcl_LrangeObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -3543,6 +3560,9 @@ MODULE_SCOPE int Tcl_ThrowObjCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
MODULE_SCOPE int Tcl_TimeObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE int Tcl_TimeRateObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE int Tcl_TraceObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -4112,6 +4132,7 @@ MODULE_SCOPE int TclObjCallVarTraces(Interp *iPtr, Var *arrayPtr,
|
||||
*/
|
||||
|
||||
MODULE_SCOPE int TclCompareObjKeys(void *keyPtr, Tcl_HashEntry *hPtr);
|
||||
MODULE_SCOPE void TclFreeObj(Tcl_Obj *objPtr);
|
||||
MODULE_SCOPE void TclFreeObjEntry(Tcl_HashEntry *hPtr);
|
||||
MODULE_SCOPE TCL_HASH_TYPE TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
|
||||
@@ -4172,9 +4193,8 @@ MODULE_SCOPE int TclIndexDecode(int encoded, int endValue);
|
||||
|
||||
/* Constants used in index value encoding routines. */
|
||||
#define TCL_INDEX_END (-2)
|
||||
#define TCL_INDEX_BEFORE (-1)
|
||||
#define TCL_INDEX_NONE (-1) /* Index out of range or END+1 */
|
||||
#define TCL_INDEX_START (0)
|
||||
#define TCL_INDEX_AFTER (INT_MAX)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -4419,8 +4439,8 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
(objPtr)->bytes = &tclEmptyString; \
|
||||
(objPtr)->length = 0; \
|
||||
} else { \
|
||||
(objPtr)->bytes = (char *) ckalloc((unsigned) ((len) + 1)); \
|
||||
memcpy((objPtr)->bytes, (bytePtr), (unsigned) (len)); \
|
||||
(objPtr)->bytes = (char *) ckalloc((len) + 1); \
|
||||
memcpy((objPtr)->bytes, (bytePtr) ? (bytePtr) : &tclEmptyString, (len)); \
|
||||
(objPtr)->bytes[len] = '\0'; \
|
||||
(objPtr)->length = (len); \
|
||||
}
|
||||
@@ -4480,6 +4500,18 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
(objPtr)->bytes = NULL; \
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
* Macro used by the Tcl core to test whether an object has a
|
||||
* string representation (or is a 'pure' internal value).
|
||||
* The ANSI C "prototype" for this macro is:
|
||||
*
|
||||
* MODULE_SCOPE int TclHasStringRep(Tcl_Obj *objPtr);
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define TclHasStringRep(objPtr) ((objPtr)->bytes != NULL)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
* Macros used by the Tcl core to grow Tcl_Token arrays. They use the same
|
||||
@@ -4528,19 +4560,19 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
allocated = TCL_MAX_TOKENS; \
|
||||
} \
|
||||
newPtr = (Tcl_Token *) attemptckrealloc((char *) oldPtr, \
|
||||
(unsigned int) (allocated * sizeof(Tcl_Token))); \
|
||||
allocated * sizeof(Tcl_Token)); \
|
||||
if (newPtr == NULL) { \
|
||||
allocated = _needed + (append) + TCL_MIN_TOKEN_GROWTH; \
|
||||
if (allocated > TCL_MAX_TOKENS) { \
|
||||
allocated = TCL_MAX_TOKENS; \
|
||||
} \
|
||||
newPtr = (Tcl_Token *) ckrealloc((char *) oldPtr, \
|
||||
(unsigned int) (allocated * sizeof(Tcl_Token))); \
|
||||
allocated * sizeof(Tcl_Token)); \
|
||||
} \
|
||||
(available) = allocated; \
|
||||
if (oldPtr == NULL) { \
|
||||
memcpy(newPtr, staticPtr, \
|
||||
(size_t) ((used) * sizeof(Tcl_Token))); \
|
||||
(used) * sizeof(Tcl_Token)); \
|
||||
} \
|
||||
(tokenPtr) = newPtr; \
|
||||
} \
|
||||
@@ -4610,6 +4642,10 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr);
|
||||
#define TclIsPureDict(objPtr) \
|
||||
(((objPtr)->bytes==NULL) && ((objPtr)->typePtr==&tclDictType))
|
||||
#define TclHasIntRep(objPtr, type) \
|
||||
((objPtr)->typePtr == (type))
|
||||
#define TclFetchIntRep(objPtr, type) \
|
||||
(TclHasIntRep((objPtr), (type)) ? &((objPtr)->internalRep) : NULL)
|
||||
|
||||
|
||||
/*
|
||||
@@ -4699,18 +4735,18 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
|
||||
#define TclSetIntObj(objPtr, i) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.wideValue = (Tcl_WideInt) i; \
|
||||
TclInvalidateStringRep(objPtr); \
|
||||
TclFreeIntRep(objPtr); \
|
||||
(objPtr)->internalRep.wideValue = (Tcl_WideInt)(i); \
|
||||
(objPtr)->typePtr = &tclIntType; \
|
||||
Tcl_StoreIntRep(objPtr, &tclIntType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define TclSetDoubleObj(objPtr, d) \
|
||||
do { \
|
||||
TclInvalidateStringRep(objPtr); \
|
||||
TclFreeIntRep(objPtr); \
|
||||
(objPtr)->internalRep.doubleValue = (double)(d); \
|
||||
(objPtr)->typePtr = &tclDoubleType; \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.doubleValue = (double) d; \
|
||||
TclInvalidateStringRep(objPtr); \
|
||||
Tcl_StoreIntRep(objPtr, &tclDoubleType, &ir); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
|
||||
+10
-1
@@ -15,7 +15,6 @@
|
||||
#ifndef _TCLINTDECLS
|
||||
#define _TCLINTDECLS
|
||||
|
||||
#include "tclPort.h"
|
||||
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#ifdef BUILD_tcl
|
||||
@@ -649,6 +648,11 @@ EXTERN int TclPtrObjMakeUpvar(Tcl_Interp *interp,
|
||||
EXTERN int TclPtrUnsetVar(Tcl_Interp *interp, Tcl_Var varPtr,
|
||||
Tcl_Var arrayPtr, Tcl_Obj *part1Ptr,
|
||||
Tcl_Obj *part2Ptr, const int flags);
|
||||
/* 257 */
|
||||
EXTERN void TclStaticPackage(Tcl_Interp *interp,
|
||||
const char *pkgName,
|
||||
Tcl_PackageInitProc *initProc,
|
||||
Tcl_PackageInitProc *safeInitProc);
|
||||
|
||||
typedef struct TclIntStubs {
|
||||
int magic;
|
||||
@@ -911,6 +915,7 @@ typedef struct TclIntStubs {
|
||||
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 */
|
||||
void (*tclStaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 257 */
|
||||
} TclIntStubs;
|
||||
|
||||
extern const TclIntStubs *tclIntStubsPtr;
|
||||
@@ -1352,6 +1357,8 @@ extern const TclIntStubs *tclIntStubsPtr;
|
||||
(tclIntStubsPtr->tclPtrObjMakeUpvar) /* 255 */
|
||||
#define TclPtrUnsetVar \
|
||||
(tclIntStubsPtr->tclPtrUnsetVar) /* 256 */
|
||||
#define TclStaticPackage \
|
||||
(tclIntStubsPtr->tclStaticPackage) /* 257 */
|
||||
|
||||
#endif /* defined(USE_TCL_STUBS) */
|
||||
|
||||
@@ -1382,6 +1389,8 @@ extern const TclIntStubs *tclIntStubsPtr;
|
||||
# undef TclGetCommandFullName
|
||||
# undef TclCopyChannelOld
|
||||
# undef TclSockMinimumBuffersOld
|
||||
# undef Tcl_StaticPackage
|
||||
# define Tcl_StaticPackage (tclIntStubsPtr->tclStaticPackage)
|
||||
#endif
|
||||
|
||||
#endif /* _TCLINTDECLS */
|
||||
|
||||
+20
-20
@@ -409,7 +409,7 @@ Tcl_Init(
|
||||
" } else {\n"
|
||||
" lappend scripts {::tcl::pkgconfig get scriptdir,runtime}\n"
|
||||
" }\n"
|
||||
" lappend scripts {zipfs tcl_library}\n"
|
||||
" lappend scripts {::tcl::zipfs::tcl_library_init}\n"
|
||||
" lappend scripts {\n"
|
||||
"set parentDir [file dirname [file dirname [info nameofexecutable]]]\n"
|
||||
"set grandParentDir [file dirname $parentDir]\n"
|
||||
@@ -1188,7 +1188,7 @@ Tcl_CreateAlias(
|
||||
int i;
|
||||
int result;
|
||||
|
||||
objv = TclStackAlloc(slaveInterp, (unsigned) sizeof(Tcl_Obj *) * argc);
|
||||
objv = TclStackAlloc(slaveInterp, sizeof(Tcl_Obj *) * argc);
|
||||
for (i = 0; i < argc; i++) {
|
||||
objv[i] = Tcl_NewStringObj(argv[i], -1);
|
||||
Tcl_IncrRefCount(objv[i]);
|
||||
@@ -1826,13 +1826,13 @@ AliasNRCmd(
|
||||
cmdc = prefc + objc - 1;
|
||||
|
||||
listPtr = Tcl_NewListObj(cmdc, NULL);
|
||||
listRep = listPtr->internalRep.twoPtrValue.ptr1;
|
||||
listRep = ListRepPtr(listPtr);
|
||||
listRep->elemCount = cmdc;
|
||||
cmdv = &listRep->elements;
|
||||
|
||||
prefv = &aliasPtr->objPtr;
|
||||
memcpy(cmdv, prefv, (size_t) (prefc * sizeof(Tcl_Obj *)));
|
||||
memcpy(cmdv+prefc, objv+1, (size_t) ((objc-1) * sizeof(Tcl_Obj *)));
|
||||
memcpy(cmdv, prefv, prefc * sizeof(Tcl_Obj *));
|
||||
memcpy(cmdv+prefc, objv+1, (objc-1) * sizeof(Tcl_Obj *));
|
||||
|
||||
for (i=0; i<cmdc; i++) {
|
||||
Tcl_IncrRefCount(cmdv[i]);
|
||||
@@ -1880,8 +1880,8 @@ TclAliasObjCmd(
|
||||
cmdv = TclStackAlloc(interp, cmdc * sizeof(Tcl_Obj *));
|
||||
}
|
||||
|
||||
memcpy(cmdv, prefv, (size_t) (prefc * sizeof(Tcl_Obj *)));
|
||||
memcpy(cmdv+prefc, objv+1, (size_t) ((objc-1) * sizeof(Tcl_Obj *)));
|
||||
memcpy(cmdv, prefv, prefc * sizeof(Tcl_Obj *));
|
||||
memcpy(cmdv+prefc, objv+1, (objc-1) * sizeof(Tcl_Obj *));
|
||||
|
||||
Tcl_ResetResult(targetInterp);
|
||||
|
||||
@@ -1970,8 +1970,8 @@ TclLocalAliasObjCmd(
|
||||
cmdv = TclStackAlloc(interp, cmdc * sizeof(Tcl_Obj *));
|
||||
}
|
||||
|
||||
memcpy(cmdv, prefv, (size_t) (prefc * sizeof(Tcl_Obj *)));
|
||||
memcpy(cmdv+prefc, objv+1, (size_t) ((objc-1) * sizeof(Tcl_Obj *)));
|
||||
memcpy(cmdv, prefv, prefc * sizeof(Tcl_Obj *));
|
||||
memcpy(cmdv+prefc, objv+1, (objc-1) * sizeof(Tcl_Obj *));
|
||||
|
||||
for (i=0; i<cmdc; i++) {
|
||||
Tcl_IncrRefCount(cmdv[i]);
|
||||
@@ -3007,7 +3007,7 @@ SlaveRecursionLimit(
|
||||
return TCL_OK;
|
||||
} else {
|
||||
limit = Tcl_SetRecursionLimit(slaveInterp, 0);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(limit));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(limit));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
@@ -4516,12 +4516,12 @@ SlaveCommandLimitCmd(
|
||||
Tcl_NewStringObj(options[0], -1), empty);
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], -1),
|
||||
Tcl_NewIntObj(Tcl_LimitGetGranularity(slaveInterp,
|
||||
Tcl_NewWideIntObj(Tcl_LimitGetGranularity(slaveInterp,
|
||||
TCL_LIMIT_COMMANDS)));
|
||||
|
||||
if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_COMMANDS)) {
|
||||
Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], -1),
|
||||
Tcl_NewIntObj(Tcl_LimitGetCommands(slaveInterp)));
|
||||
Tcl_NewWideIntObj(Tcl_LimitGetCommands(slaveInterp)));
|
||||
} else {
|
||||
Tcl_Obj *empty;
|
||||
|
||||
@@ -4549,13 +4549,13 @@ SlaveCommandLimitCmd(
|
||||
}
|
||||
break;
|
||||
case OPT_GRAN:
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
|
||||
Tcl_LimitGetGranularity(slaveInterp, TCL_LIMIT_COMMANDS)));
|
||||
break;
|
||||
case OPT_VAL:
|
||||
if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_COMMANDS)) {
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewIntObj(Tcl_LimitGetCommands(slaveInterp)));
|
||||
Tcl_NewWideIntObj(Tcl_LimitGetCommands(slaveInterp)));
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -4703,7 +4703,7 @@ SlaveTimeLimitCmd(
|
||||
Tcl_NewStringObj(options[0], -1), empty);
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], -1),
|
||||
Tcl_NewIntObj(Tcl_LimitGetGranularity(slaveInterp,
|
||||
Tcl_NewWideIntObj(Tcl_LimitGetGranularity(slaveInterp,
|
||||
TCL_LIMIT_TIME)));
|
||||
|
||||
if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_TIME)) {
|
||||
@@ -4711,9 +4711,9 @@ SlaveTimeLimitCmd(
|
||||
|
||||
Tcl_LimitGetTime(slaveInterp, &limitMoment);
|
||||
Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], -1),
|
||||
Tcl_NewLongObj(limitMoment.usec/1000));
|
||||
Tcl_NewWideIntObj(limitMoment.usec/1000));
|
||||
Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[3], -1),
|
||||
Tcl_NewLongObj(limitMoment.sec));
|
||||
Tcl_NewWideIntObj(limitMoment.sec));
|
||||
} else {
|
||||
Tcl_Obj *empty;
|
||||
|
||||
@@ -4743,7 +4743,7 @@ SlaveTimeLimitCmd(
|
||||
}
|
||||
break;
|
||||
case OPT_GRAN:
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
|
||||
Tcl_LimitGetGranularity(slaveInterp, TCL_LIMIT_TIME)));
|
||||
break;
|
||||
case OPT_MILLI:
|
||||
@@ -4752,7 +4752,7 @@ SlaveTimeLimitCmd(
|
||||
|
||||
Tcl_LimitGetTime(slaveInterp, &limitMoment);
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewLongObj(limitMoment.usec/1000));
|
||||
Tcl_NewWideIntObj(limitMoment.usec/1000));
|
||||
}
|
||||
break;
|
||||
case OPT_SEC:
|
||||
@@ -4760,7 +4760,7 @@ SlaveTimeLimitCmd(
|
||||
Tcl_Time limitMoment;
|
||||
|
||||
Tcl_LimitGetTime(slaveInterp, &limitMoment);
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(limitMoment.sec));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(limitMoment.sec));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
+4
-3
@@ -416,7 +416,8 @@ LinkTraceProc(
|
||||
case TCL_LINK_DOUBLE:
|
||||
if (Tcl_GetDoubleFromObj(NULL, valueObj, &linkPtr->lastValue.d) != TCL_OK) {
|
||||
#ifdef ACCEPT_NAN
|
||||
if (valueObj->typePtr != &tclDoubleType) {
|
||||
Tcl_ObjIntRep *irPtr = TclFetchIntRep(valueObj, &tclDoubleType);
|
||||
if (irPtr == NULL) {
|
||||
#endif
|
||||
if (GetInvalidDoubleFromObj(valueObj, &linkPtr->lastValue.d) != TCL_OK) {
|
||||
Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
|
||||
@@ -425,7 +426,7 @@ LinkTraceProc(
|
||||
}
|
||||
#ifdef ACCEPT_NAN
|
||||
}
|
||||
linkPtr->lastValue.d = valueObj->internalRep.doubleValue;
|
||||
linkPtr->lastValue.d = irPtr->doubleValue;
|
||||
#endif
|
||||
}
|
||||
LinkedVar(double) = linkPtr->lastValue.d;
|
||||
@@ -734,7 +735,7 @@ GetInvalidDoubleFromObj(Tcl_Obj *objPtr, double *doublePtr)
|
||||
{
|
||||
int intValue;
|
||||
|
||||
if (objPtr->typePtr == &invalidRealType) {
|
||||
if (TclHasIntRep(objPtr, &invalidRealType)) {
|
||||
goto gotdouble;
|
||||
}
|
||||
if (GetInvalidIntFromObj(objPtr, &intValue) == TCL_OK) {
|
||||
|
||||
+194
-92
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Prototypes for functions defined later in this file:
|
||||
@@ -46,6 +47,27 @@ const Tcl_ObjType tclListType = {
|
||||
SetListFromAny /* setFromAnyProc */
|
||||
};
|
||||
|
||||
/* Macros to manipulate the List internal rep */
|
||||
|
||||
#define ListSetIntRep(objPtr, listRepPtr) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (listRepPtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
(listRepPtr)->refCount++; \
|
||||
Tcl_StoreIntRep((objPtr), &tclListType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define ListGetIntRep(objPtr, listRepPtr) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), &tclListType); \
|
||||
(listRepPtr) = irPtr ? irPtr->twoPtrValue.ptr1 : NULL; \
|
||||
} while (0)
|
||||
|
||||
#define ListResetIntRep(objPtr, listRepPtr) \
|
||||
TclFetchIntRep((objPtr), &tclListType)->twoPtrValue.ptr1 = (listRepPtr)
|
||||
|
||||
#ifndef TCL_MIN_ELEMENT_GROWTH
|
||||
#define TCL_MIN_ELEMENT_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_Obj *)
|
||||
#endif
|
||||
@@ -374,8 +396,7 @@ Tcl_SetListObj(
|
||||
listRepPtr = NewListIntRep(objc, objv, 1);
|
||||
ListSetIntRep(objPtr, listRepPtr);
|
||||
} else {
|
||||
objPtr->bytes = &tclEmptyString;
|
||||
objPtr->length = 0;
|
||||
Tcl_InitStringRep(objPtr, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,8 +428,10 @@ TclListObjCopy(
|
||||
* to be returned. */
|
||||
{
|
||||
Tcl_Obj *copyPtr;
|
||||
List *listRepPtr;
|
||||
|
||||
if (listPtr->typePtr != &tclListType) {
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
if (NULL == listRepPtr) {
|
||||
if (SetListFromAny(interp, listPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -543,10 +566,13 @@ Tcl_ListObjGetElements(
|
||||
{
|
||||
register List *listRepPtr;
|
||||
|
||||
if (listPtr->typePtr != &tclListType) {
|
||||
int result;
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
|
||||
if (listPtr->bytes == &tclEmptyString) {
|
||||
if (listRepPtr == NULL) {
|
||||
int result, length;
|
||||
|
||||
(void) Tcl_GetStringFromObj(listPtr, &length);
|
||||
if (length == 0) {
|
||||
*objcPtr = 0;
|
||||
*objvPtr = NULL;
|
||||
return TCL_OK;
|
||||
@@ -555,8 +581,8 @@ Tcl_ListObjGetElements(
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
}
|
||||
listRepPtr = ListRepPtr(listPtr);
|
||||
*objcPtr = listRepPtr->elemCount;
|
||||
*objvPtr = &listRepPtr->elements;
|
||||
return TCL_OK;
|
||||
@@ -653,10 +679,13 @@ Tcl_ListObjAppendElement(
|
||||
if (Tcl_IsShared(listPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement");
|
||||
}
|
||||
if (listPtr->typePtr != &tclListType) {
|
||||
int result;
|
||||
|
||||
if (listPtr->bytes == &tclEmptyString) {
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
if (listRepPtr == NULL) {
|
||||
int result, length;
|
||||
|
||||
(void) Tcl_GetStringFromObj(listPtr, &length);
|
||||
if (length == 0) {
|
||||
Tcl_SetListObj(listPtr, 1, &objPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -664,9 +693,9 @@ Tcl_ListObjAppendElement(
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
}
|
||||
|
||||
listRepPtr = ListRepPtr(listPtr);
|
||||
numElems = listRepPtr->elemCount;
|
||||
numRequired = numElems + 1 ;
|
||||
needGrow = (numRequired > listRepPtr->maxElemCount);
|
||||
@@ -757,12 +786,16 @@ Tcl_ListObjAppendElement(
|
||||
* Old intrep to be freed, re-use refCounts.
|
||||
*/
|
||||
|
||||
memcpy(dst, src, (size_t) numElems * sizeof(Tcl_Obj *));
|
||||
memcpy(dst, src, numElems * sizeof(Tcl_Obj *));
|
||||
ckfree(listRepPtr);
|
||||
}
|
||||
listRepPtr = newPtr;
|
||||
}
|
||||
listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr;
|
||||
ListResetIntRep(listPtr, listRepPtr);
|
||||
listRepPtr->refCount++;
|
||||
TclFreeIntRep(listPtr);
|
||||
ListSetIntRep(listPtr, listRepPtr);
|
||||
listRepPtr->refCount--;
|
||||
|
||||
/*
|
||||
* Add objPtr to the end of listPtr's array of element pointers. Increment
|
||||
@@ -817,10 +850,12 @@ Tcl_ListObjIndex(
|
||||
{
|
||||
register List *listRepPtr;
|
||||
|
||||
if (listPtr->typePtr != &tclListType) {
|
||||
int result;
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
if (listRepPtr == NULL) {
|
||||
int result, length;
|
||||
|
||||
if (listPtr->bytes == &tclEmptyString) {
|
||||
(void) Tcl_GetStringFromObj(listPtr, &length);
|
||||
if (length == 0) {
|
||||
*objPtrPtr = NULL;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -828,9 +863,9 @@ Tcl_ListObjIndex(
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
}
|
||||
|
||||
listRepPtr = ListRepPtr(listPtr);
|
||||
if ((index < 0) || (index >= listRepPtr->elemCount)) {
|
||||
*objPtrPtr = NULL;
|
||||
} else {
|
||||
@@ -870,10 +905,12 @@ Tcl_ListObjLength(
|
||||
{
|
||||
register List *listRepPtr;
|
||||
|
||||
if (listPtr->typePtr != &tclListType) {
|
||||
int result;
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
if (listRepPtr == NULL) {
|
||||
int result, length;
|
||||
|
||||
if (listPtr->bytes == &tclEmptyString) {
|
||||
(void) Tcl_GetStringFromObj(listPtr, &length);
|
||||
if (length == 0) {
|
||||
*intPtr = 0;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -881,9 +918,9 @@ Tcl_ListObjLength(
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
}
|
||||
|
||||
listRepPtr = ListRepPtr(listPtr);
|
||||
*intPtr = listRepPtr->elemCount;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -943,9 +980,14 @@ Tcl_ListObjReplace(
|
||||
if (Tcl_IsShared(listPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace");
|
||||
}
|
||||
if (listPtr->typePtr != &tclListType) {
|
||||
if (listPtr->bytes == &tclEmptyString) {
|
||||
if (!objc) {
|
||||
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
if (listRepPtr == NULL) {
|
||||
int length;
|
||||
|
||||
(void) Tcl_GetStringFromObj(listPtr, &length);
|
||||
if (length == 0) {
|
||||
if (objc == 0) {
|
||||
return TCL_OK;
|
||||
}
|
||||
Tcl_SetListObj(listPtr, objc, NULL);
|
||||
@@ -956,6 +998,7 @@ Tcl_ListObjReplace(
|
||||
return result;
|
||||
}
|
||||
}
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -966,7 +1009,6 @@ Tcl_ListObjReplace(
|
||||
* Resist any temptation to optimize this case.
|
||||
*/
|
||||
|
||||
listRepPtr = ListRepPtr(listPtr);
|
||||
elemPtrs = &listRepPtr->elements;
|
||||
numElems = listRepPtr->elemCount;
|
||||
|
||||
@@ -1020,7 +1062,7 @@ Tcl_ListObjReplace(
|
||||
}
|
||||
if (newPtr) {
|
||||
listRepPtr = newPtr;
|
||||
listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr;
|
||||
ListResetIntRep(listPtr, listRepPtr);
|
||||
elemPtrs = &listRepPtr->elements;
|
||||
listRepPtr->maxElemCount = attempt;
|
||||
needGrow = numRequired > listRepPtr->maxElemCount;
|
||||
@@ -1093,7 +1135,7 @@ Tcl_ListObjReplace(
|
||||
}
|
||||
}
|
||||
|
||||
listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr;
|
||||
ListResetIntRep(listPtr, listRepPtr);
|
||||
listRepPtr->refCount++;
|
||||
|
||||
elemPtrs = &listRepPtr->elements;
|
||||
@@ -1122,7 +1164,7 @@ Tcl_ListObjReplace(
|
||||
*/
|
||||
|
||||
if (first > 0) {
|
||||
memcpy(elemPtrs, oldPtrs, (size_t) first * sizeof(Tcl_Obj *));
|
||||
memcpy(elemPtrs, oldPtrs, first * sizeof(Tcl_Obj *));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1166,10 +1208,15 @@ Tcl_ListObjReplace(
|
||||
listRepPtr->elemCount = numRequired;
|
||||
|
||||
/*
|
||||
* Invalidate and free any old string representation since it no longer
|
||||
* reflects the list's internal representation.
|
||||
* Invalidate and free any old representations that may not agree
|
||||
* with the revised list's internal representation.
|
||||
*/
|
||||
|
||||
listRepPtr->refCount++;
|
||||
TclFreeIntRep(listPtr);
|
||||
ListSetIntRep(listPtr, listRepPtr);
|
||||
listRepPtr->refCount--;
|
||||
|
||||
TclInvalidateStringRep(listPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1208,6 +1255,7 @@ TclLindexList(
|
||||
|
||||
int index; /* Index into the list. */
|
||||
Tcl_Obj *indexListCopy;
|
||||
List *listRepPtr;
|
||||
|
||||
/*
|
||||
* Determine whether argPtr designates a list or a single index. We have
|
||||
@@ -1215,7 +1263,8 @@ TclLindexList(
|
||||
* shimmering; see TIP#22 and TIP#33 for the details.
|
||||
*/
|
||||
|
||||
if (argPtr->typePtr != &tclListType
|
||||
ListGetIntRep(argPtr, listRepPtr);
|
||||
if ((listRepPtr == NULL)
|
||||
&& TclGetIntForIndexM(NULL , argPtr, 0, &index) == TCL_OK) {
|
||||
/*
|
||||
* argPtr designates a single index.
|
||||
@@ -1246,13 +1295,12 @@ TclLindexList(
|
||||
return TclLindexFlat(interp, listPtr, 1, &argPtr);
|
||||
}
|
||||
|
||||
{
|
||||
int indexCount = -1; /* Size of the array of list indices. */
|
||||
Tcl_Obj **indices = NULL; /* Array of list indices. */
|
||||
ListGetIntRep(indexListCopy, listRepPtr);
|
||||
|
||||
TclListObjGetElements(NULL, indexListCopy, &indexCount, &indices);
|
||||
listPtr = TclLindexFlat(interp, listPtr, indexCount, indices);
|
||||
}
|
||||
assert(listRepPtr != NULL);
|
||||
|
||||
listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount,
|
||||
&listRepPtr->elements);
|
||||
Tcl_DecrRefCount(indexListCopy);
|
||||
return listPtr;
|
||||
}
|
||||
@@ -1356,6 +1404,7 @@ TclLindexFlat(
|
||||
*
|
||||
* Core of the 'lset' command when objc == 4. Objv[2] may be either a
|
||||
* scalar index or a list of indices.
|
||||
* It also handles 'lpop' when given a NULL value.
|
||||
*
|
||||
* Results:
|
||||
* Returns the new value of the list variable, or NULL if there was an
|
||||
@@ -1380,13 +1429,14 @@ TclLsetList(
|
||||
Tcl_Interp *interp, /* Tcl interpreter. */
|
||||
Tcl_Obj *listPtr, /* Pointer to the list being modified. */
|
||||
Tcl_Obj *indexArgPtr, /* Index or index-list arg to 'lset'. */
|
||||
Tcl_Obj *valuePtr) /* Value arg to 'lset'. */
|
||||
Tcl_Obj *valuePtr) /* Value arg to 'lset' or NULL to 'lpop'. */
|
||||
{
|
||||
int indexCount = 0; /* Number of indices in the index list. */
|
||||
Tcl_Obj **indices = NULL; /* Vector of indices in the index list. */
|
||||
Tcl_Obj *retValuePtr; /* Pointer to the list to be returned. */
|
||||
int index; /* Current index in the list - discarded. */
|
||||
Tcl_Obj *indexListCopy;
|
||||
List *listRepPtr;
|
||||
|
||||
/*
|
||||
* Determine whether the index arg designates a list or a single index.
|
||||
@@ -1394,7 +1444,8 @@ TclLsetList(
|
||||
* shimmering; see TIP #22 and #23 for details.
|
||||
*/
|
||||
|
||||
if (indexArgPtr->typePtr != &tclListType
|
||||
ListGetIntRep(indexArgPtr, listRepPtr);
|
||||
if (listRepPtr == NULL
|
||||
&& TclGetIntForIndexM(NULL, indexArgPtr, 0, &index) == TCL_OK) {
|
||||
/*
|
||||
* indexArgPtr designates a single index.
|
||||
@@ -1431,6 +1482,7 @@ TclLsetList(
|
||||
* TclLsetFlat --
|
||||
*
|
||||
* Core engine of the 'lset' command.
|
||||
* It also handles 'lpop' when given a NULL value.
|
||||
*
|
||||
* Results:
|
||||
* Returns the new value of the list variable, or NULL if an error
|
||||
@@ -1475,18 +1527,22 @@ TclLsetFlat(
|
||||
int indexCount, /* Number of index args. */
|
||||
Tcl_Obj *const indexArray[],
|
||||
/* Index args. */
|
||||
Tcl_Obj *valuePtr) /* Value arg to 'lset'. */
|
||||
Tcl_Obj *valuePtr) /* Value arg to 'lset' or NULL to 'lpop'. */
|
||||
{
|
||||
int index, result, len;
|
||||
Tcl_Obj *subListPtr, *retValuePtr, *chainPtr;
|
||||
Tcl_ObjIntRep *irPtr;
|
||||
|
||||
/*
|
||||
* If there are no indices, simply return the new value. (Without
|
||||
* indices, [lset] is a synonym for [set].
|
||||
* [lpop] does not use this but protect for NULL valuePtr just in case.
|
||||
*/
|
||||
|
||||
if (indexCount == 0) {
|
||||
Tcl_IncrRefCount(valuePtr);
|
||||
if (valuePtr != NULL) {
|
||||
Tcl_IncrRefCount(valuePtr);
|
||||
}
|
||||
return valuePtr;
|
||||
}
|
||||
|
||||
@@ -1546,12 +1602,14 @@ TclLsetFlat(
|
||||
}
|
||||
indexArray++;
|
||||
|
||||
if (index < 0 || index > elemCount) {
|
||||
if (index < 0 || index > elemCount
|
||||
|| (valuePtr == NULL && index >= elemCount)) {
|
||||
/* ...the index points outside the sublist. */
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewStringObj("list index out of range", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSET",
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
|
||||
valuePtr == NULL ? "LPOP" : "LSET",
|
||||
"BADINDEX", NULL);
|
||||
}
|
||||
result = TCL_ERROR;
|
||||
@@ -1609,7 +1667,8 @@ TclLsetFlat(
|
||||
* them at that time.
|
||||
*/
|
||||
|
||||
parentList->internalRep.twoPtrValue.ptr2 = chainPtr;
|
||||
irPtr = TclFetchIntRep(parentList, &tclListType);
|
||||
irPtr->twoPtrValue.ptr2 = chainPtr;
|
||||
chainPtr = parentList;
|
||||
}
|
||||
} while (indexCount > 0);
|
||||
@@ -1623,22 +1682,32 @@ TclLsetFlat(
|
||||
|
||||
while (chainPtr) {
|
||||
Tcl_Obj *objPtr = chainPtr;
|
||||
|
||||
if (result == TCL_OK) {
|
||||
/*
|
||||
* We're going to store valuePtr, so spoil string reps of all
|
||||
* containing lists.
|
||||
*/
|
||||
|
||||
TclInvalidateStringRep(objPtr);
|
||||
}
|
||||
List *listRepPtr;
|
||||
|
||||
/*
|
||||
* Clear away our intrep surgery mess.
|
||||
*/
|
||||
|
||||
chainPtr = objPtr->internalRep.twoPtrValue.ptr2;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
irPtr = TclFetchIntRep(objPtr, &tclListType);
|
||||
listRepPtr = irPtr->twoPtrValue.ptr1;
|
||||
chainPtr = irPtr->twoPtrValue.ptr2;
|
||||
|
||||
if (result == TCL_OK) {
|
||||
|
||||
/*
|
||||
* We're going to store valuePtr, so spoil string reps of all
|
||||
* containing lists.
|
||||
*/
|
||||
|
||||
listRepPtr->refCount++;
|
||||
TclFreeIntRep(objPtr);
|
||||
ListSetIntRep(objPtr, listRepPtr);
|
||||
listRepPtr->refCount--;
|
||||
|
||||
TclInvalidateStringRep(objPtr);
|
||||
} else {
|
||||
irPtr->twoPtrValue.ptr2 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != TCL_OK) {
|
||||
@@ -1661,12 +1730,14 @@ TclLsetFlat(
|
||||
|
||||
len = -1;
|
||||
TclListObjLength(NULL, subListPtr, &len);
|
||||
if (index == len) {
|
||||
if (valuePtr == NULL) {
|
||||
Tcl_ListObjReplace(NULL, subListPtr, index, 1, 0, NULL);
|
||||
} else if (index == len) {
|
||||
Tcl_ListObjAppendElement(NULL, subListPtr, valuePtr);
|
||||
} else {
|
||||
TclListObjSetElement(NULL, subListPtr, index, valuePtr);
|
||||
TclInvalidateStringRep(subListPtr);
|
||||
}
|
||||
TclInvalidateStringRep(subListPtr);
|
||||
Tcl_IncrRefCount(retValuePtr);
|
||||
return retValuePtr;
|
||||
}
|
||||
@@ -1722,10 +1793,13 @@ TclListObjSetElement(
|
||||
if (Tcl_IsShared(listPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "TclListObjSetElement");
|
||||
}
|
||||
if (listPtr->typePtr != &tclListType) {
|
||||
int result;
|
||||
|
||||
if (listPtr->bytes == &tclEmptyString) {
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
if (listRepPtr == NULL) {
|
||||
int result, length;
|
||||
|
||||
(void) Tcl_GetStringFromObj(listPtr, &length);
|
||||
if (length == 0) {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewStringObj("list index out of range", -1));
|
||||
@@ -1738,9 +1812,9 @@ TclListObjSetElement(
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
}
|
||||
|
||||
listRepPtr = ListRepPtr(listPtr);
|
||||
elemCount = listRepPtr->elemCount;
|
||||
|
||||
/*
|
||||
@@ -1783,7 +1857,8 @@ TclListObjSetElement(
|
||||
|
||||
listRepPtr->refCount--;
|
||||
|
||||
listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr = newPtr;
|
||||
listRepPtr = newPtr;
|
||||
ListResetIntRep(listPtr, listRepPtr);
|
||||
}
|
||||
elemPtrs = &listRepPtr->elements;
|
||||
|
||||
@@ -1805,6 +1880,18 @@ TclListObjSetElement(
|
||||
|
||||
elemPtrs[index] = valuePtr;
|
||||
|
||||
/*
|
||||
* Invalidate outdated intreps.
|
||||
*/
|
||||
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
listRepPtr->refCount++;
|
||||
TclFreeIntRep(listPtr);
|
||||
ListSetIntRep(listPtr, listRepPtr);
|
||||
listRepPtr->refCount--;
|
||||
|
||||
TclInvalidateStringRep(listPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1820,9 +1907,8 @@ TclListObjSetElement(
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Frees listPtr's List* internal representation and sets listPtr's
|
||||
* internalRep.twoPtrValue.ptr1 to NULL. Decrements the ref counts of all
|
||||
* element objects, which may free them.
|
||||
* Frees listPtr's List* internal representation, if no longer shared.
|
||||
* May decrement the ref counts of element objects, which may free them.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1831,7 +1917,10 @@ static void
|
||||
FreeListInternalRep(
|
||||
Tcl_Obj *listPtr) /* List object with internal rep to free. */
|
||||
{
|
||||
List *listRepPtr = ListRepPtr(listPtr);
|
||||
List *listRepPtr;
|
||||
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
assert(listRepPtr != NULL);
|
||||
|
||||
if (listRepPtr->refCount-- <= 1) {
|
||||
Tcl_Obj **elemPtrs = &listRepPtr->elements;
|
||||
@@ -1842,8 +1931,6 @@ FreeListInternalRep(
|
||||
}
|
||||
ckfree(listRepPtr);
|
||||
}
|
||||
|
||||
listPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1868,8 +1955,10 @@ DupListInternalRep(
|
||||
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
|
||||
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
{
|
||||
List *listRepPtr = ListRepPtr(srcPtr);
|
||||
List *listRepPtr;
|
||||
|
||||
ListGetIntRep(srcPtr, listRepPtr);
|
||||
assert(listRepPtr != NULL);
|
||||
ListSetIntRep(copyPtr, listRepPtr);
|
||||
}
|
||||
|
||||
@@ -1908,7 +1997,7 @@ SetListFromAny(
|
||||
* describe duplicate keys).
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &tclDictType && !objPtr->bytes) {
|
||||
if (!TclHasStringRep(objPtr) && TclHasIntRep(objPtr, &tclDictType)) {
|
||||
Tcl_Obj *keyPtr, *valuePtr;
|
||||
Tcl_DictSearch search;
|
||||
int done, size;
|
||||
@@ -1966,10 +2055,12 @@ SetListFromAny(
|
||||
|
||||
while (nextElem < limit) {
|
||||
const char *elemStart;
|
||||
char *check;
|
||||
int elemSize, literal;
|
||||
|
||||
if (TCL_OK != TclFindElement(interp, nextElem, limit - nextElem,
|
||||
&elemStart, &nextElem, &elemSize, &literal)) {
|
||||
fail:
|
||||
while (--elemPtrs >= &listRepPtr->elements) {
|
||||
Tcl_DecrRefCount(*elemPtrs);
|
||||
}
|
||||
@@ -1980,14 +2071,21 @@ SetListFromAny(
|
||||
break;
|
||||
}
|
||||
|
||||
/* TODO: replace panic with error on alloc failure? */
|
||||
if (literal) {
|
||||
TclNewStringObj(*elemPtrs, elemStart, elemSize);
|
||||
} else {
|
||||
TclNewObj(*elemPtrs);
|
||||
(*elemPtrs)->bytes = ckalloc((unsigned) elemSize + 1);
|
||||
(*elemPtrs)->length = TclCopyAndCollapse(elemSize, elemStart,
|
||||
(*elemPtrs)->bytes);
|
||||
TclNewObj(*elemPtrs);
|
||||
TclInvalidateStringRep(*elemPtrs);
|
||||
check = Tcl_InitStringRep(*elemPtrs, literal ? elemStart : NULL,
|
||||
elemSize);
|
||||
if (elemSize && check == NULL) {
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot construct list, out of memory", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
goto fail;
|
||||
}
|
||||
if (!literal) {
|
||||
Tcl_InitStringRep(*elemPtrs, NULL,
|
||||
TclCopyAndCollapse(elemSize, elemStart, check));
|
||||
}
|
||||
|
||||
Tcl_IncrRefCount(*elemPtrs++);/* Since list now holds ref to it. */
|
||||
@@ -1997,12 +2095,11 @@ SetListFromAny(
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the old internalRep before setting the new one. We do this as late
|
||||
* Store the new internalRep. We do this as late
|
||||
* as possible to allow the conversion code, in particular
|
||||
* Tcl_GetStringFromObj, to use that old internalRep.
|
||||
* Tcl_GetStringFromObj, to use the old internalRep.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
ListSetIntRep(objPtr, listRepPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -2034,12 +2131,17 @@ UpdateStringOfList(
|
||||
{
|
||||
# define LOCAL_SIZE 64
|
||||
char localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
List *listRepPtr = ListRepPtr(listPtr);
|
||||
int numElems = listRepPtr->elemCount;
|
||||
int i, length, bytesNeeded = 0;
|
||||
const char *elem;
|
||||
int numElems, i, length, bytesNeeded = 0;
|
||||
const char *elem, *start;
|
||||
char *dst;
|
||||
Tcl_Obj **elemPtrs;
|
||||
List *listRepPtr;
|
||||
|
||||
ListGetIntRep(listPtr, listRepPtr);
|
||||
|
||||
assert(listRepPtr != NULL);
|
||||
|
||||
numElems = listRepPtr->elemCount;
|
||||
|
||||
/*
|
||||
* Mark the list as being canonical; although it will now have a string
|
||||
@@ -2054,8 +2156,7 @@ UpdateStringOfList(
|
||||
*/
|
||||
|
||||
if (numElems == 0) {
|
||||
listPtr->bytes = &tclEmptyString;
|
||||
listPtr->length = 0;
|
||||
Tcl_InitStringRep(listPtr, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2084,22 +2185,23 @@ UpdateStringOfList(
|
||||
if (bytesNeeded > INT_MAX - numElems + 1) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
bytesNeeded += numElems;
|
||||
bytesNeeded += numElems - 1;
|
||||
|
||||
/*
|
||||
* Pass 2: copy into string rep buffer.
|
||||
*/
|
||||
|
||||
listPtr->length = bytesNeeded - 1;
|
||||
listPtr->bytes = ckalloc(bytesNeeded);
|
||||
dst = listPtr->bytes;
|
||||
start = dst = Tcl_InitStringRep(listPtr, NULL, bytesNeeded);
|
||||
TclOOM(dst, bytesNeeded);
|
||||
for (i = 0; i < numElems; i++) {
|
||||
flagPtr[i] |= (i ? TCL_DONT_QUOTE_HASH : 0);
|
||||
elem = TclGetStringFromObj(elemPtrs[i], &length);
|
||||
dst += TclConvertElement(elem, length, dst, flagPtr[i]);
|
||||
*dst++ = ' ';
|
||||
}
|
||||
listPtr->bytes[listPtr->length] = '\0';
|
||||
|
||||
/* Set the string length to what was actually written, the safe choice */
|
||||
(void) Tcl_InitStringRep(listPtr, NULL, dst - 1 - start);
|
||||
|
||||
if (flagPtr != localFlags) {
|
||||
ckfree(flagPtr);
|
||||
|
||||
+28
-17
@@ -200,25 +200,36 @@ TclCreateLiteral(
|
||||
for (globalPtr=globalTablePtr->buckets[globalHash] ; globalPtr!=NULL;
|
||||
globalPtr = globalPtr->nextPtr) {
|
||||
objPtr = globalPtr->objPtr;
|
||||
if ((globalPtr->nsPtr == nsPtr)
|
||||
&& (objPtr->length == length) && ((length == 0)
|
||||
|| ((objPtr->bytes[0] == bytes[0])
|
||||
&& (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) {
|
||||
if (globalPtr->nsPtr == nsPtr) {
|
||||
/*
|
||||
* A literal was found: return it
|
||||
* Literals should always have UTF-8 representations... but this
|
||||
* is not guaranteed so we need to be careful anyway.
|
||||
*
|
||||
* https://stackoverflow.com/q/54337750/301832
|
||||
*/
|
||||
|
||||
if (newPtr) {
|
||||
*newPtr = 0;
|
||||
int objLength;
|
||||
char *objBytes = TclGetStringFromObj(objPtr, &objLength);
|
||||
|
||||
if ((objLength == length) && ((length == 0)
|
||||
|| ((objBytes[0] == bytes[0])
|
||||
&& (memcmp(objBytes, bytes, length) == 0)))) {
|
||||
/*
|
||||
* A literal was found: return it
|
||||
*/
|
||||
|
||||
if (newPtr) {
|
||||
*newPtr = 0;
|
||||
}
|
||||
if (globalPtrPtr) {
|
||||
*globalPtrPtr = globalPtr;
|
||||
}
|
||||
if (flags & LITERAL_ON_HEAP) {
|
||||
ckfree(bytes);
|
||||
}
|
||||
globalPtr->refCount++;
|
||||
return objPtr;
|
||||
}
|
||||
if (globalPtrPtr) {
|
||||
*globalPtrPtr = globalPtr;
|
||||
}
|
||||
if ((flags & LITERAL_ON_HEAP)) {
|
||||
ckfree(bytes);
|
||||
}
|
||||
globalPtr->refCount++;
|
||||
return objPtr;
|
||||
}
|
||||
}
|
||||
if (!newPtr) {
|
||||
@@ -413,7 +424,7 @@ TclRegisterLiteral(
|
||||
objPtr = localPtr->objPtr;
|
||||
if ((objPtr->length == length) && ((length == 0)
|
||||
|| ((objPtr->bytes[0] == bytes[0])
|
||||
&& (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) {
|
||||
&& (memcmp(objPtr->bytes, bytes, length) == 0)))) {
|
||||
if ((flags & LITERAL_ON_HEAP)) {
|
||||
ckfree(bytes);
|
||||
}
|
||||
@@ -1046,7 +1057,7 @@ TclInvalidateCmdLiteral(
|
||||
strlen(name), -1, NULL, nsPtr, 0, NULL);
|
||||
|
||||
if (literalObjPtr != NULL) {
|
||||
if (literalObjPtr->typePtr == &tclCmdNameType) {
|
||||
if (TclHasIntRep(literalObjPtr, &tclCmdNameType)) {
|
||||
TclFreeIntRep(literalObjPtr);
|
||||
}
|
||||
/* Balance the refcount effects of TclCreateLiteral() above */
|
||||
|
||||
+1
-1
@@ -405,7 +405,7 @@ Tcl_LoadObjCmd(
|
||||
len = strlen(fullFileName) + 1;
|
||||
pkgPtr->fileName = ckalloc(len);
|
||||
memcpy(pkgPtr->fileName, fullFileName, len);
|
||||
len = (unsigned) Tcl_DStringLength(&pkgName) + 1;
|
||||
len = Tcl_DStringLength(&pkgName) + 1;
|
||||
pkgPtr->packageName = ckalloc(len);
|
||||
memcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName), len);
|
||||
pkgPtr->loadHandle = loadHandle;
|
||||
|
||||
+12
-5
@@ -59,20 +59,27 @@
|
||||
* encoding to UTF-8).
|
||||
*/
|
||||
|
||||
#ifdef UNICODE
|
||||
#if defined(UNICODE) && (TCL_UTF_MAX <= 4)
|
||||
# define NewNativeObj Tcl_NewUnicodeObj
|
||||
#else /* !UNICODE */
|
||||
#else /* !UNICODE || (TCL_UTF_MAX > 4) */
|
||||
static inline Tcl_Obj *
|
||||
NewNativeObj(
|
||||
char *string,
|
||||
TCHAR *string,
|
||||
int length)
|
||||
{
|
||||
Tcl_DString ds;
|
||||
|
||||
Tcl_ExternalToUtfDString(NULL, string, length, &ds);
|
||||
#ifdef UNICODE
|
||||
if (length > 0) {
|
||||
length *= sizeof(WCHAR);
|
||||
}
|
||||
Tcl_WinTCharToUtf(string, length, &ds);
|
||||
#else
|
||||
Tcl_ExternalToUtfDString(NULL, (char *) string, length, &ds);
|
||||
#endif
|
||||
return TclDStringToObj(&ds);
|
||||
}
|
||||
#endif /* !UNICODE */
|
||||
#endif /* !UNICODE || (TCL_UTF_MAX > 4) */
|
||||
|
||||
/*
|
||||
* Declarations for various library functions and variables (don't want to
|
||||
|
||||
+40
-29
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h" /* for TclLogCommandInfo visibility */
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Thread-local storage used to avoid having a global lock on data that is not
|
||||
@@ -152,6 +153,22 @@ static const Tcl_ObjType nsNameType = {
|
||||
SetNsNameFromAny /* setFromAnyProc */
|
||||
};
|
||||
|
||||
#define NsNameSetIntRep(objPtr, nnPtr) \
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
(nnPtr)->refCount++; \
|
||||
ir.twoPtrValue.ptr1 = (nnPtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((objPtr), &nsNameType, &ir); \
|
||||
} while (0)
|
||||
|
||||
#define NsNameGetIntRep(objPtr, nnPtr) \
|
||||
do { \
|
||||
const Tcl_ObjIntRep *irPtr; \
|
||||
irPtr = TclFetchIntRep((objPtr), &nsNameType); \
|
||||
(nnPtr) = irPtr ? irPtr->twoPtrValue.ptr1 : NULL; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Array of values describing how to implement each standard subcommand of the
|
||||
* "namespace" command.
|
||||
@@ -859,7 +876,7 @@ Tcl_CreateNamespace(
|
||||
name = Tcl_DStringValue(namePtr);
|
||||
nameLen = Tcl_DStringLength(namePtr);
|
||||
nsPtr->fullName = ckalloc(nameLen + 1);
|
||||
memcpy(nsPtr->fullName, name, (unsigned) nameLen + 1);
|
||||
memcpy(nsPtr->fullName, name, nameLen + 1);
|
||||
|
||||
Tcl_DStringFree(&buffer1);
|
||||
Tcl_DStringFree(&buffer2);
|
||||
@@ -1445,7 +1462,7 @@ Tcl_Export(
|
||||
|
||||
len = strlen(pattern);
|
||||
patternCpy = ckalloc(len + 1);
|
||||
memcpy(patternCpy, pattern, (unsigned) len + 1);
|
||||
memcpy(patternCpy, pattern, len + 1);
|
||||
|
||||
nsPtr->exportArrayPtr[nsPtr->numExportPatterns] = patternCpy;
|
||||
nsPtr->numExportPatterns++;
|
||||
@@ -2898,15 +2915,16 @@ GetNamespaceFromObj(
|
||||
Tcl_Namespace **nsPtrPtr) /* Result namespace pointer goes here. */
|
||||
{
|
||||
ResolvedNsName *resNamePtr;
|
||||
Namespace *nsPtr, *refNsPtr;
|
||||
|
||||
if (objPtr->typePtr == &nsNameType) {
|
||||
NsNameGetIntRep(objPtr, resNamePtr);
|
||||
if (resNamePtr) {
|
||||
Namespace *nsPtr, *refNsPtr;
|
||||
|
||||
/*
|
||||
* Check that the ResolvedNsName is still valid; avoid letting the ref
|
||||
* cross interps.
|
||||
*/
|
||||
|
||||
resNamePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
nsPtr = resNamePtr->nsPtr;
|
||||
refNsPtr = resNamePtr->refNsPtr;
|
||||
if (!(nsPtr->flags & NS_DYING) && (interp == nsPtr->interp)
|
||||
@@ -2915,9 +2933,11 @@ GetNamespaceFromObj(
|
||||
*nsPtrPtr = (Tcl_Namespace *) nsPtr;
|
||||
return TCL_OK;
|
||||
}
|
||||
Tcl_StoreIntRep(objPtr, &nsNameType, NULL);
|
||||
}
|
||||
if (SetNsNameFromAny(interp, objPtr) == TCL_OK) {
|
||||
resNamePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
NsNameGetIntRep(objPtr, resNamePtr);
|
||||
assert(resNamePtr != NULL);
|
||||
*nsPtrPtr = (Tcl_Namespace *) resNamePtr->nsPtr;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -4687,7 +4707,10 @@ FreeNsNameInternalRep(
|
||||
register Tcl_Obj *objPtr) /* nsName object with internal representation
|
||||
* to free. */
|
||||
{
|
||||
ResolvedNsName *resNamePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ResolvedNsName *resNamePtr;
|
||||
|
||||
NsNameGetIntRep(objPtr, resNamePtr);
|
||||
assert(resNamePtr != NULL);
|
||||
|
||||
/*
|
||||
* Decrement the reference count of the namespace. If there are no more
|
||||
@@ -4704,7 +4727,6 @@ FreeNsNameInternalRep(
|
||||
TclNsDecrRefCount(resNamePtr->nsPtr);
|
||||
ckfree(resNamePtr);
|
||||
}
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4731,11 +4753,11 @@ DupNsNameInternalRep(
|
||||
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
|
||||
register Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
{
|
||||
ResolvedNsName *resNamePtr = srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
ResolvedNsName *resNamePtr;
|
||||
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = resNamePtr;
|
||||
resNamePtr->refCount++;
|
||||
copyPtr->typePtr = &nsNameType;
|
||||
NsNameGetIntRep(srcPtr, resNamePtr);
|
||||
assert(resNamePtr != NULL);
|
||||
NsNameSetIntRep(copyPtr, resNamePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4780,24 +4802,15 @@ SetNsNameFromAny(
|
||||
TclGetNamespaceForQualName(interp, name, NULL, TCL_FIND_ONLY_NS,
|
||||
&nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);
|
||||
|
||||
if ((nsPtr == NULL) || (nsPtr->flags & NS_DYING)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we found a namespace, then create a new ResolvedNsName structure
|
||||
* that holds a reference to it.
|
||||
*/
|
||||
|
||||
if ((nsPtr == NULL) || (nsPtr->flags & NS_DYING)) {
|
||||
/*
|
||||
* Our failed lookup proves any previously cached nsName intrep is no
|
||||
* longer valid. Get rid of it so we no longer waste memory storing
|
||||
* it, nor time determining its invalidity again and again.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &nsNameType) {
|
||||
TclFreeIntRep(objPtr);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
nsPtr->refCount++;
|
||||
resNamePtr = ckalloc(sizeof(ResolvedNsName));
|
||||
resNamePtr->nsPtr = nsPtr;
|
||||
@@ -4806,10 +4819,8 @@ SetNsNameFromAny(
|
||||
} else {
|
||||
resNamePtr->refNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
|
||||
}
|
||||
resNamePtr->refCount = 1;
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = resNamePtr;
|
||||
objPtr->typePtr = &nsNameType;
|
||||
resNamePtr->refCount = 0;
|
||||
NsNameSetIntRep(objPtr, resNamePtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
+103
-38
@@ -26,6 +26,7 @@ static const struct {
|
||||
int flag;
|
||||
} defineCmds[] = {
|
||||
{"constructor", TclOODefineConstructorObjCmd, 0},
|
||||
{"definitionnamespace", TclOODefineDefnNsObjCmd, 0},
|
||||
{"deletemethod", TclOODefineDeleteMethodObjCmd, 0},
|
||||
{"destructor", TclOODefineDestructorObjCmd, 0},
|
||||
{"export", TclOODefineExportObjCmd, 0},
|
||||
@@ -59,7 +60,6 @@ static const struct {
|
||||
* Function declarations for things defined in this file.
|
||||
*/
|
||||
|
||||
static Class * AllocClass(Tcl_Interp *interp, Object *useThisObj);
|
||||
static Object * AllocObject(Tcl_Interp *interp, const char *nameStr,
|
||||
Namespace *nsPtr, const char *nsNameStr);
|
||||
static int CloneClassMethod(Tcl_Interp *interp, Class *clsPtr,
|
||||
@@ -84,8 +84,6 @@ static void ObjectNamespaceDeleted(ClientData clientData);
|
||||
static void ObjectRenamedTrace(ClientData clientData,
|
||||
Tcl_Interp *interp, const char *oldName,
|
||||
const char *newName, int flags);
|
||||
static void ReleaseClassContents(Tcl_Interp *interp,Object *oPtr);
|
||||
static void DeleteDescendants(Tcl_Interp *interp,Object *oPtr);
|
||||
static inline void RemoveClass(Class **list, int num, int idx);
|
||||
static inline void RemoveObject(Object **list, int num, int idx);
|
||||
static inline void SquelchCachedName(Object *oPtr);
|
||||
@@ -448,29 +446,39 @@ InitClassSystemRoots(
|
||||
{
|
||||
Class fakeCls;
|
||||
Object fakeObject;
|
||||
Tcl_Obj *defNsName;
|
||||
|
||||
/* Stand up a phony class for bootstrapping. */
|
||||
fPtr->objectCls = &fakeCls;
|
||||
/* referenced in AllocClass to increment the refCount. */
|
||||
/* referenced in TclOOAllocClass to increment the refCount. */
|
||||
fakeCls.thisPtr = &fakeObject;
|
||||
|
||||
fPtr->objectCls = AllocClass(interp,
|
||||
fPtr->objectCls = TclOOAllocClass(interp,
|
||||
AllocObject(interp, "object", (Namespace *)fPtr->ooNs, NULL));
|
||||
/* Corresponding TclOODecrRefCount in KillFoudation */
|
||||
AddRef(fPtr->objectCls->thisPtr);
|
||||
|
||||
/* This is why it is unnecessary in this routine to replace the
|
||||
/*
|
||||
* This is why it is unnecessary in this routine to replace the
|
||||
* incremented reference count of fPtr->objectCls that was swallowed by
|
||||
* fakeObject. */
|
||||
* fakeObject.
|
||||
*/
|
||||
|
||||
fPtr->objectCls->superclasses.num = 0;
|
||||
ckfree(fPtr->objectCls->superclasses.list);
|
||||
fPtr->objectCls->superclasses.list = NULL;
|
||||
|
||||
/* special initialization for the primordial objects */
|
||||
/*
|
||||
* Special initialization for the primordial objects.
|
||||
*/
|
||||
|
||||
fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT;
|
||||
fPtr->objectCls->flags |= ROOT_OBJECT;
|
||||
TclNewLiteralStringObj(defNsName, "::oo::objdefine");
|
||||
fPtr->objectCls->objDefinitionNs = defNsName;
|
||||
Tcl_IncrRefCount(defNsName);
|
||||
|
||||
fPtr->classCls = AllocClass(interp,
|
||||
fPtr->classCls = TclOOAllocClass(interp,
|
||||
AllocObject(interp, "class", (Namespace *)fPtr->ooNs, NULL));
|
||||
/* Corresponding TclOODecrRefCount in KillFoudation */
|
||||
AddRef(fPtr->classCls->thisPtr);
|
||||
@@ -483,7 +491,10 @@ InitClassSystemRoots(
|
||||
* KillFoundation.
|
||||
*/
|
||||
|
||||
/* Rewire bootstrapped objects. */
|
||||
/*
|
||||
* Rewire bootstrapped objects.
|
||||
*/
|
||||
|
||||
fPtr->objectCls->thisPtr->selfCls = fPtr->classCls;
|
||||
AddRef(fPtr->classCls->thisPtr);
|
||||
TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
|
||||
@@ -494,6 +505,9 @@ InitClassSystemRoots(
|
||||
|
||||
fPtr->classCls->thisPtr->flags |= ROOT_CLASS;
|
||||
fPtr->classCls->flags |= ROOT_CLASS;
|
||||
TclNewLiteralStringObj(defNsName, "::oo::define");
|
||||
fPtr->classCls->clsDefinitionNs = defNsName;
|
||||
Tcl_IncrRefCount(defNsName);
|
||||
|
||||
/* Standard initialization for new Objects */
|
||||
TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls);
|
||||
@@ -839,15 +853,15 @@ ObjectRenamedTrace(
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* DeleteDescendants --
|
||||
* TclOODeleteDescendants --
|
||||
*
|
||||
* Delete all descendants of a particular class.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
DeleteDescendants(
|
||||
void
|
||||
TclOODeleteDescendants(
|
||||
Tcl_Interp *interp, /* The interpreter containing the class. */
|
||||
Object *oPtr) /* The object representing the class. */
|
||||
{
|
||||
@@ -864,7 +878,8 @@ DeleteDescendants(
|
||||
/* This condition also covers the case where mixinSubclassPtr ==
|
||||
* clsPtr
|
||||
*/
|
||||
if (!Deleted(mixinSubclassPtr->thisPtr)) {
|
||||
if (!Deleted(mixinSubclassPtr->thisPtr)
|
||||
&& !(mixinSubclassPtr->thisPtr->flags & DONT_DELETE)) {
|
||||
Tcl_DeleteCommandFromToken(interp,
|
||||
mixinSubclassPtr->thisPtr->command);
|
||||
}
|
||||
@@ -883,8 +898,10 @@ DeleteDescendants(
|
||||
if (clsPtr->subclasses.num > 0) {
|
||||
while (clsPtr->subclasses.num > 0) {
|
||||
subclassPtr = clsPtr->subclasses.list[clsPtr->subclasses.num-1];
|
||||
if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)) {
|
||||
Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command);
|
||||
if (!Deleted(subclassPtr->thisPtr) && !IsRoot(subclassPtr)
|
||||
&& !(subclassPtr->thisPtr->flags & DONT_DELETE)) {
|
||||
Tcl_DeleteCommandFromToken(interp,
|
||||
subclassPtr->thisPtr->command);
|
||||
}
|
||||
TclOORemoveFromSubclasses(subclassPtr, clsPtr);
|
||||
}
|
||||
@@ -906,7 +923,8 @@ DeleteDescendants(
|
||||
* This condition also covers the case where instancePtr == oPtr
|
||||
*/
|
||||
|
||||
if (!Deleted(instancePtr) && !IsRoot(instancePtr)) {
|
||||
if (!Deleted(instancePtr) && !IsRoot(instancePtr) &&
|
||||
!(instancePtr->flags & DONT_DELETE)) {
|
||||
Tcl_DeleteCommandFromToken(interp, instancePtr->command);
|
||||
}
|
||||
TclOORemoveFromInstances(instancePtr, clsPtr);
|
||||
@@ -922,7 +940,7 @@ DeleteDescendants(
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ReleaseClassContents --
|
||||
* TclOOReleaseClassContents --
|
||||
*
|
||||
* Tear down the special class data structure, including deleting all
|
||||
* dependent classes and objects.
|
||||
@@ -930,8 +948,8 @@ DeleteDescendants(
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ReleaseClassContents(
|
||||
void
|
||||
TclOOReleaseClassContents(
|
||||
Tcl_Interp *interp, /* The interpreter containing the class. */
|
||||
Object *oPtr) /* The object representing the class. */
|
||||
{
|
||||
@@ -954,12 +972,22 @@ ReleaseClassContents(
|
||||
} else if (IsRootObject(oPtr)) {
|
||||
Tcl_Panic("deleting class structure for non-deleted %s",
|
||||
"::oo::object");
|
||||
} else {
|
||||
Tcl_Panic("deleting class structure for non-deleted %s",
|
||||
"general object");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop using the class for definition information.
|
||||
*/
|
||||
|
||||
if (clsPtr->clsDefinitionNs) {
|
||||
Tcl_DecrRefCount(clsPtr->clsDefinitionNs);
|
||||
clsPtr->clsDefinitionNs = NULL;
|
||||
}
|
||||
if (clsPtr->objDefinitionNs) {
|
||||
Tcl_DecrRefCount(clsPtr->objDefinitionNs);
|
||||
clsPtr->objDefinitionNs = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Squelch method implementation chain caches.
|
||||
*/
|
||||
@@ -1108,7 +1136,7 @@ ObjectNamespaceDeleted(
|
||||
|
||||
/* Let the dominoes fall */
|
||||
if (oPtr->classPtr) {
|
||||
DeleteDescendants(interp, oPtr);
|
||||
TclOODeleteDescendants(interp, oPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1184,7 +1212,9 @@ ObjectNamespaceDeleted(
|
||||
TclOORemoveFromInstances(oPtr, mixinPtr);
|
||||
TclOODecrRefCount(mixinPtr->thisPtr);
|
||||
}
|
||||
ckfree(oPtr->mixins.list);
|
||||
if (oPtr->mixins.list != NULL) {
|
||||
ckfree(oPtr->mixins.list);
|
||||
}
|
||||
}
|
||||
|
||||
FOREACH(filterObj, oPtr->filters) {
|
||||
@@ -1237,8 +1267,8 @@ ObjectNamespaceDeleted(
|
||||
|
||||
/*
|
||||
* Because an object can be a class that is an instance of itself, the
|
||||
* class object's class structure should only be cleaned after most of the
|
||||
* cleanup on the object is done.
|
||||
* class object's class structure should only be cleaned after most of
|
||||
* the cleanup on the object is done.
|
||||
*
|
||||
* The class of objects needs some special care; if it is deleted (and
|
||||
* we're not killing the whole interpreter) we force the delete of the
|
||||
@@ -1253,7 +1283,7 @@ ObjectNamespaceDeleted(
|
||||
}
|
||||
|
||||
if (oPtr->classPtr != NULL) {
|
||||
ReleaseClassContents(interp, oPtr);
|
||||
TclOOReleaseClassContents(interp, oPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1357,6 +1387,41 @@ TclOOAddToInstances(
|
||||
AddRef(oPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOORemoveFromMixins --
|
||||
*
|
||||
* Utility function to remove a class from the list of mixins within an
|
||||
* object.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclOORemoveFromMixins(
|
||||
Class *mixinPtr, /* The mixin to remove. */
|
||||
Object *oPtr) /* The object (possibly) containing the
|
||||
* reference to the mixin. */
|
||||
{
|
||||
int i, res = 0;
|
||||
Class *mixPtr;
|
||||
|
||||
FOREACH(mixPtr, oPtr->mixins) {
|
||||
if (mixinPtr == mixPtr) {
|
||||
RemoveItem(Class, oPtr->mixins, i);
|
||||
TclOODecrRefCount(mixPtr->thisPtr);
|
||||
res++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oPtr->mixins.num == 0) {
|
||||
ckfree(oPtr->mixins.list);
|
||||
oPtr->mixins.list = NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1489,10 +1554,10 @@ TclOOAddToMixinSubs(
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* AllocClass --
|
||||
* TclOOAllocClass --
|
||||
*
|
||||
* Allocate a basic class. Does not add class to its
|
||||
* class's instance list.
|
||||
* Allocate a basic class. Does not add class to its class's instance
|
||||
* list.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1516,8 +1581,8 @@ InitClassPath(
|
||||
}
|
||||
}
|
||||
|
||||
static Class *
|
||||
AllocClass(
|
||||
Class *
|
||||
TclOOAllocClass(
|
||||
Tcl_Interp *interp, /* Interpreter within which to allocate the
|
||||
* class. */
|
||||
Object *useThisObj) /* Object that is to act as the class
|
||||
@@ -1758,13 +1823,13 @@ TclNewObjectInstanceCommon(
|
||||
|
||||
if (TclOOIsReachable(fPtr->classCls, classPtr)) {
|
||||
/*
|
||||
* Is a class, so attach a class structure. Note that the AllocClass
|
||||
* function splices the structure into the object, so we don't have
|
||||
* to. Once that's done, we need to repatch the object to have the
|
||||
* right class since AllocClass interferes with that.
|
||||
* Is a class, so attach a class structure. Note that the
|
||||
* TclOOAllocClass function splices the structure into the object, so
|
||||
* we don't have to. Once that's done, we need to repatch the object
|
||||
* to have the right class since TclOOAllocClass interferes with that.
|
||||
*/
|
||||
|
||||
AllocClass(interp, oPtr);
|
||||
TclOOAllocClass(interp, oPtr);
|
||||
TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls);
|
||||
} else {
|
||||
oPtr->classPtr = NULL;
|
||||
|
||||
+278
-17
@@ -15,6 +15,7 @@
|
||||
#endif
|
||||
#include "tclInt.h"
|
||||
#include "tclOOInt.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Structure containing a CallContext and any other values needed only during
|
||||
@@ -30,6 +31,22 @@ struct ChainBuilder {
|
||||
* for. */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structures used for traversing the class hierarchy to find out where
|
||||
* definitions are supposed to be done.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Class *definerCls;
|
||||
Tcl_Obj *namespaceName;
|
||||
} DefineEntry;
|
||||
|
||||
typedef struct {
|
||||
DefineEntry *list;
|
||||
int num;
|
||||
int size;
|
||||
} DefineChain;
|
||||
|
||||
/*
|
||||
* Extra flags used for call chain management.
|
||||
*/
|
||||
@@ -77,6 +94,9 @@ static void AddClassFiltersToCallContext(Object *const oPtr,
|
||||
static void AddClassMethodNames(Class *clsPtr, const int flags,
|
||||
Tcl_HashTable *const namesPtr,
|
||||
Tcl_HashTable *const examinedClassesPtr);
|
||||
static inline void AddDefinitionNamespaceToChain(Class *const definerCls,
|
||||
Tcl_Obj *const namespaceName,
|
||||
DefineChain *const definePtr, int flags);
|
||||
static inline void AddMethodToCallChain(Method *const mPtr,
|
||||
struct ChainBuilder *const cbPtr,
|
||||
Tcl_HashTable *const doneFilters,
|
||||
@@ -105,6 +125,10 @@ static int AddSimpleClassChainToCallContext(Class *classPtr,
|
||||
struct ChainBuilder *const cbPtr,
|
||||
Tcl_HashTable *const doneFilters, int flags,
|
||||
Class *const filterDecl);
|
||||
static void AddSimpleClassDefineNamespaces(Class *classPtr,
|
||||
DefineChain *const definePtr, int flags);
|
||||
static inline void AddSimpleDefineNamespaces(Object *const oPtr,
|
||||
DefineChain *const definePtr, int flags);
|
||||
static int CmpStr(const void *ptr1, const void *ptr2);
|
||||
static void DupMethodNameRep(Tcl_Obj *srcPtr, Tcl_Obj *dstPtr);
|
||||
static Tcl_NRPostProc FinalizeMethodRefs;
|
||||
@@ -128,6 +152,7 @@ static const Tcl_ObjType methodNameType = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -222,11 +247,12 @@ StashCallChain(
|
||||
Tcl_Obj *objPtr,
|
||||
CallChain *callPtr)
|
||||
{
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
callPtr->refCount++;
|
||||
TclGetString(objPtr);
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->typePtr = &methodNameType;
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = callPtr;
|
||||
ir.twoPtrValue.ptr1 = callPtr;
|
||||
Tcl_StoreIntRep(objPtr, &methodNameType, &ir);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -253,21 +279,16 @@ DupMethodNameRep(
|
||||
Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *dstPtr)
|
||||
{
|
||||
register CallChain *callPtr = srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
dstPtr->typePtr = &methodNameType;
|
||||
dstPtr->internalRep.twoPtrValue.ptr1 = callPtr;
|
||||
callPtr->refCount++;
|
||||
StashCallChain(dstPtr,
|
||||
TclFetchIntRep(srcPtr, &methodNameType)->twoPtrValue.ptr1);
|
||||
}
|
||||
|
||||
static void
|
||||
FreeMethodNameRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
register CallChain *callPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
TclOODeleteChain(callPtr);
|
||||
objPtr->typePtr = NULL;
|
||||
TclOODeleteChain(
|
||||
TclFetchIntRep(objPtr, &methodNameType)->twoPtrValue.ptr1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -610,7 +631,7 @@ SortMethodNames(
|
||||
|
||||
if (i > 0) {
|
||||
if (i > 1) {
|
||||
qsort((void *) strings, (unsigned) i, sizeof(char *), CmpStr);
|
||||
qsort((void *) strings, i, sizeof(char *), CmpStr);
|
||||
}
|
||||
*stringsPtr = strings;
|
||||
} else {
|
||||
@@ -1165,15 +1186,16 @@ TclOOGetCallContext(
|
||||
* the object, and in the class).
|
||||
*/
|
||||
|
||||
const Tcl_ObjIntRep *irPtr;
|
||||
const int reuseMask = (WANT_PUBLIC(flags) ? ~0 : ~PUBLIC_METHOD);
|
||||
|
||||
if (cacheInThisObj->typePtr == &methodNameType) {
|
||||
callPtr = cacheInThisObj->internalRep.twoPtrValue.ptr1;
|
||||
if ((irPtr = TclFetchIntRep(cacheInThisObj, &methodNameType))) {
|
||||
callPtr = irPtr->twoPtrValue.ptr1;
|
||||
if (IsStillValid(callPtr, oPtr, flags, reuseMask)) {
|
||||
callPtr->refCount++;
|
||||
goto returnContext;
|
||||
}
|
||||
FreeMethodNameRep(cacheInThisObj);
|
||||
Tcl_StoreIntRep(cacheInThisObj, &methodNameType, NULL);
|
||||
}
|
||||
|
||||
if (oPtr->flags & USE_CLASS_CACHE) {
|
||||
@@ -1704,7 +1726,6 @@ AddSimpleClassChainToCallContext(
|
||||
if (flags & CONSTRUCTOR) {
|
||||
AddMethodToCallChain(classPtr->constructorPtr, cbPtr, doneFilters,
|
||||
filterDecl, flags);
|
||||
|
||||
} else if (flags & DESTRUCTOR) {
|
||||
AddMethodToCallChain(classPtr->destructorPtr, cbPtr, doneFilters,
|
||||
filterDecl, flags);
|
||||
@@ -1836,6 +1857,246 @@ TclOORenderCallChain(
|
||||
return resultObj;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOGetDefineContextNamespace --
|
||||
*
|
||||
* Responsible for determining which namespace to use for definitions.
|
||||
* This is done by building a define chain, which models (strongly!) the
|
||||
* way that a call chain works but with a different internal model.
|
||||
*
|
||||
* Then it walks the chain to find the first namespace name that actually
|
||||
* resolves to an existing namespace.
|
||||
*
|
||||
* Returns:
|
||||
* Name of namespace, or NULL if none can be found. Note that this
|
||||
* function does *not* set an error message in the interpreter on failure.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define DEFINE_CHAIN_STATIC_SIZE 4 /* Enough space to store most cases. */
|
||||
|
||||
Tcl_Namespace *
|
||||
TclOOGetDefineContextNamespace(
|
||||
Tcl_Interp *interp, /* In what interpreter should namespace names
|
||||
* actually be resolved. */
|
||||
Object *oPtr, /* The object to get the context for. */
|
||||
int forClass) /* What sort of context are we looking for.
|
||||
* If true, we are going to use this for
|
||||
* [oo::define], otherwise, we are going to
|
||||
* use this for [oo::objdefine]. */
|
||||
{
|
||||
DefineChain define;
|
||||
DefineEntry staticSpace[DEFINE_CHAIN_STATIC_SIZE];
|
||||
DefineEntry *entryPtr;
|
||||
Tcl_Namespace *nsPtr = NULL;
|
||||
int i;
|
||||
|
||||
define.list = staticSpace;
|
||||
define.num = 0;
|
||||
define.size = DEFINE_CHAIN_STATIC_SIZE;
|
||||
|
||||
/*
|
||||
* Add the actual define locations. We have to do this twice to handle
|
||||
* class mixins right.
|
||||
*/
|
||||
|
||||
AddSimpleDefineNamespaces(oPtr, &define, forClass | BUILDING_MIXINS);
|
||||
AddSimpleDefineNamespaces(oPtr, &define, forClass);
|
||||
|
||||
/*
|
||||
* Go through the list until we find a namespace whose name we can
|
||||
* resolve.
|
||||
*/
|
||||
|
||||
FOREACH_STRUCT(entryPtr, define) {
|
||||
if (TclGetNamespaceFromObj(interp, entryPtr->namespaceName,
|
||||
&nsPtr) == TCL_OK) {
|
||||
break;
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
if (define.list != staticSpace) {
|
||||
ckfree(define.list);
|
||||
}
|
||||
return nsPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* AddSimpleDefineNamespaces --
|
||||
*
|
||||
* Adds to the definition chain all the definitions provided by an
|
||||
* object's class and its mixins, taking into account everything they
|
||||
* inherit from.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline void
|
||||
AddSimpleDefineNamespaces(
|
||||
Object *const oPtr, /* Object to add define chain entries for. */
|
||||
DefineChain *const definePtr,
|
||||
/* Where to add the define chain entries. */
|
||||
int flags) /* What sort of define chain are we
|
||||
* building. */
|
||||
{
|
||||
Class *mixinPtr;
|
||||
int i;
|
||||
|
||||
FOREACH(mixinPtr, oPtr->mixins) {
|
||||
AddSimpleClassDefineNamespaces(mixinPtr, definePtr,
|
||||
flags | TRAVERSED_MIXIN);
|
||||
}
|
||||
|
||||
AddSimpleClassDefineNamespaces(oPtr->selfCls, definePtr, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* AddSimpleClassDefineNamespaces --
|
||||
*
|
||||
* Adds to the definition chain all the definitions provided by a class
|
||||
* and its superclasses and its class mixins.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
AddSimpleClassDefineNamespaces(
|
||||
Class *classPtr, /* Class to add the define chain entries for. */
|
||||
DefineChain *const definePtr,
|
||||
/* Where to add the define chain entries. */
|
||||
int flags) /* What sort of define chain are we
|
||||
* building. */
|
||||
{
|
||||
int i;
|
||||
Class *superPtr;
|
||||
|
||||
/*
|
||||
* We hard-code the tail-recursive form. It's by far the most common case
|
||||
* *and* it is much more gentle on the stack.
|
||||
*/
|
||||
|
||||
tailRecurse:
|
||||
FOREACH(superPtr, classPtr->mixins) {
|
||||
AddSimpleClassDefineNamespaces(superPtr, definePtr,
|
||||
flags | TRAVERSED_MIXIN);
|
||||
}
|
||||
|
||||
if (flags & ~(TRAVERSED_MIXIN | BUILDING_MIXINS)) {
|
||||
AddDefinitionNamespaceToChain(classPtr, classPtr->clsDefinitionNs,
|
||||
definePtr, flags);
|
||||
} else {
|
||||
AddDefinitionNamespaceToChain(classPtr, classPtr->objDefinitionNs,
|
||||
definePtr, flags);
|
||||
}
|
||||
|
||||
switch (classPtr->superclasses.num) {
|
||||
case 1:
|
||||
classPtr = classPtr->superclasses.list[0];
|
||||
goto tailRecurse;
|
||||
default:
|
||||
FOREACH(superPtr, classPtr->superclasses) {
|
||||
AddSimpleClassDefineNamespaces(superPtr, definePtr, flags);
|
||||
}
|
||||
case 0:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* AddDefinitionNamespaceToChain --
|
||||
*
|
||||
* Adds a single item to the definition chain (if it is meaningful),
|
||||
* reallocating the space for the chain if necessary.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline void
|
||||
AddDefinitionNamespaceToChain(
|
||||
Class *const definerCls, /* What class defines this entry. */
|
||||
Tcl_Obj *const namespaceName, /* The name for this entry (or NULL, a
|
||||
* no-op). */
|
||||
DefineChain *const definePtr,
|
||||
/* The define chain to add the method
|
||||
* implementation to. */
|
||||
int flags) /* Used to check if we're mixin-consistent
|
||||
* only. Mixin-consistent means that either
|
||||
* we're looking to add things from a mixin
|
||||
* and we have passed a mixin, or we're not
|
||||
* looking to add things from a mixin and have
|
||||
* not passed a mixin. */
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Return if this entry is blank. This is also where we enforce
|
||||
* mixin-consistency.
|
||||
*/
|
||||
|
||||
if (namespaceName == NULL || !MIXIN_CONSISTENT(flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* First test whether the method is already in the call chain.
|
||||
*/
|
||||
|
||||
for (i=0 ; i<definePtr->num ; i++) {
|
||||
if (definePtr->list[i].definerCls == definerCls) {
|
||||
/*
|
||||
* 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 invocations in the call chain; it just rearranges them.
|
||||
*
|
||||
* We skip changing anything if the place we found was already at
|
||||
* the end of the list.
|
||||
*/
|
||||
|
||||
if (i < definePtr->num - 1) {
|
||||
memmove(&definePtr->list[i], &definePtr->list[i + 1],
|
||||
sizeof(DefineEntry) * (definePtr->num - i - 1));
|
||||
definePtr->list[i].definerCls = definerCls;
|
||||
definePtr->list[i].namespaceName = namespaceName;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to really add the define. This is made a bit more complex by the
|
||||
* fact that we are using some "static" space initially, and only start
|
||||
* realloc-ing if the chain gets long.
|
||||
*/
|
||||
|
||||
if (definePtr->num == definePtr->size) {
|
||||
definePtr->size *= 2;
|
||||
if (definePtr->num == DEFINE_CHAIN_STATIC_SIZE) {
|
||||
DefineEntry *staticList = definePtr->list;
|
||||
|
||||
definePtr->list =
|
||||
ckalloc(sizeof(DefineEntry) * definePtr->size);
|
||||
memcpy(definePtr->list, staticList,
|
||||
sizeof(DefineEntry) * definePtr->num);
|
||||
} else {
|
||||
definePtr->list = ckrealloc(definePtr->list,
|
||||
sizeof(DefineEntry) * definePtr->size);
|
||||
}
|
||||
}
|
||||
definePtr->list[i].definerCls = definerCls;
|
||||
definePtr->list[i].namespaceName = namespaceName;
|
||||
definePtr->num++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
|
||||
+208
-27
@@ -63,6 +63,8 @@ static inline int MagicDefinitionInvoke(Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static inline Class * GetClassInOuterContext(Tcl_Interp *interp,
|
||||
Tcl_Obj *className, const char *errMsg);
|
||||
static inline Tcl_Namespace *GetNamespaceInOuterContext(Tcl_Interp *interp,
|
||||
Tcl_Obj *namespaceName);
|
||||
static inline int InitDefineContext(Tcl_Interp *interp,
|
||||
Tcl_Namespace *namespacePtr, Object *oPtr,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
@@ -828,8 +830,7 @@ InitDefineContext(
|
||||
|
||||
if (namespacePtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot process definitions; support namespace deleted",
|
||||
-1));
|
||||
"no definition namespace available", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -888,12 +889,12 @@ TclOOGetDefineCmdContext(
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* GetClassInOuterContext --
|
||||
* GetClassInOuterContext, GetNamespaceInOuterContext --
|
||||
*
|
||||
* Wrapper round Tcl_GetObjectFromObj to perform the lookup in the
|
||||
* context that called oo::define (or equivalent). Note that this may
|
||||
* have to go up multiple levels to get the level that we started doing
|
||||
* definitions at.
|
||||
* Wrappers round Tcl_GetObjectFromObj and TclGetNamespaceFromObj to
|
||||
* perform the lookup in the context that called oo::define (or
|
||||
* equivalent). Note that this may have to go up multiple levels to get
|
||||
* the level that we started doing definitions at.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -928,6 +929,31 @@ GetClassInOuterContext(
|
||||
}
|
||||
return oPtr->classPtr;
|
||||
}
|
||||
|
||||
static inline Tcl_Namespace *
|
||||
GetNamespaceInOuterContext(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *namespaceName)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Namespace *nsPtr;
|
||||
int result;
|
||||
CallFrame *savedFramePtr = iPtr->varFramePtr;
|
||||
|
||||
while (iPtr->varFramePtr->isProcCallFrame == FRAME_IS_OO_DEFINE
|
||||
|| iPtr->varFramePtr->isProcCallFrame == PRIVATE_FRAME) {
|
||||
if (iPtr->varFramePtr->callerVarPtr == NULL) {
|
||||
Tcl_Panic("getting outer context when already in global context");
|
||||
}
|
||||
iPtr->varFramePtr = iPtr->varFramePtr->callerVarPtr;
|
||||
}
|
||||
result = TclGetNamespaceFromObj(interp, namespaceName, &nsPtr);
|
||||
iPtr->varFramePtr = savedFramePtr;
|
||||
if (result != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
return nsPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -1053,7 +1079,7 @@ TclOODefineObjCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
Tcl_Namespace *nsPtr;
|
||||
Object *oPtr;
|
||||
int result;
|
||||
|
||||
@@ -1068,7 +1094,7 @@ TclOODefineObjCmd(
|
||||
}
|
||||
if (oPtr->classPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%s does not refer to a class",TclGetString(objv[1])));
|
||||
"%s does not refer to a class", TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
|
||||
TclGetString(objv[1]), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -1079,7 +1105,8 @@ TclOODefineObjCmd(
|
||||
* command(s).
|
||||
*/
|
||||
|
||||
if (InitDefineContext(interp, fPtr->defineNs, oPtr, objc,objv) != TCL_OK){
|
||||
nsPtr = TclOOGetDefineContextNamespace(interp, oPtr, 1);
|
||||
if (InitDefineContext(interp, nsPtr, oPtr, objc, objv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1095,7 +1122,7 @@ TclOODefineObjCmd(
|
||||
}
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
result = MagicDefinitionInvoke(interp, fPtr->defineNs, 2, objc, objv);
|
||||
result = MagicDefinitionInvoke(interp, nsPtr, 2, objc, objv);
|
||||
}
|
||||
TclOODecrRefCount(oPtr);
|
||||
|
||||
@@ -1128,7 +1155,7 @@ TclOOObjDefObjCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
Tcl_Namespace *nsPtr;
|
||||
Object *oPtr;
|
||||
int result;
|
||||
|
||||
@@ -1147,7 +1174,8 @@ TclOOObjDefObjCmd(
|
||||
* command(s).
|
||||
*/
|
||||
|
||||
if (InitDefineContext(interp, fPtr->objdefNs, oPtr, objc,objv) != TCL_OK){
|
||||
nsPtr = TclOOGetDefineContextNamespace(interp, oPtr, 0);
|
||||
if (InitDefineContext(interp, nsPtr, oPtr, objc, objv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1163,7 +1191,7 @@ TclOOObjDefObjCmd(
|
||||
}
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 2, objc, objv);
|
||||
result = MagicDefinitionInvoke(interp, nsPtr, 2, objc, objv);
|
||||
}
|
||||
TclOODecrRefCount(oPtr);
|
||||
|
||||
@@ -1196,7 +1224,7 @@ TclOODefineSelfObjCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
Tcl_Namespace *nsPtr;
|
||||
Object *oPtr;
|
||||
int result, private;
|
||||
|
||||
@@ -1217,7 +1245,8 @@ TclOODefineSelfObjCmd(
|
||||
* command(s).
|
||||
*/
|
||||
|
||||
if (InitDefineContext(interp, fPtr->objdefNs, oPtr, objc,objv) != TCL_OK){
|
||||
nsPtr = TclOOGetDefineContextNamespace(interp, oPtr, 0);
|
||||
if (InitDefineContext(interp, nsPtr, oPtr, objc, objv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (private) {
|
||||
@@ -1236,7 +1265,7 @@ TclOODefineSelfObjCmd(
|
||||
}
|
||||
TclDecrRefCount(objNameObj);
|
||||
} else {
|
||||
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 1, objc, objv);
|
||||
result = MagicDefinitionInvoke(interp, nsPtr, 1, objc, objv);
|
||||
}
|
||||
TclOODecrRefCount(oPtr);
|
||||
|
||||
@@ -1375,6 +1404,8 @@ TclOODefineClassObjCmd(
|
||||
{
|
||||
Object *oPtr;
|
||||
Class *clsPtr;
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
int wasClass, willBeClass;
|
||||
|
||||
/*
|
||||
* Parse the context to get the object to operate on.
|
||||
@@ -1410,12 +1441,20 @@ TclOODefineClassObjCmd(
|
||||
if (clsPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (oPtr == clsPtr->thisPtr) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"may not change classes into an instance of themselves", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's class.
|
||||
*/
|
||||
|
||||
wasClass = (oPtr->classPtr != NULL);
|
||||
willBeClass = (TclOOIsReachable(fPtr->classCls, clsPtr));
|
||||
|
||||
if (oPtr->selfCls != clsPtr) {
|
||||
TclOORemoveFromInstances(oPtr, oPtr->selfCls);
|
||||
TclOODecrRefCount(oPtr->selfCls->thisPtr);
|
||||
@@ -1423,6 +1462,28 @@ TclOODefineClassObjCmd(
|
||||
AddRef(oPtr->selfCls->thisPtr);
|
||||
TclOOAddToInstances(oPtr, oPtr->selfCls);
|
||||
|
||||
/*
|
||||
* Create or delete the class guts if necessary.
|
||||
*/
|
||||
|
||||
if (wasClass && !willBeClass) {
|
||||
/*
|
||||
* This is the most global of all epochs. Bump it! No cache can be
|
||||
* trusted!
|
||||
*/
|
||||
|
||||
TclOORemoveFromMixins(oPtr->classPtr, oPtr);
|
||||
oPtr->fPtr->epoch++;
|
||||
oPtr->flags |= DONT_DELETE;
|
||||
TclOODeleteDescendants(interp, oPtr);
|
||||
oPtr->flags &= ~DONT_DELETE;
|
||||
TclOOReleaseClassContents(interp, oPtr);
|
||||
ckfree(oPtr->classPtr);
|
||||
oPtr->classPtr = NULL;
|
||||
} else if (!wasClass && willBeClass) {
|
||||
TclOOAllocClass(interp, oPtr);
|
||||
}
|
||||
|
||||
if (oPtr->classPtr != NULL) {
|
||||
BumpGlobalEpoch(interp, oPtr->classPtr);
|
||||
} else {
|
||||
@@ -1501,6 +1562,91 @@ TclOODefineConstructorObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineDefnNsObjCmd --
|
||||
*
|
||||
* Implementation of the "definitionnamespace" subcommand of the
|
||||
* "oo::define" command.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclOODefineDefnNsObjCmd(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
static const char *kindList[] = {
|
||||
"-class",
|
||||
"-instance",
|
||||
NULL
|
||||
};
|
||||
int kind = 0;
|
||||
Object *oPtr;
|
||||
Tcl_Namespace *nsPtr;
|
||||
Tcl_Obj *nsNamePtr, **storagePtr;
|
||||
|
||||
oPtr = (Object *) TclOOGetDefineCmdContext(interp);
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (!oPtr->classPtr) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"attempt to misuse API", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (oPtr->flags & (ROOT_OBJECT | ROOT_CLASS)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"may not modify the definition namespace of the root classes",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the arguments and work out what the user wants to do.
|
||||
*/
|
||||
|
||||
if (objc != 2 && objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?kind? namespace");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objc == 3 && Tcl_GetIndexFromObj(interp, objv[1], kindList, "kind", 0,
|
||||
&kind) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (!Tcl_GetString(objv[objc - 1])[0]) {
|
||||
nsNamePtr = NULL;
|
||||
} else {
|
||||
nsPtr = GetNamespaceInOuterContext(interp, objv[objc - 1]);
|
||||
if (nsPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
nsNamePtr = Tcl_NewStringObj(nsPtr->fullName, -1);
|
||||
Tcl_IncrRefCount(nsNamePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the correct field of the class definition.
|
||||
*/
|
||||
|
||||
if (kind) {
|
||||
storagePtr = &oPtr->classPtr->objDefinitionNs;
|
||||
} else {
|
||||
storagePtr = &oPtr->classPtr->clsDefinitionNs;
|
||||
}
|
||||
if (*storagePtr != NULL) {
|
||||
Tcl_DecrRefCount(*storagePtr);
|
||||
}
|
||||
*storagePtr = nsNamePtr;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1801,12 +1947,28 @@ TclOODefineMethodObjCmd(
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
/*
|
||||
* Table of export modes for methods and their corresponding enum.
|
||||
*/
|
||||
|
||||
static const char *const exportModes[] = {
|
||||
"-export",
|
||||
"-private",
|
||||
"-unexport",
|
||||
NULL
|
||||
};
|
||||
enum ExportMode {
|
||||
MODE_EXPORT,
|
||||
MODE_PRIVATE,
|
||||
MODE_UNEXPORT
|
||||
} exportMode;
|
||||
|
||||
int isInstanceMethod = (clientData != NULL);
|
||||
Object *oPtr;
|
||||
int isPublic;
|
||||
int isPublic = 0;
|
||||
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "name args body");
|
||||
if (objc < 4 || objc > 5) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "name ?option? args body");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1820,10 +1982,29 @@ TclOODefineMethodObjCmd(
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*")
|
||||
? PUBLIC_METHOD : 0;
|
||||
if (IsPrivateDefine(interp)) {
|
||||
isPublic = TRUE_PRIVATE_METHOD;
|
||||
if (objc == 5) {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[2], exportModes, "export flag",
|
||||
0, (int *) &exportMode) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
switch (exportMode) {
|
||||
case MODE_EXPORT:
|
||||
isPublic = PUBLIC_METHOD;
|
||||
break;
|
||||
case MODE_PRIVATE:
|
||||
isPublic = TRUE_PRIVATE_METHOD;
|
||||
break;
|
||||
case MODE_UNEXPORT:
|
||||
isPublic = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (IsPrivateDefine(interp)) {
|
||||
isPublic = TRUE_PRIVATE_METHOD;
|
||||
} else {
|
||||
isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*")
|
||||
? PUBLIC_METHOD : 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1832,12 +2013,12 @@ TclOODefineMethodObjCmd(
|
||||
|
||||
if (isInstanceMethod) {
|
||||
if (TclOONewProcInstanceMethod(interp, oPtr, isPublic, objv[1],
|
||||
objv[2], objv[3], NULL) == NULL) {
|
||||
objv[objc - 2], objv[objc - 1], NULL) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
if (TclOONewProcMethod(interp, oPtr->classPtr, isPublic, objv[1],
|
||||
objv[2], objv[3], NULL) == NULL) {
|
||||
objv[objc - 2], objv[objc - 1], NULL) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+60
-6
@@ -33,6 +33,7 @@ static Tcl_ObjCmdProc InfoObjectVariablesCmd;
|
||||
static Tcl_ObjCmdProc InfoClassCallCmd;
|
||||
static Tcl_ObjCmdProc InfoClassConstrCmd;
|
||||
static Tcl_ObjCmdProc InfoClassDefnCmd;
|
||||
static Tcl_ObjCmdProc InfoClassDefnNsCmd;
|
||||
static Tcl_ObjCmdProc InfoClassDestrCmd;
|
||||
static Tcl_ObjCmdProc InfoClassFiltersCmd;
|
||||
static Tcl_ObjCmdProc InfoClassForwardCmd;
|
||||
@@ -73,6 +74,7 @@ static const EnsembleImplMap infoClassCmds[] = {
|
||||
{"call", InfoClassCallCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"constructor", InfoClassConstrCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"definition", InfoClassDefnCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"definitionnamespace", InfoClassDefnNsCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"destructor", InfoClassDestrCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"filters", InfoClassFiltersCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"forward", InfoClassForwardCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
@@ -116,12 +118,14 @@ TclOOInitInfo(
|
||||
*/
|
||||
|
||||
infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY);
|
||||
Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
|
||||
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1),
|
||||
Tcl_NewStringObj("::oo::InfoObject", -1));
|
||||
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1),
|
||||
Tcl_NewStringObj("::oo::InfoClass", -1));
|
||||
Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
|
||||
if (infoCmd) {
|
||||
Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
|
||||
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1),
|
||||
Tcl_NewStringObj("::oo::InfoObject", -1));
|
||||
Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1),
|
||||
Tcl_NewStringObj("::oo::InfoClass", -1));
|
||||
Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1030,6 +1034,56 @@ InfoClassDefnCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* InfoClassDefnNsCmd --
|
||||
*
|
||||
* Implements [info class definitionnamespace $clsName ?$kind?]
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
InfoClassDefnNsCmd(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
static const char *kindList[] = {
|
||||
"-class",
|
||||
"-instance",
|
||||
NULL
|
||||
};
|
||||
int kind = 0;
|
||||
Tcl_Obj *nsNamePtr;
|
||||
Class *clsPtr;
|
||||
|
||||
if (objc != 2 && objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "className ?kind?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
clsPtr = GetClassFromObj(interp, objv[1]);
|
||||
if (clsPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objc == 3 && Tcl_GetIndexFromObj(interp, objv[2], kindList, "kind", 0,
|
||||
&kind) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (kind) {
|
||||
nsNamePtr = clsPtr->objDefinitionNs;
|
||||
} else {
|
||||
nsNamePtr = clsPtr->clsDefinitionNs;
|
||||
}
|
||||
if (nsNamePtr) {
|
||||
Tcl_SetObjResult(interp, nsNamePtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+36
-2
@@ -47,7 +47,7 @@ typedef struct Method {
|
||||
* special flag record which is just used for
|
||||
* the setting of the flags field. */
|
||||
int refCount;
|
||||
ClientData clientData; /* Type-specific data. */
|
||||
void *clientData; /* Type-specific data. */
|
||||
Tcl_Obj *namePtr; /* Name of the method. */
|
||||
struct Object *declaringObjectPtr;
|
||||
/* The object that declares this method, or
|
||||
@@ -84,7 +84,7 @@ typedef struct ProcedureMethod {
|
||||
* body bytecodes. */
|
||||
int flags; /* Flags to control features. */
|
||||
int refCount;
|
||||
ClientData clientData;
|
||||
void *clientData;
|
||||
TclOO_PmCDDeleteProc *deleteClientdataProc;
|
||||
TclOO_PmCDCloneProc *cloneClientdataProc;
|
||||
ProcErrorProc *errProc; /* Replacement error handler. */
|
||||
@@ -242,6 +242,10 @@ typedef struct Object {
|
||||
/* Object/class has (or had) private methods,
|
||||
* and so shouldn't be cached so
|
||||
* aggressively. */
|
||||
#define DONT_DELETE 0x40000 /* Inhibit deletion of this object. Used
|
||||
* during fundamental object type mutation to
|
||||
* make sure that the object actually survives
|
||||
* to the end of the operation. */
|
||||
|
||||
/*
|
||||
* And the definition of a class. Note that every class also has an associated
|
||||
@@ -300,6 +304,24 @@ typedef struct Class {
|
||||
PrivateVariableList privateVariables;
|
||||
/* Configurations for the variable resolver
|
||||
* used inside methods. */
|
||||
Tcl_Obj *clsDefinitionNs; /* Name of the namespace to use for
|
||||
* definitions commands of instances of this
|
||||
* class in when those instances are defined
|
||||
* as classes. If NULL, use the value from the
|
||||
* class hierarchy. It's an error at
|
||||
* [oo::define] call time if this namespace is
|
||||
* defined but doesn't exist; we also check at
|
||||
* setting time but don't check between
|
||||
* times. */
|
||||
Tcl_Obj *objDefinitionNs; /* Name of the namespace to use for
|
||||
* definitions commands of instances of this
|
||||
* class in when those instances are defined
|
||||
* as instances. If NULL, use the value from
|
||||
* the class hierarchy. It's an error at
|
||||
* [oo::objdefine]/[self] call time if this
|
||||
* namespace is defined but doesn't exist; we
|
||||
* also check at setting time but don't check
|
||||
* between times. */
|
||||
} Class;
|
||||
|
||||
/*
|
||||
@@ -437,6 +459,9 @@ MODULE_SCOPE int TclOOObjDefObjCmd(ClientData clientData,
|
||||
MODULE_SCOPE int TclOODefineConstructorObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const *objv);
|
||||
MODULE_SCOPE int TclOODefineDefnNsObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const *objv);
|
||||
MODULE_SCOPE int TclOODefineDeleteMethodObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const *objv);
|
||||
@@ -526,6 +551,8 @@ MODULE_SCOPE int TclOO_Object_VarName(ClientData clientData,
|
||||
MODULE_SCOPE void TclOOAddToInstances(Object *oPtr, Class *clsPtr);
|
||||
MODULE_SCOPE void TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr);
|
||||
MODULE_SCOPE void TclOOAddToSubclasses(Class *subPtr, Class *superPtr);
|
||||
MODULE_SCOPE Class * TclOOAllocClass(Tcl_Interp *interp,
|
||||
Object *useThisObj);
|
||||
MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp,
|
||||
Tcl_Class cls, const char *nameStr,
|
||||
const char *nsNameStr, int objc,
|
||||
@@ -540,11 +567,15 @@ MODULE_SCOPE int TclOODefineSlots(Foundation *fPtr);
|
||||
MODULE_SCOPE void TclOODeleteChain(CallChain *callPtr);
|
||||
MODULE_SCOPE void TclOODeleteChainCache(Tcl_HashTable *tablePtr);
|
||||
MODULE_SCOPE void TclOODeleteContext(CallContext *contextPtr);
|
||||
MODULE_SCOPE void TclOODeleteDescendants(Tcl_Interp *interp,
|
||||
Object *oPtr);
|
||||
MODULE_SCOPE void TclOODelMethodRef(Method *method);
|
||||
MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr,
|
||||
Tcl_Obj *methodNameObj, int flags,
|
||||
Object *contextObjPtr, Class *contextClsPtr,
|
||||
Tcl_Obj *cacheInThisObj);
|
||||
MODULE_SCOPE Tcl_Namespace *TclOOGetDefineContextNamespace(
|
||||
Tcl_Interp *interp, Object *oPtr, int forClass);
|
||||
MODULE_SCOPE CallChain *TclOOGetStereotypeCallChain(Class *clsPtr,
|
||||
Tcl_Obj *methodNameObj, int flags);
|
||||
MODULE_SCOPE Foundation *TclOOGetFoundation(Tcl_Interp *interp);
|
||||
@@ -567,7 +598,10 @@ MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp,
|
||||
MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr,
|
||||
const DeclaredClassMethod *dcm);
|
||||
MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr);
|
||||
MODULE_SCOPE void TclOOReleaseClassContents(Tcl_Interp *interp,
|
||||
Object *oPtr);
|
||||
MODULE_SCOPE int TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
|
||||
MODULE_SCOPE int TclOORemoveFromMixins(Class *mixinPtr, Object *oPtr);
|
||||
MODULE_SCOPE int TclOORemoveFromMixinSubs(Class *subPtr,
|
||||
Class *mixinPtr);
|
||||
MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr,
|
||||
|
||||
+32
-37
@@ -67,7 +67,7 @@ static Tcl_Obj ** InitEnsembleRewrite(Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const *objv, int toRewrite,
|
||||
int rewriteLength, Tcl_Obj *const *rewriteObjs,
|
||||
int *lengthPtr);
|
||||
static int InvokeProcedureMethod(ClientData clientData,
|
||||
static int InvokeProcedureMethod(void *clientData,
|
||||
Tcl_Interp *interp, Tcl_ObjectContext context,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static Tcl_NRPostProc FinalizeForwardCall;
|
||||
@@ -77,22 +77,22 @@ static int PushMethodCallFrame(Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv,
|
||||
PMFrameData *fdPtr);
|
||||
static void DeleteProcedureMethodRecord(ProcedureMethod *pmPtr);
|
||||
static void DeleteProcedureMethod(ClientData clientData);
|
||||
static void DeleteProcedureMethod(void *clientData);
|
||||
static int CloneProcedureMethod(Tcl_Interp *interp,
|
||||
ClientData clientData, ClientData *newClientData);
|
||||
void *clientData, void **newClientData);
|
||||
static void MethodErrorHandler(Tcl_Interp *interp,
|
||||
Tcl_Obj *procNameObj);
|
||||
static void ConstructorErrorHandler(Tcl_Interp *interp,
|
||||
Tcl_Obj *procNameObj);
|
||||
static void DestructorErrorHandler(Tcl_Interp *interp,
|
||||
Tcl_Obj *procNameObj);
|
||||
static Tcl_Obj * RenderDeclarerName(ClientData clientData);
|
||||
static int InvokeForwardMethod(ClientData clientData,
|
||||
static Tcl_Obj * RenderDeclarerName(void *clientData);
|
||||
static int InvokeForwardMethod(void *clientData,
|
||||
Tcl_Interp *interp, Tcl_ObjectContext context,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static void DeleteForwardMethod(ClientData clientData);
|
||||
static void DeleteForwardMethod(void *clientData);
|
||||
static int CloneForwardMethod(Tcl_Interp *interp,
|
||||
ClientData clientData, ClientData *newClientData);
|
||||
void *clientData, void **newClientData);
|
||||
static int ProcedureMethodVarResolver(Tcl_Interp *interp,
|
||||
const char *varName, Tcl_Namespace *contextNs,
|
||||
int flags, Tcl_Var *varPtr);
|
||||
@@ -146,7 +146,7 @@ Tcl_NewInstanceMethod(
|
||||
/* The type of method this is, which defines
|
||||
* how to invoke, delete and clone the
|
||||
* method. */
|
||||
ClientData clientData) /* Some data associated with the particular
|
||||
void *clientData) /* Some data associated with the particular
|
||||
* method to be created. */
|
||||
{
|
||||
register Object *oPtr = (Object *) object;
|
||||
@@ -218,7 +218,7 @@ Tcl_NewMethod(
|
||||
/* The type of method this is, which defines
|
||||
* how to invoke, delete and clone the
|
||||
* method. */
|
||||
ClientData clientData) /* Some data associated with the particular
|
||||
void *clientData) /* Some data associated with the particular
|
||||
* method to be created. */
|
||||
{
|
||||
register Class *clsPtr = (Class *) cls;
|
||||
@@ -458,7 +458,7 @@ TclOOMakeProcInstanceMethod(
|
||||
* NULL. */
|
||||
const Tcl_MethodType *typePtr,
|
||||
/* The type of the method to create. */
|
||||
ClientData clientData, /* The per-method type-specific data. */
|
||||
void *clientData, /* The per-method type-specific data. */
|
||||
Proc **procPtrPtr) /* A pointer to the variable in which to write
|
||||
* the procedure record reference. Presumably
|
||||
* inside the structure indicated by the
|
||||
@@ -571,7 +571,7 @@ TclOOMakeProcMethod(
|
||||
* NULL. */
|
||||
const Tcl_MethodType *typePtr,
|
||||
/* The type of the method to create. */
|
||||
ClientData clientData, /* The per-method type-specific data. */
|
||||
void *clientData, /* The per-method type-specific data. */
|
||||
Proc **procPtrPtr) /* A pointer to the variable in which to write
|
||||
* the procedure record reference. Presumably
|
||||
* inside the structure indicated by the
|
||||
@@ -666,7 +666,7 @@ TclOOMakeProcMethod(
|
||||
|
||||
static int
|
||||
InvokeProcedureMethod(
|
||||
ClientData clientData, /* Pointer to some per-method context. */
|
||||
void *clientData, /* Pointer to some per-method context. */
|
||||
Tcl_Interp *interp,
|
||||
Tcl_ObjectContext context, /* The method calling context. */
|
||||
int objc, /* Number of arguments. */
|
||||
@@ -745,7 +745,7 @@ InvokeProcedureMethod(
|
||||
|
||||
static int
|
||||
FinalizePMCall(
|
||||
ClientData data[],
|
||||
void *data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
@@ -799,6 +799,7 @@ PushMethodCallFrame(
|
||||
register int result;
|
||||
const char *namePtr;
|
||||
CallFrame **framePtrPtr = &fdPtr->framePtr;
|
||||
ByteCode *codePtr;
|
||||
|
||||
/*
|
||||
* Compute basic information on the basis of the type of method it is.
|
||||
@@ -864,10 +865,8 @@ PushMethodCallFrame(
|
||||
* alternative is *so* slow...
|
||||
*/
|
||||
|
||||
if (pmPtr->procPtr->bodyPtr->typePtr == &tclByteCodeType) {
|
||||
ByteCode *codePtr =
|
||||
pmPtr->procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
|
||||
|
||||
ByteCodeGetIntRep(pmPtr->procPtr->bodyPtr, &tclByteCodeType, codePtr);
|
||||
if (codePtr) {
|
||||
codePtr->nsPtr = nsPtr;
|
||||
}
|
||||
result = TclProcCompileProc(interp, pmPtr->procPtr,
|
||||
@@ -978,10 +977,8 @@ ProcedureMethodVarResolver(
|
||||
* Must not retain reference to resolved information. [Bug 3105999]
|
||||
*/
|
||||
|
||||
if (rPtr != NULL) {
|
||||
rPtr->deleteProc(rPtr);
|
||||
}
|
||||
return (*varPtr? TCL_OK : TCL_CONTINUE);
|
||||
rPtr->deleteProc(rPtr);
|
||||
return (*varPtr ? TCL_OK : TCL_CONTINUE);
|
||||
}
|
||||
|
||||
static Tcl_Var
|
||||
@@ -1153,7 +1150,7 @@ ProcedureMethodCompiledVarResolver(
|
||||
|
||||
static Tcl_Obj *
|
||||
RenderDeclarerName(
|
||||
ClientData clientData)
|
||||
void *clientData)
|
||||
{
|
||||
struct PNI *pni = clientData;
|
||||
Tcl_Object object = Tcl_MethodDeclarerObject(pni->method);
|
||||
@@ -1295,7 +1292,7 @@ DeleteProcedureMethodRecord(
|
||||
|
||||
static void
|
||||
DeleteProcedureMethod(
|
||||
ClientData clientData)
|
||||
void *clientData)
|
||||
{
|
||||
register ProcedureMethod *pmPtr = clientData;
|
||||
|
||||
@@ -1307,8 +1304,8 @@ DeleteProcedureMethod(
|
||||
static int
|
||||
CloneProcedureMethod(
|
||||
Tcl_Interp *interp,
|
||||
ClientData clientData,
|
||||
ClientData *newClientData)
|
||||
void *clientData,
|
||||
void **newClientData)
|
||||
{
|
||||
ProcedureMethod *pmPtr = clientData;
|
||||
ProcedureMethod *pm2Ptr;
|
||||
@@ -1341,7 +1338,7 @@ CloneProcedureMethod(
|
||||
|
||||
bodyObj = Tcl_DuplicateObj(pmPtr->procPtr->bodyPtr);
|
||||
Tcl_GetString(bodyObj);
|
||||
TclFreeIntRep(bodyObj);
|
||||
Tcl_StoreIntRep(pmPtr->procPtr->bodyPtr, &tclByteCodeType, NULL);
|
||||
|
||||
/*
|
||||
* Create the actual copy of the method record, manufacturing a new proc
|
||||
@@ -1461,7 +1458,7 @@ TclOONewForwardMethod(
|
||||
|
||||
static int
|
||||
InvokeForwardMethod(
|
||||
ClientData clientData, /* Pointer to some per-method context. */
|
||||
void *clientData, /* Pointer to some per-method context. */
|
||||
Tcl_Interp *interp,
|
||||
Tcl_ObjectContext context, /* The method calling context. */
|
||||
int objc, /* Number of arguments. */
|
||||
@@ -1495,7 +1492,7 @@ InvokeForwardMethod(
|
||||
|
||||
static int
|
||||
FinalizeForwardCall(
|
||||
ClientData data[],
|
||||
void *data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
@@ -1517,7 +1514,7 @@ FinalizeForwardCall(
|
||||
|
||||
static void
|
||||
DeleteForwardMethod(
|
||||
ClientData clientData)
|
||||
void *clientData)
|
||||
{
|
||||
ForwardMethod *fmPtr = clientData;
|
||||
|
||||
@@ -1528,8 +1525,8 @@ DeleteForwardMethod(
|
||||
static int
|
||||
CloneForwardMethod(
|
||||
Tcl_Interp *interp,
|
||||
ClientData clientData,
|
||||
ClientData *newClientData)
|
||||
void *clientData,
|
||||
void **newClientData)
|
||||
{
|
||||
ForwardMethod *fmPtr = clientData;
|
||||
ForwardMethod *fm2Ptr = ckalloc(sizeof(ForwardMethod));
|
||||
@@ -1570,9 +1567,7 @@ TclOOGetMethodBody(
|
||||
if (mPtr->typePtr == &procMethodType) {
|
||||
ProcedureMethod *pmPtr = mPtr->clientData;
|
||||
|
||||
if (pmPtr->procPtr->bodyPtr->bytes == NULL) {
|
||||
(void) Tcl_GetString(pmPtr->procPtr->bodyPtr);
|
||||
}
|
||||
(void) TclGetString(pmPtr->procPtr->bodyPtr);
|
||||
return pmPtr->procPtr->bodyPtr;
|
||||
}
|
||||
return NULL;
|
||||
@@ -1680,7 +1675,7 @@ int
|
||||
Tcl_MethodIsType(
|
||||
Tcl_Method method,
|
||||
const Tcl_MethodType *typePtr,
|
||||
ClientData *clientDataPtr)
|
||||
void **clientDataPtr)
|
||||
{
|
||||
Method *mPtr = (Method *) method;
|
||||
|
||||
@@ -1718,7 +1713,7 @@ TclOONewProcInstanceMethodEx(
|
||||
TclOO_PreCallProc *preCallPtr,
|
||||
TclOO_PostCallProc *postCallPtr,
|
||||
ProcErrorProc *errProc,
|
||||
ClientData clientData,
|
||||
void *clientData,
|
||||
Tcl_Obj *nameObj, /* The name of the method, which must not be
|
||||
* NULL. */
|
||||
Tcl_Obj *argsObj, /* The formal argument list for the method,
|
||||
@@ -1755,7 +1750,7 @@ TclOONewProcMethodEx(
|
||||
TclOO_PreCallProc *preCallPtr,
|
||||
TclOO_PostCallProc *postCallPtr,
|
||||
ProcErrorProc *errProc,
|
||||
ClientData clientData,
|
||||
void *clientData,
|
||||
Tcl_Obj *nameObj, /* The name of the method, which may be NULL;
|
||||
* if so, up to caller to manage storage
|
||||
* (e.g., because it is a constructor or
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user