Compare commits
802
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd300c252a | ||
|
|
71ae5810dc | ||
|
|
7df97e9292 | ||
|
|
9f9c9efac0 | ||
|
|
417474f1fd | ||
|
|
6fb4854406 | ||
|
|
817da23169 | ||
|
|
f2c8c6c408 | ||
|
|
747b668676 | ||
|
|
d96dda52c4 | ||
|
|
869730bf85 | ||
|
|
e4912abbd2 | ||
|
|
9b1a75a1cc | ||
|
|
6ed025f0c6 | ||
|
|
1749b4cc87 | ||
|
|
0305f67f88 | ||
|
|
3a8a841386 | ||
|
|
f1eba71130 | ||
|
|
8e7402f6f2 | ||
|
|
1bef1aacd2 | ||
|
|
c1de90d70a | ||
|
|
f4882bb16f | ||
|
|
00c94ffc5d | ||
|
|
96bf31bbbd | ||
|
|
0dfee54d3f | ||
|
|
689987ea92 | ||
|
|
b1266f39d8 | ||
|
|
68d03f6af8 | ||
|
|
9d183921c9 | ||
|
|
384b9de6bb | ||
|
|
fef5802d1e | ||
|
|
95068d8d48 | ||
|
|
b938ddd055 | ||
|
|
2b8e087252 | ||
|
|
01dccf28f9 | ||
|
|
89fee22341 | ||
|
|
0817b5a4ef | ||
|
|
abf9722f42 | ||
|
|
74e4654447 | ||
|
|
e30b6432e1 | ||
|
|
d74f47cb2a | ||
|
|
230de714e7 | ||
|
|
9535d1ecdc | ||
|
|
40c2f59cf4 | ||
|
|
9eb32ba719 | ||
|
|
2d46cfab69 | ||
|
|
6c1d937172 | ||
|
|
6d27f27fe6 | ||
|
|
d64266c046 | ||
|
|
aaf56c8086 | ||
|
|
f080055506 | ||
|
|
0f1fe8880d | ||
|
|
af74f1af12 | ||
|
|
69c460065e | ||
|
|
079965ccb5 | ||
|
|
7afcb333c4 | ||
|
|
c4f3c560ab | ||
|
|
2c246b85fa | ||
|
|
9d9c83fd39 | ||
|
|
f9944f5235 | ||
|
|
d8ec6222e8 | ||
|
|
04ea3b8bff | ||
|
|
ec4d7da07d | ||
|
|
c92353bea9 | ||
|
|
c73dcaad20 | ||
|
|
d164d828d7 | ||
|
|
2ff70c01f6 | ||
|
|
d7fe4af621 | ||
|
|
8e7a963f7f | ||
|
|
3e3f2b1354 | ||
|
|
cda174b1aa | ||
|
|
934e6a9837 | ||
|
|
2b821c69de | ||
|
|
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 | ||
|
|
050b6c3d5f | ||
|
|
f04b875d88 | ||
|
|
4fdbe79875 | ||
|
|
a29e4e5b15 | ||
|
|
57d9952ece | ||
|
|
cbd7fd7dec | ||
|
|
1eba3f12e0 | ||
|
|
82c3e7df6d | ||
|
|
9acb35c45d | ||
|
|
dc75a4866c | ||
|
|
6806ca9630 | ||
|
|
68c0005c84 | ||
|
|
e15d1f5f79 | ||
|
|
b752d879c7 | ||
|
|
886343e50b | ||
|
|
9589c85462 | ||
|
|
2473a591bf | ||
|
|
52ed230e6f | ||
|
|
d273753223 | ||
|
|
a475e0b1ee | ||
|
|
5fd6fc8ae4 | ||
|
|
fc24d0b9cf | ||
|
|
85b1f06c9c | ||
|
|
b24cecb582 | ||
|
|
963cceee57 | ||
|
|
5add43aac8 | ||
|
|
2d41d8b6e2 | ||
|
|
f7183b361e | ||
|
|
e0587d1564 | ||
|
|
6a355b11a6 | ||
|
|
1890d482a7 | ||
|
|
9a62e42dd6 | ||
|
|
e66cb0c31e | ||
|
|
4b4a960bfb | ||
|
|
0a876f8e00 | ||
|
|
445aa5833b | ||
|
|
9d568b1bdd | ||
|
|
73b6b4eab6 | ||
|
|
0fcfbd81df | ||
|
|
cf1edde4f6 | ||
|
|
08d4e75deb | ||
|
|
bcd9ec5103 | ||
|
|
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 | ||
|
|
cc6faa155b | ||
|
|
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 | ||
|
|
1ff54c600e | ||
|
|
1337738c22 | ||
|
|
96b9e6e871 | ||
|
|
52c009322f | ||
|
|
274d86b2ec | ||
|
|
b28e8c3bd1 | ||
|
|
63802cdd70 | ||
|
|
f44fb9b450 | ||
|
|
f338047c19 | ||
|
|
691b2ab5c4 | ||
|
|
352d056288 | ||
|
|
bf9af9a408 | ||
|
|
231a11e2ce | ||
|
|
394e22ef5d | ||
|
|
5b1614f31a | ||
|
|
36f2cb4d7d | ||
|
|
68cad4302a | ||
|
|
8c05c20df4 | ||
|
|
37c458acb7 | ||
|
|
775ce545d2 | ||
|
|
9b417d4592 | ||
|
|
d8decf16a5 | ||
|
|
74357f24f8 | ||
|
|
8bfcffa20a | ||
|
|
90221ac971 | ||
|
|
da46155931 | ||
|
|
4dbcfc37b3 | ||
|
|
f59c9faee2 | ||
|
|
94c0eede77 | ||
|
|
61a92173cc | ||
|
|
c393791ed5 | ||
|
|
239ba78ee4 | ||
|
|
359b371edd | ||
|
|
67b4e0d544 | ||
|
|
7c859988ba | ||
|
|
a221655e1a | ||
|
|
af3a20ad4e | ||
|
|
f4f6ef461b | ||
|
|
d918760272 | ||
|
|
9e61a85e86 | ||
|
|
eec0f0f9da | ||
|
|
e13c5f55a1 | ||
|
|
c74364be4c | ||
|
|
4252e1f99f | ||
|
|
eeead325b4 | ||
|
|
5a177e9aaf | ||
|
|
9bd3b59e1d | ||
|
|
77bd578d9f | ||
|
|
fd7ecfb877 | ||
|
|
d60637c153 | ||
|
|
f206e0fb4b | ||
|
|
9db2475e4e | ||
|
|
050e383cf2 | ||
|
|
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 | ||
|
|
61169e4e9e | ||
|
|
2db0464fd9 | ||
|
|
5eafb95b32 | ||
|
|
2a340ce4c1 | ||
|
|
044bd42331 | ||
|
|
4d9ba4a652 | ||
|
|
9ff5b7077a | ||
|
|
7234985a63 | ||
|
|
434c0fa7fb | ||
|
|
c848d68793 | ||
|
|
27f230c6bf | ||
|
|
a6454e20a4 | ||
|
|
344b135505 | ||
|
|
be8b7d25f6 | ||
|
|
0bef3861ff | ||
|
|
dc5861414a | ||
|
|
bd9f2eb15d | ||
|
|
1dbb35b63b | ||
|
|
a9e916f1b9 | ||
|
|
c908681186 | ||
|
|
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 | ||
|
|
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 |
@@ -19,14 +19,18 @@
|
||||
*/tcltest*
|
||||
*/versions.vc
|
||||
*/version.vc
|
||||
*/libtcl.vfs
|
||||
*/libtcl_*.zip
|
||||
html
|
||||
libtommath/bn.ilg
|
||||
libtommath/bn.ind
|
||||
libtommath/pretty.build
|
||||
libtommath/tommath.src
|
||||
libtommath/*.log
|
||||
libtommath/*.pdf
|
||||
libtommath/*.pl
|
||||
libtommath/*.sh
|
||||
libtommath/doc/*
|
||||
libtommath/tombc/*
|
||||
libtommath/pre_gen/*
|
||||
libtommath/pics/*
|
||||
|
||||
+297
@@ -0,0 +1,297 @@
|
||||
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_UTF_MAX=3
|
||||
- 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 --disable-shared"
|
||||
- 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_UTF_MAX=3"
|
||||
- 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 --disable-shared"
|
||||
- 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_UTF_MAX=3"
|
||||
- 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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -28,10 +28,10 @@ First, the Tcl interpreter breaks the command into \fIwords\fR
|
||||
and performs substitutions as described below.
|
||||
These substitutions are performed in the same way for all
|
||||
commands.
|
||||
Secondly, the first word is used to locate a command procedure to
|
||||
carry out the command, then all of the words of the command are
|
||||
passed to the command procedure.
|
||||
The command procedure is free to interpret each of its words
|
||||
Secondly, the first word is used to locate a routine to
|
||||
carry out the command, and the remaining words of the command are
|
||||
passed to that routine.
|
||||
The routine is free to interpret each of its words
|
||||
in any way it likes, such as an integer, variable name, list,
|
||||
or Tcl script.
|
||||
Different commands interpret their words differently.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -78,11 +78,5 @@ turns each character in the string into its lower-case equivalent.
|
||||
turns the first character in the string into its title-case equivalent
|
||||
and all following characters into their lower-case equivalents.
|
||||
|
||||
.SH BUGS
|
||||
.PP
|
||||
At this time, the case conversions are only defined for the ISO8859-1
|
||||
characters. Unicode characters above 0x00ff are not modified by these
|
||||
routines.
|
||||
|
||||
.SH KEYWORDS
|
||||
utf, unicode, toupper, tolower, totitle, case
|
||||
|
||||
@@ -132,10 +132,11 @@ 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
|
||||
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.
|
||||
in \fIbuf\fR. If ch is a high surrogate (range U+D800 - U+DBFF), then
|
||||
the return value will be 1 and a single byte in the range 0xF0 - 0xF4
|
||||
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 specifying ch = -1.
|
||||
.PP
|
||||
\fBTcl_UtfToUniChar\fR reads one UTF-8 character starting at \fIsrc\fR
|
||||
and stores it as a Tcl_UniChar in \fI*chPtr\fR. The return value is the
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ has been completed.
|
||||
.VS TIP508
|
||||
Manages the default value of the array. Arrays initially have no default
|
||||
value, but this command allows you to set one; the default value will be
|
||||
returned when reading from an element of the array \farrayName\fR if the read
|
||||
returned when reading from an element of the array \fIarrayName\fR if the read
|
||||
would otherwise result in an error. Note that this may cause the \fBappend\fR,
|
||||
\fBdict\fR, \fBincr\fR and \fBlappend\fR commands to change their behavior in
|
||||
relation to non-existing array elements.
|
||||
|
||||
+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 \fBnew\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:
|
||||
+30
-13
@@ -52,7 +52,7 @@ the \fBmethod\fR definition, below.
|
||||
.RS
|
||||
.PP
|
||||
Class methods can be called on either the class itself or on the instances of
|
||||
that class. When they are called, the current object (see the \fBself\R and
|
||||
that class. When they are called, the current object (see the \fBsel\fR and
|
||||
\fBmy\fR commands) is the class on which they are called or the class of the
|
||||
instance on which they are called, depending on whether they are called on the
|
||||
class or an instance of the class, respectively. If called on a subclass or
|
||||
@@ -132,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
|
||||
@@ -142,12 +142,17 @@ 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
|
||||
@@ -279,7 +284,8 @@ this feature for classes requires the definition of a metaclass.
|
||||
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).
|
||||
(except when they have a call chain through the class being modified) or the
|
||||
class object itself.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
@@ -305,7 +311,8 @@ 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
|
||||
(except when they have a call chain through the class being modified), or the
|
||||
class object itself. Does
|
||||
not change the export status of the method; if it was exported before, it will
|
||||
be afterwards.
|
||||
.SH "CONFIGURING OBJECTS"
|
||||
@@ -337,7 +344,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
|
||||
@@ -345,12 +352,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
|
||||
@@ -425,8 +438,10 @@ well be in an inconsistent state unless additional configuration work is done.
|
||||
\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.
|
||||
must have previously existed in that object (e.g., because it was created
|
||||
through \fBoo::objdefine method\fR). Does not affect the classes that the
|
||||
object is an instance of, or remove the exposure of those class-provided
|
||||
methods in the instance of that class.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
@@ -444,8 +459,10 @@ By default, this slot works by appending.
|
||||
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.
|
||||
that the object is an instance of and cannot rename in an instance object the
|
||||
methods provided by those classes (though a \fBoo::objdefine forward\fRed
|
||||
method may provide an equivalent capability). Does not change the export
|
||||
status of the method; if it was exported before, it will be afterwards.
|
||||
.TP
|
||||
\fBself \fR
|
||||
.VS TIP470
|
||||
|
||||
+2
-1
@@ -126,7 +126,8 @@ applied to integers.
|
||||
.TP 20
|
||||
\fB**\fR
|
||||
.
|
||||
Exponentiation. Valid for numeric operands.
|
||||
Exponentiation. Valid for numeric operands. The maximum exponent value
|
||||
that Tcl can handle if the first number is an integer > 1 is 268435455.
|
||||
.TP 20
|
||||
\fB*\0\0/\0\0%\fR
|
||||
.
|
||||
|
||||
+111
@@ -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:
|
||||
+147
-237
@@ -13,129 +13,102 @@
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
info \- Return information about the state of the Tcl interpreter
|
||||
info \- Information about the state of the Tcl interpreter
|
||||
.SH SYNOPSIS
|
||||
\fBinfo \fIoption \fR?\fIarg arg ...\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This command provides information about various internals of the Tcl
|
||||
interpreter.
|
||||
The legal \fIoption\fRs (which may be abbreviated) are:
|
||||
Available commands:
|
||||
.TP
|
||||
\fBinfo args \fIprocname\fR
|
||||
.
|
||||
Returns a list containing the names of the arguments to procedure
|
||||
\fIprocname\fR, in order. \fIProcname\fR must be the name of a
|
||||
Tcl command procedure.
|
||||
Returns the names of the parameters to the procedure named \fIprocname\fR.
|
||||
.TP
|
||||
\fBinfo body \fIprocname\fR
|
||||
.
|
||||
Returns the body of procedure \fIprocname\fR. \fIProcname\fR must be
|
||||
the name of a Tcl command procedure.
|
||||
Returns the body of the procedure named \fIprocname\fR.
|
||||
.TP
|
||||
\fBinfo class\fI subcommand class\fR ?\fIarg ...\fR
|
||||
.
|
||||
Returns information about the class, \fIclass\fR. The \fIsubcommand\fRs are
|
||||
described in \fBCLASS INTROSPECTION\fR below.
|
||||
Returns information about the class named \fIclass\fR.
|
||||
See \fBCLASS INTROSPECTION\fR below.
|
||||
.TP
|
||||
\fBinfo cmdcount\fR
|
||||
.
|
||||
Returns a count of the total number of commands that have been invoked
|
||||
in this interpreter.
|
||||
Returns the total number of commands evaluated in this interpreter.
|
||||
.TP
|
||||
\fBinfo cmdtype \fIcommandName\fR
|
||||
.VS TIP426
|
||||
Returns a description of the kind of command named by \fIcommandName\fR. The
|
||||
supported types are:
|
||||
Returns a the type of the command named \fIcommandName\fR.
|
||||
Built-in types are:
|
||||
.RS
|
||||
.IP \fBalias\fR
|
||||
Indicates that \fIcommandName\fR was created by \fBinterp alias\fR. Note that
|
||||
safe interpreters can only see a subset of aliases (specifically those between
|
||||
two commands within themselves).
|
||||
\fIcommandName\fR was created by \fBinterp alias\fR.
|
||||
In a safe interpreter an alias is only visible if both the alias and the
|
||||
target are visible.
|
||||
.IP \fBcoroutine\fR
|
||||
Indicates that \fIcommandName\fR was created by \fBcoroutine\fR.
|
||||
\fIcommandName\fR was created by \fBcoroutine\fR.
|
||||
.IP \fBensemble\fR
|
||||
Indicates that \fIcommandName\fR was created by \fBnamespace ensemble\fR.
|
||||
\fIcommandName\fR was created by \fBnamespace ensemble\fR.
|
||||
.IP \fBimport\fR
|
||||
Indicates that \fIcommandName\fR was created by \fBnamespace import\fR.
|
||||
\fIcommandName\fR was created by \fBnamespace import\fR.
|
||||
.IP \fBnative\fR
|
||||
Indicates that \fIcommandName\fR was created by the \fBTcl_CreateObjProc\fR
|
||||
\fIcommandName\fR was created by the \fBTcl_CreateObjProc\fR
|
||||
interface directly without further registration of the type of command.
|
||||
.IP \fBobject\fR
|
||||
Indicates that \fIcommandName\fR is the public command that represents an
|
||||
\fIcommandName\fR is the public command that represents an
|
||||
instance of \fBoo::object\fR or one of its subclasses.
|
||||
.IP \fBprivateObject\fR
|
||||
Indicates that \fIcommandName\fR is the private command (\fBmy\fR by default)
|
||||
\fIcommandName\fR is the private command, \fBmy\fR by default,
|
||||
that represents an instance of \fBoo::object\fR or one of its subclasses.
|
||||
.IP \fBproc\fR
|
||||
Indicates that \fIcommandName\fR was created by \fBproc\fR.
|
||||
\fIcommandName\fR was created by \fBproc\fR.
|
||||
.IP \fBslave\fR
|
||||
Indicates that \fIcommandName\fR was created by \fBinterp create\fR.
|
||||
\fIcommandName\fR was created by \fBinterp create\fR.
|
||||
.IP \fBzlibStream\fR
|
||||
Indicates that \fIcommandName\fR was created by \fBzlib stream\fR.
|
||||
\fIcommandName\fR was created by \fBzlib stream\fR.
|
||||
.PP
|
||||
There may be other registered types as well; this is a set that is extensible
|
||||
at the implementation level with \fBTcl_RegisterCommandTypeName\fR.
|
||||
Other types may be also registered as well. See \fBTcl_RegisterCommandTypeName\fR.
|
||||
.RE
|
||||
.VE TIP426
|
||||
.TP
|
||||
\fBinfo commands \fR?\fIpattern\fR?
|
||||
.
|
||||
If \fIpattern\fR is not specified,
|
||||
returns a list of names of all the Tcl commands visible
|
||||
(i.e. executable without using a qualified name) to the current namespace,
|
||||
including both the built-in commands written in C and
|
||||
the command procedures defined using the \fBproc\fR command.
|
||||
If \fIpattern\fR is specified,
|
||||
only those names matching \fIpattern\fR are returned.
|
||||
Matching is determined using the same rules as for \fBstring match\fR.
|
||||
\fIpattern\fR can be a qualified name like \fBFoo::print*\fR.
|
||||
That is, it may specify a particular namespace
|
||||
using a sequence of namespace names separated by double colons (\fB::\fR),
|
||||
and may have pattern matching special characters
|
||||
at the end to specify a set of commands in that namespace.
|
||||
If \fIpattern\fR is a qualified name,
|
||||
the resulting list of command names has each one qualified with the name
|
||||
of the specified namespace, and only the commands defined in the named
|
||||
namespace are returned.
|
||||
.\" Technically, most of this hasn't changed; that's mostly just the
|
||||
.\" way it always worked. Hardly anyone knew that though.
|
||||
Returns the names of all commands visible in the current namespace. If
|
||||
\fIpattern\fR is given, returns only those names that match according to
|
||||
\fBstring match\fR. Only the last component of \fIpattern\fR is a pattern.
|
||||
Other components identify a namespace. See \fBNAMESPACE RESOLUTION\fR in the
|
||||
\fBnamespace\fR(n) documentation.
|
||||
.TP
|
||||
\fBinfo complete \fIcommand\fR
|
||||
.
|
||||
Returns 1 if \fIcommand\fR is a complete Tcl command in the sense of
|
||||
having no unclosed quotes, braces, brackets or array element names.
|
||||
If the command does not appear to be complete then 0 is returned.
|
||||
This command is typically used in line-oriented input environments
|
||||
to allow users to type in commands that span multiple lines; if the
|
||||
command is not complete, the script can delay evaluating it until additional
|
||||
lines have been typed to complete the command.
|
||||
Returns 1 if \fIcommand\fR is a complete command, and \fB0\fR otherwise.
|
||||
Typically used in line-oriented input environments
|
||||
to allow users to type in commands that span multiple lines.
|
||||
.TP
|
||||
\fBinfo coroutine\fR
|
||||
.
|
||||
Returns the name of the currently executing \fBcoroutine\fR, or the empty
|
||||
string if either no coroutine is currently executing, or the current coroutine
|
||||
has been deleted (but has not yet returned or yielded since deletion).
|
||||
Returns the name of the current \fBcoroutine\fR, or the empty
|
||||
string if there is no current coroutine or the current coroutine
|
||||
has been deleted.
|
||||
.TP
|
||||
\fBinfo default \fIprocname arg varname\fR
|
||||
\fBinfo default \fIprocname parameter varname\fR
|
||||
.
|
||||
\fIProcname\fR must be the name of a Tcl command procedure and \fIarg\fR
|
||||
must be the name of an argument to that procedure. If \fIarg\fR
|
||||
does not have a default value then the command returns \fB0\fR.
|
||||
Otherwise it returns \fB1\fR and places the default value of \fIarg\fR
|
||||
into variable \fIvarname\fR.
|
||||
If the parameter \fIparameter\fR for the procedure named \fIprocname\fR has a
|
||||
default value, stores that value in \fIvarname\fR and returns \fB1\fR.
|
||||
Otherwise, returns \fB0\fR.
|
||||
.TP
|
||||
\fBinfo errorstack \fR?\fIinterp\fR?
|
||||
.
|
||||
Returns, in a form that is programmatically easy to parse, the function names
|
||||
and arguments at each level from the call stack of the last error in the given
|
||||
\fIinterp\fR, or in the current one if not specified.
|
||||
Returns a description of the active command at each level for the
|
||||
last error in the current interpreter, or in the interpreter named
|
||||
\fIinterp\fR if given.
|
||||
.RS
|
||||
.PP
|
||||
This form is an even-sized list alternating tokens and parameters. Tokens are
|
||||
The description is a dictionary of tokens and parameters. Tokens are
|
||||
currently either \fBCALL\fR, \fBUP\fR, or \fBINNER\fR, but other values may be
|
||||
introduced in the future. \fBCALL\fR indicates a procedure call, and its
|
||||
introduced in the future. \fBCALL\fR indicates a command call, and its
|
||||
parameter is the corresponding \fBinfo level\fR \fB0\fR. \fBUP\fR indicates a
|
||||
shift in variable frames generated by \fBuplevel\fR or similar, and applies to
|
||||
the previous \fBCALL\fR item. Its parameter is the level offset. \fBINNER\fR
|
||||
@@ -143,126 +116,103 @@ identifies the
|
||||
.QW "inner context" ,
|
||||
which is the innermost atomic command or bytecode instruction that raised the
|
||||
error, along with its arguments when available. While \fBCALL\fR and \fBUP\fR
|
||||
allow to follow complex call paths, \fBINNER\fR homes in on the offending
|
||||
operation in the innermost procedure call, even going to sub-expression
|
||||
provide a trail of the call path, \fBINNER\fR provides details of the offending
|
||||
operation in the innermost procedure call, even to sub-expression
|
||||
granularity.
|
||||
.PP
|
||||
This information is also present in the \fB\-errorstack\fR entry of the
|
||||
options dictionary returned by 3-argument \fBcatch\fR; \fBinfo errorstack\fR
|
||||
is a convenient way of retrieving it for uncaught errors at top-level in an
|
||||
interactive \fBtclsh\fR.
|
||||
interactive \fBinterpreter\fR.
|
||||
.RE
|
||||
.TP
|
||||
\fBinfo exists \fIvarName\fR
|
||||
.
|
||||
Returns \fB1\fR if the variable named \fIvarName\fR exists in the
|
||||
current context (either as a global or local variable) and has been
|
||||
defined by being given a value, returns \fB0\fR otherwise.
|
||||
Returns \fB1\fR if a variable named \fIvarName\fR is visible and has been
|
||||
defined, and \fB0\fR otherwise.
|
||||
.TP
|
||||
\fBinfo frame\fR ?\fInumber\fR?
|
||||
\fBinfo frame\fR ?\fIdepth\fR?
|
||||
.
|
||||
This command provides access to all frames on the stack, even those
|
||||
hidden from \fBinfo level\fR. If \fInumber\fR is not specified, this
|
||||
command returns a number giving the frame level of the command. This
|
||||
is 1 if the command is invoked at top-level. If \fInumber\fR is
|
||||
specified, then the result is a dictionary containing the location
|
||||
information for the command at the \fInumber\fRed level on the stack.
|
||||
Returns the depth of the call to \fBinfo frame\fR itself. Otherwise, returns a
|
||||
dictionary describing the active command at the \fIdepth\fR, which counts all
|
||||
commands visible to \fBinfo level\fR, plus commands that don't create a new
|
||||
level, such as \fBeval\fR, \fBsource\fR, or \fIuplevel\fR. The frame depth is
|
||||
always greater than the current level.
|
||||
.RS
|
||||
.PP
|
||||
If \fInumber\fR is positive (> 0) then it selects a particular stack
|
||||
level (1 refers to the outer-most active command, 2 to the command it
|
||||
called, and so on, up to the current frame level which refers to
|
||||
\fBinfo frame\fR itself); otherwise it gives a level relative to the
|
||||
current command (0 refers to the current command, i.e., \fBinfo
|
||||
frame\fR itself, -1 to its caller, and so on).
|
||||
If \fIdepth\fR is greater than \fB0\fR it is the frame at that depth. Otherwise
|
||||
it is the number of frames up from the current frame.
|
||||
.PP
|
||||
This is similar to how \fBinfo level\fR works, except that this
|
||||
subcommand reports all frames, like \fBsource\fRd scripts,
|
||||
\fBeval\fRs, \fBuplevel\fRs, etc.
|
||||
.PP
|
||||
Note that for nested commands, like
|
||||
As with \fBinfo level\fR and error traces, for nested commands like
|
||||
.QW "foo [bar [x]]" ,
|
||||
only
|
||||
.QW x
|
||||
will be seen by an \fBinfo frame\fR invoked within
|
||||
is seen by \fBinfo frame\fR invoked within
|
||||
.QW x .
|
||||
This is the same as for \fBinfo level\fR and error stack traces.
|
||||
.PP
|
||||
The result dictionary may contain the keys listed below, with the
|
||||
specified meanings for their values:
|
||||
The dictionary may contain the following keys:
|
||||
.TP
|
||||
\fBtype\fR
|
||||
.
|
||||
This entry is always present and describes the nature of the location
|
||||
for the command. The recognized values are \fBsource\fR, \fBproc\fR,
|
||||
Always present. Possible values are \fBsource\fR, \fBproc\fR,
|
||||
\fBeval\fR, and \fBprecompiled\fR.
|
||||
.RS
|
||||
.TP
|
||||
\fBsource\fR\0\0\0\0\0\0\0\0
|
||||
.
|
||||
means that the command is found in a script loaded by the \fBsource\fR
|
||||
A script loaded via the \fBsource\fR
|
||||
command.
|
||||
.TP
|
||||
\fBproc\fR\0\0\0\0\0\0\0\0
|
||||
.
|
||||
means that the command is found in dynamically created procedure body.
|
||||
The body of a procedure that could not be traced back to a
|
||||
line in a particular script.
|
||||
.TP
|
||||
\fBeval\fR\0\0\0\0\0\0\0\0
|
||||
.
|
||||
means that the command is executed by \fBeval\fR or \fBuplevel\fR.
|
||||
The body of a script provided to \fBeval\fR or \fBuplevel\fR.
|
||||
.TP
|
||||
\fBprecompiled\fR\0\0\0\0\0\0\0\0
|
||||
.
|
||||
means that the command is found in a pre-compiled script (loadable by
|
||||
the package \fBtbcload\fR), and no further information will be
|
||||
available.
|
||||
A pre-compiled script (loadable by the package
|
||||
\fBtbcload\fR), and no further information is available.
|
||||
.RE
|
||||
.TP
|
||||
\fBline\fR
|
||||
.
|
||||
This entry provides the number of the line the command is at inside of
|
||||
the script it is a part of. This information is not present for type
|
||||
\fBprecompiled\fR. For type \fBsource\fR this information is counted
|
||||
relative to the beginning of the file, whereas for the last two types
|
||||
the line is counted relative to the start of the script.
|
||||
The line number of of the command inside its script. Not available for
|
||||
\fBprecompiled\fR commands. When the type is \fBsource\fR, the line number is
|
||||
relative to the beginning of the file, whereas for the last two types it is
|
||||
relative to the start of the script.
|
||||
.TP
|
||||
\fBfile\fR
|
||||
.
|
||||
This entry is present only for type \fBsource\fR. It provides the
|
||||
normalized path of the file the command is in.
|
||||
For type \fBsource\fR, provides the normalized path of the file that contains
|
||||
the command.
|
||||
.TP
|
||||
\fBcmd\fR
|
||||
.
|
||||
This entry provides the string representation of the command. This is
|
||||
usually the unsubstituted form, however for commands which are a
|
||||
canonically-constructed list (e.g., as produced by the \fBlist\fR command)
|
||||
executed by \fBeval\fR it is the substituted form as they have no other
|
||||
string representation. Care is taken that the canonicality property of
|
||||
the latter is not spoiled.
|
||||
The command before substitutions were performed.
|
||||
.TP
|
||||
\fBproc\fR
|
||||
.
|
||||
This entry is present only if the command is found in the body of a
|
||||
regular Tcl procedure. It then provides the name of that procedure.
|
||||
For type \fBprod\fR, the name of the procedure containing the command.
|
||||
.TP
|
||||
\fBlambda\fR
|
||||
.
|
||||
This entry is present only if the command is found in the body of an
|
||||
anonymous Tcl procedure, i.e. a lambda. It then provides the entire
|
||||
definition of the lambda in question.
|
||||
For a command in a script evaluated as the body of an unnamed routine via the
|
||||
\fBapply\fR command, the definition of that routine.
|
||||
.TP
|
||||
\fBlevel\fR
|
||||
.
|
||||
This entry is present only if the queried frame has a corresponding
|
||||
frame returned by \fBinfo level\fR. It provides the index of this
|
||||
frame, relative to the current level (0 and negative numbers).
|
||||
For a frame that corresponds to a level, (to be determined).
|
||||
.PP
|
||||
A thing of note is that for procedures statically defined in files the
|
||||
locations of commands in their bodies will be reported with type
|
||||
\fBsource\fR and absolute line numbers, and not as type
|
||||
\fBproc\fR. The same is true for procedures nested in statically
|
||||
defined procedures, and literal eval scripts in files or statically
|
||||
defined procedures.
|
||||
When a command can be traced to its literal definition in some script, e.g.
|
||||
procedures nested in statically defined procedures, and literal eval scripts in
|
||||
files or statically defined procedures, its type is \fBsource\fR and its
|
||||
location is the absolute line number in the script. Otherwise, its type is
|
||||
\fBproc\fR and its location is its line number within the body of the
|
||||
procedure.
|
||||
.PP
|
||||
In contrast, procedure definitions and \fBeval\fR within a dynamically
|
||||
\fBeval\fRuated environment count line numbers relative to the start of
|
||||
@@ -270,7 +220,7 @@ their script, even if they would be able to count relative to the
|
||||
start of the outer dynamic script. That type of number usually makes
|
||||
more sense.
|
||||
.PP
|
||||
A different way of describing this behaviour is that file based
|
||||
A different way of describing this behaviour is that file-based
|
||||
locations are tracked as deeply as possible, and where this is not
|
||||
possible the lines are counted based on the smallest possible
|
||||
\fBeval\fR or procedure body, as that scope is usually easier to find
|
||||
@@ -284,152 +234,112 @@ counted relative to the start of each word (smallest scope)
|
||||
.TP
|
||||
\fBinfo functions \fR?\fIpattern\fR?
|
||||
.
|
||||
If \fIpattern\fR is not specified, returns a list of all the math
|
||||
If \fIpattern\fR is not given, returns a list of all the math
|
||||
functions currently defined.
|
||||
If \fIpattern\fR is specified, only those functions whose name matches
|
||||
\fIpattern\fR are returned. Matching is determined using the same
|
||||
rules as for \fBstring match\fR.
|
||||
If \fIpattern\fR is given, returns only those names that match
|
||||
\fIpattern\fR according to \fBstring match\fR.
|
||||
.TP
|
||||
\fBinfo globals \fR?\fIpattern\fR?
|
||||
.
|
||||
If \fIpattern\fR is not specified, returns a list of all the names
|
||||
If \fIpattern\fR is not given, returns a list of all the names
|
||||
of currently-defined global variables.
|
||||
Global variables are variables in the global namespace.
|
||||
If \fIpattern\fR is specified, only those names matching \fIpattern\fR
|
||||
If \fIpattern\fR is given, only those names matching \fIpattern\fR
|
||||
are returned. Matching is determined using the same rules as for
|
||||
\fBstring match\fR.
|
||||
.TP
|
||||
\fBinfo hostname\fR
|
||||
.
|
||||
Returns the name of the computer on which this invocation is being
|
||||
executed.
|
||||
Note that this name is not guaranteed to be the fully qualified domain
|
||||
name of the host. Where machines have several different names (as is
|
||||
Returns the name of the current host.
|
||||
|
||||
This name is not guaranteed to be the fully-qualified domain
|
||||
name of the host. Where machines have several different names, as is
|
||||
common on systems with both TCP/IP (DNS) and NetBIOS-based networking
|
||||
installed,) it is the name that is suitable for TCP/IP networking that
|
||||
installed, it is the name that is suitable for TCP/IP networking that
|
||||
is returned.
|
||||
.TP
|
||||
\fBinfo level\fR ?\fInumber\fR?
|
||||
\fBinfo level\fR ?\fIlevel\fR?
|
||||
.
|
||||
If \fInumber\fR is not specified, this command returns a number
|
||||
giving the stack level of the invoking procedure, or 0 if the
|
||||
command is invoked at top-level. If \fInumber\fR is specified,
|
||||
then the result is a list consisting of the name and arguments for the
|
||||
procedure call at level \fInumber\fR on the stack. If \fInumber\fR
|
||||
is positive then it selects a particular stack level (1 refers
|
||||
to the top-most active procedure, 2 to the procedure it called, and
|
||||
so on); otherwise it gives a level relative to the current level
|
||||
(0 refers to the current procedure, -1 to its caller, and so on).
|
||||
See the \fBuplevel\fR command for more information on what stack
|
||||
levels mean.
|
||||
If \fInumber\fR is not given, the level this routine was called from.
|
||||
Otherwise returns the complete command active at the given level. If
|
||||
\fInumber\fR is greater than \fB0\fR, it is the desired level. Otherwise, it
|
||||
is \fInumber\fR levels up from the current level. A complete command is the
|
||||
words in the command, with all subsitutions performed, meaning that it is a
|
||||
list. See \fBuplevel\fR for more information on levels.
|
||||
.TP
|
||||
\fBinfo library\fR
|
||||
.
|
||||
Returns the name of the library directory in which standard Tcl
|
||||
scripts are stored.
|
||||
This is actually the value of the \fBtcl_library\fR
|
||||
variable and may be changed by setting \fBtcl_library\fR.
|
||||
Returns the value of \fBtcl_library\fR, which is the name of the library
|
||||
directory in which the scripts distributed with Tcl scripts are stored.
|
||||
.TP
|
||||
\fBinfo loaded \fR?\fIinterp\fR? ?\fIpackage\fR?
|
||||
.
|
||||
Returns the filename loaded as part of \fIpackage\fR. If \fIpackage\fR
|
||||
is not specified, returns a list describing all of the packages
|
||||
that have been loaded into \fIinterp\fR with the \fBload\fR command.
|
||||
Each list element is a sub-list with two elements consisting of the
|
||||
name of the file from which the package was loaded and the name of
|
||||
the package.
|
||||
For statically-loaded packages the file name will be an empty string.
|
||||
If \fIinterp\fR is omitted then information is returned for all packages
|
||||
loaded in any interpreter in the process.
|
||||
To get a list of just the packages in the current interpreter, specify
|
||||
an empty string for the \fIinterp\fR argument.
|
||||
Returns the name of each file loaded in \fIinterp\fR va \fBload\fR as part of
|
||||
\fIpackage\fR . If \fIpackage\fR is not given, returns a list where each item
|
||||
is the name of the loaded file and the name of the package for which the file
|
||||
was loaded. For a statically-loaded package the name of the file is the empty
|
||||
string. For \fInterp\fR, the empty string is the current interpreter.
|
||||
.TP
|
||||
\fBinfo locals \fR?\fIpattern\fR?
|
||||
.
|
||||
If \fIpattern\fR is not specified, returns a list of all the names
|
||||
of currently-defined local variables, including arguments to the
|
||||
current procedure, if any.
|
||||
Variables defined with the \fBglobal\fR, \fBupvar\fR and
|
||||
\fBvariable\fR commands will not be returned.
|
||||
If \fIpattern\fR is specified, only those names matching \fIpattern\fR
|
||||
are returned. Matching is determined using the same rules as for
|
||||
\fBstring match\fR.
|
||||
If \fIpattern\fR is given, returns the name of each local variable matching
|
||||
\fIpattern\fR according to \fBstring match\fR. Otherwise, returns the name of
|
||||
each local variable. A variables defined with the \fBglobal\fR, \fBupvar\fR or
|
||||
\fBvariable\fR is not local.
|
||||
|
||||
.TP
|
||||
\fBinfo nameofexecutable\fR
|
||||
.
|
||||
Returns the full path name of the binary file from which the application
|
||||
was invoked. If Tcl was unable to identify the file, then an empty
|
||||
string is returned.
|
||||
Returns the absolute pathname of the program for the current interpreter. If
|
||||
such a file can not be identified an empty string is returned.
|
||||
.TP
|
||||
\fBinfo object\fI subcommand object\fR ?\fIarg ...\fR
|
||||
.
|
||||
Returns information about the object, \fIobject\fR. The \fIsubcommand\fRs are
|
||||
described in \fBOBJECT INTROSPECTION\fR below.
|
||||
Returns information about the object named \fIobject\fR. \fIsubcommand\fR is
|
||||
described \fBOBJECT INTROSPECTION\fR below.
|
||||
.TP
|
||||
\fBinfo patchlevel\fR
|
||||
.
|
||||
Returns the value of the global variable \fBtcl_patchLevel\fR, which holds
|
||||
the exact version of the Tcl library by default.
|
||||
Returns the value of the global variable \fBtcl_patchLevel\fR, in which the
|
||||
exact version of the Tcl library initially stored.
|
||||
.TP
|
||||
\fBinfo procs \fR?\fIpattern\fR?
|
||||
.
|
||||
If \fIpattern\fR is not specified, returns a list of all the
|
||||
names of Tcl command procedures in the current namespace.
|
||||
If \fIpattern\fR is specified,
|
||||
only those procedure names in the current namespace
|
||||
matching \fIpattern\fR are returned.
|
||||
Matching is determined using the same rules as for
|
||||
\fBstring match\fR.
|
||||
If \fIpattern\fR contains any namespace separators, they are used to
|
||||
select a namespace relative to the current namespace (or relative to
|
||||
the global namespace if \fIpattern\fR starts with \fB::\fR) to match
|
||||
within; the matching pattern is taken to be the part after the last
|
||||
namespace separator.
|
||||
Returns the names of all visible procedures. If \fIpattern\fR is given, returns
|
||||
only those names that match according to \fBstring match\fR. Only the final
|
||||
component in \fIpattern\fR is actually considered a pattern. Any qualifying
|
||||
components simply select a namespace. See \fBNAMESPACE RESOLUTION\fR in the
|
||||
\fBnamespace\fR(n) documentation.
|
||||
.TP
|
||||
\fBinfo script\fR ?\fIfilename\fR?
|
||||
.
|
||||
If a Tcl script file is currently being evaluated (i.e. there is a
|
||||
call to \fBTcl_EvalFile\fR active or there is an active invocation
|
||||
of the \fBsource\fR command), then this command returns the name
|
||||
of the innermost file being processed. If \fIfilename\fR is specified,
|
||||
then the return value of this command will be modified for the
|
||||
duration of the active invocation to return that name. This is
|
||||
useful in virtual file system applications.
|
||||
Otherwise the command returns an empty string.
|
||||
Returns the pathname of the innermost script currently being evaluated, or the
|
||||
empty string if no pathname can be determined. If \fIfilename\fR is given,
|
||||
sets the return value of any future calls to \fBinfo script\fR for the duration
|
||||
of the innermost active script. This is useful in virtual file system
|
||||
applications.
|
||||
.TP
|
||||
\fBinfo sharedlibextension\fR
|
||||
.
|
||||
Returns the extension used on this platform for the names of files
|
||||
containing shared libraries (for example, \fB.so\fR under Solaris).
|
||||
If shared libraries are not supported on this platform then an empty
|
||||
string is returned.
|
||||
Returns the extension used on this platform for names of shared libraries, e.g.
|
||||
\fB.so\fR under Solaris. Returns the empty string if shared libraries are not
|
||||
supported on this platform.
|
||||
.TP
|
||||
\fBinfo tclversion\fR
|
||||
.
|
||||
Returns the value of the global variable \fBtcl_version\fR, which holds the
|
||||
major and minor version of the Tcl library by default.
|
||||
Returns the value of the global variable \fBtcl_version\fR, in which the
|
||||
major and minor version of the Tcl library are stored.
|
||||
.TP
|
||||
\fBinfo vars\fR ?\fIpattern\fR?
|
||||
.
|
||||
If \fIpattern\fR is not specified,
|
||||
returns a list of all the names of currently-visible variables.
|
||||
This includes locals and currently-visible globals.
|
||||
If \fIpattern\fR is specified, only those names matching \fIpattern\fR
|
||||
are returned. Matching is determined using the same rules as for
|
||||
\fBstring match\fR.
|
||||
\fIpattern\fR can be a qualified name like \fBFoo::option*\fR.
|
||||
That is, it may specify a particular namespace
|
||||
using a sequence of namespace names separated by double colons (\fB::\fR),
|
||||
and may have pattern matching special characters
|
||||
at the end to specify a set of variables in that namespace.
|
||||
If \fIpattern\fR is a qualified name,
|
||||
the resulting list of variable names
|
||||
has each matching namespace variable qualified with the name
|
||||
of its namespace.
|
||||
Note that a currently-visible variable may not yet
|
||||
.QW exist
|
||||
if it has not
|
||||
been set (e.g. a variable declared but not set by \fBvariable\fR).
|
||||
If \fIpattern\fR is not given, returns the names of all visible variables. If
|
||||
\fIpattern\fR is given, returns only those names that match according to
|
||||
\fBstring match\fR. Only the last component of \fIpattern\fR is a pattern.
|
||||
Other components identify a namespace. See \fBNAMESPACE RESOLUTION\fR in the
|
||||
\fBnamespace\fR(n) documentation. When \fIpattern\fR is a qualified name,
|
||||
results are fully qualified.
|
||||
|
||||
A variable that has declared but not yet defined is included in the results.
|
||||
.SS "CLASS INTROSPECTION"
|
||||
.PP
|
||||
The following \fIsubcommand\fR values are supported by \fBinfo class\fR:
|
||||
@@ -492,7 +402,7 @@ the class \fIclass\fR; the definition namespace only affects the instances of
|
||||
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,
|
||||
If \fIclass\fR does not provide a definition namespace of the given 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.
|
||||
@@ -523,7 +433,7 @@ instances to those that match it according to the rules of \fBstring match\fR.
|
||||
.
|
||||
This subcommand returns a list of all public (i.e. exported) methods of the
|
||||
class called \fIclass\fR. Any of the following \fIoption\fRs may be
|
||||
specified, controlling exactly which method names are returned:
|
||||
given, controlling exactly which method names are returned:
|
||||
.RS
|
||||
.TP
|
||||
\fB\-all\fR
|
||||
@@ -600,7 +510,7 @@ This subcommand returns a list of all variables that have been declared for
|
||||
the class named \fIclass\fR (i.e. that are automatically present in the
|
||||
class's methods, constructor and destructor).
|
||||
.VS TIP500
|
||||
If the \fB\-private\fR option is specified, this lists the private variables
|
||||
If the \fB\-private\fR option is given, this lists the private variables
|
||||
declared instead.
|
||||
.VE TIP500
|
||||
.SS "OBJECT INTROSPECTION"
|
||||
@@ -638,7 +548,7 @@ methods.
|
||||
.TP
|
||||
\fBinfo object class\fI object\fR ?\fIclassName\fR?
|
||||
.
|
||||
If \fIclassName\fR is unspecified, this subcommand returns class of the
|
||||
If \fIclassName\fR is not given, this subcommand returns class of the
|
||||
\fIobject\fR object. If \fIclassName\fR is present, this subcommand returns a
|
||||
boolean value indicating whether the \fIobject\fR is of that class.
|
||||
.TP
|
||||
@@ -707,7 +617,7 @@ direct or indirect).
|
||||
.
|
||||
This subcommand returns a list of all public (i.e. exported) methods of the
|
||||
object called \fIobject\fR. Any of the following \fIoption\fRs may be
|
||||
specified, controlling exactly which method names are returned:
|
||||
given, controlling exactly which method names are returned:
|
||||
.RS
|
||||
.TP
|
||||
\fB\-all\fR
|
||||
@@ -777,7 +687,7 @@ This subcommand returns a list of all variables that have been declared for
|
||||
the object named \fIobject\fR (i.e. that are automatically present in the
|
||||
object's methods).
|
||||
.VS TIP500
|
||||
If the \fB\-private\fR option is specified, this lists the private variables
|
||||
If the \fB\-private\fR option is given, this lists the private variables
|
||||
declared instead.
|
||||
.VE TIP500
|
||||
.TP
|
||||
|
||||
+1
-1
@@ -201,7 +201,7 @@ slave interpreter identified by \fIpath\fR. If no arguments are
|
||||
given, option and current setting are returned. If \fB\-frame\fR
|
||||
is given, the debug setting is set to the given boolean if provided
|
||||
and the current setting is returned.
|
||||
This only effects the output of \fBinfo frame\fR, in that exact
|
||||
This only affects the output of \fBinfo frame\fR, in that exact
|
||||
frame-level information for command invocation at the bytecode level
|
||||
is only captured with this setting on.
|
||||
.RS
|
||||
|
||||
+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:
|
||||
+5
-4
@@ -151,10 +151,11 @@ is the same as
|
||||
.QW "\fB** 2 [** 3 4]\fR" .
|
||||
Each \fInumber\fR may be
|
||||
any numeric value, though the second number must not be fractional if the
|
||||
first is negative. If no arguments are given, the result will be one, and if
|
||||
only one argument is given, the result will be that argument. The
|
||||
result will have an integral value only when all arguments are
|
||||
integral values.
|
||||
first is negative. The maximum exponent value that Tcl can handle if the
|
||||
first number is an integer > 1 is 268435455. If no arguments are given,
|
||||
the result will be one, and if only one argument is given, the result will
|
||||
be that argument. The result will have an integral value only when all
|
||||
arguments are integral values.
|
||||
.SS "COMPARISON OPERATORS"
|
||||
.PP
|
||||
The behaviors of the comparison operator commands (most of which operate
|
||||
|
||||
+27
-4
@@ -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
|
||||
.
|
||||
@@ -89,6 +88,23 @@ If \fIcharIndex\fR is less than 0 or greater than or equal to the
|
||||
length of the string then this command returns an empty string.
|
||||
.RE
|
||||
.TP
|
||||
\fBstring insert \fIstring index insertString\fR
|
||||
.
|
||||
Returns a copy of \fIstring\fR with \fIinsertString\fR inserted at the
|
||||
\fIindex\fR'th character. \fIindex\fR may be specified as described in the
|
||||
\fBSTRING INDICES\fR section.
|
||||
.RS
|
||||
.PP
|
||||
If \fIindex\fR is start-relative, the first character inserted in the returned
|
||||
string will be at the specified index. If \fIindex\fR is end-relative, the last
|
||||
character inserted in the returned string will be at the specified index.
|
||||
.PP
|
||||
If \fIindex\fR is at or before the start of \fIstring\fR (e.g., \fIindex\fR is
|
||||
\fB0\fR), \fIinsertString\fR is prepended to \fIstring\fR. If \fIindex\fR is at
|
||||
or after the end of \fIstring\fR (e.g., \fIindex\fR is \fBend\fR),
|
||||
\fIinsertString\fR is appended to \fIstring\fR.
|
||||
.RE
|
||||
.TP
|
||||
\fBstring is \fIclass\fR ?\fB\-strict\fR? ?\fB\-failindex \fIvarname\fR? \fIstring\fR
|
||||
.
|
||||
Returns 1 if \fIstring\fR is a valid member of the specified character
|
||||
@@ -111,17 +127,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:
|
||||
@@ -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
|
||||
|
||||
+2
-3
@@ -110,7 +110,6 @@ for the current platform. On Windows, this value is
|
||||
.QW \fBzipfs:/\fR .
|
||||
On Unix, this value is
|
||||
.QW \fB//zipfs:/\fR .
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs unmount \fImountpoint\fR
|
||||
.
|
||||
@@ -184,7 +183,7 @@ before unmounting it again:
|
||||
.PP
|
||||
.CS
|
||||
set zip myApp.zip
|
||||
set base [file join [\fbzipfs root\fR] myApp]
|
||||
set base [file join [\fBzipfs root\fR] myApp]
|
||||
|
||||
\fBzipfs mount\fR $base $zip
|
||||
# $base now has the contents of myApp.zip
|
||||
@@ -213,7 +212,7 @@ building the ZIP and when mounting it.
|
||||
set zip myApp.zip
|
||||
set sourceDir [file normalize myApp]
|
||||
set password "hunter2"
|
||||
set base [file join [\fbzipfs root\fR] myApp]
|
||||
set base [file join [\fBzipfs root\fR] myApp]
|
||||
|
||||
# Create with password
|
||||
\fBzipfs mkzip\fR $targetZip $sourceDir $sourceDir $password
|
||||
|
||||
+167
-162
@@ -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,54 +643,53 @@ 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},
|
||||
{0x3220, 0x4db5}, {0x4dc0, 0x9fef}, {0xa000, 0xa48c}, {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, 0xab65}, {0xab70, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3},
|
||||
{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},
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -828,7 +833,7 @@ element(
|
||||
*/
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
|
||||
np = Tcl_UniCharToUtfDString(startp, len, &ds);
|
||||
for (cn=cnames; cn->name!=NULL; cn++) {
|
||||
if (strlen(cn->name)==len && strncmp(cn->name, np, len)==0) {
|
||||
break; /* NOTE BREAK OUT */
|
||||
|
||||
+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]);
|
||||
|
||||
+53
-7
@@ -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,11 +860,11 @@ 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)
|
||||
}
|
||||
declare 245 {
|
||||
declare 245 {deprecated {No longer in use, changed to macro}} {
|
||||
int Tcl_StringMatch(const char *str, const char *pattern)
|
||||
}
|
||||
declare 246 {deprecated {}} {
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+95
-55
@@ -260,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},
|
||||
@@ -318,6 +319,7 @@ 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},
|
||||
@@ -558,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;
|
||||
@@ -973,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.
|
||||
@@ -985,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::") */
|
||||
@@ -996,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++){
|
||||
@@ -1057,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
|
||||
@@ -2746,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]);
|
||||
@@ -2775,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,
|
||||
@@ -2795,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]);
|
||||
@@ -3867,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) {
|
||||
@@ -4402,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;
|
||||
@@ -4970,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
|
||||
@@ -4982,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
|
||||
@@ -6151,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;
|
||||
}
|
||||
|
||||
@@ -7015,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);
|
||||
|
||||
@@ -7428,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) {
|
||||
@@ -7464,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) {
|
||||
@@ -7538,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;
|
||||
}
|
||||
@@ -7600,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) {
|
||||
@@ -7643,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) {
|
||||
@@ -7703,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) {
|
||||
@@ -7714,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) {
|
||||
@@ -7751,17 +7789,19 @@ ExprAbsFunc(
|
||||
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;
|
||||
@@ -7794,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);
|
||||
@@ -7857,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;
|
||||
}
|
||||
@@ -8123,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) {
|
||||
@@ -8146,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;
|
||||
}
|
||||
}
|
||||
|
||||
+156
-94
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -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;
|
||||
}
|
||||
@@ -3033,9 +3093,11 @@ 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++;
|
||||
if (i) cut++;
|
||||
} else if (strict || !TclIsSpaceProc(c)) {
|
||||
goto bad64;
|
||||
} else {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+16
-16
@@ -382,7 +382,7 @@ CatchObjCmdCallback(
|
||||
}
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -932,7 +932,7 @@ Tcl_ExitObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
int value;
|
||||
Tcl_WideInt value;
|
||||
|
||||
if ((objc != 1) && (objc != 2)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
|
||||
@@ -941,10 +941,10 @@ Tcl_ExitObjCmd(
|
||||
|
||||
if (objc == 1) {
|
||||
value = 0;
|
||||
} else if (Tcl_GetIntFromObj(interp, objv[1], &value) != TCL_OK) {
|
||||
} else if (TclGetWideBitsFromObj(interp, objv[1], &value) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_Exit(value);
|
||||
Tcl_Exit((int)value);
|
||||
/*NOTREACHED*/
|
||||
return TCL_OK; /* Better not ever reach this! */
|
||||
}
|
||||
@@ -1179,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;
|
||||
}
|
||||
|
||||
@@ -1259,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;
|
||||
}
|
||||
|
||||
@@ -1882,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;
|
||||
}
|
||||
|
||||
@@ -2278,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
|
||||
|
||||
|
||||
+132
-46
@@ -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;
|
||||
|
||||
+553
-53
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclRegexp.h"
|
||||
#include "tclStringTrim.h"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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[4] = "";
|
||||
|
||||
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));
|
||||
}
|
||||
@@ -1456,6 +1457,63 @@ StringIndexCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* StringInsertCmd --
|
||||
*
|
||||
* This procedure is invoked to process the "string insert" Tcl command.
|
||||
* See the user documentation for details on what it does. Note that this
|
||||
* command only functions correctly on properly formed Tcl UTF strings.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
StringInsertCmd(
|
||||
ClientData dummy, /* Not used */
|
||||
Tcl_Interp *interp, /* Current interpreter */
|
||||
int objc, /* Number of arguments */
|
||||
Tcl_Obj *const objv[]) /* Argument objects */
|
||||
{
|
||||
int length; /* String length */
|
||||
int index; /* Insert index */
|
||||
Tcl_Obj *outObj; /* Output object */
|
||||
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "string index insertString");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
length = Tcl_GetCharLength(objv[1]);
|
||||
if (TclGetIntForIndexM(interp, objv[2], length, &index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
if (index > length) {
|
||||
index = length;
|
||||
}
|
||||
|
||||
outObj = TclStringReplace(interp, objv[1], index, 0, objv[3],
|
||||
TCL_STRING_IN_PLACE);
|
||||
|
||||
if (outObj != NULL) {
|
||||
Tcl_SetObjResult(interp, outObj);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1490,19 +1548,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 +1629,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 +1647,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);
|
||||
@@ -1624,8 +1730,8 @@ StringIsCmd(
|
||||
break;
|
||||
case STR_IS_INT:
|
||||
case STR_IS_ENTIER:
|
||||
if ((objPtr->typePtr == &tclIntType) ||
|
||||
(objPtr->typePtr == &tclBignumType)) {
|
||||
if (TclHasIntRep(objPtr, &tclIntType) ||
|
||||
TclHasIntRep(objPtr, &tclBignumType)) {
|
||||
break;
|
||||
}
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
@@ -1806,8 +1912,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
|
||||
@@ -1825,7 +1931,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;
|
||||
}
|
||||
@@ -1887,7 +1993,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(
|
||||
@@ -1903,7 +2009,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;
|
||||
|
||||
@@ -2065,7 +2172,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.
|
||||
@@ -2154,7 +2261,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(
|
||||
@@ -2447,7 +2554,7 @@ StringStartCmd(
|
||||
cur += 1;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2509,7 +2616,7 @@ StringEndCmd(
|
||||
} else {
|
||||
cur = numChars;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2556,10 +2663,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;
|
||||
}
|
||||
@@ -2583,9 +2690,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;
|
||||
}
|
||||
@@ -2630,11 +2735,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. */
|
||||
@@ -2655,10 +2761,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;
|
||||
}
|
||||
@@ -2755,7 +2861,7 @@ StringBytesCmd(
|
||||
}
|
||||
|
||||
(void) TclGetStringFromObj(objv[1], &length);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(length));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(length));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2789,7 +2895,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;
|
||||
}
|
||||
|
||||
@@ -3220,6 +3326,7 @@ TclInitStringCmd(
|
||||
{"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0},
|
||||
{"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0},
|
||||
{"index", StringIndexCmd, TclCompileStringIndexCmd, NULL, NULL, 0},
|
||||
{"insert", StringInsertCmd, TclCompileStringInsertCmd, NULL, NULL, 0},
|
||||
{"is", StringIsCmd, TclCompileStringIsCmd, NULL, NULL, 0},
|
||||
{"last", StringLastCmd, TclCompileStringLastCmd, NULL, NULL, 0},
|
||||
{"length", StringLenCmd, TclCompileStringLenCmd, NULL, NULL, 0},
|
||||
@@ -3678,10 +3785,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3982,7 +4089,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;
|
||||
}
|
||||
@@ -4001,7 +4108,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);
|
||||
}
|
||||
@@ -4019,6 +4126,399 @@ 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 (!count) { /* no iterations - avoid divide by zero */
|
||||
objs[0] = objs[2] = objs[4] = Tcl_NewWideIntObj(0);
|
||||
goto retRes;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
retRes:
|
||||
/* estimated net execution time (in millisecs) */
|
||||
if (!calibrate) {
|
||||
if (middle >= 1) {
|
||||
objs[6] = Tcl_ObjPrintf("%.3f", (double)middle / 1000);
|
||||
} else {
|
||||
objs[6] = Tcl_NewWideIntObj(0);
|
||||
}
|
||||
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 {
|
||||
/*
|
||||
|
||||
+96
-30
@@ -448,6 +448,63 @@ TclCompileStringIndexCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringInsertCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *tokenPtr;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
int idx;
|
||||
|
||||
if (parsePtr->numWords != 4) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* Compute and push the string in which to insert */
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
|
||||
/* See what can be discovered about index at compile time */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (TCL_OK != TclGetIndexFromToken(tokenPtr, TCL_INDEX_START,
|
||||
TCL_INDEX_END, &idx)) {
|
||||
|
||||
/* Nothing useful knowable - cease compile; let it direct eval */
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* Compute and push the string to be inserted */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 3);
|
||||
|
||||
if (idx == TCL_INDEX_START) {
|
||||
/* Prepend the insertion string */
|
||||
OP4( REVERSE, 2);
|
||||
OP1( STR_CONCAT1, 2);
|
||||
} else if (idx == TCL_INDEX_END) {
|
||||
/* Append the insertion string */
|
||||
OP1( STR_CONCAT1, 2);
|
||||
} else {
|
||||
/* Prefix + insertion + suffix */
|
||||
if (idx < TCL_INDEX_END) {
|
||||
/* See comments in compiler for [linsert]. */
|
||||
idx++;
|
||||
}
|
||||
OP4( OVER, 1);
|
||||
OP44( STR_RANGE_IMM, 0, idx-1);
|
||||
OP4( REVERSE, 3);
|
||||
OP44( STR_RANGE_IMM, idx, TCL_INDEX_END);
|
||||
OP1( STR_CONCAT1, 3);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringIsCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -461,7 +518,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 +526,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,
|
||||
@@ -703,7 +760,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);
|
||||
@@ -934,7 +1003,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;
|
||||
}
|
||||
@@ -943,14 +1012,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;
|
||||
}
|
||||
@@ -958,7 +1027,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( "");
|
||||
@@ -1008,7 +1077,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;
|
||||
}
|
||||
@@ -1017,7 +1086,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;
|
||||
}
|
||||
@@ -1036,8 +1105,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
|
||||
@@ -1045,20 +1114,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
|
||||
*/
|
||||
@@ -1091,34 +1157,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);
|
||||
@@ -1127,7 +1193,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);
|
||||
@@ -1144,10 +1210,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 ( "");
|
||||
@@ -1156,7 +1222,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;
|
||||
@@ -1493,7 +1559,7 @@ TclSubstCompile(
|
||||
for (endTokenPtr = tokenPtr + parse.numTokens;
|
||||
tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
|
||||
int length, literal, catchRange, breakJump;
|
||||
char buf[TCL_UTF_MAX];
|
||||
char buf[4] = "";
|
||||
JumpFixup startFixup, okFixup, returnFixup, breakFixup;
|
||||
JumpFixup continueFixup, otherFixup, endFixup;
|
||||
|
||||
|
||||
@@ -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) {
|
||||
@@ -2066,9 +2066,9 @@ ParseLexeme(
|
||||
if (Tcl_UtfCharComplete(start, numBytes)) {
|
||||
scanned = TclUtfToUniChar(start, &ch);
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
char utfBytes[4];
|
||||
|
||||
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[4] = "";
|
||||
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[4] = "";
|
||||
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
|
||||
|
||||
+1
-1
@@ -2744,7 +2744,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 */
|
||||
|
||||
+66
-16
@@ -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);
|
||||
@@ -753,7 +754,8 @@ EXTERN void Tcl_StaticPackage(Tcl_Interp *interp,
|
||||
Tcl_PackageInitProc *initProc,
|
||||
Tcl_PackageInitProc *safeInitProc);
|
||||
/* 245 */
|
||||
EXTERN int Tcl_StringMatch(const char *str, const char *pattern);
|
||||
TCL_DEPRECATED("No longer in use, changed to macro")
|
||||
int Tcl_StringMatch(const char *str, const char *pattern);
|
||||
/* 246 */
|
||||
TCL_DEPRECATED("")
|
||||
int Tcl_TellOld(Tcl_Channel chan);
|
||||
@@ -1875,6 +1877,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 +1954,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 +2000,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 +2068,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 +2162,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,8 +2176,8 @@ 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 */
|
||||
int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */
|
||||
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 */
|
||||
TCL_DEPRECATED_API("No longer in use, changed to macro") 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 */
|
||||
int (*tcl_TraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 248 */
|
||||
@@ -2429,7 +2451,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 +2568,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 +2662,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 +3878,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 +3905,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 +3944,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 +4072,10 @@ 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)
|
||||
#undef Tcl_StringMatch
|
||||
#define Tcl_StringMatch(str, pattern) Tcl_StringCaseMatch((str), (pattern), 0)
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
||||
+52
-40
@@ -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,7 +1613,9 @@ 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",
|
||||
|
||||
+79
-51
@@ -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,9 +2073,9 @@ 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),
|
||||
@@ -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(
|
||||
|
||||
+215
-351
@@ -499,11 +499,11 @@ VarHashCreateVar(
|
||||
*/
|
||||
|
||||
#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
((TclHasIntRep((objPtr), &tclIntType)) \
|
||||
? (*(tPtr) = TCL_NUMBER_INT, \
|
||||
*(ptrPtr) = (ClientData) \
|
||||
(&((objPtr)->internalRep.wideValue)), TCL_OK) : \
|
||||
((objPtr)->typePtr == &tclDoubleType) \
|
||||
TclHasIntRep((objPtr), &tclDoubleType) \
|
||||
? (((TclIsNaN((objPtr)->internalRep.doubleValue)) \
|
||||
? (*(tPtr) = TCL_NUMBER_NAN) \
|
||||
: (*(tPtr) = TCL_NUMBER_DOUBLE)), \
|
||||
@@ -748,20 +748,22 @@ ReleaseDictIterator(
|
||||
{
|
||||
Tcl_DictSearch *searchPtr;
|
||||
Tcl_Obj *dictPtr;
|
||||
const Tcl_ObjIntRep *irPtr;
|
||||
|
||||
irPtr = TclFetchIntRep(objPtr, &dictIteratorType);
|
||||
assert(irPtr != NULL);
|
||||
|
||||
/*
|
||||
* First kill the search, and then release the reference to the dictionary
|
||||
* that we were holding.
|
||||
*/
|
||||
|
||||
searchPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
searchPtr = irPtr->twoPtrValue.ptr1;
|
||||
Tcl_DictObjDone(searchPtr);
|
||||
ckfree(searchPtr);
|
||||
|
||||
dictPtr = objPtr->internalRep.twoPtrValue.ptr2;
|
||||
dictPtr = irPtr->twoPtrValue.ptr2;
|
||||
TclDecrRefCount(dictPtr);
|
||||
|
||||
objPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1450,19 +1452,23 @@ CompileExprObj(
|
||||
* Get the expression ByteCode from the object. If it exists, make sure it
|
||||
* is valid in the current context.
|
||||
*/
|
||||
if (objPtr->typePtr == &exprCodeType) {
|
||||
|
||||
ByteCodeGetIntRep(objPtr, &exprCodeType, codePtr);
|
||||
|
||||
if (codePtr != NULL) {
|
||||
Namespace *namespacePtr = iPtr->varFramePtr->nsPtr;
|
||||
|
||||
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (((Interp *) *codePtr->interpHandle != iPtr)
|
||||
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|
||||
|| (codePtr->nsPtr != namespacePtr)
|
||||
|| (codePtr->nsEpoch != namespacePtr->resolverEpoch)
|
||||
|| (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)) {
|
||||
TclFreeIntRep(objPtr);
|
||||
Tcl_StoreIntRep(objPtr, &exprCodeType, NULL);
|
||||
codePtr = NULL;
|
||||
}
|
||||
}
|
||||
if (objPtr->typePtr != &exprCodeType) {
|
||||
|
||||
if (codePtr == NULL) {
|
||||
/*
|
||||
* TIP #280: No invoker (yet) - Expression compilation.
|
||||
*/
|
||||
@@ -1562,7 +1568,9 @@ static void
|
||||
FreeExprCodeInternalRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ByteCode *codePtr;
|
||||
ByteCodeGetIntRep(objPtr, &exprCodeType, codePtr);
|
||||
assert(codePtr != NULL);
|
||||
|
||||
TclReleaseByteCode(codePtr);
|
||||
}
|
||||
@@ -1600,7 +1608,8 @@ TclCompileObj(
|
||||
* compilation). Otherwise, check that it is "fresh" enough.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &tclByteCodeType) {
|
||||
ByteCodeGetIntRep(objPtr, &tclByteCodeType, codePtr);
|
||||
if (codePtr != NULL) {
|
||||
/*
|
||||
* Make sure the Bytecode hasn't been invalidated by, e.g., someone
|
||||
* redefining a command with a compile procedure (this might make the
|
||||
@@ -1618,7 +1627,6 @@ TclCompileObj(
|
||||
* here.
|
||||
*/
|
||||
|
||||
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (((Interp *) *codePtr->interpHandle != iPtr)
|
||||
|| (codePtr->compileEpoch != iPtr->compileEpoch)
|
||||
|| (codePtr->nsPtr != namespacePtr)
|
||||
@@ -1746,7 +1754,7 @@ TclCompileObj(
|
||||
iPtr->invokeWord = word;
|
||||
TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
|
||||
iPtr->invokeCmdFramePtr = NULL;
|
||||
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ByteCodeGetIntRep(objPtr, &tclByteCodeType, codePtr);
|
||||
if (iPtr->varFramePtr->localCachePtr) {
|
||||
codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
|
||||
codePtr->localCachePtr->refCount++;
|
||||
@@ -1822,11 +1830,11 @@ TclIncrObj(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if ((type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) {
|
||||
if ((type1 == TCL_NUMBER_INT) && (type2 == TCL_NUMBER_INT)) {
|
||||
Tcl_WideInt w1, w2, sum;
|
||||
|
||||
TclGetWideIntFromObj(NULL, valuePtr, &w1);
|
||||
TclGetWideIntFromObj(NULL, incrPtr, &w2);
|
||||
w1 = *((const Tcl_WideInt *)ptr1);
|
||||
w2 = *((const Tcl_WideInt *)ptr2);
|
||||
sum = w1 + w2;
|
||||
|
||||
/*
|
||||
@@ -1901,7 +1909,7 @@ ArgumentBCEnter(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
#define bcFramePtr (&TD->cmdFrame)
|
||||
#define initCatchTop ((ptrdiff_t *) (&TD->stack[-1]))
|
||||
#define initCatchTop ((ptrdiff_t *) (TD->stack-1))
|
||||
#define initTosPtr ((Tcl_Obj **) (initCatchTop+codePtr->maxExceptDepth))
|
||||
#define esPtr (iPtr->execEnvPtr->execStackPtr)
|
||||
|
||||
@@ -4760,7 +4768,7 @@ TEBCresume(
|
||||
*/
|
||||
|
||||
if ((TclListObjGetElements(interp, valuePtr, &objc, &objv) == TCL_OK)
|
||||
&& (value2Ptr->typePtr != &tclListType)
|
||||
&& !TclHasIntRep(value2Ptr, &tclListType)
|
||||
&& (TclGetIntForIndexM(NULL, value2Ptr, objc-1,
|
||||
&index) == TCL_OK)) {
|
||||
TclDecrRefCount(value2Ptr);
|
||||
@@ -4955,22 +4963,17 @@ TEBCresume(
|
||||
|
||||
/* Every range of an empty list is an empty list */
|
||||
if (objc == 0) {
|
||||
TRACE_APPEND(("\n"));
|
||||
NEXT_INST_F(9, 0, 0);
|
||||
/* avoid return of not canonical list (e. g. spaces in string repr.) */
|
||||
if (!valuePtr->bytes || !valuePtr->length) {
|
||||
TRACE_APPEND(("\n"));
|
||||
NEXT_INST_F(9, 0, 0);
|
||||
}
|
||||
goto emptyList;
|
||||
}
|
||||
|
||||
/* Decode index value operands. */
|
||||
|
||||
/*
|
||||
assert ( toIdx != TCL_INDEX_AFTER);
|
||||
*
|
||||
* Extra safety for legacy bytecodes:
|
||||
*/
|
||||
if (toIdx == TCL_INDEX_AFTER) {
|
||||
toIdx = TCL_INDEX_END;
|
||||
}
|
||||
|
||||
if ((toIdx == TCL_INDEX_BEFORE) || (fromIdx == TCL_INDEX_AFTER)) {
|
||||
if (toIdx == TCL_INDEX_NONE) {
|
||||
emptyList:
|
||||
objResultPtr = Tcl_NewObj();
|
||||
TRACE_APPEND(("\"%.30s\"", O2S(objResultPtr)));
|
||||
@@ -4985,11 +4988,11 @@ TEBCresume(
|
||||
|
||||
assert ( toIdx >= 0 && toIdx < objc);
|
||||
/*
|
||||
assert ( fromIdx != TCL_INDEX_BEFORE );
|
||||
assert ( fromIdx != TCL_INDEX_NONE );
|
||||
*
|
||||
* Extra safety for legacy bytecodes:
|
||||
*/
|
||||
if (fromIdx == TCL_INDEX_BEFORE) {
|
||||
if (fromIdx == TCL_INDEX_NONE) {
|
||||
fromIdx = TCL_INDEX_START;
|
||||
}
|
||||
|
||||
@@ -5212,7 +5215,7 @@ TEBCresume(
|
||||
objResultPtr = Tcl_NewStringObj((const char *)
|
||||
valuePtr->bytes+index, 1);
|
||||
} else {
|
||||
char buf[4];
|
||||
char buf[4] = "";
|
||||
int ch = Tcl_GetUniChar(valuePtr, index);
|
||||
|
||||
/*
|
||||
@@ -5224,8 +5227,8 @@ TEBCresume(
|
||||
objResultPtr = Tcl_NewObj();
|
||||
} else {
|
||||
length = Tcl_UniCharToUtf(ch, buf);
|
||||
if (!length) {
|
||||
length = Tcl_UniCharToUtf(-1, buf);
|
||||
if ((ch >= 0xD800) && (length < 3)) {
|
||||
length += Tcl_UniCharToUtf(-1, buf + length);
|
||||
}
|
||||
objResultPtr = Tcl_NewStringObj(buf, length);
|
||||
}
|
||||
@@ -5276,17 +5279,13 @@ TEBCresume(
|
||||
/* Decode index operands. */
|
||||
|
||||
/*
|
||||
assert ( toIdx != TCL_INDEX_BEFORE );
|
||||
assert ( toIdx != TCL_INDEX_AFTER);
|
||||
assert ( toIdx != TCL_INDEX_NONE );
|
||||
*
|
||||
* Extra safety for legacy bytecodes:
|
||||
*/
|
||||
if (toIdx == TCL_INDEX_BEFORE) {
|
||||
if (toIdx == TCL_INDEX_NONE) {
|
||||
goto emptyRange;
|
||||
}
|
||||
if (toIdx == TCL_INDEX_AFTER) {
|
||||
toIdx = TCL_INDEX_END;
|
||||
}
|
||||
|
||||
toIdx = TclIndexDecode(toIdx, length - 1);
|
||||
if (toIdx < 0) {
|
||||
@@ -5298,17 +5297,13 @@ TEBCresume(
|
||||
assert ( toIdx >= 0 && toIdx < length );
|
||||
|
||||
/*
|
||||
assert ( fromIdx != TCL_INDEX_BEFORE );
|
||||
assert ( fromIdx != TCL_INDEX_AFTER);
|
||||
assert ( fromIdx != TCL_INDEX_NONE );
|
||||
*
|
||||
* Extra safety for legacy bytecodes:
|
||||
*/
|
||||
if (fromIdx == TCL_INDEX_BEFORE) {
|
||||
if (fromIdx == TCL_INDEX_NONE) {
|
||||
fromIdx = TCL_INDEX_START;
|
||||
}
|
||||
if (fromIdx == TCL_INDEX_AFTER) {
|
||||
goto emptyRange;
|
||||
}
|
||||
|
||||
fromIdx = TclIndexDecode(fromIdx, length - 1);
|
||||
if (fromIdx < 0) {
|
||||
@@ -5491,8 +5486,8 @@ TEBCresume(
|
||||
* both.
|
||||
*/
|
||||
|
||||
if ((valuePtr->typePtr == &tclStringType)
|
||||
|| (value2Ptr->typePtr == &tclStringType)) {
|
||||
if (TclHasIntRep(valuePtr, &tclStringType)
|
||||
|| TclHasIntRep(value2Ptr, &tclStringType)) {
|
||||
Tcl_UniChar *ustring1, *ustring2;
|
||||
|
||||
ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
|
||||
@@ -5636,7 +5631,7 @@ TEBCresume(
|
||||
/* [string is wideinteger] is WIDE_MIN to WIDE_MAX range */
|
||||
Tcl_WideInt w;
|
||||
|
||||
if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) {
|
||||
if (TclGetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) {
|
||||
type1 = TCL_NUMBER_INT;
|
||||
}
|
||||
}
|
||||
@@ -6298,7 +6293,7 @@ TEBCresume(
|
||||
|
||||
case INST_TRY_CVT_TO_BOOLEAN:
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
if (valuePtr->typePtr == &tclBooleanType) {
|
||||
if (TclHasIntRep(valuePtr, &tclBooleanType)) {
|
||||
objResultPtr = TCONST(1);
|
||||
} else {
|
||||
int result = (TclSetBooleanFromAny(NULL, valuePtr) == TCL_OK);
|
||||
@@ -7104,13 +7099,16 @@ TEBCresume(
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
TclNewObj(statePtr);
|
||||
statePtr->typePtr = &dictIteratorType;
|
||||
statePtr->internalRep.twoPtrValue.ptr1 = searchPtr;
|
||||
statePtr->internalRep.twoPtrValue.ptr2 = dictPtr;
|
||||
{
|
||||
Tcl_ObjIntRep ir;
|
||||
TclNewObj(statePtr);
|
||||
ir.twoPtrValue.ptr1 = searchPtr;
|
||||
ir.twoPtrValue.ptr2 = dictPtr;
|
||||
Tcl_StoreIntRep(statePtr, &dictIteratorType, &ir);
|
||||
}
|
||||
varPtr = LOCAL(opnd);
|
||||
if (varPtr->value.objPtr) {
|
||||
if (varPtr->value.objPtr->typePtr == &dictIteratorType) {
|
||||
if (TclHasIntRep(varPtr->value.objPtr, &dictIteratorType)) {
|
||||
Tcl_Panic("mis-issued dictFirst!");
|
||||
}
|
||||
TclDecrRefCount(varPtr->value.objPtr);
|
||||
@@ -7123,11 +7121,17 @@ TEBCresume(
|
||||
opnd = TclGetUInt4AtPtr(pc+1);
|
||||
TRACE(("%u => ", opnd));
|
||||
statePtr = (*LOCAL(opnd)).value.objPtr;
|
||||
if (statePtr == NULL || statePtr->typePtr != &dictIteratorType) {
|
||||
Tcl_Panic("mis-issued dictNext!");
|
||||
{
|
||||
const Tcl_ObjIntRep *irPtr;
|
||||
|
||||
if (statePtr &&
|
||||
(irPtr = TclFetchIntRep(statePtr, &dictIteratorType))) {
|
||||
searchPtr = irPtr->twoPtrValue.ptr1;
|
||||
Tcl_DictObjNext(searchPtr, &keyPtr, &valuePtr, &done);
|
||||
} else {
|
||||
Tcl_Panic("mis-issued dictNext!");
|
||||
}
|
||||
}
|
||||
searchPtr = statePtr->internalRep.twoPtrValue.ptr1;
|
||||
Tcl_DictObjNext(searchPtr, &keyPtr, &valuePtr, &done);
|
||||
pushDictIteratorResult:
|
||||
if (done) {
|
||||
TclNewObj(emptyPtr);
|
||||
@@ -7788,6 +7792,91 @@ FinalizeOONextFilter(
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* WidePwrSmallExpon --
|
||||
*
|
||||
* Helper to calculate small powers of integers whose result is wide.
|
||||
*/
|
||||
static inline Tcl_WideInt
|
||||
WidePwrSmallExpon(Tcl_WideInt w1, long exponent) {
|
||||
|
||||
Tcl_WideInt wResult;
|
||||
|
||||
wResult = w1 * w1; /* b**2 */
|
||||
switch (exponent) {
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
wResult *= w1; /* b**3 */
|
||||
break;
|
||||
case 4:
|
||||
wResult *= wResult; /* b**4 */
|
||||
break;
|
||||
case 5:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= w1; /* b**5 */
|
||||
break;
|
||||
case 6:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
break;
|
||||
case 7:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= w1; /* b**7 */
|
||||
break;
|
||||
case 8:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= wResult; /* b**8 */
|
||||
break;
|
||||
case 9:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= wResult; /* b**8 */
|
||||
wResult *= w1; /* b**9 */
|
||||
break;
|
||||
case 10:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= w1; /* b**5 */
|
||||
wResult *= wResult; /* b**10 */
|
||||
break;
|
||||
case 11:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= w1; /* b**5 */
|
||||
wResult *= wResult; /* b**10 */
|
||||
wResult *= w1; /* b**11 */
|
||||
break;
|
||||
case 12:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= wResult; /* b**12 */
|
||||
break;
|
||||
case 13:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= wResult; /* b**12 */
|
||||
wResult *= w1; /* b**13 */
|
||||
break;
|
||||
case 14:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= w1; /* b**7 */
|
||||
wResult *= wResult; /* b**14 */
|
||||
break;
|
||||
case 15:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= w1; /* b**7 */
|
||||
wResult *= wResult; /* b**14 */
|
||||
wResult *= w1; /* b**15 */
|
||||
break;
|
||||
case 16:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= wResult; /* b**8 */
|
||||
wResult *= wResult; /* b**16 */
|
||||
break;
|
||||
}
|
||||
return wResult;
|
||||
}
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -7850,7 +7939,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
Tcl_WideInt w1, w2, wResult;
|
||||
mp_int big1, big2, bigResult, bigRemainder;
|
||||
Tcl_Obj *objResultPtr;
|
||||
int invalid, numPos, zero;
|
||||
int invalid, zero;
|
||||
long shift;
|
||||
|
||||
(void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);
|
||||
@@ -7884,9 +7973,9 @@ ExecuteExtendedBinaryMathOp(
|
||||
|
||||
return constants[0];
|
||||
}
|
||||
if (type2 != TCL_NUMBER_BIG) {
|
||||
if (type2 == TCL_NUMBER_INT) {
|
||||
Tcl_WideInt wQuotient, wRemainder;
|
||||
Tcl_GetWideIntFromObj(NULL, value2Ptr, &w2);
|
||||
w2 = *((const Tcl_WideInt *)ptr2);
|
||||
wQuotient = w1 / w2;
|
||||
|
||||
/*
|
||||
@@ -7896,8 +7985,8 @@ ExecuteExtendedBinaryMathOp(
|
||||
|
||||
if (((wQuotient < (Tcl_WideInt) 0)
|
||||
|| ((wQuotient == (Tcl_WideInt) 0)
|
||||
&& ((w1 < (Tcl_WideInt)0 && w2 > (Tcl_WideInt)0)
|
||||
|| (w1 > (Tcl_WideInt)0 && w2 < (Tcl_WideInt)0))))
|
||||
&& ((w1 < 0 && w2 > 0)
|
||||
|| (w1 > 0 && w2 < 0))))
|
||||
&& (wQuotient * w2 != w1)) {
|
||||
wQuotient -= (Tcl_WideInt) 1;
|
||||
}
|
||||
@@ -7931,7 +8020,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
mp_init(&bigResult);
|
||||
mp_init(&bigRemainder);
|
||||
mp_div(&big1, &big2, &bigResult, &bigRemainder);
|
||||
if (!mp_iszero(&bigRemainder) && (bigRemainder.sign != big2.sign)) {
|
||||
if ((bigRemainder.used != 0) && (bigRemainder.sign != big2.sign)) {
|
||||
/*
|
||||
* Convert to Tcl's integer division rules.
|
||||
*/
|
||||
@@ -7953,11 +8042,11 @@ ExecuteExtendedBinaryMathOp(
|
||||
|
||||
switch (type2) {
|
||||
case TCL_NUMBER_INT:
|
||||
invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0);
|
||||
invalid = (*((const Tcl_WideInt *)ptr2) < 0);
|
||||
break;
|
||||
case TCL_NUMBER_BIG:
|
||||
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
|
||||
invalid = mp_isneg(&big2);
|
||||
invalid = big2.sign != MP_ZPOS;
|
||||
mp_clear(&big2);
|
||||
break;
|
||||
default:
|
||||
@@ -7974,7 +8063,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
* Zero shifted any number of bits is still zero.
|
||||
*/
|
||||
|
||||
if ((type1==TCL_NUMBER_INT) && (*((const Tcl_WideInt *)ptr1) == (Tcl_WideInt)0)) {
|
||||
if ((type1==TCL_NUMBER_INT) && (*((const Tcl_WideInt *)ptr1) == 0)) {
|
||||
return constants[0];
|
||||
}
|
||||
|
||||
@@ -8006,9 +8095,9 @@ ExecuteExtendedBinaryMathOp(
|
||||
* Handle shifts within the native wide range.
|
||||
*/
|
||||
|
||||
if ((type1 != TCL_NUMBER_BIG)
|
||||
if ((type1 == TCL_NUMBER_INT)
|
||||
&& ((size_t)shift < CHAR_BIT*sizeof(Tcl_WideInt))) {
|
||||
TclGetWideIntFromObj(NULL, valuePtr, &w1);
|
||||
w1 = *((const Tcl_WideInt *)ptr1);
|
||||
if (!((w1>0 ? w1 : ~w1)
|
||||
& -(((Tcl_WideInt)1)
|
||||
<< (CHAR_BIT*sizeof(Tcl_WideInt) - 1 - shift)))) {
|
||||
@@ -8032,11 +8121,11 @@ ExecuteExtendedBinaryMathOp(
|
||||
|
||||
switch (type1) {
|
||||
case TCL_NUMBER_INT:
|
||||
zero = (*(const Tcl_WideInt *)ptr1 > (Tcl_WideInt)0);
|
||||
zero = (*(const Tcl_WideInt *)ptr1 > 0);
|
||||
break;
|
||||
case TCL_NUMBER_BIG:
|
||||
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
|
||||
zero = (!mp_isneg(&big1));
|
||||
zero = (big1.sign == MP_ZPOS);
|
||||
mp_clear(&big1);
|
||||
break;
|
||||
default:
|
||||
@@ -8057,7 +8146,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
if (type1 == TCL_NUMBER_INT) {
|
||||
w1 = *(const Tcl_WideInt *)ptr1;
|
||||
if ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideInt)) {
|
||||
if (w1 >= (Tcl_WideInt)0) {
|
||||
if (w1 >= 0) {
|
||||
return constants[0];
|
||||
}
|
||||
WIDE_RESULT(-1);
|
||||
@@ -8072,16 +8161,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
if (opcode == INST_LSHIFT) {
|
||||
mp_mul_2d(&big1, shift, &bigResult);
|
||||
} else {
|
||||
mp_init(&bigRemainder);
|
||||
mp_div_2d(&big1, shift, &bigResult, &bigRemainder);
|
||||
if (mp_isneg(&bigRemainder)) {
|
||||
/*
|
||||
* Convert to Tcl's integer division rules.
|
||||
*/
|
||||
|
||||
mp_sub_d(&bigResult, 1, &bigResult);
|
||||
}
|
||||
mp_clear(&bigRemainder);
|
||||
mp_tc_div_2d(&big1, shift, &bigResult);
|
||||
}
|
||||
mp_clear(&big1);
|
||||
BIG_RESULT(&bigResult);
|
||||
@@ -8090,139 +8170,23 @@ ExecuteExtendedBinaryMathOp(
|
||||
case INST_BITOR:
|
||||
case INST_BITXOR:
|
||||
case INST_BITAND:
|
||||
if ((type1 == TCL_NUMBER_BIG) || (type2 == TCL_NUMBER_BIG)) {
|
||||
mp_int *First, *Second;
|
||||
|
||||
if ((type1 != TCL_NUMBER_INT) || (type2 != TCL_NUMBER_INT)) {
|
||||
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
|
||||
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
|
||||
|
||||
/*
|
||||
* Count how many positive arguments we have. If only one of the
|
||||
* arguments is negative, store it in 'Second'.
|
||||
*/
|
||||
|
||||
if (!mp_isneg(&big1)) {
|
||||
numPos = 1 + !mp_isneg(&big2);
|
||||
First = &big1;
|
||||
Second = &big2;
|
||||
} else {
|
||||
First = &big2;
|
||||
Second = &big1;
|
||||
numPos = (!mp_isneg(First));
|
||||
}
|
||||
mp_init(&bigResult);
|
||||
|
||||
switch (opcode) {
|
||||
case INST_BITAND:
|
||||
switch (numPos) {
|
||||
case 2:
|
||||
/*
|
||||
* Both arguments positive, base case.
|
||||
*/
|
||||
|
||||
mp_and(First, Second, &bigResult);
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
* First is positive; second negative:
|
||||
* P & N = P & ~~N = P&~(-N-1) = P & (P ^ (-N-1))
|
||||
*/
|
||||
|
||||
mp_neg(Second, Second);
|
||||
mp_sub_d(Second, 1, Second);
|
||||
mp_xor(First, Second, &bigResult);
|
||||
mp_and(First, &bigResult, &bigResult);
|
||||
break;
|
||||
case 0:
|
||||
/*
|
||||
* Both arguments negative:
|
||||
* a & b = ~ (~a | ~b) = -(-a-1|-b-1)-1
|
||||
*/
|
||||
|
||||
mp_neg(First, First);
|
||||
mp_sub_d(First, 1, First);
|
||||
mp_neg(Second, Second);
|
||||
mp_sub_d(Second, 1, Second);
|
||||
mp_or(First, Second, &bigResult);
|
||||
mp_neg(&bigResult, &bigResult);
|
||||
mp_sub_d(&bigResult, 1, &bigResult);
|
||||
break;
|
||||
}
|
||||
mp_tc_and(&big1, &big2, &bigResult);
|
||||
break;
|
||||
|
||||
case INST_BITOR:
|
||||
switch (numPos) {
|
||||
case 2:
|
||||
/*
|
||||
* Both arguments positive, base case.
|
||||
*/
|
||||
|
||||
mp_or(First, Second, &bigResult);
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
* First is positive; second negative:
|
||||
* N|P = ~(~N&~P) = ~((-N-1)&~P) = -((-N-1)&((-N-1)^P))-1
|
||||
*/
|
||||
|
||||
mp_neg(Second, Second);
|
||||
mp_sub_d(Second, 1, Second);
|
||||
mp_xor(First, Second, &bigResult);
|
||||
mp_and(Second, &bigResult, &bigResult);
|
||||
mp_neg(&bigResult, &bigResult);
|
||||
mp_sub_d(&bigResult, 1, &bigResult);
|
||||
break;
|
||||
case 0:
|
||||
/*
|
||||
* Both arguments negative:
|
||||
* a | b = ~ (~a & ~b) = -(-a-1&-b-1)-1
|
||||
*/
|
||||
|
||||
mp_neg(First, First);
|
||||
mp_sub_d(First, 1, First);
|
||||
mp_neg(Second, Second);
|
||||
mp_sub_d(Second, 1, Second);
|
||||
mp_and(First, Second, &bigResult);
|
||||
mp_neg(&bigResult, &bigResult);
|
||||
mp_sub_d(&bigResult, 1, &bigResult);
|
||||
break;
|
||||
}
|
||||
mp_tc_or(&big1, &big2, &bigResult);
|
||||
break;
|
||||
|
||||
case INST_BITXOR:
|
||||
switch (numPos) {
|
||||
case 2:
|
||||
/*
|
||||
* Both arguments positive, base case.
|
||||
*/
|
||||
|
||||
mp_xor(First, Second, &bigResult);
|
||||
break;
|
||||
case 1:
|
||||
/*
|
||||
* First is positive; second negative:
|
||||
* P^N = ~(P^~N) = -(P^(-N-1))-1
|
||||
*/
|
||||
|
||||
mp_neg(Second, Second);
|
||||
mp_sub_d(Second, 1, Second);
|
||||
mp_xor(First, Second, &bigResult);
|
||||
mp_neg(&bigResult, &bigResult);
|
||||
mp_sub_d(&bigResult, 1, &bigResult);
|
||||
break;
|
||||
case 0:
|
||||
/*
|
||||
* Both arguments negative:
|
||||
* a ^ b = (~a ^ ~b) = (-a-1^-b-1)
|
||||
*/
|
||||
|
||||
mp_neg(First, First);
|
||||
mp_sub_d(First, 1, First);
|
||||
mp_neg(Second, Second);
|
||||
mp_sub_d(Second, 1, Second);
|
||||
mp_xor(First, Second, &bigResult);
|
||||
break;
|
||||
}
|
||||
mp_tc_xor(&big1, &big2, &bigResult);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -8231,26 +8195,6 @@ ExecuteExtendedBinaryMathOp(
|
||||
BIG_RESULT(&bigResult);
|
||||
}
|
||||
|
||||
if ((type1 == TCL_NUMBER_INT) || (type2 == TCL_NUMBER_INT)) {
|
||||
TclGetWideIntFromObj(NULL, valuePtr, &w1);
|
||||
TclGetWideIntFromObj(NULL, value2Ptr, &w2);
|
||||
|
||||
switch (opcode) {
|
||||
case INST_BITAND:
|
||||
wResult = w1 & w2;
|
||||
break;
|
||||
case INST_BITOR:
|
||||
wResult = w1 | w2;
|
||||
break;
|
||||
case INST_BITXOR:
|
||||
wResult = w1 ^ w2;
|
||||
break;
|
||||
default:
|
||||
/* Unused, here to silence compiler warning. */
|
||||
wResult = 0;
|
||||
}
|
||||
WIDE_RESULT(wResult);
|
||||
}
|
||||
w1 = *((const Tcl_WideInt *)ptr1);
|
||||
w2 = *((const Tcl_WideInt *)ptr2);
|
||||
|
||||
@@ -8284,7 +8228,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
dResult = pow(d1, d2);
|
||||
goto doubleResult;
|
||||
}
|
||||
w2 = 0;
|
||||
w1 = w2 = 0; /* to silence compiler warning (maybe-uninitialized) */
|
||||
if (type2 == TCL_NUMBER_INT) {
|
||||
w2 = *((const Tcl_WideInt *) ptr2);
|
||||
if (w2 == 0) {
|
||||
@@ -8300,28 +8244,21 @@ ExecuteExtendedBinaryMathOp(
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type2) {
|
||||
case TCL_NUMBER_INT:
|
||||
w2 = *((const Tcl_WideInt *)ptr2);
|
||||
negativeExponent = (w2 < 0);
|
||||
oddExponent = (int) (w2 & (Tcl_WideInt)1);
|
||||
break;
|
||||
case TCL_NUMBER_BIG:
|
||||
} else {
|
||||
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
|
||||
negativeExponent = mp_isneg(&big2);
|
||||
negativeExponent = big2.sign != MP_ZPOS;
|
||||
mp_mod_2d(&big2, 1, &big2);
|
||||
oddExponent = !mp_iszero(&big2);
|
||||
oddExponent = big2.used != 0;
|
||||
mp_clear(&big2);
|
||||
break;
|
||||
}
|
||||
|
||||
if (type1 == TCL_NUMBER_INT) {
|
||||
w1 = *((const Tcl_WideInt *)ptr1);
|
||||
}
|
||||
if (negativeExponent) {
|
||||
if (type1 == TCL_NUMBER_INT) {
|
||||
|
||||
if (negativeExponent) {
|
||||
switch (w1) {
|
||||
case 0:
|
||||
/*
|
||||
@@ -8342,17 +8279,21 @@ ExecuteExtendedBinaryMathOp(
|
||||
return constants[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (negativeExponent) {
|
||||
|
||||
/*
|
||||
* Integers with magnitude greater than 1 raise to a negative
|
||||
* power yield the answer zero (see TIP 123).
|
||||
*/
|
||||
|
||||
return constants[0];
|
||||
}
|
||||
|
||||
if (type1 == TCL_NUMBER_INT) {
|
||||
switch (w1) {
|
||||
if (type1 != TCL_NUMBER_INT) {
|
||||
goto overflowExpon;
|
||||
}
|
||||
|
||||
switch (w1) {
|
||||
case 0:
|
||||
/*
|
||||
* Zero to a positive power is zero.
|
||||
@@ -8370,7 +8311,6 @@ ExecuteExtendedBinaryMathOp(
|
||||
return constants[1];
|
||||
}
|
||||
WIDE_RESULT(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -8388,33 +8328,29 @@ ExecuteExtendedBinaryMathOp(
|
||||
return GENERAL_ARITHMETIC_ERROR;
|
||||
}
|
||||
|
||||
if (type1 == TCL_NUMBER_INT) {
|
||||
if (w1 == 2) {
|
||||
/*
|
||||
* Reduce small powers of 2 to shifts.
|
||||
*/
|
||||
/* From here (up to overflowExpon) w1 and exponent w2 are wide-int's. */
|
||||
assert(type1 == TCL_NUMBER_INT && type2 == TCL_NUMBER_INT);
|
||||
|
||||
if ((Tcl_WideUInt) w2 < (Tcl_WideUInt) CHAR_BIT*sizeof(Tcl_WideInt) - 1) {
|
||||
WIDE_RESULT(((Tcl_WideInt) 1) << (int)w2);
|
||||
}
|
||||
goto overflowExpon;
|
||||
}
|
||||
if (w1 == -2) {
|
||||
int signum = oddExponent ? -1 : 1;
|
||||
if (w1 == 2) {
|
||||
/*
|
||||
* Reduce small powers of 2 to shifts.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Reduce small powers of 2 to shifts.
|
||||
*/
|
||||
|
||||
if ((Tcl_WideUInt)w2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1){
|
||||
WIDE_RESULT(signum * (((Tcl_WideInt) 1) << (int) w2));
|
||||
}
|
||||
goto overflowExpon;
|
||||
if ((Tcl_WideUInt) w2 < (Tcl_WideUInt) CHAR_BIT*sizeof(Tcl_WideInt) - 1) {
|
||||
WIDE_RESULT(((Tcl_WideInt) 1) << (int)w2);
|
||||
}
|
||||
goto overflowExpon;
|
||||
}
|
||||
if (type1 == TCL_NUMBER_INT) {
|
||||
w1 = *((const Tcl_WideInt *) ptr1);
|
||||
} else {
|
||||
if (w1 == -2) {
|
||||
int signum = oddExponent ? -1 : 1;
|
||||
|
||||
/*
|
||||
* Reduce small powers of 2 to shifts.
|
||||
*/
|
||||
|
||||
if ((Tcl_WideUInt)w2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1){
|
||||
WIDE_RESULT(signum * (((Tcl_WideInt) 1) << (int) w2));
|
||||
}
|
||||
goto overflowExpon;
|
||||
}
|
||||
if (w2 - 2 < (long)MaxBase64Size
|
||||
@@ -8423,80 +8359,8 @@ ExecuteExtendedBinaryMathOp(
|
||||
/*
|
||||
* Small powers of integers whose result is wide.
|
||||
*/
|
||||
wResult = WidePwrSmallExpon(w1, (long)w2);
|
||||
|
||||
wResult = w1 * w1; /* b**2 */
|
||||
switch (w2) {
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
wResult *= w1; /* b**3 */
|
||||
break;
|
||||
case 4:
|
||||
wResult *= wResult; /* b**4 */
|
||||
break;
|
||||
case 5:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= w1; /* b**5 */
|
||||
break;
|
||||
case 6:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
break;
|
||||
case 7:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= w1; /* b**7 */
|
||||
break;
|
||||
case 8:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= wResult; /* b**8 */
|
||||
break;
|
||||
case 9:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= wResult; /* b**8 */
|
||||
wResult *= w1; /* b**9 */
|
||||
break;
|
||||
case 10:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= w1; /* b**5 */
|
||||
wResult *= wResult; /* b**10 */
|
||||
break;
|
||||
case 11:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= w1; /* b**5 */
|
||||
wResult *= wResult; /* b**10 */
|
||||
wResult *= w1; /* b**11 */
|
||||
break;
|
||||
case 12:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= wResult; /* b**12 */
|
||||
break;
|
||||
case 13:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= wResult; /* b**12 */
|
||||
wResult *= w1; /* b**13 */
|
||||
break;
|
||||
case 14:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= w1; /* b**7 */
|
||||
wResult *= wResult; /* b**14 */
|
||||
break;
|
||||
case 15:
|
||||
wResult *= w1; /* b**3 */
|
||||
wResult *= wResult; /* b**6 */
|
||||
wResult *= w1; /* b**7 */
|
||||
wResult *= wResult; /* b**14 */
|
||||
wResult *= w1; /* b**15 */
|
||||
break;
|
||||
case 16:
|
||||
wResult *= wResult; /* b**4 */
|
||||
wResult *= wResult; /* b**8 */
|
||||
wResult *= wResult; /* b**16 */
|
||||
break;
|
||||
}
|
||||
WIDE_RESULT(wResult);
|
||||
}
|
||||
|
||||
@@ -8535,18 +8399,18 @@ ExecuteExtendedBinaryMathOp(
|
||||
}
|
||||
|
||||
overflowExpon:
|
||||
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
|
||||
if (big2.used > 1) {
|
||||
mp_clear(&big2);
|
||||
|
||||
if ((TclGetWideIntFromObj(NULL, value2Ptr, &w2) != TCL_OK)
|
||||
|| (value2Ptr->typePtr != &tclIntType)
|
||||
|| (Tcl_WideUInt)w2 >= (1<<28)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"exponent too large", -1));
|
||||
return GENERAL_ARITHMETIC_ERROR;
|
||||
}
|
||||
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
|
||||
mp_init(&bigResult);
|
||||
mp_expt_d_ex(&big1, big2.dp[0], &bigResult, 1);
|
||||
mp_expt_d_ex(&big1, w2, &bigResult, 1);
|
||||
mp_clear(&big1);
|
||||
mp_clear(&big2);
|
||||
BIG_RESULT(&bigResult);
|
||||
}
|
||||
|
||||
@@ -8605,9 +8469,9 @@ ExecuteExtendedBinaryMathOp(
|
||||
#endif
|
||||
DOUBLE_RESULT(dResult);
|
||||
}
|
||||
if ((type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) {
|
||||
TclGetWideIntFromObj(NULL, valuePtr, &w1);
|
||||
TclGetWideIntFromObj(NULL, value2Ptr, &w2);
|
||||
if ((type1 == TCL_NUMBER_INT) && (type2 == TCL_NUMBER_INT)) {
|
||||
w1 = *((const Tcl_WideInt *)ptr1);
|
||||
w2 = *((const Tcl_WideInt *)ptr2);
|
||||
|
||||
switch (opcode) {
|
||||
case INST_ADD:
|
||||
@@ -8704,7 +8568,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
mp_mul(&big1, &big2, &bigResult);
|
||||
break;
|
||||
case INST_DIV:
|
||||
if (mp_iszero(&big2)) {
|
||||
if (big2.used == 0) {
|
||||
mp_clear(&big1);
|
||||
mp_clear(&big2);
|
||||
mp_clear(&bigResult);
|
||||
@@ -8713,7 +8577,7 @@ ExecuteExtendedBinaryMathOp(
|
||||
mp_init(&bigRemainder);
|
||||
mp_div(&big1, &big2, &bigResult, &bigRemainder);
|
||||
/* TODO: internals intrusion */
|
||||
if (!mp_iszero(&bigRemainder)
|
||||
if ((bigRemainder.used != 0)
|
||||
&& (bigRemainder.sign != big2.sign)) {
|
||||
/*
|
||||
* Convert to Tcl's integer division rules.
|
||||
@@ -8860,7 +8724,7 @@ TclCompareTwoNumbers(
|
||||
goto wideCompare;
|
||||
case TCL_NUMBER_BIG:
|
||||
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
|
||||
if (mp_isneg(&big2)) {
|
||||
if (big2.sign != MP_ZPOS) {
|
||||
compare = MP_GT;
|
||||
} else {
|
||||
compare = MP_LT;
|
||||
@@ -8897,7 +8761,7 @@ TclCompareTwoNumbers(
|
||||
}
|
||||
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
|
||||
if ((d1 < (double)WIDE_MAX) && (d1 > (double)WIDE_MIN)) {
|
||||
if (mp_isneg(&big2)) {
|
||||
if (big2.sign != MP_ZPOS) {
|
||||
compare = MP_GT;
|
||||
} else {
|
||||
compare = MP_LT;
|
||||
@@ -9758,7 +9622,7 @@ EvalStatsCmd(
|
||||
for (i = 0; i < globalTablePtr->numBuckets; i++) {
|
||||
for (entryPtr = globalTablePtr->buckets[i]; entryPtr != NULL;
|
||||
entryPtr = entryPtr->nextPtr) {
|
||||
if (entryPtr->objPtr->typePtr == &tclByteCodeType) {
|
||||
if (TclHasIntRep(entryPtr->objPtr, &tclByteCodeType)) {
|
||||
numByteCodeLits++;
|
||||
}
|
||||
(void) TclGetStringFromObj(entryPtr->objPtr, &length);
|
||||
|
||||
+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...
|
||||
|
||||
@@ -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 *));
|
||||
|
||||
+39
-26
@@ -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;
|
||||
@@ -6204,7 +6216,7 @@ ReadChars(
|
||||
* and do not encounter the eof char this time.
|
||||
*/
|
||||
|
||||
dstLimit = dstRead - 1 + TCL_UTF_MAX;
|
||||
dstLimit = dstRead + (TCL_UTF_MAX - 1);
|
||||
statePtr->flags = savedFlags;
|
||||
statePtr->inputEncodingFlags = savedIEFlags;
|
||||
statePtr->inputEncodingState = savedState;
|
||||
@@ -6229,7 +6241,7 @@ ReadChars(
|
||||
* here in this call.
|
||||
*/
|
||||
|
||||
dstLimit = dstRead - 1 + TCL_UTF_MAX;
|
||||
dstLimit = dstRead + (TCL_UTF_MAX - 1);
|
||||
statePtr->flags = savedFlags;
|
||||
statePtr->inputEncodingFlags = savedIEFlags;
|
||||
statePtr->inputEncodingState = savedState;
|
||||
@@ -6322,7 +6334,7 @@ ReadChars(
|
||||
* bytes demanded by the Tcl_ExternalToUtf() call!
|
||||
*/
|
||||
|
||||
dstLimit = Tcl_UtfAtIndex(dst, charsToRead) - 1 + TCL_UTF_MAX - dst;
|
||||
dstLimit = Tcl_UtfAtIndex(dst, charsToRead) - dst + (TCL_UTF_MAX - 1);
|
||||
statePtr->flags = savedFlags;
|
||||
statePtr->inputEncodingFlags = savedIEFlags;
|
||||
statePtr->inputEncodingState = savedState;
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
|
||||
|
||||
+100
-62
@@ -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)
|
||||
@@ -2498,7 +2498,7 @@ typedef struct List {
|
||||
#define TclGetLongFromObj(interp, objPtr, longPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(LONG_MIN) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(LONG_MAX)) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(LONG_MAX)) \
|
||||
? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
: Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
|
||||
#endif
|
||||
@@ -2506,14 +2506,14 @@ typedef struct List {
|
||||
#define TclGetIntFromObj(interp, objPtr, intPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.wideValue >= (Tcl_WideInt)(INT_MIN) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(INT_MAX)) \
|
||||
&& (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)))
|
||||
|
||||
@@ -2750,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;
|
||||
@@ -2861,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
|
||||
@@ -2877,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*/
|
||||
@@ -2894,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 */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -3030,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);
|
||||
@@ -3065,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);
|
||||
@@ -3080,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,
|
||||
@@ -3245,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);
|
||||
@@ -3263,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);
|
||||
@@ -3280,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);
|
||||
|
||||
|
||||
/*
|
||||
@@ -3327,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,
|
||||
@@ -3452,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[]);
|
||||
@@ -3544,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[]);
|
||||
@@ -3788,6 +3807,9 @@ MODULE_SCOPE int TclCompileStringFirstCmd(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileStringIndexCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileStringInsertCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileStringIsCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
@@ -4113,6 +4135,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);
|
||||
|
||||
@@ -4173,9 +4196,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)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -4420,8 +4442,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); \
|
||||
}
|
||||
@@ -4481,6 +4503,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
|
||||
@@ -4529,19 +4563,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; \
|
||||
} \
|
||||
@@ -4611,6 +4645,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)
|
||||
|
||||
|
||||
/*
|
||||
@@ -4700,18 +4738,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 */
|
||||
|
||||
+19
-19
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -1087,7 +1087,6 @@ TclOOReleaseClassContents(
|
||||
if (IsRootClass(oPtr) && !Deleted(fPtr->objectCls->thisPtr)) {
|
||||
Tcl_DeleteCommandFromToken(interp, fPtr->objectCls->thisPtr->command);
|
||||
}
|
||||
oPtr->classPtr = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1213,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) {
|
||||
@@ -1414,6 +1415,10 @@ TclOORemoveFromMixins(
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oPtr->mixins.num == 0) {
|
||||
ckfree(oPtr->mixins.list);
|
||||
oPtr->mixins.list = NULL;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
+19
-20
@@ -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
|
||||
@@ -95,7 +96,7 @@ static void AddClassMethodNames(Class *clsPtr, const int flags,
|
||||
Tcl_HashTable *const examinedClassesPtr);
|
||||
static inline void AddDefinitionNamespaceToChain(Class *const definerCls,
|
||||
Tcl_Obj *const namespaceName,
|
||||
DefineChain *const definePtr, const int flags);
|
||||
DefineChain *const definePtr, int flags);
|
||||
static inline void AddMethodToCallChain(Method *const mPtr,
|
||||
struct ChainBuilder *const cbPtr,
|
||||
Tcl_HashTable *const doneFilters,
|
||||
@@ -151,6 +152,7 @@ static const Tcl_ObjType methodNameType = {
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -245,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
|
||||
@@ -276,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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -633,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 {
|
||||
@@ -1188,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) {
|
||||
@@ -1995,7 +1994,7 @@ AddSimpleClassDefineNamespaces(
|
||||
} else {
|
||||
AddDefinitionNamespaceToChain(classPtr, classPtr->objDefinitionNs,
|
||||
definePtr, flags);
|
||||
}
|
||||
}
|
||||
|
||||
switch (classPtr->superclasses.num) {
|
||||
case 1:
|
||||
@@ -2023,8 +2022,8 @@ AddSimpleClassDefineNamespaces(
|
||||
|
||||
static inline void
|
||||
AddDefinitionNamespaceToChain(
|
||||
Class *definerCls, /* What class defines this entry. */
|
||||
Tcl_Obj *namespaceName, /* The name for this entry (or NULL, a
|
||||
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
|
||||
|
||||
+47
-10
@@ -1478,6 +1478,8 @@ TclOODefineClassObjCmd(
|
||||
TclOODeleteDescendants(interp, oPtr);
|
||||
oPtr->flags &= ~DONT_DELETE;
|
||||
TclOOReleaseClassContents(interp, oPtr);
|
||||
ckfree(oPtr->classPtr);
|
||||
oPtr->classPtr = NULL;
|
||||
} else if (!wasClass && willBeClass) {
|
||||
TclOOAllocClass(interp, oPtr);
|
||||
}
|
||||
@@ -1603,7 +1605,7 @@ TclOODefineDefnNsObjCmd(
|
||||
"may not modify the definition namespace of the root classes",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
|
||||
return TCL_ERROR;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1945,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;
|
||||
}
|
||||
|
||||
@@ -1964,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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1976,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;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-6
@@ -118,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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+2
-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. */
|
||||
|
||||
+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
|
||||
|
||||
+356
-98
@@ -17,6 +17,7 @@
|
||||
#include "tclInt.h"
|
||||
#include "tommath.h"
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Table of all object types.
|
||||
@@ -177,7 +178,7 @@ static Tcl_ThreadDataKey pendingObjDataKey;
|
||||
|
||||
#define PACK_BIGNUM(bignum, objPtr) \
|
||||
if ((bignum).used > 0x7fff) { \
|
||||
mp_int *temp = (void *) ckalloc((unsigned) sizeof(mp_int)); \
|
||||
mp_int *temp = (void *) ckalloc(sizeof(mp_int)); \
|
||||
*temp = bignum; \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr1 = temp; \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(-1); \
|
||||
@@ -1065,9 +1066,8 @@ TclDbInitNewObj(
|
||||
* debugging. */
|
||||
{
|
||||
objPtr->refCount = 0;
|
||||
objPtr->bytes = &tclEmptyString;
|
||||
objPtr->length = 0;
|
||||
objPtr->typePtr = NULL;
|
||||
TclInitStringRep(objPtr, NULL, 0);
|
||||
|
||||
#if TCL_THREADS
|
||||
/*
|
||||
@@ -1722,6 +1722,91 @@ Tcl_GetStringFromObj(
|
||||
return objPtr->bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_InitStringRep --
|
||||
*
|
||||
* This function is called in several configurations to provide all
|
||||
* the tools needed to set an object's string representation. The
|
||||
* function is determined by the arguments.
|
||||
*
|
||||
* (objPtr->bytes != NULL && bytes != NULL) || (numBytes < 0)
|
||||
* Invalid call -- panic!
|
||||
*
|
||||
* objPtr->bytes == NULL && bytes == NULL && numBytes >= 0
|
||||
* Allocation only - allocate space for (numBytes+1) chars.
|
||||
* store in objPtr->bytes and return. Also sets
|
||||
* objPtr->length to 0 and objPtr->bytes[0] to NUL.
|
||||
*
|
||||
* objPtr->bytes == NULL && bytes != NULL && numBytes >= 0
|
||||
* Allocate and copy. bytes is assumed to point to chars to
|
||||
* copy into the string rep. objPtr->length = numBytes. Allocate
|
||||
* array of (numBytes + 1) chars. store in objPtr->bytes. Copy
|
||||
* numBytes chars from bytes to objPtr->bytes; Set
|
||||
* objPtr->bytes[numBytes] to NUL and return objPtr->bytes.
|
||||
* Caller must guarantee there are numBytes chars at bytes to
|
||||
* be copied.
|
||||
*
|
||||
* objPtr->bytes != NULL && bytes == NULL && numBytes >= 0
|
||||
* Truncate. Set objPtr->length to numBytes and
|
||||
* objPr->bytes[numBytes] to NUL. Caller has to guarantee
|
||||
* that a prior allocating call allocated enough bytes for
|
||||
* this to be valid. Return objPtr->bytes.
|
||||
*
|
||||
* Caller is expected to ascertain that the bytes copied into
|
||||
* the string rep make up complete valid UTF-8 characters.
|
||||
*
|
||||
* Results:
|
||||
* A pointer to the string rep of objPtr.
|
||||
*
|
||||
* Side effects:
|
||||
* As described above.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
Tcl_InitStringRep(
|
||||
Tcl_Obj *objPtr, /* Object whose string rep is to be set */
|
||||
const char *bytes,
|
||||
unsigned int numBytes)
|
||||
{
|
||||
assert(objPtr->bytes == NULL || bytes == NULL);
|
||||
|
||||
if (numBytes > INT_MAX) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
|
||||
/* Allocate */
|
||||
if (objPtr->bytes == NULL) {
|
||||
/* Allocate only as empty - extend later if bytes copied */
|
||||
objPtr->length = 0;
|
||||
if (numBytes) {
|
||||
objPtr->bytes = attemptckalloc(numBytes + 1);
|
||||
if (objPtr->bytes == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (bytes) {
|
||||
/* Copy */
|
||||
memcpy(objPtr->bytes, bytes, numBytes);
|
||||
objPtr->length = (int) numBytes;
|
||||
}
|
||||
} else {
|
||||
TclInitStringRep(objPtr, NULL, 0);
|
||||
}
|
||||
} else {
|
||||
/* objPtr->bytes != NULL bytes == NULL - Truncate */
|
||||
objPtr->bytes = ckrealloc(objPtr->bytes, numBytes + 1);
|
||||
objPtr->length = (int)numBytes;
|
||||
}
|
||||
|
||||
/* Terminate */
|
||||
objPtr->bytes[objPtr->length] = '\0';
|
||||
|
||||
return objPtr->bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1748,6 +1833,117 @@ Tcl_InvalidateStringRep(
|
||||
TclInvalidateStringRep(objPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_HasStringRep --
|
||||
*
|
||||
* This function reports whether object has a string representation.
|
||||
*
|
||||
* Results:
|
||||
* Boolean.
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Tcl_HasStringRep(
|
||||
Tcl_Obj *objPtr) /* Object to test */
|
||||
{
|
||||
return TclHasStringRep(objPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_StoreIntRep --
|
||||
*
|
||||
* This function is called to set the object's internal
|
||||
* representation to match a particular type.
|
||||
*
|
||||
* It is the caller's responsibility to guarantee that
|
||||
* the value of the submitted IntRep is in agreement with
|
||||
* the value of any existing string rep.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Calls the freeIntRepProc of the current Tcl_ObjType, if any.
|
||||
* Sets the internalRep and typePtr fields to the submitted values.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Tcl_StoreIntRep(
|
||||
Tcl_Obj *objPtr, /* Object whose internal rep should be set. */
|
||||
const Tcl_ObjType *typePtr, /* New type for the object */
|
||||
const Tcl_ObjIntRep *irPtr) /* New IntRep for the object */
|
||||
{
|
||||
/* Clear out any existing IntRep ( "shimmer" ) */
|
||||
TclFreeIntRep(objPtr);
|
||||
|
||||
/* When irPtr == NULL, just leave objPtr with no IntRep for typePtr */
|
||||
if (irPtr) {
|
||||
/* Copy the new IntRep into place */
|
||||
objPtr->internalRep = *irPtr;
|
||||
|
||||
/* Set the type to match */
|
||||
objPtr->typePtr = typePtr;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_FetchIntRep --
|
||||
*
|
||||
* This function is called to retrieve the object's internal
|
||||
* representation matching a requested type, if any.
|
||||
*
|
||||
* Results:
|
||||
* A read-only pointer to the associated Tcl_ObjIntRep, or
|
||||
* NULL if no such internal representation exists.
|
||||
*
|
||||
* Side effects:
|
||||
* Calls the freeIntRepProc of the current Tcl_ObjType, if any.
|
||||
* Sets the internalRep and typePtr fields to the submitted values.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_ObjIntRep *
|
||||
Tcl_FetchIntRep(
|
||||
Tcl_Obj *objPtr, /* Object to fetch from. */
|
||||
const Tcl_ObjType *typePtr) /* Requested type */
|
||||
{
|
||||
return TclFetchIntRep(objPtr, typePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_FreeIntRep --
|
||||
*
|
||||
* This function is called to free an object's internal representation.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Calls the freeIntRepProc of the current Tcl_ObjType, if any.
|
||||
* Sets typePtr field to NULL.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
Tcl_FreeIntRep(
|
||||
Tcl_Obj *objPtr) /* Object whose internal rep should be freed. */
|
||||
{
|
||||
TclFreeIntRep(objPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1778,7 +1974,7 @@ Tcl_Obj *
|
||||
Tcl_NewBooleanObj(
|
||||
register int boolValue) /* Boolean used to initialize new object. */
|
||||
{
|
||||
return Tcl_DbNewLongObj(boolValue!=0, "unknown", 0);
|
||||
return Tcl_DbNewWideIntObj(boolValue!=0, "unknown", 0);
|
||||
}
|
||||
|
||||
#else /* if not TCL_MEM_DEBUG */
|
||||
@@ -1835,6 +2031,7 @@ Tcl_DbNewBooleanObj(
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclDbNewObj(objPtr, file, line);
|
||||
/* Optimized TclInvalidateStringRep() */
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
objPtr->internalRep.wideValue = (boolValue != 0);
|
||||
@@ -2221,6 +2418,7 @@ Tcl_DbNewDoubleObj(
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclDbNewObj(objPtr, file, line);
|
||||
/* Optimized TclInvalidateStringRep() */
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
objPtr->internalRep.doubleValue = dblValue;
|
||||
@@ -2381,15 +2579,12 @@ static void
|
||||
UpdateStringOfDouble(
|
||||
register Tcl_Obj *objPtr) /* Double obj with string rep to update. */
|
||||
{
|
||||
char buffer[TCL_DOUBLE_SPACE];
|
||||
register int len;
|
||||
char *dst = Tcl_InitStringRep(objPtr, NULL, TCL_DOUBLE_SPACE);
|
||||
|
||||
Tcl_PrintDouble(NULL, objPtr->internalRep.doubleValue, buffer);
|
||||
len = strlen(buffer);
|
||||
TclOOM(dst, TCL_DOUBLE_SPACE + 1);
|
||||
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
|
||||
objPtr->length = len;
|
||||
Tcl_PrintDouble(NULL, objPtr->internalRep.doubleValue, dst);
|
||||
(void) Tcl_InitStringRep(objPtr, NULL, strlen(dst));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2422,6 +2617,7 @@ UpdateStringOfDouble(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_NewIntObj
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
|
||||
@@ -2429,7 +2625,7 @@ Tcl_Obj *
|
||||
Tcl_NewIntObj(
|
||||
register int intValue) /* Int used to initialize the new object. */
|
||||
{
|
||||
return Tcl_DbNewLongObj((long)intValue, "unknown", 0);
|
||||
return Tcl_DbNewWideIntObj((long)intValue, "unknown", 0);
|
||||
}
|
||||
|
||||
#else /* if not TCL_MEM_DEBUG */
|
||||
@@ -2444,6 +2640,7 @@ Tcl_NewIntObj(
|
||||
return objPtr;
|
||||
}
|
||||
#endif /* if TCL_MEM_DEBUG */
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2462,7 +2659,7 @@ Tcl_NewIntObj(
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_SetIntObj
|
||||
void
|
||||
Tcl_SetIntObj(
|
||||
@@ -2475,6 +2672,7 @@ Tcl_SetIntObj(
|
||||
|
||||
TclSetIntObj(objPtr, intValue);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2578,14 +2776,11 @@ static void
|
||||
UpdateStringOfInt(
|
||||
register Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
{
|
||||
char buffer[TCL_INTEGER_SPACE];
|
||||
register int len;
|
||||
char *dst = Tcl_InitStringRep( objPtr, NULL, TCL_INTEGER_SPACE);
|
||||
|
||||
len = TclFormatInt(buffer, objPtr->internalRep.wideValue);
|
||||
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
|
||||
objPtr->length = len;
|
||||
TclOOM(dst, TCL_INTEGER_SPACE + 1);
|
||||
(void) Tcl_InitStringRep(objPtr, NULL,
|
||||
TclFormatInt(dst, objPtr->internalRep.wideValue));
|
||||
}
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
|
||||
@@ -2593,14 +2788,11 @@ static void
|
||||
UpdateStringOfOldInt(
|
||||
register Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
{
|
||||
char buffer[TCL_INTEGER_SPACE];
|
||||
register int len;
|
||||
char *dst = Tcl_InitStringRep( objPtr, NULL, TCL_INTEGER_SPACE);
|
||||
|
||||
len = TclFormatInt(buffer, objPtr->internalRep.longValue);
|
||||
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
|
||||
objPtr->length = len;
|
||||
TclOOM(dst, TCL_INTEGER_SPACE + 1);
|
||||
(void) Tcl_InitStringRep(objPtr, NULL,
|
||||
TclFormatInt(dst, objPtr->internalRep.longValue));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -2634,6 +2826,7 @@ UpdateStringOfOldInt(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_NewLongObj
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
|
||||
@@ -2642,7 +2835,7 @@ Tcl_NewLongObj(
|
||||
register long longValue) /* Long integer used to initialize the
|
||||
* new object. */
|
||||
{
|
||||
return Tcl_DbNewLongObj(longValue, "unknown", 0);
|
||||
return Tcl_DbNewWideIntObj(longValue, "unknown", 0);
|
||||
}
|
||||
|
||||
#else /* if not TCL_MEM_DEBUG */
|
||||
@@ -2658,6 +2851,7 @@ Tcl_NewLongObj(
|
||||
return objPtr;
|
||||
}
|
||||
#endif /* if TCL_MEM_DEBUG */
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2691,6 +2885,7 @@ Tcl_NewLongObj(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_DbNewLongObj
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
|
||||
@@ -2706,6 +2901,7 @@ Tcl_DbNewLongObj(
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclDbNewObj(objPtr, file, line);
|
||||
/* Optimized TclInvalidateStringRep */
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
objPtr->internalRep.wideValue = longValue;
|
||||
@@ -2724,9 +2920,10 @@ Tcl_DbNewLongObj(
|
||||
int line) /* Line number in the source file; used for
|
||||
* debugging. */
|
||||
{
|
||||
return Tcl_NewLongObj(longValue);
|
||||
return Tcl_NewWideIntObj(longValue);
|
||||
}
|
||||
#endif /* TCL_MEM_DEBUG */
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2746,6 +2943,7 @@ Tcl_DbNewLongObj(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#undef Tcl_SetLongObj
|
||||
void
|
||||
Tcl_SetLongObj(
|
||||
@@ -2759,6 +2957,7 @@ Tcl_SetLongObj(
|
||||
|
||||
TclSetIntObj(objPtr, longValue);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2831,27 +3030,23 @@ Tcl_GetLongFromObj(
|
||||
*/
|
||||
|
||||
mp_int big;
|
||||
unsigned long scratch, value = 0, numBytes = sizeof(unsigned long);
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
UNPACK_BIGNUM(objPtr, big);
|
||||
if ((size_t) big.used <= (CHAR_BIT * sizeof(unsigned long) + DIGIT_BIT - 1)
|
||||
/ DIGIT_BIT) {
|
||||
unsigned long scratch, value = 0, numBytes = sizeof(unsigned long);
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) {
|
||||
while (numBytes-- > 0) {
|
||||
if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) {
|
||||
while (numBytes-- > 0) {
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
}
|
||||
if (big.sign) {
|
||||
if (value <= 1 + (unsigned long)LONG_MAX) {
|
||||
*longPtr = - (long) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (big.sign) {
|
||||
if (value <= 1 + (unsigned long)LONG_MAX) {
|
||||
*longPtr = - (long) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
} else {
|
||||
if (value <= (unsigned long)ULONG_MAX) {
|
||||
*longPtr = (long) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
} else {
|
||||
if (value <= (unsigned long)ULONG_MAX) {
|
||||
*longPtr = (long) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3073,29 +3268,25 @@ Tcl_GetWideIntFromObj(
|
||||
*/
|
||||
|
||||
mp_int big;
|
||||
Tcl_WideUInt value = 0;
|
||||
unsigned long numBytes = sizeof(Tcl_WideInt);
|
||||
Tcl_WideInt scratch;
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
UNPACK_BIGNUM(objPtr, big);
|
||||
if ((size_t) big.used <= (CHAR_BIT * sizeof(Tcl_WideInt)
|
||||
+ DIGIT_BIT - 1) / DIGIT_BIT) {
|
||||
Tcl_WideUInt value = 0;
|
||||
unsigned long numBytes = sizeof(Tcl_WideInt);
|
||||
Tcl_WideInt scratch;
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) {
|
||||
while (numBytes-- > 0) {
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) {
|
||||
while (numBytes-- > 0) {
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
}
|
||||
if (big.sign) {
|
||||
if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) {
|
||||
*wideIntPtr = - (Tcl_WideInt) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (big.sign) {
|
||||
if (value <= 1 + ~(Tcl_WideUInt)WIDE_MIN) {
|
||||
*wideIntPtr = - (Tcl_WideInt) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
} else {
|
||||
if (value <= (Tcl_WideUInt)WIDE_MAX) {
|
||||
*wideIntPtr = (Tcl_WideInt) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
} else {
|
||||
if (value <= (Tcl_WideUInt)WIDE_MAX) {
|
||||
*wideIntPtr = (Tcl_WideInt) value;
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3262,12 +3453,10 @@ UpdateStringOfBignum(
|
||||
{
|
||||
mp_int bignumVal;
|
||||
int size;
|
||||
int status;
|
||||
char *stringVal;
|
||||
|
||||
UNPACK_BIGNUM(objPtr, bignumVal);
|
||||
status = mp_radix_size(&bignumVal, 10, &size);
|
||||
if (status != MP_OKAY) {
|
||||
if (MP_OKAY != mp_radix_size(&bignumVal, 10, &size)) {
|
||||
Tcl_Panic("radix size failure in UpdateStringOfBignum");
|
||||
}
|
||||
if (size < 2) {
|
||||
@@ -3282,13 +3471,14 @@ UpdateStringOfBignum(
|
||||
|
||||
Tcl_Panic("UpdateStringOfBignum: string length limit exceeded");
|
||||
}
|
||||
stringVal = ckalloc(size);
|
||||
status = mp_toradix_n(&bignumVal, stringVal, 10, size);
|
||||
if (status != MP_OKAY) {
|
||||
|
||||
stringVal = Tcl_InitStringRep(objPtr, NULL, size - 1);
|
||||
|
||||
TclOOM(stringVal, size);
|
||||
if (MP_OKAY != mp_toradix_n(&bignumVal, stringVal, 10, size)) {
|
||||
Tcl_Panic("conversion failure in UpdateStringOfBignum");
|
||||
}
|
||||
objPtr->bytes = stringVal;
|
||||
objPtr->length = size - 1; /* size includes a trailing NUL byte. */
|
||||
(void) Tcl_InitStringRep(objPtr, NULL, size - 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3408,11 +3598,17 @@ GetBignumFromObj(
|
||||
mp_init_copy(bignumValue, &temp);
|
||||
} else {
|
||||
UNPACK_BIGNUM(objPtr, *bignumValue);
|
||||
/* Optimized TclFreeIntRep */
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = NULL;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = NULL;
|
||||
/*
|
||||
* TODO: If objPtr has a string rep, this leaves
|
||||
* it undisturbed. Not clear that's proper. Pure
|
||||
* bignum values are converted to empty string.
|
||||
*/
|
||||
if (objPtr->bytes == NULL) {
|
||||
TclInitStringRep(objPtr, &tclEmptyString, 0);
|
||||
TclInitStringRep(objPtr, NULL, 0);
|
||||
}
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -3527,33 +3723,30 @@ Tcl_SetBignumObj(
|
||||
Tcl_Obj *objPtr, /* Object to set */
|
||||
mp_int *bignumValue) /* Value to store */
|
||||
{
|
||||
Tcl_WideUInt value = 0;
|
||||
unsigned long numBytes = sizeof(Tcl_WideUInt);
|
||||
Tcl_WideUInt scratch;
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj");
|
||||
}
|
||||
if ((size_t) bignumValue->used
|
||||
<= (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
|
||||
Tcl_WideUInt value = 0;
|
||||
unsigned long numBytes = sizeof(Tcl_WideUInt);
|
||||
Tcl_WideUInt scratch;
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
|
||||
goto tooLargeForWide;
|
||||
}
|
||||
while (numBytes-- > 0) {
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
}
|
||||
if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) {
|
||||
goto tooLargeForWide;
|
||||
}
|
||||
if (bignumValue->sign) {
|
||||
TclSetIntObj(objPtr, -(Tcl_WideInt)value);
|
||||
} else {
|
||||
TclSetIntObj(objPtr, (Tcl_WideInt)value);
|
||||
}
|
||||
mp_clear(bignumValue);
|
||||
return;
|
||||
if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
|
||||
goto tooLargeForWide;
|
||||
}
|
||||
while (numBytes-- > 0) {
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
}
|
||||
if (value > ((Tcl_WideUInt)WIDE_MAX + bignumValue->sign)) {
|
||||
goto tooLargeForWide;
|
||||
}
|
||||
if (bignumValue->sign) {
|
||||
TclSetIntObj(objPtr, -(Tcl_WideInt)value);
|
||||
} else {
|
||||
TclSetIntObj(objPtr, (Tcl_WideInt)value);
|
||||
}
|
||||
mp_clear(bignumValue);
|
||||
return;
|
||||
tooLargeForWide:
|
||||
TclInvalidateStringRep(objPtr);
|
||||
TclFreeIntRep(objPtr);
|
||||
@@ -3655,6 +3848,71 @@ TclGetNumberFromObj(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_IncrRefCount --
|
||||
*
|
||||
* Increments the reference count of the object.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#undef Tcl_IncrRefCount
|
||||
void
|
||||
Tcl_IncrRefCount(
|
||||
Tcl_Obj *objPtr) /* The object we are registering a reference to. */
|
||||
{
|
||||
++(objPtr)->refCount;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_DecrRefCount --
|
||||
*
|
||||
* Decrements the reference count of the object.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#undef Tcl_DecrRefCount
|
||||
void
|
||||
Tcl_DecrRefCount(
|
||||
Tcl_Obj *objPtr) /* The object we are releasing a reference to. */
|
||||
{
|
||||
if (objPtr->refCount-- <= 1) {
|
||||
TclFreeObj(objPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_IsShared --
|
||||
*
|
||||
* Tests if the object has a ref count greater than one.
|
||||
*
|
||||
* Results:
|
||||
* Boolean value that is the result of the test.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#undef Tcl_IsShared
|
||||
int
|
||||
Tcl_IsShared(
|
||||
Tcl_Obj *objPtr) /* The object to test for being shared. */
|
||||
{
|
||||
return ((objPtr)->refCount > 1);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+1
-1
@@ -45,7 +45,6 @@ static TCL_NORETURN1 Tcl_PanicProc *panicProc = NULL;
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#undef Tcl_SetPanicProc
|
||||
void
|
||||
Tcl_SetPanicProc(
|
||||
TCL_NORETURN1 Tcl_PanicProc *proc)
|
||||
@@ -59,6 +58,7 @@ Tcl_SetPanicProc(
|
||||
else
|
||||
#endif
|
||||
panicProc = proc;
|
||||
TclInitSubsystems();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+12
-53
@@ -19,12 +19,7 @@
|
||||
|
||||
/*
|
||||
* The following table provides parsing information about each possible 8-bit
|
||||
* character. The table is designed to be referenced with either signed or
|
||||
* unsigned characters, so it has 384 entries. The first 128 entries
|
||||
* correspond to negative character values, the next 256 correspond to
|
||||
* positive character values. The last 128 entries are identical to the first
|
||||
* 128. The table is always indexed with a 128-byte offset (the 128th entry
|
||||
* corresponds to a character value of 0).
|
||||
* character. The table is designed to be referenced with unsigned characters.
|
||||
*
|
||||
* The macro CHAR_TYPE is used to index into the table and return information
|
||||
* about its character argument. The following return values are defined.
|
||||
@@ -44,42 +39,6 @@
|
||||
*/
|
||||
|
||||
const char tclCharTypeTable[] = {
|
||||
/*
|
||||
* Negative character values, from -128 to -1:
|
||||
*/
|
||||
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL, TYPE_NORMAL,
|
||||
|
||||
/*
|
||||
* Positive character values, from 0-127:
|
||||
@@ -592,7 +551,7 @@ Tcl_ParseCommand(
|
||||
|
||||
int
|
||||
TclIsSpaceProc(
|
||||
char byte)
|
||||
int byte)
|
||||
{
|
||||
return CHAR_TYPE(byte) & (TYPE_SPACE) || byte == '\n';
|
||||
}
|
||||
@@ -621,7 +580,7 @@ TclIsSpaceProc(
|
||||
|
||||
int
|
||||
TclIsBareword(
|
||||
char byte)
|
||||
int byte)
|
||||
{
|
||||
if (byte < '0' || byte > 'z') {
|
||||
return 0;
|
||||
@@ -832,7 +791,7 @@ TclParseBackslash(
|
||||
Tcl_UniChar unichar = 0;
|
||||
int result;
|
||||
int count;
|
||||
char buf[TCL_UTF_MAX];
|
||||
char buf[4] = "";
|
||||
|
||||
if (numBytes == 0) {
|
||||
if (readPtr != NULL) {
|
||||
@@ -890,7 +849,7 @@ TclParseBackslash(
|
||||
count += TclParseHex(p+1, (numBytes > 3) ? 2 : numBytes-2, &result);
|
||||
if (count == 2) {
|
||||
/*
|
||||
* No hexadigits -> This is just "x".
|
||||
* No hexdigits -> This is just "x".
|
||||
*/
|
||||
|
||||
result = 'x';
|
||||
@@ -905,7 +864,7 @@ TclParseBackslash(
|
||||
count += TclParseHex(p+1, (numBytes > 5) ? 4 : numBytes-2, &result);
|
||||
if (count == 2) {
|
||||
/*
|
||||
* No hexadigits -> This is just "u".
|
||||
* No hexdigits -> This is just "u".
|
||||
*/
|
||||
result = 'u';
|
||||
}
|
||||
@@ -914,7 +873,7 @@ TclParseBackslash(
|
||||
count += TclParseHex(p+1, (numBytes > 9) ? 8 : numBytes-2, &result);
|
||||
if (count == 2) {
|
||||
/*
|
||||
* No hexadigits -> This is just "U".
|
||||
* No hexdigits -> This is just "U".
|
||||
*/
|
||||
result = 'U';
|
||||
}
|
||||
@@ -967,7 +926,7 @@ TclParseBackslash(
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
|
||||
memcpy(utfBytes, p, (size_t) (numBytes - 1));
|
||||
memcpy(utfBytes, p, numBytes - 1);
|
||||
utfBytes[numBytes - 1] = '\0';
|
||||
count = TclUtfToUniChar(utfBytes, &unichar) + 1;
|
||||
}
|
||||
@@ -980,9 +939,9 @@ TclParseBackslash(
|
||||
*readPtr = count;
|
||||
}
|
||||
count = Tcl_UniCharToUtf(result, dst);
|
||||
if (!count) {
|
||||
/* Special case for handling upper surrogates. */
|
||||
count = Tcl_UniCharToUtf(-1, dst);
|
||||
if ((result >= 0xD800) && (count < 3)) {
|
||||
/* Special case for handling high surrogates. */
|
||||
count += Tcl_UniCharToUtf(-1, dst + count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -2192,7 +2151,7 @@ TclSubstTokens(
|
||||
Tcl_Obj *appendObj = NULL;
|
||||
const char *append = NULL;
|
||||
int appendByteLength = 0;
|
||||
char utfCharBytes[TCL_UTF_MAX];
|
||||
char utfCharBytes[4] = "";
|
||||
|
||||
switch (tokenPtr->type) {
|
||||
case TCL_TOKEN_TEXT:
|
||||
|
||||
+1
-1
@@ -12,6 +12,6 @@
|
||||
#define TYPE_CLOSE_BRACK 0x20
|
||||
#define TYPE_BRACE 0x40
|
||||
|
||||
#define CHAR_TYPE(c) (tclCharTypeTable+128)[(int)(c)]
|
||||
#define CHAR_TYPE(c) tclCharTypeTable[(unsigned char)(c)]
|
||||
|
||||
MODULE_SCOPE const char tclCharTypeTable[];
|
||||
|
||||
+109
-212
@@ -36,7 +36,7 @@ static int MakePathFromNormalized(Tcl_Interp *interp,
|
||||
* internally.
|
||||
*/
|
||||
|
||||
static const Tcl_ObjType tclFsPathType = {
|
||||
static const Tcl_ObjType fsPathType = {
|
||||
"path", /* name */
|
||||
FreeFsPathInternalRep, /* freeIntRepProc */
|
||||
DupFsPathInternalRep, /* dupIntRepProc */
|
||||
@@ -51,19 +51,14 @@ static const Tcl_ObjType tclFsPathType = {
|
||||
* represent relative or absolute paths, and has certain optimisations when
|
||||
* used to represent paths which are already normalized and absolute.
|
||||
*
|
||||
* Note that both 'translatedPathPtr' and 'normPathPtr' can be a circular
|
||||
* reference to the container Tcl_Obj of this FsPath.
|
||||
*
|
||||
* There are two cases, with the first being the most common:
|
||||
*
|
||||
* (i) flags == 0, => Ordinary path.
|
||||
*
|
||||
* translatedPathPtr contains the translated path (which may be a circular
|
||||
* reference to the object itself). If it is NULL then the path is pure
|
||||
* normalized (and the normPathPtr will be a circular reference). cwdPtr is
|
||||
* null for an absolute path, and non-null for a relative path (unless the cwd
|
||||
* has never been set, in which case the cwdPtr may also be null for a
|
||||
* relative path).
|
||||
* translatedPathPtr contains the translated path. If it is NULL then the path
|
||||
* is pure normalized. cwdPtr is null for an absolute path, and non-null for a
|
||||
* relative path (unless the cwd has never been set, in which case the cwdPtr
|
||||
* may also be null for a relative path).
|
||||
*
|
||||
* (ii) flags != 0, => Special path, see TclNewFSPathObj
|
||||
*
|
||||
@@ -79,11 +74,7 @@ typedef struct FsPath {
|
||||
* Tcl_Obj's string rep is already both
|
||||
* translated and normalized. */
|
||||
Tcl_Obj *normPathPtr; /* Normalized absolute path, without ., .. or
|
||||
* ~user sequences. If the Tcl_Obj containing
|
||||
* this FsPath is already normalized, this may
|
||||
* be a circular reference back to the
|
||||
* container. If that is NOT the case, we have
|
||||
* a refCount on the object. */
|
||||
* ~user sequences. */
|
||||
Tcl_Obj *cwdPtr; /* If null, path is absolute, else this points
|
||||
* to the cwd object used for this path. We
|
||||
* have a refCount on the object. */
|
||||
@@ -110,9 +101,14 @@ typedef struct FsPath {
|
||||
* fields.
|
||||
*/
|
||||
|
||||
#define PATHOBJ(pathPtr) ((FsPath *) (pathPtr)->internalRep.twoPtrValue.ptr1)
|
||||
#define PATHOBJ(pathPtr) ((FsPath *) (TclFetchIntRep((pathPtr), &fsPathType)->twoPtrValue.ptr1))
|
||||
#define SETPATHOBJ(pathPtr,fsPathPtr) \
|
||||
((pathPtr)->internalRep.twoPtrValue.ptr1 = (void *) (fsPathPtr))
|
||||
do { \
|
||||
Tcl_ObjIntRep ir; \
|
||||
ir.twoPtrValue.ptr1 = (void *) (fsPathPtr); \
|
||||
ir.twoPtrValue.ptr2 = NULL; \
|
||||
Tcl_StoreIntRep((pathPtr), &fsPathType, &ir); \
|
||||
} while (0)
|
||||
#define PATHFLAGS(pathPtr) (PATHOBJ(pathPtr)->flags)
|
||||
|
||||
/*
|
||||
@@ -564,7 +560,7 @@ TclPathPart(
|
||||
Tcl_Obj *pathPtr, /* Path to take dirname of */
|
||||
Tcl_PathPart portion) /* Requested portion of name */
|
||||
{
|
||||
if (pathPtr->typePtr == &tclFsPathType) {
|
||||
if (TclHasIntRep(pathPtr, &fsPathType)) {
|
||||
FsPath *fsPathPtr = PATHOBJ(pathPtr);
|
||||
|
||||
if (PATHFLAGS(pathPtr) != 0) {
|
||||
@@ -829,7 +825,7 @@ Tcl_FSJoinPath(
|
||||
* reference count. */
|
||||
int elements) /* Number of elements to use (-1 = all) */
|
||||
{
|
||||
Tcl_Obj *copy, *res;
|
||||
Tcl_Obj *res;
|
||||
int objc;
|
||||
Tcl_Obj **objv;
|
||||
|
||||
@@ -838,17 +834,17 @@ Tcl_FSJoinPath(
|
||||
}
|
||||
|
||||
elements = ((elements >= 0) && (elements <= objc)) ? elements : objc;
|
||||
copy = TclListObjCopy(NULL, listObj);
|
||||
Tcl_ListObjGetElements(NULL, listObj, &objc, &objv);
|
||||
res = TclJoinPath(elements, objv);
|
||||
Tcl_DecrRefCount(copy);
|
||||
res = TclJoinPath(elements, objv, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
Tcl_Obj *
|
||||
TclJoinPath(
|
||||
int elements,
|
||||
Tcl_Obj * const objv[])
|
||||
int elements, /* Number of elements to use (-1 = all) */
|
||||
Tcl_Obj * const objv[], /* Path elements to join */
|
||||
int forceRelative) /* If non-zero, assume all more paths are
|
||||
* relative (e. g. simple normalization) */
|
||||
{
|
||||
Tcl_Obj *res = NULL;
|
||||
int i;
|
||||
@@ -864,6 +860,7 @@ TclJoinPath(
|
||||
|
||||
if (elements == 2) {
|
||||
Tcl_Obj *elt = objv[0];
|
||||
Tcl_ObjIntRep *eltIr = TclFetchIntRep(elt, &fsPathType);
|
||||
|
||||
/*
|
||||
* This is a special case where we can be much more efficient, where
|
||||
@@ -877,12 +874,15 @@ TclJoinPath(
|
||||
* to be an absolute path. Added a check for that elt is absolute.
|
||||
*/
|
||||
|
||||
if ((elt->typePtr == &tclFsPathType)
|
||||
if ((eltIr)
|
||||
&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))
|
||||
&& TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
|
||||
Tcl_Obj *tailObj = objv[1];
|
||||
Tcl_PathType type = TclGetPathType(tailObj, NULL, NULL, NULL);
|
||||
&& TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
|
||||
Tcl_Obj *tailObj = objv[1];
|
||||
Tcl_PathType type;
|
||||
|
||||
/* if forceRelative - second path is relative */
|
||||
type = forceRelative ? TCL_PATH_RELATIVE :
|
||||
TclGetPathType(tailObj, NULL, NULL, NULL);
|
||||
if (type == TCL_PATH_RELATIVE) {
|
||||
const char *str;
|
||||
int len;
|
||||
@@ -960,7 +960,9 @@ TclJoinPath(
|
||||
|
||||
strElt = TclGetStringFromObj(elt, &strEltLen);
|
||||
driveNameLength = 0;
|
||||
type = TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
|
||||
/* if forceRelative - all paths excepting first one are relative */
|
||||
type = (forceRelative && (i > 0)) ? TCL_PATH_RELATIVE :
|
||||
TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
|
||||
if (type != TCL_PATH_RELATIVE) {
|
||||
/*
|
||||
* Zero out the current result.
|
||||
@@ -1164,39 +1166,16 @@ Tcl_FSConvertToPathType(
|
||||
* path.
|
||||
*/
|
||||
|
||||
if (pathPtr->typePtr == &tclFsPathType) {
|
||||
if (TclHasIntRep(pathPtr, &fsPathType)) {
|
||||
if (TclFSEpochOk(PATHOBJ(pathPtr)->filesystemEpoch)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (pathPtr->bytes == NULL) {
|
||||
UpdateStringOfFsPath(pathPtr);
|
||||
}
|
||||
FreeFsPathInternalRep(pathPtr);
|
||||
TclGetString(pathPtr);
|
||||
Tcl_StoreIntRep(pathPtr, &fsPathType, NULL);
|
||||
}
|
||||
|
||||
return SetFsPathFromAny(interp, pathPtr);
|
||||
|
||||
/*
|
||||
* We used to have more complex code here:
|
||||
*
|
||||
* FsPath *fsPathPtr = PATHOBJ(pathPtr);
|
||||
* if (fsPathPtr->cwdPtr == NULL || PATHFLAGS(pathPtr) != 0) {
|
||||
* return TCL_OK;
|
||||
* } else {
|
||||
* if (TclFSCwdPointerEquals(&fsPathPtr->cwdPtr)) {
|
||||
* return TCL_OK;
|
||||
* } else {
|
||||
* if (pathPtr->bytes == NULL) {
|
||||
* UpdateStringOfFsPath(pathPtr);
|
||||
* }
|
||||
* FreeFsPathInternalRep(pathPtr);
|
||||
* return Tcl_ConvertToType(interp, pathPtr, &tclFsPathType);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* But we no longer believe this is necessary.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1328,9 +1307,7 @@ TclNewFSPathObj(
|
||||
|
||||
SETPATHOBJ(pathPtr, fsPathPtr);
|
||||
PATHFLAGS(pathPtr) = TCLPATH_APPENDED;
|
||||
pathPtr->typePtr = &tclFsPathType;
|
||||
pathPtr->bytes = NULL;
|
||||
pathPtr->length = 0;
|
||||
TclInvalidateStringRep(pathPtr);
|
||||
|
||||
/*
|
||||
* Look for path components made up of only "."
|
||||
@@ -1357,6 +1334,7 @@ TclNewFSPathObj(
|
||||
count = 0;
|
||||
state = 1;
|
||||
}
|
||||
break;
|
||||
case 1: /* Scanning for next dirsep */
|
||||
switch (*p) {
|
||||
case '/':
|
||||
@@ -1430,8 +1408,9 @@ TclFSMakePathRelative(
|
||||
{
|
||||
int cwdLen, len;
|
||||
const char *tempStr;
|
||||
Tcl_ObjIntRep *irPtr = TclFetchIntRep(pathPtr, &fsPathType);
|
||||
|
||||
if (pathPtr->typePtr == &tclFsPathType) {
|
||||
if (irPtr) {
|
||||
FsPath *fsPathPtr = PATHOBJ(pathPtr);
|
||||
|
||||
if (PATHFLAGS(pathPtr) != 0 && fsPathPtr->cwdPtr == cwdPtr) {
|
||||
@@ -1499,30 +1478,10 @@ MakePathFromNormalized(
|
||||
{
|
||||
FsPath *fsPathPtr;
|
||||
|
||||
if (pathPtr->typePtr == &tclFsPathType) {
|
||||
if (TclHasIntRep(pathPtr, &fsPathType)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free old representation
|
||||
*/
|
||||
|
||||
if (pathPtr->typePtr != NULL) {
|
||||
if (pathPtr->bytes == NULL) {
|
||||
if (pathPtr->typePtr->updateStringProc == NULL) {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"can't find object string representation", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "WTF",
|
||||
NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
pathPtr->typePtr->updateStringProc(pathPtr);
|
||||
}
|
||||
TclFreeIntRep(pathPtr);
|
||||
}
|
||||
|
||||
fsPathPtr = ckalloc(sizeof(FsPath));
|
||||
|
||||
/*
|
||||
@@ -1531,11 +1490,7 @@ MakePathFromNormalized(
|
||||
|
||||
fsPathPtr->translatedPathPtr = NULL;
|
||||
|
||||
/*
|
||||
* Circular reference by design.
|
||||
*/
|
||||
|
||||
fsPathPtr->normPathPtr = pathPtr;
|
||||
Tcl_IncrRefCount(fsPathPtr->normPathPtr = Tcl_DuplicateObj(pathPtr));
|
||||
fsPathPtr->cwdPtr = NULL;
|
||||
fsPathPtr->nativePathPtr = NULL;
|
||||
fsPathPtr->fsPtr = NULL;
|
||||
@@ -1544,7 +1499,6 @@ MakePathFromNormalized(
|
||||
|
||||
SETPATHOBJ(pathPtr, fsPathPtr);
|
||||
PATHFLAGS(pathPtr) = 0;
|
||||
pathPtr->typePtr = &tclFsPathType;
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1595,25 +1549,12 @@ Tcl_FSNewNativePath(
|
||||
* safe.
|
||||
*/
|
||||
|
||||
if (pathPtr->typePtr != NULL) {
|
||||
if (pathPtr->bytes == NULL) {
|
||||
if (pathPtr->typePtr->updateStringProc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pathPtr->typePtr->updateStringProc(pathPtr);
|
||||
}
|
||||
TclFreeIntRep(pathPtr);
|
||||
}
|
||||
|
||||
Tcl_StoreIntRep(pathPtr, &fsPathType, NULL);
|
||||
fsPathPtr = ckalloc(sizeof(FsPath));
|
||||
|
||||
fsPathPtr->translatedPathPtr = NULL;
|
||||
|
||||
/*
|
||||
* Circular reference, by design.
|
||||
*/
|
||||
|
||||
fsPathPtr->normPathPtr = pathPtr;
|
||||
Tcl_IncrRefCount(fsPathPtr->normPathPtr = Tcl_DuplicateObj(pathPtr));
|
||||
fsPathPtr->cwdPtr = NULL;
|
||||
fsPathPtr->nativePathPtr = clientData;
|
||||
fsPathPtr->fsPtr = fromFilesystem;
|
||||
@@ -1621,7 +1562,6 @@ Tcl_FSNewNativePath(
|
||||
|
||||
SETPATHOBJ(pathPtr, fsPathPtr);
|
||||
PATHFLAGS(pathPtr) = 0;
|
||||
pathPtr->typePtr = &tclFsPathType;
|
||||
|
||||
return pathPtr;
|
||||
}
|
||||
@@ -1668,20 +1608,22 @@ Tcl_FSGetTranslatedPath(
|
||||
|
||||
Tcl_Obj *translatedCwdPtr = Tcl_FSGetTranslatedPath(interp,
|
||||
srcFsPathPtr->cwdPtr);
|
||||
Tcl_ObjIntRep *translatedCwdIrPtr;
|
||||
|
||||
if (translatedCwdPtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retObj = Tcl_FSJoinToPath(translatedCwdPtr, 1,
|
||||
&srcFsPathPtr->normPathPtr);
|
||||
srcFsPathPtr->translatedPathPtr = retObj;
|
||||
if (translatedCwdPtr->typePtr == &tclFsPathType) {
|
||||
Tcl_IncrRefCount(srcFsPathPtr->translatedPathPtr = retObj);
|
||||
translatedCwdIrPtr = TclFetchIntRep(translatedCwdPtr, &fsPathType);
|
||||
if (translatedCwdIrPtr) {
|
||||
srcFsPathPtr->filesystemEpoch
|
||||
= PATHOBJ(translatedCwdPtr)->filesystemEpoch;
|
||||
} else {
|
||||
srcFsPathPtr->filesystemEpoch = 0;
|
||||
}
|
||||
Tcl_IncrRefCount(retObj);
|
||||
Tcl_DecrRefCount(translatedCwdPtr);
|
||||
} else {
|
||||
/*
|
||||
@@ -1737,7 +1679,7 @@ Tcl_FSGetTranslatedStringPath(
|
||||
const char *orig = TclGetStringFromObj(transPtr, &len);
|
||||
char *result = ckalloc(len+1);
|
||||
|
||||
memcpy(result, orig, (size_t) len+1);
|
||||
memcpy(result, orig, len+1);
|
||||
TclDecrRefCount(transPtr);
|
||||
return result;
|
||||
}
|
||||
@@ -1791,9 +1733,7 @@ Tcl_FSGetNormalizedPath(
|
||||
return NULL;
|
||||
}
|
||||
/* TODO: Figure out why this is needed. */
|
||||
if (pathPtr->bytes == NULL) {
|
||||
UpdateStringOfFsPath(pathPtr);
|
||||
}
|
||||
TclGetString(pathPtr);
|
||||
|
||||
TclGetStringFromObj(fsPathPtr->normPathPtr, &tailLen);
|
||||
if (tailLen) {
|
||||
@@ -1845,7 +1785,7 @@ Tcl_FSGetNormalizedPath(
|
||||
|
||||
/*
|
||||
* NOTE: here we are (dangerously?) assuming that origDir points
|
||||
* to a Tcl_Obj with Tcl_ObjType == &tclFsPathType. The
|
||||
* to a Tcl_Obj with Tcl_ObjType == &fsPathType. The
|
||||
* pathType = Tcl_FSGetPathType(fsPathPtr->cwdPtr);
|
||||
* above that set the pathType value should have established that,
|
||||
* but it's far less clear on what basis we know there's been no
|
||||
@@ -1863,6 +1803,7 @@ Tcl_FSGetNormalizedPath(
|
||||
/*
|
||||
* That's our reference to copy used.
|
||||
*/
|
||||
copy = NULL;
|
||||
|
||||
TclDecrRefCount(dir);
|
||||
TclDecrRefCount(origDir);
|
||||
@@ -1875,7 +1816,7 @@ Tcl_FSGetNormalizedPath(
|
||||
/*
|
||||
* That's our reference to copy used.
|
||||
*/
|
||||
|
||||
copy = NULL;
|
||||
TclDecrRefCount(dir);
|
||||
}
|
||||
PATHFLAGS(pathPtr) = 0;
|
||||
@@ -1887,10 +1828,8 @@ Tcl_FSGetNormalizedPath(
|
||||
|
||||
if (fsPathPtr->cwdPtr != NULL) {
|
||||
if (!TclFSCwdPointerEquals(&fsPathPtr->cwdPtr)) {
|
||||
if (pathPtr->bytes == NULL) {
|
||||
UpdateStringOfFsPath(pathPtr);
|
||||
}
|
||||
FreeFsPathInternalRep(pathPtr);
|
||||
TclGetString(pathPtr);
|
||||
Tcl_StoreIntRep(pathPtr, &fsPathType, NULL);
|
||||
if (SetFsPathFromAny(interp, pathPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1916,7 +1855,6 @@ Tcl_FSGetNormalizedPath(
|
||||
}
|
||||
if (fsPathPtr->normPathPtr == NULL) {
|
||||
Tcl_Obj *useThisCwd = NULL;
|
||||
int pureNormalized = 1;
|
||||
|
||||
/*
|
||||
* Since normPathPtr is NULL, but this is a valid path object, we know
|
||||
@@ -1966,7 +1904,6 @@ Tcl_FSGetNormalizedPath(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pureNormalized = 0;
|
||||
Tcl_DecrRefCount(absolutePath);
|
||||
absolutePath = Tcl_FSJoinToPath(useThisCwd, 1, &absolutePath);
|
||||
Tcl_IncrRefCount(absolutePath);
|
||||
@@ -1986,7 +1923,6 @@ Tcl_FSGetNormalizedPath(
|
||||
if (absolutePath == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pureNormalized = 0;
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
}
|
||||
@@ -1995,35 +1931,12 @@ Tcl_FSGetNormalizedPath(
|
||||
* Already has refCount incremented.
|
||||
*/
|
||||
|
||||
if (fsPathPtr->normPathPtr) {
|
||||
Tcl_DecrRefCount(fsPathPtr->normPathPtr);
|
||||
}
|
||||
fsPathPtr->normPathPtr = TclFSNormalizeAbsolutePath(interp,
|
||||
absolutePath);
|
||||
|
||||
/*
|
||||
* Check if path is pure normalized (this can only be the case if it
|
||||
* is an absolute path).
|
||||
*/
|
||||
|
||||
if (pureNormalized) {
|
||||
int normPathLen, pathLen;
|
||||
const char *normPath;
|
||||
|
||||
path = TclGetStringFromObj(pathPtr, &pathLen);
|
||||
normPath = TclGetStringFromObj(fsPathPtr->normPathPtr, &normPathLen);
|
||||
if ((pathLen == normPathLen) && !memcmp(path, normPath, pathLen)) {
|
||||
/*
|
||||
* The path was already normalized. Get rid of the duplicate.
|
||||
*/
|
||||
|
||||
TclDecrRefCount(fsPathPtr->normPathPtr);
|
||||
|
||||
/*
|
||||
* We do *not* increment the refCount for this circular
|
||||
* reference.
|
||||
*/
|
||||
|
||||
fsPathPtr->normPathPtr = pathPtr;
|
||||
}
|
||||
}
|
||||
if (useThisCwd != NULL) {
|
||||
/*
|
||||
* We just need to free an object we allocated above for relative
|
||||
@@ -2170,7 +2083,7 @@ TclFSEnsureEpochOk(
|
||||
{
|
||||
FsPath *srcFsPathPtr;
|
||||
|
||||
if (pathPtr->typePtr != &tclFsPathType) {
|
||||
if (!TclHasIntRep(pathPtr, &fsPathType)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2186,10 +2099,8 @@ TclFSEnsureEpochOk(
|
||||
* We have to discard the stale representation and recalculate it.
|
||||
*/
|
||||
|
||||
if (pathPtr->bytes == NULL) {
|
||||
UpdateStringOfFsPath(pathPtr);
|
||||
}
|
||||
FreeFsPathInternalRep(pathPtr);
|
||||
TclGetString(pathPtr);
|
||||
Tcl_StoreIntRep(pathPtr, &fsPathType, NULL);
|
||||
if (SetFsPathFromAny(NULL, pathPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2234,7 +2145,7 @@ TclFSSetPathDetails(
|
||||
* Make sure pathPtr is of the correct type.
|
||||
*/
|
||||
|
||||
if (pathPtr->typePtr != &tclFsPathType) {
|
||||
if (!TclHasIntRep(pathPtr, &fsPathType)) {
|
||||
if (SetFsPathFromAny(NULL, pathPtr) != TCL_OK) {
|
||||
return;
|
||||
}
|
||||
@@ -2333,7 +2244,7 @@ SetFsPathFromAny(
|
||||
Tcl_Obj *transPtr;
|
||||
char *name;
|
||||
|
||||
if (pathPtr->typePtr == &tclFsPathType) {
|
||||
if (TclHasIntRep(pathPtr, &fsPathType)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2357,36 +2268,29 @@ SetFsPathFromAny(
|
||||
* Handle tilde substitutions, if needed.
|
||||
*/
|
||||
|
||||
if (name[0] == '~') {
|
||||
if (len && name[0] == '~') {
|
||||
Tcl_DString temp;
|
||||
int split;
|
||||
char separator = '/';
|
||||
|
||||
/*
|
||||
* We have multiple cases '~/foo/bar...', '~user/foo/bar...', etc.
|
||||
* split becomes value 1 for '~/...' as well as for '~'.
|
||||
*/
|
||||
split = FindSplitPos(name, separator);
|
||||
if (split != len) {
|
||||
/*
|
||||
* We have multiple pieces '~user/foo/bar...'
|
||||
*/
|
||||
|
||||
name[split] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Do some tilde substitution.
|
||||
*/
|
||||
|
||||
if (name[1] == '\0') {
|
||||
if (split == 1) {
|
||||
/*
|
||||
* We have just '~'
|
||||
* We have just '~' (or '~/...')
|
||||
*/
|
||||
|
||||
const char *dir;
|
||||
Tcl_DString dirString;
|
||||
|
||||
if (split != len) {
|
||||
name[split] = separator;
|
||||
}
|
||||
|
||||
dir = TclGetEnv("HOME", &dirString);
|
||||
if (dir == NULL) {
|
||||
if (interp) {
|
||||
@@ -2406,23 +2310,26 @@ SetFsPathFromAny(
|
||||
* We have a user name '~user'
|
||||
*/
|
||||
|
||||
const char *expandedUser;
|
||||
Tcl_DString userName;
|
||||
|
||||
Tcl_DStringInit(&userName);
|
||||
Tcl_DStringAppend(&userName, name+1, split-1);
|
||||
expandedUser = Tcl_DStringValue(&userName);
|
||||
|
||||
Tcl_DStringInit(&temp);
|
||||
if (TclpGetUserHome(name+1, &temp) == NULL) {
|
||||
if (TclpGetUserHome(expandedUser, &temp) == NULL) {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"user \"%s\" doesn't exist", name+1));
|
||||
"user \"%s\" doesn't exist", expandedUser));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER",
|
||||
NULL);
|
||||
}
|
||||
Tcl_DStringFree(&userName);
|
||||
Tcl_DStringFree(&temp);
|
||||
if (split != len) {
|
||||
name[split] = separator;
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (split != len) {
|
||||
name[split] = separator;
|
||||
}
|
||||
Tcl_DStringFree(&userName);
|
||||
}
|
||||
|
||||
transPtr = TclDStringToObj(&temp);
|
||||
@@ -2459,13 +2366,17 @@ SetFsPathFromAny(
|
||||
|
||||
pair[0] = transPtr;
|
||||
pair[1] = Tcl_NewStringObj(name+split+1, -1);
|
||||
transPtr = TclJoinPath(2, pair);
|
||||
Tcl_DecrRefCount(pair[0]);
|
||||
Tcl_DecrRefCount(pair[1]);
|
||||
transPtr = TclJoinPath(2, pair, 1);
|
||||
if (transPtr != pair[0]) {
|
||||
Tcl_DecrRefCount(pair[0]);
|
||||
}
|
||||
if (transPtr != pair[1]) {
|
||||
Tcl_DecrRefCount(pair[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
transPtr = TclJoinPath(1, &pathPtr);
|
||||
transPtr = TclJoinPath(1, &pathPtr, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2475,27 +2386,21 @@ SetFsPathFromAny(
|
||||
|
||||
fsPathPtr = ckalloc(sizeof(FsPath));
|
||||
|
||||
fsPathPtr->translatedPathPtr = transPtr;
|
||||
if (transPtr != pathPtr) {
|
||||
Tcl_IncrRefCount(fsPathPtr->translatedPathPtr);
|
||||
/* Redo translation when $env(HOME) changes */
|
||||
fsPathPtr->filesystemEpoch = TclFSEpoch();
|
||||
if (transPtr == pathPtr) {
|
||||
transPtr = Tcl_DuplicateObj(pathPtr);
|
||||
fsPathPtr->filesystemEpoch = 0;
|
||||
} else {
|
||||
fsPathPtr->filesystemEpoch = 0;
|
||||
fsPathPtr->filesystemEpoch = TclFSEpoch();
|
||||
}
|
||||
Tcl_IncrRefCount(transPtr);
|
||||
fsPathPtr->translatedPathPtr = transPtr;
|
||||
fsPathPtr->normPathPtr = NULL;
|
||||
fsPathPtr->cwdPtr = NULL;
|
||||
fsPathPtr->nativePathPtr = NULL;
|
||||
fsPathPtr->fsPtr = NULL;
|
||||
|
||||
/*
|
||||
* Free old representation before installing our new one.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(pathPtr);
|
||||
SETPATHOBJ(pathPtr, fsPathPtr);
|
||||
PATHFLAGS(pathPtr) = 0;
|
||||
pathPtr->typePtr = &tclFsPathType;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2518,6 +2423,7 @@ FreeFsPathInternalRep(
|
||||
}
|
||||
if (fsPathPtr->cwdPtr != NULL) {
|
||||
TclDecrRefCount(fsPathPtr->cwdPtr);
|
||||
fsPathPtr->cwdPtr = NULL;
|
||||
}
|
||||
if (fsPathPtr->nativePathPtr != NULL && fsPathPtr->fsPtr != NULL) {
|
||||
Tcl_FSFreeInternalRepProc *freeProc =
|
||||
@@ -2530,7 +2436,6 @@ FreeFsPathInternalRep(
|
||||
}
|
||||
|
||||
ckfree(fsPathPtr);
|
||||
pathPtr->typePtr = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2543,24 +2448,14 @@ DupFsPathInternalRep(
|
||||
|
||||
SETPATHOBJ(copyPtr, copyFsPathPtr);
|
||||
|
||||
if (srcFsPathPtr->translatedPathPtr == srcPtr) {
|
||||
/* Cycle in src -> make cycle in copy. */
|
||||
copyFsPathPtr->translatedPathPtr = copyPtr;
|
||||
} else {
|
||||
copyFsPathPtr->translatedPathPtr = srcFsPathPtr->translatedPathPtr;
|
||||
if (copyFsPathPtr->translatedPathPtr != NULL) {
|
||||
Tcl_IncrRefCount(copyFsPathPtr->translatedPathPtr);
|
||||
}
|
||||
copyFsPathPtr->translatedPathPtr = srcFsPathPtr->translatedPathPtr;
|
||||
if (copyFsPathPtr->translatedPathPtr != NULL) {
|
||||
Tcl_IncrRefCount(copyFsPathPtr->translatedPathPtr);
|
||||
}
|
||||
|
||||
if (srcFsPathPtr->normPathPtr == srcPtr) {
|
||||
/* Cycle in src -> make cycle in copy. */
|
||||
copyFsPathPtr->normPathPtr = copyPtr;
|
||||
} else {
|
||||
copyFsPathPtr->normPathPtr = srcFsPathPtr->normPathPtr;
|
||||
if (copyFsPathPtr->normPathPtr != NULL) {
|
||||
Tcl_IncrRefCount(copyFsPathPtr->normPathPtr);
|
||||
}
|
||||
copyFsPathPtr->normPathPtr = srcFsPathPtr->normPathPtr;
|
||||
if (copyFsPathPtr->normPathPtr != NULL) {
|
||||
Tcl_IncrRefCount(copyFsPathPtr->normPathPtr);
|
||||
}
|
||||
|
||||
copyFsPathPtr->cwdPtr = srcFsPathPtr->cwdPtr;
|
||||
@@ -2586,8 +2481,6 @@ DupFsPathInternalRep(
|
||||
}
|
||||
copyFsPathPtr->fsPtr = srcFsPathPtr->fsPtr;
|
||||
copyFsPathPtr->filesystemEpoch = srcFsPathPtr->filesystemEpoch;
|
||||
|
||||
copyPtr->typePtr = &tclFsPathType;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2619,11 +2512,15 @@ UpdateStringOfFsPath(
|
||||
}
|
||||
|
||||
copy = AppendPath(fsPathPtr->cwdPtr, fsPathPtr->normPathPtr);
|
||||
if (Tcl_IsShared(copy)) {
|
||||
copy = Tcl_DuplicateObj(copy);
|
||||
}
|
||||
|
||||
Tcl_IncrRefCount(copy);
|
||||
/* Steal copy's string rep */
|
||||
pathPtr->bytes = TclGetStringFromObj(copy, &cwdLen);
|
||||
pathPtr->length = cwdLen;
|
||||
copy->bytes = &tclEmptyString;
|
||||
copy->length = 0;
|
||||
TclInitStringRep(copy, NULL, 0);
|
||||
TclDecrRefCount(copy);
|
||||
}
|
||||
|
||||
@@ -2660,7 +2557,7 @@ TclNativePathInFilesystem(
|
||||
* semantics of Tcl (at present anyway), so we have to abide by them here.
|
||||
*/
|
||||
|
||||
if (pathPtr->typePtr == &tclFsPathType) {
|
||||
if (TclHasIntRep(pathPtr, &fsPathType)) {
|
||||
if (pathPtr->bytes != NULL && pathPtr->bytes[0] == '\0') {
|
||||
/*
|
||||
* We reject the empty path "".
|
||||
@@ -2675,7 +2572,7 @@ TclNativePathInFilesystem(
|
||||
} else {
|
||||
/*
|
||||
* It is somewhat unusual to reach this code path without the object
|
||||
* being of tclFsPathType. However, we do our best to deal with the
|
||||
* being of fsPathType. However, we do our best to deal with the
|
||||
* situation.
|
||||
*/
|
||||
|
||||
|
||||
+1
-1
@@ -333,7 +333,7 @@ TclCleanupChildren(
|
||||
int count;
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET);
|
||||
Tcl_Seek(errorChan, 0, SEEK_SET);
|
||||
objPtr = Tcl_NewObj();
|
||||
count = Tcl_ReadChars(errorChan, objPtr, -1, 0);
|
||||
if (count < 0) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user