Compare commits
968
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7e4f45ab42 | ||
|
|
71ae5810dc | ||
|
|
7df97e9292 | ||
|
|
9f9c9efac0 | ||
|
|
417474f1fd | ||
|
|
6fb4854406 | ||
|
|
817da23169 | ||
|
|
f2c8c6c408 | ||
|
|
747b668676 | ||
|
|
d96dda52c4 | ||
|
|
869730bf85 | ||
|
|
e4912abbd2 | ||
|
|
9b1a75a1cc | ||
|
|
6ed025f0c6 | ||
|
|
1749b4cc87 | ||
|
|
0305f67f88 | ||
|
|
3a8a841386 | ||
|
|
c1de90d70a | ||
|
|
f4882bb16f | ||
|
|
81bc53def9 | ||
|
|
00c94ffc5d | ||
|
|
96bf31bbbd | ||
|
|
0dfee54d3f | ||
|
|
689987ea92 | ||
|
|
b1266f39d8 | ||
|
|
68d03f6af8 | ||
|
|
9d183921c9 | ||
|
|
384b9de6bb | ||
|
|
fef5802d1e | ||
|
|
95068d8d48 | ||
|
|
b938ddd055 | ||
|
|
2b8e087252 | ||
|
|
01dccf28f9 | ||
|
|
89fee22341 | ||
|
|
88de9d25c6 | ||
|
|
fd5560d08a | ||
|
|
b6f978fdf7 | ||
|
|
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 | ||
|
|
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 | ||
|
|
1fae54c8c0 | ||
|
|
35299947e3 | ||
|
|
38f743a2c7 | ||
|
|
4a6019f7a6 | ||
|
|
fa3d7ed178 | ||
|
|
d1e5b0f72f | ||
|
|
dca8be01de | ||
|
|
511765faae | ||
|
|
3046c87be9 | ||
|
|
f2d42d756e | ||
|
|
8d9924c328 | ||
|
|
54488f1714 | ||
|
|
5b4a1fcaf3 | ||
|
|
e348eadefd | ||
|
|
b3d56cb364 | ||
|
|
65ae2c205e | ||
|
|
5e8ed94397 | ||
|
|
0eccb10a23 | ||
|
|
b16a1198d9 | ||
|
|
4402274b45 | ||
|
|
237b0edf0d | ||
|
|
77a9cc76b1 | ||
|
|
fc38a30572 | ||
|
|
fa2ceeffff | ||
|
|
18b503297b | ||
|
|
44fd5b0f83 | ||
|
|
13f704914a | ||
|
|
3166f1ad45 | ||
|
|
b82e966961 | ||
|
|
6fe99b6e66 | ||
|
|
cbbc8d66b8 | ||
|
|
4dc3934516 | ||
|
|
bd29989aab | ||
|
|
3416e2d194 | ||
|
|
730f1c88eb | ||
|
|
d16fc1a584 | ||
|
|
563ffe0ad3 | ||
|
|
5deb25bc9b | ||
|
|
0f4e877214 | ||
|
|
4df4dafad6 | ||
|
|
83ec300abd | ||
|
|
ddae61a859 | ||
|
|
75399e97a8 | ||
|
|
13446e004a | ||
|
|
4930197d21 | ||
|
|
008a36f3e4 | ||
|
|
dc53840e35 | ||
|
|
5471354571 | ||
|
|
7d16c9044e | ||
|
|
155f409a38 | ||
|
|
20c06fad80 | ||
|
|
4abbc2cf7d | ||
|
|
a6d8a3e498 | ||
|
|
c1c94e4437 | ||
|
|
c5bbe85f29 | ||
|
|
29a883d89f | ||
|
|
d6bc59fcc3 | ||
|
|
3475b52b60 | ||
|
|
efa3f28435 | ||
|
|
931a2a1ad2 | ||
|
|
3a8f5fae79 | ||
|
|
cef3740779 | ||
|
|
4d25d5aefd | ||
|
|
3c18b618a5 | ||
|
|
179e8f4df7 | ||
|
|
2798a075ee | ||
|
|
5429d6aeaf | ||
|
|
1c2958d455 | ||
|
|
e2d299f771 | ||
|
|
57f1472371 | ||
|
|
bea160e7f6 | ||
|
|
d739e9b6a8 | ||
|
|
2577d3bd45 | ||
|
|
c65da32867 | ||
|
|
ff9bd4ad1c | ||
|
|
3788abb994 | ||
|
|
a0c7ff582a | ||
|
|
b3dceb5360 | ||
|
|
500a1629c4 | ||
|
|
4c1c62892a | ||
|
|
434a115a3c | ||
|
|
74707353e8 | ||
|
|
dbdd83e5d0 | ||
|
|
538c6791ab | ||
|
|
22a5d73ebf | ||
|
|
820cc5a23d | ||
|
|
f7dfeb706f | ||
|
|
78ef9a971b | ||
|
|
ce6023fade | ||
|
|
4e9742386c | ||
|
|
030a749dc8 | ||
|
|
2f4c1aecdb | ||
|
|
b3291aebaa | ||
|
|
569b59f564 | ||
|
|
ccbbac847a | ||
|
|
8e4701fd31 | ||
|
|
de66468301 | ||
|
|
56f89b9850 | ||
|
|
1ff54c600e | ||
|
|
1337738c22 | ||
|
|
96b9e6e871 | ||
|
|
af5d98388a | ||
|
|
fd15b04d3b | ||
|
|
3dc41c544f | ||
|
|
52c009322f | ||
|
|
fd54886393 | ||
|
|
016dc0c5f0 | ||
|
|
97ed5b117d | ||
|
|
fbc8feeb40 | ||
|
|
a870464cc5 | ||
|
|
5f392f74b6 | ||
|
|
fef802ea7a | ||
|
|
d7a697aa50 | ||
|
|
9654f8c692 | ||
|
|
b28e8c3bd1 | ||
|
|
7ecdd17b4d | ||
|
|
125b29bfe3 | ||
|
|
63802cdd70 | ||
|
|
c69ccc749e | ||
|
|
f44fb9b450 | ||
|
|
f338047c19 | ||
|
|
691b2ab5c4 | ||
|
|
352d056288 | ||
|
|
335774aef1 | ||
|
|
cb2049e18e | ||
|
|
6457b295e1 | ||
|
|
bf9af9a408 | ||
|
|
231a11e2ce | ||
|
|
b7495e42ca | ||
|
|
7e4b0ec852 | ||
|
|
9db751daeb | ||
|
|
a883ddbe3e | ||
|
|
7e67cf48eb | ||
|
|
4ad4d79d41 | ||
|
|
90d55a9da9 | ||
|
|
983b95bdbd | ||
|
|
394e22ef5d | ||
|
|
140cd14f15 | ||
|
|
5b1614f31a | ||
|
|
c4e867d8dd | ||
|
|
0748314c35 | ||
|
|
f8876cc390 | ||
|
|
36f2cb4d7d | ||
|
|
86013715f6 | ||
|
|
cee756478e | ||
|
|
2517987176 | ||
|
|
49cd80a29d | ||
|
|
68cad4302a | ||
|
|
c201290179 | ||
|
|
8c05c20df4 | ||
|
|
3ecac0e0ab | ||
|
|
e4c108f3d7 | ||
|
|
d2c82fc45a | ||
|
|
7c2e55d3fd | ||
|
|
0c78f5bbad | ||
|
|
37c458acb7 | ||
|
|
775ce545d2 | ||
|
|
9b417d4592 | ||
|
|
2e0a0b5305 | ||
|
|
1caba8a761 | ||
|
|
6efd8f71f2 | ||
|
|
e5cf3448bd | ||
|
|
ea29292705 | ||
|
|
d32d625787 | ||
|
|
50ae8fdcf6 | ||
|
|
cb061edef8 | ||
|
|
49aba3d99e | ||
|
|
d8decf16a5 | ||
|
|
74357f24f8 | ||
|
|
fca6e38924 | ||
|
|
09446c7544 | ||
|
|
8bfcffa20a | ||
|
|
8a4ad6884b | ||
|
|
2021349249 | ||
|
|
e7392a5c22 | ||
|
|
6b0dccd9d5 | ||
|
|
90221ac971 | ||
|
|
e006418946 | ||
|
|
49ebd1264d | ||
|
|
94d07354ce | ||
|
|
2881b5c3df | ||
|
|
e0209e39ea | ||
|
|
e154c51512 | ||
|
|
e1196c53f2 | ||
|
|
56b431c4c2 | ||
|
|
ac4291f473 | ||
|
|
4dbcfc37b3 | ||
|
|
f59c9faee2 | ||
|
|
94c0eede77 | ||
|
|
61a92173cc | ||
|
|
c393791ed5 | ||
|
|
239ba78ee4 | ||
|
|
359b371edd | ||
|
|
67b4e0d544 | ||
|
|
2482413c83 | ||
|
|
de2192ab20 | ||
|
|
7fcc213b7a | ||
|
|
5aceb08fb4 | ||
|
|
1d465c4012 | ||
|
|
cc945fabb7 | ||
|
|
621251ae2e | ||
|
|
13e35220c2 | ||
|
|
45e6ca04f5 | ||
|
|
7c859988ba | ||
|
|
a221655e1a | ||
|
|
af3a20ad4e | ||
|
|
f4f6ef461b | ||
|
|
5719d6ca30 | ||
|
|
d918760272 | ||
|
|
58d332cff9 | ||
|
|
1f2c3cb141 | ||
|
|
398efeba2d | ||
|
|
0591917a06 | ||
|
|
9e61a85e86 | ||
|
|
bbdb1f12a0 | ||
|
|
fed4d43bd5 | ||
|
|
f9a4d9f781 | ||
|
|
1a664df87f | ||
|
|
eec0f0f9da | ||
|
|
77282aad96 | ||
|
|
c9301353fc | ||
|
|
4b7747b505 | ||
|
|
e7a40e1084 | ||
|
|
ee49fa81d9 | ||
|
|
cc4dae5c0f | ||
|
|
3826a26f8a | ||
|
|
045e0f533d | ||
|
|
ac711bcf45 | ||
|
|
b5f75d3392 | ||
|
|
ffc7a9f0b9 | ||
|
|
a557024511 | ||
|
|
0efc494b97 | ||
|
|
70fb513ba3 | ||
|
|
8985ee2114 | ||
|
|
33d71c61d9 | ||
|
|
e13c5f55a1 | ||
|
|
c74364be4c | ||
|
|
85aac3aef7 | ||
|
|
c3c71b5f3c | ||
|
|
d1ec31a73d | ||
|
|
9feb8b7c29 | ||
|
|
b45b819dfe | ||
|
|
c365555a69 | ||
|
|
9707adf634 | ||
|
|
05e0ee4c06 | ||
|
|
50a1375461 | ||
|
|
8f20d609b9 | ||
|
|
ef381abdfd | ||
|
|
3dc49c128c | ||
|
|
38dcdcb300 | ||
|
|
d0ac3d107b | ||
|
|
f08ec44049 | ||
|
|
acbdbb87fb | ||
|
|
a9dab78604 | ||
|
|
084fba1d17 | ||
|
|
c414b83e0a | ||
|
|
3f2c2080cc | ||
|
|
3d5f129cb0 | ||
|
|
6d137e77a5 | ||
|
|
4ee2aeb33d | ||
|
|
fd03d49b6f | ||
|
|
29fbee5784 | ||
|
|
eede8c60a1 | ||
|
|
9dabbdf40b | ||
|
|
2f3fc1cfa2 | ||
|
|
66dc9d1fbf | ||
|
|
e170502d63 | ||
|
|
b1e6b58b6a | ||
|
|
71e4ddb74f | ||
|
|
4603752cef | ||
|
|
1795b4118f | ||
|
|
b47bd89d44 | ||
|
|
33201eb14c | ||
|
|
079f1e33dc | ||
|
|
cf341f6a19 | ||
|
|
ce13b82329 | ||
|
|
2afacbce95 | ||
|
|
c8e7bb7653 | ||
|
|
eeebae7172 | ||
|
|
80d62f0547 | ||
|
|
e588745d77 | ||
|
|
b3fc99501e | ||
|
|
c475df7cfb | ||
|
|
51ce0579e8 | ||
|
|
57102e40e9 | ||
|
|
afc4e512cb | ||
|
|
eeead325b4 | ||
|
|
5a177e9aaf | ||
|
|
9bd3b59e1d | ||
|
|
77bd578d9f | ||
|
|
fd7ecfb877 | ||
|
|
0d36d5f3d8 | ||
|
|
a54459bed6 | ||
|
|
7fe9e1b90c | ||
|
|
d60637c153 | ||
|
|
f206e0fb4b | ||
|
|
050e383cf2 | ||
|
|
29bbdb74d3 | ||
|
|
1545e31557 | ||
|
|
71f7b946a6 | ||
|
|
83a8197fe9 | ||
|
|
153e32d613 | ||
|
|
1b580435fc | ||
|
|
f185b8c243 | ||
|
|
991ad56e9c | ||
|
|
371c0aec0b | ||
|
|
2f35271c9d | ||
|
|
3cf665c0f5 | ||
|
|
ef90044383 | ||
|
|
5fb141ae40 | ||
|
|
da19723bdc | ||
|
|
d1b1eb61ee | ||
|
|
bacdc67e69 | ||
|
|
fc3ea33681 | ||
|
|
86fa45a2d2 | ||
|
|
e3d338650f | ||
|
|
88f8e603d9 | ||
|
|
2c4913d479 | ||
|
|
3681b8fdb5 | ||
|
|
9b3dad29d7 | ||
|
|
743a4fee3d | ||
|
|
35b9322dc3 | ||
|
|
a194fa9779 | ||
|
|
b8ef30620b | ||
|
|
46c8ea3458 | ||
|
|
10673db0ce | ||
|
|
14c5c590e0 | ||
|
|
533ca10a79 | ||
|
|
916a8e7276 | ||
|
|
baa4ae5c90 | ||
|
|
ae8248cd39 | ||
|
|
2293dabf3f | ||
|
|
90c1f734c0 | ||
|
|
f2ec60553a | ||
|
|
b91a2765ae | ||
|
|
fae1c11488 | ||
|
|
2db0464fd9 | ||
|
|
202eeb707c | ||
|
|
2a340ce4c1 | ||
|
|
ae6192f9cb | ||
|
|
4d9ba4a652 | ||
|
|
9ff5b7077a | ||
|
|
351c77bca3 | ||
|
|
c1555b7cfd | ||
|
|
48ed067359 | ||
|
|
7234985a63 | ||
|
|
434c0fa7fb | ||
|
|
3fe69cba13 | ||
|
|
27f230c6bf | ||
|
|
a3204f806c | ||
|
|
be8b7d25f6 | ||
|
|
0bef3861ff | ||
|
|
dc5861414a | ||
|
|
3616fc519b | ||
|
|
bd9f2eb15d | ||
|
|
1dbb35b63b | ||
|
|
5fd49d1907 | ||
|
|
7024801722 | ||
|
|
40dfdbd929 | ||
|
|
0cb6effe14 | ||
|
|
a0c07fcf28 | ||
|
|
221f1bc18e | ||
|
|
c0c1cce296 | ||
|
|
a628ce605f | ||
|
|
3607c177d9 | ||
|
|
e1efe253d2 | ||
|
|
544d338e0e | ||
|
|
a9e916f1b9 | ||
|
|
c908681186 | ||
|
|
3b3a5ff07f | ||
|
|
e239fa05dd | ||
|
|
c5a85dbfdc | ||
|
|
d49ccd64f2 | ||
|
|
2815504547 | ||
|
|
19d052ff26 | ||
|
|
90806d3525 | ||
|
|
24886887f9 | ||
|
|
c0012125d2 | ||
|
|
896002d66a | ||
|
|
4389db676e | ||
|
|
1af6acb542 | ||
|
|
e9ccb8b496 | ||
|
|
8ffa3470bb | ||
|
|
77c0d1662a | ||
|
|
8fa6374b22 | ||
|
|
adb60835f7 | ||
|
|
fb62f4567b | ||
|
|
49e332ded2 | ||
|
|
079887fe42 | ||
|
|
8a227678b2 | ||
|
|
c7c8527ce3 | ||
|
|
1462dc4b66 | ||
|
|
0a2f847ac9 | ||
|
|
cc64de63b9 | ||
|
|
0708073b35 | ||
|
|
f88eecc172 | ||
|
|
f92a2c43b3 | ||
|
|
42ed459018 | ||
|
|
67e505d2ab | ||
|
|
802b562cbf | ||
|
|
336cf18ae8 | ||
|
|
5e8c17ac4e | ||
|
|
22ef6f7e0d | ||
|
|
de970528d7 | ||
|
|
2af8b0203e | ||
|
|
3bd15d3a70 | ||
|
|
d67fcf3f9c | ||
|
|
a65e5f86de | ||
|
|
8b268fb161 | ||
|
|
415a0e9de3 | ||
|
|
41765c8938 | ||
|
|
de6b083f58 | ||
|
|
ed8604f566 | ||
|
|
bbcc51539b | ||
|
|
b1dc2099c7 | ||
|
|
89524bf484 | ||
|
|
9b5022802e | ||
|
|
d6ea58f110 | ||
|
|
c53cfa6c6a | ||
|
|
5381389cdd | ||
|
|
08d9bb4c7c | ||
|
|
e51352557d | ||
|
|
159d4b2635 | ||
|
|
b16fb594ee | ||
|
|
23c0ba0065 | ||
|
|
2ebce7dad7 | ||
|
|
a8960a0876 | ||
|
|
9bd337033d | ||
|
|
cca5a0c27a | ||
|
|
b20173ba38 | ||
|
|
12edf1f533 | ||
|
|
9e607ddb5a | ||
|
|
33602d0a11 | ||
|
|
4b7fc1bb11 | ||
|
|
9a51ddaa6e | ||
|
|
e72c67b399 | ||
|
|
b81fc4d41d | ||
|
|
bfa8e4f4dc | ||
|
|
ed0399c961 | ||
|
|
68b7104563 | ||
|
|
6c2d2971a2 | ||
|
|
a592eefcbe | ||
|
|
2fce52b2ae | ||
|
|
750bed46fd | ||
|
|
d48588c89c | ||
|
|
d5552e2fbe | ||
|
|
0cdd360369 | ||
|
|
449ce271b1 | ||
|
|
9011c35db1 | ||
|
|
ccbd8395f4 | ||
|
|
25084ac51a | ||
|
|
4c1161c24a | ||
|
|
05d83f7b1a | ||
|
|
5a70bbe10b | ||
|
|
43e76a45e9 | ||
|
|
e78b0c8945 | ||
|
|
7cfeb436e4 | ||
|
|
1212cb034f | ||
|
|
6c3fce3382 | ||
|
|
bc2940927e | ||
|
|
5c21b9c7c7 | ||
|
|
2b692ce09c | ||
|
|
d236581f7b | ||
|
|
555cf46f2a | ||
|
|
00a454298c | ||
|
|
fb1a2c58dd | ||
|
|
40ee63b6ff | ||
|
|
38670f6730 | ||
|
|
fd1058d488 | ||
|
|
16ad898a13 | ||
|
|
90fc87af1c | ||
|
|
dc151ef624 | ||
|
|
37143a57b5 | ||
|
|
44b5581c48 | ||
|
|
fde54630a5 | ||
|
|
d72bb516ef | ||
|
|
a316791c49 | ||
|
|
42e84df47a | ||
|
|
abc071c974 | ||
|
|
ee6c9c9f00 | ||
|
|
bc213f0ba3 | ||
|
|
1e4644762a | ||
|
|
2efba704b3 | ||
|
|
fd49860e24 | ||
|
|
e615b54704 | ||
|
|
e2d691eda8 | ||
|
|
16483765ba | ||
|
|
9b461748a0 | ||
|
|
fbc3a63f6c | ||
|
|
f2262dec1c | ||
|
|
506f1152a8 | ||
|
|
33d0dac397 | ||
|
|
4cb3305614 | ||
|
|
029c8634fd | ||
|
|
9fde0d3e5a | ||
|
|
aec96db016 | ||
|
|
e97fab49d3 | ||
|
|
eee33c1731 | ||
|
|
ec7df3f449 | ||
|
|
7b2a90493f | ||
|
|
3304a8bc1e | ||
|
|
d0002e5394 | ||
|
|
3119d45e4c | ||
|
|
f87d2e5bb6 | ||
|
|
ffc62d0068 | ||
|
|
07b7df0b0e | ||
|
|
227c81511f | ||
|
|
bc8b826f65 | ||
|
|
d7890f281b | ||
|
|
3e5f21836f | ||
|
|
7d307a1ae7 | ||
|
|
f989073e0d | ||
|
|
837e136aa6 | ||
|
|
f211f9c476 | ||
|
|
43c2d3e981 | ||
|
|
15a1396579 | ||
|
|
40d62156ac | ||
|
|
df55f87e2d | ||
|
|
dbb5e86cde | ||
|
|
d9dbe7bb1e | ||
|
|
bb9fba63c4 | ||
|
|
33458f6fe4 | ||
|
|
020fdb84f4 | ||
|
|
059410842d | ||
|
|
a13a688507 | ||
|
|
792e537014 | ||
|
|
9a0684671a | ||
|
|
e2e1132eba | ||
|
|
ca5093b1ea | ||
|
|
694ffb7454 | ||
|
|
d28c66ab23 | ||
|
|
d5fb92d9a3 | ||
|
|
6abeee6109 | ||
|
|
3408cb4cab | ||
|
|
3f704efe4e | ||
|
|
7add065e0f | ||
|
|
3f1e1192cb | ||
|
|
a9aed18760 | ||
|
|
50dbacbaf0 | ||
|
|
cebf94f0db | ||
|
|
c8d1b2568b | ||
|
|
f707c50e9d | ||
|
|
6c3864d50e | ||
|
|
2c218563b3 | ||
|
|
0d83fc1704 | ||
|
|
9f2bd1e80f | ||
|
|
c22277cf6a | ||
|
|
2e23e829d9 | ||
|
|
be804ed5e6 | ||
|
|
29704cd895 | ||
|
|
8819aab738 | ||
|
|
aeecfffbb1 | ||
|
|
712675a744 | ||
|
|
53c50e58bf | ||
|
|
5ebe18e5ec | ||
|
|
a56a457941 | ||
|
|
2c83a6f53e | ||
|
|
22da94979e | ||
|
|
17cdd5f2d2 | ||
|
|
188ebe6ceb | ||
|
|
b42de3a4f3 | ||
|
|
f51c126c9d | ||
|
|
9cf82aad7e | ||
|
|
99b30a2b32 | ||
|
|
08b6a144bd | ||
|
|
cf086db3f2 | ||
|
|
90bb5bf23c | ||
|
|
cbfce81f38 | ||
|
|
68e9e6b533 | ||
|
|
6661778d6e | ||
|
|
aec00dd13c | ||
|
|
e51db8046c | ||
|
|
f28ed288b8 | ||
|
|
1dc5de0179 | ||
|
|
0a4081dc57 | ||
|
|
7721fe8b51 | ||
|
|
f324e94785 | ||
|
|
30d0cf44cb | ||
|
|
4a7725e917 | ||
|
|
dcb52d2ea8 | ||
|
|
e29e96a9e1 | ||
|
|
25fa1a3a8c | ||
|
|
6fd2ed3f11 | ||
|
|
0276b6e644 | ||
|
|
3bd8840931 | ||
|
|
36cf99464d | ||
|
|
f19cbcbff5 | ||
|
|
c7039276a0 | ||
|
|
1f136d8cb6 | ||
|
|
a5e1e1f33e | ||
|
|
1bebb796bb | ||
|
|
a19375e928 | ||
|
|
413706af15 | ||
|
|
8370f3e275 | ||
|
|
959413c95a | ||
|
|
325b2f4ade | ||
|
|
83ac8470a0 | ||
|
|
f6b543ae94 | ||
|
|
e9a10d7cda | ||
|
|
dc0adeafb4 | ||
|
|
80bc5b30c2 | ||
|
|
0412f3af19 | ||
|
|
c79a28077f | ||
|
|
6bd1189ac2 | ||
|
|
422d353b0a | ||
|
|
847f2ba0d5 | ||
|
|
cae0944eda | ||
|
|
37f5c2af03 | ||
|
|
95de12dbb4 | ||
|
|
de712c24fb | ||
|
|
26f9497dd4 | ||
|
|
dd1274d805 | ||
|
|
5587ec4f28 | ||
|
|
02e0c5c152 | ||
|
|
c7e456e77d | ||
|
|
e2eaca874e | ||
|
|
4fb87dc8de | ||
|
|
217acf1c4c | ||
|
|
c60bcbe173 | ||
|
|
666e80e5bd | ||
|
|
9597c478f9 | ||
|
|
1575eb36c1 | ||
|
|
b3e0829c50 | ||
|
|
403350cc99 | ||
|
|
a8069e81b7 | ||
|
|
11cd48efa3 | ||
|
|
96c666ffcf | ||
|
|
9b6ba77224 | ||
|
|
1c6910c2ec | ||
|
|
3557938100 | ||
|
|
ffb8dbaeee | ||
|
|
0cffbf8eb7 | ||
|
|
334a96f761 | ||
|
|
50cb73a76e | ||
|
|
35c72808bf | ||
|
|
859eff84db | ||
|
|
38dfb78b4e | ||
|
|
a1db4012d9 | ||
|
|
3f0cb9473b | ||
|
|
2edb721609 | ||
|
|
82abe83414 | ||
|
|
1bf1abb40a | ||
|
|
dd7b94054a | ||
|
|
ea1ff58500 | ||
|
|
9bbbadaa57 | ||
|
|
3c1c246415 | ||
|
|
52d39094e4 | ||
|
|
4aba0742ce | ||
|
|
6f1a0f1c60 | ||
|
|
99359a48d9 | ||
|
|
ef405dbe9c | ||
|
|
ee1f2a2484 | ||
|
|
9e6f2e579a | ||
|
|
ddb07346c0 | ||
|
|
2d8bb440c9 | ||
|
|
a23ee46c67 | ||
|
|
8d9808cb4d | ||
|
|
fa56a98ba9 | ||
|
|
bb95c2d8e9 | ||
|
|
51e67d70c4 | ||
|
|
bdafa7afcb | ||
|
|
51ab423164 | ||
|
|
94ad48ea87 | ||
|
|
99af655c4c | ||
|
|
4085af6b83 | ||
|
|
db9c41f45c | ||
|
|
03fec9c7fe | ||
|
|
06cfc731c6 | ||
|
|
e6dbc77e0e | ||
|
|
d321f40d3b | ||
|
|
b9098ee927 | ||
|
|
0d4a963517 |
@@ -4,7 +4,6 @@ compat/zlib/win64/zdll.lib
|
||||
compat/zlib/win64/zlib1.dll
|
||||
compat/zlib/win64/libz.dll.a
|
||||
compat/zlib/zlib.3.pdf
|
||||
tools/empty.zip
|
||||
*.bmp
|
||||
*.gif
|
||||
*.png
|
||||
@@ -1,19 +0,0 @@
|
||||
compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
|
||||
compat/zlib/contrib/vstudio/readme.txt
|
||||
compat/zlib/contrib/vstudio/*/zlib.rc
|
||||
compat/zlib/win32/*.txt
|
||||
compat/zlib/win64/*.txt
|
||||
libtommath/*.dsp
|
||||
libtommath/*.sln
|
||||
libtommath/*.vcproj
|
||||
tools/tcl.hpj.in
|
||||
tools/tcl.wse.in
|
||||
win/buildall.vc.bat
|
||||
win/coffbase.txt
|
||||
win/makefile.vc
|
||||
win/rules.vc
|
||||
win/rules-ext.vc
|
||||
win/targets.vc
|
||||
win/tcl.dsp
|
||||
win/tcl.dsw
|
||||
win/tcl.hpj.in
|
||||
@@ -19,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
|
||||
|
||||
+1
-1
@@ -1426,7 +1426,7 @@
|
||||
initialization assumptions of the TIP 280 code in CompileWord().
|
||||
|
||||
* generic/tclCompExpr.c: Suppress the attempt to convert to
|
||||
numeric when pre-compiling a constant expresion indicates an error.
|
||||
numeric when pre-compiling a constant expression indicates an error.
|
||||
|
||||
2007-08-22 Miguel Sofer <msofer@users.sf.net>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ Tcl is maintained, enhanced, and distributed freely by the Tcl community.
|
||||
Source code development and tracking of bug reports and feature requests
|
||||
takes place at:
|
||||
|
||||
http://core.tcl.tk/
|
||||
http://core.tcl-lang.org/
|
||||
|
||||
Tcl/Tk release and mailing list services are hosted by SourceForge:
|
||||
|
||||
@@ -37,7 +37,7 @@ Tcl/Tk release and mailing list services are hosted by SourceForge:
|
||||
|
||||
with the Tcl Developer Xchange hosted at:
|
||||
|
||||
http://www.tcl.tk/
|
||||
http://www.tcl-lang.org/
|
||||
|
||||
Tcl is a freely available open source package. You can do virtually
|
||||
anything you like with it, such as modifying it, redistributing it,
|
||||
@@ -49,21 +49,21 @@ and selling it either in whole or in part. See the file
|
||||
|
||||
Extensive documentation is available at our website.
|
||||
The home page for this release, including new features, is
|
||||
http://www.tcl.tk/software/tcltk/8.7.html
|
||||
http://www.tcl-lang.org/software/tcltk/8.7.html
|
||||
|
||||
Detailed release notes can be found at the file distributions page
|
||||
by clicking on the relevant version.
|
||||
http://sourceforge.net/projects/tcl/files/Tcl/
|
||||
|
||||
Information about Tcl itself can be found at
|
||||
http://www.tcl.tk/about/
|
||||
http://www.tcl-lang.org/about/
|
||||
|
||||
There have been many Tcl books on the market. Many are mentioned in the Wiki:
|
||||
http://wiki.tcl.tk/_/ref?N=25206
|
||||
http://wiki.tcl-lang.org/_/ref?N=25206
|
||||
|
||||
To view the complete set of reference manual entries for Tcl 8.7 online,
|
||||
visit the URL:
|
||||
http://www.tcl.tk/man/tcl8.7/
|
||||
http://www.tcl-lang.org/man/tcl8.7/
|
||||
|
||||
2a. Unix Documentation
|
||||
----------------------
|
||||
@@ -101,7 +101,7 @@ There are brief notes in the unix/README, win/README, and macosx/README about
|
||||
compiling on these different platforms. There is additional information
|
||||
about building Tcl from sources at
|
||||
|
||||
http://www.tcl.tk/doc/howto/compile.html
|
||||
http://www.tcl-lang.org/doc/howto/compile.html
|
||||
|
||||
4. Development tools
|
||||
---------------------------
|
||||
@@ -127,7 +127,7 @@ see the "Support and bug fixes" section below.
|
||||
|
||||
A Wiki-based open community site covering all aspects of Tcl/Tk is at:
|
||||
|
||||
http://wiki.tcl.tk/
|
||||
http://wiki.tcl-lang.org/
|
||||
|
||||
It is dedicated to the Tcl programming language and its extensions. A
|
||||
wealth of useful information can be found there. It contains code
|
||||
@@ -153,7 +153,7 @@ We are very interested in receiving bug reports, patches, and suggestions
|
||||
for improvements. We prefer that you send this information to us as
|
||||
tickets entered into our tracker at:
|
||||
|
||||
http://core.tcl.tk/tcl/reportlist
|
||||
http://core.tcl-lang.org/tcl/reportlist
|
||||
|
||||
We will log and follow-up on each bug, although we cannot promise a
|
||||
specific turn-around time. Enhancements may take longer and may not happen
|
||||
@@ -169,13 +169,13 @@ questions for which no one else is likely to know the answer. In addition,
|
||||
see the following Web site for links to other organizations that offer
|
||||
Tcl/Tk training:
|
||||
|
||||
http://wiki.tcl.tk/training
|
||||
http://wiki.tcl-lang.org/training
|
||||
|
||||
9. Tracking Development
|
||||
-----------------------
|
||||
|
||||
Tcl is developed in public. To keep an eye on how Tcl is changing, see
|
||||
http://core.tcl.tk/
|
||||
http://core.tcl-lang.org/
|
||||
|
||||
10. Thank You
|
||||
-------------
|
||||
|
||||
@@ -8831,6 +8831,70 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
|
||||
|
||||
--- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2018-02-11 (enhance) stop blocking conversion of object to/from class (coulter)
|
||||
|
||||
2018-02-12 (enhance) NR-enable [package require] (coulter)
|
||||
|
||||
2018-02-14 (bug)[9fd5c6] crash in object deletion, test oo-11.5 (coulter)
|
||||
|
||||
2018-02-14 (bug)[3c32a3] crash deleting object with class mixed in (coulter)
|
||||
|
||||
2018-02-15 (platform) stop using -lieee, removed from glibc-2.27 (porter)
|
||||
***POTENTIAL INCOMPATIBILITY for math programs that embed Tcl***
|
||||
|
||||
2018-02-23 (bug)[8e6a9a] bad binary [string match], test string-11.55 (porter)
|
||||
|
||||
2018-03-05 (bug)[1873ea] repair multi-thread std channel init (sebres)
|
||||
|
||||
2018-03-09 (bug)[db36fa] broken bytecode for index values (porter)
|
||||
|
||||
2018-03-13 (bug) broken compiled [string replace], test string-14.19 (porter)
|
||||
|
||||
2018-03-14 (bug) [string trim*] engine crashed on invalid UTF (sebres)
|
||||
|
||||
2018-04-17 (bug) missing trace in compiled [array set], test var-20.11 (porter)
|
||||
|
||||
2018-04-22 (bug)[46a241] crash in unset array with search, var-13.[23] (goth)
|
||||
|
||||
2018-04-30 (bug)[27b682] race made [file delete] raise "no such file" (sebres)
|
||||
|
||||
2018-06-04 (bug)[925643] 32/64 cleanup of filesystem DIR operations (sebres)
|
||||
|
||||
2018-06-18 (bug) leaks in TclSetEnv and env cache (coulter)
|
||||
|
||||
2018-06-24 (bug)[3592747] [yieldto] dying namespace, tailcall-14.1 (coulter)
|
||||
|
||||
2018-07-09 (bug)[270f78] race in [file mkdir] (sebres)
|
||||
|
||||
2018-07-12 (bug)[3f7af0] [file delete] raised "permission denied" (sebres)
|
||||
|
||||
2018-07-26 (bug)[d051b7] overflow crash in [format] (sebres)
|
||||
|
||||
2018-08-29 revised quoting of [exec] args in generated command line (sebres)
|
||||
***POTENTIAL INCOMPATIBILITY***
|
||||
|
||||
2018-09-20 HTTP Keep-Alive with pipelined requests (nash)
|
||||
=> http 2.9.0
|
||||
|
||||
2018-09-27 (new)[TIP 505] [lreplace] accepts all out of range indices (porter)
|
||||
|
||||
2018-10-04 (bug) Prevent crash from NULL keyName (nijtmans)
|
||||
=> registry 1.3.3
|
||||
|
||||
2018-10-26 (enhance) advance dde version (nijtmans)
|
||||
=> dde 1.4.1
|
||||
|
||||
2018-10-27 tzdata updated to Olson's tzdata2018g (jima)
|
||||
|
||||
2018-10-29 Update tcltest package for Travis support (fellows)
|
||||
=> tcltest 2.5.0
|
||||
|
||||
2018-11-09 (bug)[35a8f1] overlong string length of some lists (owens)
|
||||
|
||||
2018-11-16 (bug)[00d04c] Repair [binary encode base64] (sebres)
|
||||
|
||||
- Released 8.6.9, November 16, 2018 - details at http://core.tcl-lang.org/tcl/ -
|
||||
|
||||
Changes to 8.7a1 include all changes to the 8.6 line through 8.6.7,
|
||||
plus the following, which focuses on the high-level feature changes
|
||||
in this changeset (new minor version) rather than bug fixes:
|
||||
@@ -8849,7 +8913,7 @@ in this changeset (new minor version) rather than bug fixes:
|
||||
|
||||
2016-10-04 Server socket on port 0 chooses port supporting IPv4 * IPv6 (max)
|
||||
|
||||
2016-11-25 [array named -regexp] supports backrefs (goth)
|
||||
2016-11-25 [array names -regexp] supports backrefs (goth)
|
||||
|
||||
2017-01-04 (TIP 456) New routine Tcl_OpenTcpServerEx() (limeboy)
|
||||
|
||||
@@ -8884,3 +8948,5 @@ in this changeset (new minor version) rather than bug fixes:
|
||||
|
||||
2018-03-12 (TIP 499) custom locale preference list (oehlmann)
|
||||
=> msgcat 1.7.0
|
||||
|
||||
- Released 8.7a3, Nov 30, 2018 --- http://core.tcl-lang.org/tcl/ for details -
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* fixstrtod.c --
|
||||
*
|
||||
* Source code for the "fixstrtod" procedure. This procedure is
|
||||
* used in place of strtod under Solaris 2.4, in order to fix
|
||||
* a bug where the "end" pointer gets set incorrectly.
|
||||
*
|
||||
* Copyright (c) 1995 Sun Microsystems, Inc.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#undef strtod
|
||||
|
||||
/*
|
||||
* Declare strtod explicitly rather than including stdlib.h, since in
|
||||
* somes systems (e.g. SunOS 4.1.4) stdlib.h doesn't declare strtod.
|
||||
*/
|
||||
|
||||
extern double strtod(char *, char **);
|
||||
|
||||
double
|
||||
fixstrtod(
|
||||
char *string,
|
||||
char **endPtr)
|
||||
{
|
||||
double d;
|
||||
d = strtod(string, endPtr);
|
||||
if ((endPtr != NULL) && (*endPtr != string) && ((*endPtr)[-1] == 0)) {
|
||||
*endPtr -= 1;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
@@ -29,7 +29,6 @@ extern char * malloc(unsigned int numBytes);
|
||||
extern void qsort(void *base, int n, int size, int (*compar)(
|
||||
const void *element1, const void *element2));
|
||||
extern char * realloc(char *ptr, unsigned int numBytes);
|
||||
extern double strtod(const char *string, char **endPtr);
|
||||
extern long strtol(const char *string, char **endPtr, int base);
|
||||
extern unsigned long strtoul(const char *string, char **endPtr, int base);
|
||||
|
||||
|
||||
-252
@@ -1,252 +0,0 @@
|
||||
/*
|
||||
* strtod.c --
|
||||
*
|
||||
* Source code for the "strtod" library procedure.
|
||||
*
|
||||
* Copyright (c) 1988-1993 The Regents of the University of California.
|
||||
* Copyright (c) 1994 Sun Microsystems, Inc.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
static const int maxExponent = 511; /* Largest possible base 10 exponent. Any
|
||||
* exponent larger than this will already
|
||||
* produce underflow or overflow, so there's
|
||||
* no need to worry about additional digits.
|
||||
*/
|
||||
static const double powersOf10[] = { /* Table giving binary powers of 10. Entry */
|
||||
10., /* is 10^2^i. Used to convert decimal */
|
||||
100., /* exponents into floating-point numbers. */
|
||||
1.0e4,
|
||||
1.0e8,
|
||||
1.0e16,
|
||||
1.0e32,
|
||||
1.0e64,
|
||||
1.0e128,
|
||||
1.0e256
|
||||
};
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* strtod --
|
||||
*
|
||||
* This procedure converts a floating-point number from an ASCII
|
||||
* decimal representation to internal double-precision format.
|
||||
*
|
||||
* Results:
|
||||
* The return value is the double-precision floating-point
|
||||
* representation of the characters in string. If endPtr isn't
|
||||
* NULL, then *endPtr is filled in with the address of the
|
||||
* next character after the last one that was part of the
|
||||
* floating-point number.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
double
|
||||
strtod(
|
||||
const char *string, /* A decimal ASCII floating-point number,
|
||||
* optionally preceded by white space. Must
|
||||
* have form "-I.FE-X", where I is the integer
|
||||
* part of the mantissa, F is the fractional
|
||||
* part of the mantissa, and X is the
|
||||
* exponent. Either of the signs may be "+",
|
||||
* "-", or omitted. Either I or F may be
|
||||
* omitted, or both. The decimal point isn't
|
||||
* necessary unless F is present. The "E" may
|
||||
* actually be an "e". E and X may both be
|
||||
* omitted (but not just one). */
|
||||
char **endPtr) /* If non-NULL, store terminating character's
|
||||
* address here. */
|
||||
{
|
||||
int sign, expSign = FALSE;
|
||||
double fraction, dblExp;
|
||||
const double *d;
|
||||
register const char *p;
|
||||
register int c;
|
||||
int exp = 0; /* Exponent read from "EX" field. */
|
||||
int fracExp = 0; /* Exponent that derives from the fractional
|
||||
* part. Under normal circumstatnces, it is
|
||||
* the negative of the number of digits in F.
|
||||
* However, if I is very long, the last digits
|
||||
* of I get dropped (otherwise a long I with a
|
||||
* large negative exponent could cause an
|
||||
* unnecessary overflow on I alone). In this
|
||||
* case, fracExp is incremented one for each
|
||||
* dropped digit. */
|
||||
int mantSize; /* Number of digits in mantissa. */
|
||||
int decPt; /* Number of mantissa digits BEFORE decimal
|
||||
* point. */
|
||||
const char *pExp; /* Temporarily holds location of exponent in
|
||||
* string. */
|
||||
|
||||
/*
|
||||
* Strip off leading blanks and check for a sign.
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace(UCHAR(*p))) {
|
||||
p += 1;
|
||||
}
|
||||
if (*p == '-') {
|
||||
sign = TRUE;
|
||||
p += 1;
|
||||
} else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
}
|
||||
sign = FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Count the number of digits in the mantissa (including the decimal
|
||||
* point), and also locate the decimal point.
|
||||
*/
|
||||
|
||||
decPt = -1;
|
||||
for (mantSize = 0; ; mantSize += 1)
|
||||
{
|
||||
c = *p;
|
||||
if (!isdigit(c)) {
|
||||
if ((c != '.') || (decPt >= 0)) {
|
||||
break;
|
||||
}
|
||||
decPt = mantSize;
|
||||
}
|
||||
p += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now suck up the digits in the mantissa. Use two integers to collect 9
|
||||
* digits each (this is faster than using floating-point). If the mantissa
|
||||
* has more than 18 digits, ignore the extras, since they can't affect the
|
||||
* value anyway.
|
||||
*/
|
||||
|
||||
pExp = p;
|
||||
p -= mantSize;
|
||||
if (decPt < 0) {
|
||||
decPt = mantSize;
|
||||
} else {
|
||||
mantSize -= 1; /* One of the digits was the point. */
|
||||
}
|
||||
if (mantSize > 18) {
|
||||
fracExp = decPt - 18;
|
||||
mantSize = 18;
|
||||
} else {
|
||||
fracExp = decPt - mantSize;
|
||||
}
|
||||
if (mantSize == 0) {
|
||||
fraction = 0.0;
|
||||
p = string;
|
||||
goto done;
|
||||
} else {
|
||||
int frac1, frac2;
|
||||
|
||||
frac1 = 0;
|
||||
for ( ; mantSize > 9; mantSize -= 1) {
|
||||
c = *p;
|
||||
p += 1;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
}
|
||||
frac1 = 10*frac1 + (c - '0');
|
||||
}
|
||||
frac2 = 0;
|
||||
for (; mantSize > 0; mantSize -= 1) {
|
||||
c = *p;
|
||||
p += 1;
|
||||
if (c == '.') {
|
||||
c = *p;
|
||||
p += 1;
|
||||
}
|
||||
frac2 = 10*frac2 + (c - '0');
|
||||
}
|
||||
fraction = (1.0e9 * frac1) + frac2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skim off the exponent.
|
||||
*/
|
||||
|
||||
p = pExp;
|
||||
if ((*p == 'E') || (*p == 'e')) {
|
||||
p += 1;
|
||||
if (*p == '-') {
|
||||
expSign = TRUE;
|
||||
p += 1;
|
||||
} else {
|
||||
if (*p == '+') {
|
||||
p += 1;
|
||||
}
|
||||
expSign = FALSE;
|
||||
}
|
||||
if (!isdigit(UCHAR(*p))) {
|
||||
p = pExp;
|
||||
goto done;
|
||||
}
|
||||
while (isdigit(UCHAR(*p))) {
|
||||
exp = exp * 10 + (*p - '0');
|
||||
p += 1;
|
||||
}
|
||||
}
|
||||
if (expSign) {
|
||||
exp = fracExp - exp;
|
||||
} else {
|
||||
exp = fracExp + exp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a floating-point number that represents the exponent. Do this
|
||||
* by processing the exponent one bit at a time to combine many powers of
|
||||
* 2 of 10. Then combine the exponent with the fraction.
|
||||
*/
|
||||
|
||||
if (exp < 0) {
|
||||
expSign = TRUE;
|
||||
exp = -exp;
|
||||
} else {
|
||||
expSign = FALSE;
|
||||
}
|
||||
if (exp > maxExponent) {
|
||||
exp = maxExponent;
|
||||
errno = ERANGE;
|
||||
}
|
||||
dblExp = 1.0;
|
||||
for (d = powersOf10; exp != 0; exp >>= 1, ++d) {
|
||||
if (exp & 01) {
|
||||
dblExp *= *d;
|
||||
}
|
||||
}
|
||||
if (expSign) {
|
||||
fraction /= dblExp;
|
||||
} else {
|
||||
fraction *= dblExp;
|
||||
}
|
||||
|
||||
done:
|
||||
if (endPtr != NULL) {
|
||||
*endPtr = (char *) p;
|
||||
}
|
||||
|
||||
if (sign) {
|
||||
return -fraction;
|
||||
}
|
||||
return fraction;
|
||||
}
|
||||
+1
-1
@@ -53,7 +53,7 @@ strtol(
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace(UCHAR(*p))) {
|
||||
while (TclIsSpaceProc(*p)) {
|
||||
p += 1;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -74,7 +74,7 @@ strtoul(
|
||||
*/
|
||||
|
||||
p = string;
|
||||
while (isspace(UCHAR(*p))) {
|
||||
while (TclIsSpaceProc(*p)) {
|
||||
p += 1;
|
||||
}
|
||||
if (*p == '-') {
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* unistd.h --
|
||||
*
|
||||
* Macros, constants and prototypes for Posix conformance.
|
||||
*
|
||||
* Copyright 1989 Regents of the University of California Permission to use,
|
||||
* copy, modify, and distribute this software and its documentation for any
|
||||
* purpose and without fee is hereby granted, provided that the above
|
||||
* copyright notice appear in all copies. The University of California makes
|
||||
* no representations about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*/
|
||||
|
||||
#ifndef _UNISTD
|
||||
#define _UNISTD
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Strict POSIX stuff goes here. Extensions go down below, in the ifndef
|
||||
* _POSIX_SOURCE section.
|
||||
*/
|
||||
|
||||
extern void _exit(int status);
|
||||
extern int access(const char *path, int mode);
|
||||
extern int chdir(const char *path);
|
||||
extern int chown(const char *path, uid_t owner, gid_t group);
|
||||
extern int close(int fd);
|
||||
extern int dup(int oldfd);
|
||||
extern int dup2(int oldfd, int newfd);
|
||||
extern int execl(const char *path, ...);
|
||||
extern int execle(const char *path, ...);
|
||||
extern int execlp(const char *file, ...);
|
||||
extern int execv(const char *path, char **argv);
|
||||
extern int execve(const char *path, char **argv, char **envp);
|
||||
extern int execvpw(const char *file, char **argv);
|
||||
extern pid_t fork(void);
|
||||
extern char * getcwd(char *buf, size_t size);
|
||||
extern gid_t getegid(void);
|
||||
extern uid_t geteuid(void);
|
||||
extern gid_t getgid(void);
|
||||
extern int getgroups(int bufSize, int *buffer);
|
||||
extern pid_t getpid(void);
|
||||
extern uid_t getuid(void);
|
||||
extern int isatty(int fd);
|
||||
extern long lseek(int fd, long offset, int whence);
|
||||
extern int pipe(int *fildes);
|
||||
extern int read(int fd, char *buf, size_t size);
|
||||
extern int setgid(gid_t group);
|
||||
extern int setuid(uid_t user);
|
||||
extern unsigned sleep(unsigned seconds);
|
||||
extern char * ttyname(int fd);
|
||||
extern int unlink(const char *path);
|
||||
extern int write(int fd, const char *buf, size_t size);
|
||||
|
||||
#ifndef _POSIX_SOURCE
|
||||
extern char * crypt(const char *, const char *);
|
||||
extern int fchown(int fd, uid_t owner, gid_t group);
|
||||
extern int flock(int fd, int operation);
|
||||
extern int ftruncate(int fd, unsigned long length);
|
||||
extern int ioctl(int fd, int request, ...);
|
||||
extern int readlink(const char *path, char *buf, int bufsize);
|
||||
extern int setegid(gid_t group);
|
||||
extern int seteuidw(uid_t user);
|
||||
extern int setreuid(int ruid, int euid);
|
||||
extern int symlink(const char *, const char *);
|
||||
extern int ttyslot(void);
|
||||
extern int truncate(const char *path, unsigned long length);
|
||||
extern int vfork(void);
|
||||
#endif /* _POSIX_SOURCE */
|
||||
|
||||
#endif /* _UNISTD */
|
||||
@@ -29,6 +29,12 @@
|
||||
|
||||
#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
|
||||
|
||||
#ifdef Z_U4
|
||||
typedef Z_U4 z_crc_t;
|
||||
#else
|
||||
typedef unsigned long z_crc_t;
|
||||
#endif
|
||||
|
||||
/***********************************************************************
|
||||
* Return the next byte in the pseudo-random sequence
|
||||
*/
|
||||
|
||||
@@ -97,7 +97,7 @@ void change_file_date(filename,dosdate,tmu_date)
|
||||
SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
|
||||
CloseHandle(hFile);
|
||||
#else
|
||||
#ifdef unix || __APPLE__
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
struct utimbuf ut;
|
||||
struct tm newdate;
|
||||
newdate.tm_sec = tmu_date.tm_sec;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#if defined(__APPLE__) || defined(IOAPI_NO_64)
|
||||
// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
|
||||
#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
|
||||
#define FTELLO_FUNC(stream) ftello(stream)
|
||||
@@ -92,7 +92,7 @@ uLong filetime(f, tmzip, dt)
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#ifdef unix || __APPLE__
|
||||
#if defined(unix) || defined(__APPLE__)
|
||||
uLong filetime(f, tmzip, dt)
|
||||
char *f; /* name of file to get info on */
|
||||
tm_zip *tmzip; /* return value: access, modific. and creation times */
|
||||
@@ -359,7 +359,7 @@ void addFileToZip(zipFile zf, const char *filenameinzip, const char *password, i
|
||||
void addPathToZip(zipFile zf, const char *filenameinzip, const char *password, int opt_exclude_path,int opt_compress_level) {
|
||||
tinydir_dir dir;
|
||||
int i;
|
||||
char *newname[512];
|
||||
char newname[512];
|
||||
|
||||
tinydir_open_sorted(&dir, filenameinzip);
|
||||
|
||||
|
||||
Executable → Regular
+1
-1
@@ -8,7 +8,7 @@
|
||||
.so man.macros
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj Tcl_RegisterCommandTypeName, Tcl_GetCommandTypeName \- implement new commands in C
|
||||
Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj, Tcl_RegisterCommandTypeName, Tcl_GetCommandTypeName \- implement new commands in C
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
|
||||
@@ -134,6 +134,9 @@ finalization of Tcl's subsystems via \fBTcl_Finalize\fR at an
|
||||
appropriate time. The argument passed to \fIproc\fR when it is
|
||||
invoked will be the exit status code (as passed to \fBTcl_Exit\fR)
|
||||
cast to a ClientData value.
|
||||
.PP
|
||||
\fBTcl_SetExitProc\fR can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH "SEE ALSO"
|
||||
exit(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+3
-1
@@ -58,6 +58,8 @@ internal full path name of the executable file as computed by
|
||||
equivalent to the \fBinfo nameofexecutable\fR command. NULL
|
||||
is returned if the internal full path name has not been
|
||||
computed or unknown.
|
||||
|
||||
.PP
|
||||
\fBTcl_FindExecutable\fR can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH KEYWORDS
|
||||
binary, executable file
|
||||
|
||||
+5
-1
@@ -93,7 +93,11 @@ have a panic message displayed the same way that panic messages from Tcl
|
||||
will be displayed.
|
||||
.PP
|
||||
\fBTcl_PanicVA\fR is the same as \fBTcl_Panic\fR except that instead of
|
||||
taking a variable number of arguments it takes an argument list.
|
||||
taking a variable number of arguments it takes an argument list. This
|
||||
function is deprecated and will be removed in Tcl 9.0.
|
||||
.PP
|
||||
This function can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH "SEE ALSO"
|
||||
abort(3), printf(3), exec(n), format(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+2
-2
@@ -103,8 +103,8 @@ the argument's value. The following values are acceptable values for
|
||||
\fBTCL_ARGV_CONSTANT\fR
|
||||
.
|
||||
The argument does not take any following value argument. If this argument is
|
||||
present, the int pointed to by the \fIsrcPtr\fR field is copied to the
|
||||
\fIdstPtr\fR field. The \fIclientData\fR field is ignored.
|
||||
present, the \fIsrcPtr\fR field (casted to \fIint\fR) is copied to the variable
|
||||
pointed to by the \fIdstPtr\fR field. The \fIclientData\fR field is ignored.
|
||||
.TP
|
||||
\fBTCL_ARGV_END\fR
|
||||
.
|
||||
|
||||
@@ -64,6 +64,9 @@ the event of an error it should set the interpreter's result to point to an
|
||||
error message. The result or error from the initialization procedure will
|
||||
be returned as the result of the \fBload\fR command that caused the
|
||||
initialization procedure to be invoked.
|
||||
.PP
|
||||
This function can not be used in stub-enabled extensions. Its symbol
|
||||
entry in the stub table is deprecated and it will be removed in Tcl 9.0.
|
||||
.SH KEYWORDS
|
||||
initialization procedure, package, static linking
|
||||
.SH "SEE ALSO"
|
||||
|
||||
@@ -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)
|
||||
|
||||
+9
-3
@@ -45,7 +45,9 @@ int
|
||||
.AP Tcl_Condition *condPtr in
|
||||
A condition variable, which must be associated with a mutex lock.
|
||||
.AP Tcl_Mutex *mutexPtr in
|
||||
A mutex lock.
|
||||
.VS TIP509
|
||||
A recursive mutex lock.
|
||||
.VE TIP509
|
||||
.AP "const Tcl_Time" *timePtr in
|
||||
A time limit on the condition wait. NULL to wait forever.
|
||||
Note that a polling value of 0 seconds does not make much sense.
|
||||
@@ -140,8 +142,12 @@ of code by calling \fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR.
|
||||
If one thread holds a mutex, any other thread calling \fBTcl_MutexLock\fR will
|
||||
block until \fBTcl_MutexUnlock\fR is called.
|
||||
A mutex can be destroyed after its use by calling \fBTcl_MutexFinalize\fR.
|
||||
The result of locking a mutex twice from the same thread is undefined.
|
||||
On some platforms it will result in a deadlock.
|
||||
.VS TIP509
|
||||
Mutexes are reentrant: they can be locked several times from the same
|
||||
thread. However there must be exactly one call to
|
||||
\fBTcl_MutexUnlock\fR for each call to \fBTcl_MutexLock\fR in order
|
||||
for a thread to release a mutex completely.
|
||||
.VE TIP509
|
||||
The \fBTcl_MutexLock\fR, \fBTcl_MutexUnlock\fR and \fBTcl_MutexFinalize\fR
|
||||
procedures are defined as empty macros if not compiling with threads enabled.
|
||||
For declaration of mutexes the \fBTCL_DECLARE_MUTEX\fR macro should be used.
|
||||
|
||||
@@ -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
|
||||
|
||||
+35
-11
@@ -25,6 +25,7 @@ out by the command.
|
||||
The legal \fIoptions\fR (which may be abbreviated) are:
|
||||
.TP
|
||||
\fBarray anymore \fIarrayName searchId\fR
|
||||
.
|
||||
Returns 1 if there are any more elements left to be processed
|
||||
in an array search, 0 if all elements have already been
|
||||
returned.
|
||||
@@ -37,10 +38,10 @@ with an empty name, since the return value from
|
||||
has been completed.
|
||||
.TP
|
||||
\fBarray default \fIsubcommand arrayName args...\fR
|
||||
.VS TIP508
|
||||
.VS "8.7, 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.
|
||||
@@ -48,42 +49,43 @@ relation to non-existing array elements.
|
||||
.PP
|
||||
The \fIsubcommand\fR argument controls what exact operation will be performed
|
||||
on the default value of \fIarrayName\fR. Supported \fIsubcommand\fRs are:
|
||||
.VE TIP508
|
||||
.VE "8.7, TIP508"
|
||||
.TP
|
||||
\fBarray default exists \fIarrayName\fR
|
||||
.VS TIP508
|
||||
.VS "8.7, TIP508"
|
||||
This returns a boolean value indicating whether a default value has been set
|
||||
for the array \fIarrayName\fR. Returns a false value if \fIarrayName\fR does
|
||||
not exist. Raises an error if \fIarrayName\fR is an existing variable that is
|
||||
not an array.
|
||||
.VE TIP508
|
||||
.VE "8.7, TIP508"
|
||||
.TP
|
||||
\fBarray default get \fIarrayName\fR
|
||||
.VS TIP508
|
||||
.VS "8.7, TIP508"
|
||||
This returns the current default value for the array \fIarrayName\fR. Raises
|
||||
an error if \fIarrayName\fR is an existing variable that is not an array, or
|
||||
if \fIarrayName\fR is an array without a default value.
|
||||
.VE TIP508
|
||||
.VE "8.7, TIP508"
|
||||
.TP
|
||||
\fBarray default set \fIarrayName value\fR
|
||||
.VS TIP508
|
||||
.VS "8.7, TIP508"
|
||||
This sets the default value for the array \fIarrayName\fR to \fIvalue\fR.
|
||||
Returns the empty string. Raises an error if \fIarrayName\fR is an existing
|
||||
variable that is not an array, or if \fIarrayName\fR is an illegal name for an
|
||||
array. If \fIarrayName\fR does not currently exist, it is created as an empty
|
||||
array as well as having its default value set.
|
||||
.VE TIP508
|
||||
.VE "8.7, TIP508"
|
||||
.TP
|
||||
\fBarray default unset \fIarrayName\fR
|
||||
.VS TIP508
|
||||
.VS "8.7, TIP508"
|
||||
This removes the default value for the array \fIarrayName\fR and returns the
|
||||
empty string. Does nothing if \fIarrayName\fR does not have a default
|
||||
value. Raises an error if \fIarrayName\fR is an existing variable that is not
|
||||
an array.
|
||||
.VE TIP508
|
||||
.VE "8.7, TIP508"
|
||||
.RE
|
||||
.TP
|
||||
\fBarray donesearch \fIarrayName searchId\fR
|
||||
.
|
||||
This command terminates an array search and destroys all the
|
||||
state associated with that search. \fISearchId\fR indicates
|
||||
which search on \fIarrayName\fR to destroy, and must have
|
||||
@@ -91,10 +93,12 @@ been the return value from a previous invocation of
|
||||
\fBarray startsearch\fR. Returns an empty string.
|
||||
.TP
|
||||
\fBarray exists \fIarrayName\fR
|
||||
.
|
||||
Returns 1 if \fIarrayName\fR is an array variable, 0 if there
|
||||
is no variable by that name or if it is a scalar variable.
|
||||
.TP
|
||||
\fBarray for {\fIkeyVariable valueVariable\fB} \fIarrayName body\fP
|
||||
.VS "8.7, TIP421"
|
||||
The first argument is a two element list of variable names for the
|
||||
key and value of each entry in the array. The second argument is the
|
||||
array name to iterate over. The third argument is the body to execute
|
||||
@@ -102,8 +106,10 @@ for each key and value returned.
|
||||
The ordering of the returned keys is undefined.
|
||||
If an array element is deleted or a new array element is inserted during
|
||||
the \fIarray for\fP process, the command will terminate with an error.
|
||||
.VE "8.7, TIP421"
|
||||
.TP
|
||||
\fBarray get \fIarrayName\fR ?\fIpattern\fR?
|
||||
.
|
||||
Returns a list containing pairs of elements. The first
|
||||
element in each pair is the name of an element in \fIarrayName\fR
|
||||
and the second element of each pair is the value of the
|
||||
@@ -120,6 +126,7 @@ returned are those that exist both before and after the call to
|
||||
\fBarray get\fR.
|
||||
.TP
|
||||
\fBarray names \fIarrayName\fR ?\fImode\fR? ?\fIpattern\fR?
|
||||
.
|
||||
Returns a list containing the names of all of the elements in
|
||||
the array that match \fIpattern\fR. \fIMode\fR may be one of
|
||||
\fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR. If specified, \fImode\fR
|
||||
@@ -134,6 +141,7 @@ in the array, or if \fIarrayName\fR is not the name of an array
|
||||
variable, then an empty string is returned.
|
||||
.TP
|
||||
\fBarray nextelement \fIarrayName searchId\fR
|
||||
.
|
||||
Returns the name of the next element in \fIarrayName\fR, or
|
||||
an empty string if all elements of \fIarrayName\fR have
|
||||
already been returned in this search. The \fIsearchId\fR
|
||||
@@ -145,6 +153,7 @@ then all searches are automatically terminated just as if
|
||||
\fBarray nextelement\fR operations to fail for those searches.
|
||||
.TP
|
||||
\fBarray set \fIarrayName list\fR
|
||||
.
|
||||
Sets the values of one or more elements in \fIarrayName\fR.
|
||||
\fIlist\fR must have a form like that returned by \fBarray get\fR,
|
||||
consisting of an even number of elements.
|
||||
@@ -156,11 +165,13 @@ and \fIlist\fR is empty,
|
||||
\fIarrayName\fR is created with an empty array value.
|
||||
.TP
|
||||
\fBarray size \fIarrayName\fR
|
||||
.
|
||||
Returns a decimal string giving the number of elements in the
|
||||
array.
|
||||
If \fIarrayName\fR is not the name of an array then 0 is returned.
|
||||
.TP
|
||||
\fBarray startsearch \fIarrayName\fR
|
||||
.
|
||||
This command initializes an element-by-element search through the
|
||||
array given by \fIarrayName\fR, such that invocations of the
|
||||
\fBarray nextelement\fR command will return the names of the
|
||||
@@ -177,18 +188,31 @@ over all but very large arrays. See the examples below for how to do
|
||||
this.
|
||||
.TP
|
||||
\fBarray statistics \fIarrayName\fR
|
||||
.
|
||||
Returns statistics about the distribution of data within the hashtable
|
||||
that represents the array. This information includes the number of
|
||||
entries in the table, the number of buckets, and the utilization of
|
||||
the buckets.
|
||||
.TP
|
||||
\fBarray unset \fIarrayName\fR ?\fIpattern\fR?
|
||||
.
|
||||
Unsets all of the elements in the array that match \fIpattern\fR (using the
|
||||
matching rules of \fBstring match\fR). If \fIarrayName\fR is not the name
|
||||
of an array variable or there are no matching elements in the array, no
|
||||
error will be raised. If \fIpattern\fR is omitted and \fIarrayName\fR is
|
||||
an array variable, then the command unsets the entire array.
|
||||
The command always returns an empty string.
|
||||
.TP
|
||||
\fBarray value \fIarrayName elementName\fR ?\fIdefaultValue\fR? ?\IsaveInit\fR?
|
||||
.VS "8.7, TIP224"
|
||||
Reads the element called \fIelementName\fR of the array called
|
||||
\fIarrayName\fR and returns the value it contains. If the element does not
|
||||
exist, returns \fIdefaultValue\fR instead (this defaults to the empty
|
||||
string), ignoring the array-level default set with \fBarray default\fR. If
|
||||
\fIsaveInit\fR is specified, it must be a boolean value; if it is present and
|
||||
true, and the element was not present in the array, the \fIdefaultValue\fR is
|
||||
written to the element as well as being returned.
|
||||
.VE "8.7, TIP224"
|
||||
.SH EXAMPLES
|
||||
.CS
|
||||
\fBarray set\fR colorcount {
|
||||
|
||||
@@ -41,3 +41,7 @@ current one:
|
||||
filename(n), glob(n), pwd(n)
|
||||
.SH KEYWORDS
|
||||
working directory
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+16
-10
@@ -886,40 +886,46 @@ The \fIinputString\fR argument consists of zero or more specifications of the
|
||||
following form:
|
||||
.TP
|
||||
\fItime\fR
|
||||
A time of day, which is of the form: \fBhh?:mm?:ss?? ?meridian? ?zone?\fR
|
||||
or \fBhhmm ?meridian? ?zone?\fR
|
||||
If no meridian is specified, \fBhh\fR is interpreted on
|
||||
.
|
||||
A time of day, which is of the form:
|
||||
.QW "\fIhh\fR?\fB:\fImm\fR?\fB:\fIss\fR?? ?\fImeridian\fR? ?\fIzone\fR?"
|
||||
or
|
||||
.QW "\fBhhmm \fR?\fBmeridian\fR? ?\fBzone\fR?" .
|
||||
If no \fImeridian\fR is specified, \fIhh\fR is interpreted on
|
||||
a 24-hour clock.
|
||||
.TP
|
||||
\fIdate\fR
|
||||
.
|
||||
A specific month and day with optional year. The
|
||||
acceptable formats are
|
||||
.QW "\fBmm/dd\fR?\fB/yy\fR?" ,
|
||||
.QW "\fBmonthname dd\fR?\fB, yy\fR?" ,
|
||||
.QW "\fBday, dd monthname \fR?\fByy\fR?" ,
|
||||
.QW "\fBdd monthname yy\fR" ,
|
||||
.QW "?\fBCC\fR?\fByymmdd\fR" ,
|
||||
.QW "\fImm\fB/\fIdd\fR?\fB/\fIyy\fR?" ,
|
||||
.QW "\fImonthname dd\fR?\fB, \fIyy\fR?" ,
|
||||
.QW "\fIday\fB, \fIdd monthname \fR?\fIyy\fR?" ,
|
||||
.QW "\fIdd monthname yy\fR" ,
|
||||
.QW "?\fICC\fR?\fIyymmdd\fR" ,
|
||||
and
|
||||
.QW "\fBdd-monthname-\fR?\fBCC\fR?\fByy\fR" .
|
||||
.QW "\fIdd\fB-\fImonthname\fB-\fR?\fICC\fR?\fIyy\fR" .
|
||||
The default year is the current year. If the year is less
|
||||
than 100, we treat the years 00-68 as 2000-2068 and the years 69-99
|
||||
as 1969-1999. Not all platforms can represent the years 38-70, so
|
||||
an error may result if these years are used.
|
||||
.TP
|
||||
\fIISO 8601 point-in-time\fR
|
||||
.
|
||||
An ISO 8601 point-in-time specification, such as
|
||||
.QW \fICCyymmdd\fBT\fIhhmmss\fR,
|
||||
where \fBT\fR is the literal
|
||||
.QW T ,
|
||||
.QW "\fICCyymmdd hhmmss\fR" ,
|
||||
or
|
||||
.QW \fICCyymmdd\fBT\fIhh:mm:ss\fR .
|
||||
.QW \fICCyymmdd\fBT\fIhh\fB:\fImm\fB:\fIss\fR .
|
||||
Note that only these three formats are accepted.
|
||||
The command does \fInot\fR accept the full range of point-in-time
|
||||
specifications specified in ISO8601. Other formats can be recognized by
|
||||
giving an explicit \fB\-format\fR option to the \fBclock scan\fR command.
|
||||
.TP
|
||||
\fIrelative time\fR
|
||||
.
|
||||
A specification relative to the current time. The format is \fBnumber
|
||||
unit\fR. Acceptable units are \fByear\fR, \fBfortnight\fR,
|
||||
\fBmonth\fR, \fBweek\fR, \fBday\fR,
|
||||
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2014-2018 Donal K. Fellows.
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH "cookiejar" n 0.1 http "Tcl Bundled Packages"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
cookiejar \- Implementation of the Tcl http package cookie jar protocol
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require\fR \fBcookiejar\fR ?\fB0.1\fR?
|
||||
|
||||
\fB::http::cookiejar configure\fR ?\fIoptionName\fR? ?\fIoptionValue\fR?
|
||||
\fB::http::cookiejar create\fR \fIname\fR ?\fIfilename\fR?
|
||||
\fB::http::cookiejar new\fR ?\fIfilename\fR?
|
||||
|
||||
\fIcookiejar\fR \fBdestroy\fR
|
||||
\fIcookiejar\fR \fBforceLoadDomainData\fR
|
||||
\fIcookiejar\fR \fBgetCookies\fR \fIprotocol host path\fR
|
||||
\fIcookiejar\fR \fBstoreCookie\fR \fIoptions\fR
|
||||
\fIcookiejar\fR \fBlookup\fR ?\fIhost\fR? ?\fIkey\fR?
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The cookiejar package provides an implementation of the http package's cookie
|
||||
jar protocol using an SQLite database. It provides one main command,
|
||||
\fB::http::cookiejar\fR, which is a TclOO class that should be instantiated to
|
||||
create a cookie jar that manages a particular HTTP session.
|
||||
.PP
|
||||
The database management policy can be controlled at the package level by the
|
||||
\fBconfigure\fR method on the \fB::http::cookiejar\fR class object:
|
||||
.TP
|
||||
\fB::http::cookiejar configure\fR ?\fIoptionName\fR? ?\fIoptionValue\fR?
|
||||
.
|
||||
If neither \fIoptionName\fR nor \fIoptionValue\fR are supplied, this returns a
|
||||
copy of the configuration as a Tcl dictionary. If just \fIoptionName\fR is
|
||||
supplied, just the value of the named option is returned. If both
|
||||
\fIoptionName\fR and \fIoptionValue\fR are given, the named option is changed
|
||||
to be the given value.
|
||||
.RS
|
||||
.PP
|
||||
Supported options are:
|
||||
.TP
|
||||
\fB\-domainfile \fIfilename\fR
|
||||
.
|
||||
A file (defaulting to within the cookiejar package) with a description of the
|
||||
list of top-level domains (e.g., \fB.com\fR or \fB.co.jp\fR). Such domains
|
||||
\fImust not\fR accept cookies set upon them. Note that the list of such
|
||||
domains is both security-sensitive and \fInot\fR constant and should be
|
||||
periodically refetched. Cookie jars maintain their own cache of the domain
|
||||
list.
|
||||
.TP
|
||||
\fB\-domainlist \fIurl\fR
|
||||
.
|
||||
A URL to fetch the list of top-level domains (e.g., \fB.com\fR or
|
||||
\fB.co.jp\fR) from. Such domains \fImust not\fR accept cookies set upon
|
||||
them. Note that the list of such domains is both security-sensitive and
|
||||
\fInot\fR constant and should be periodically refetched. Cookie jars maintain
|
||||
their own cache of the domain list.
|
||||
.TP
|
||||
\fB\-domainrefresh \fIintervalMilliseconds\fR
|
||||
.
|
||||
The number of milliseconds between checks of the \fI\-domainlist\fR for new
|
||||
domains.
|
||||
.TP
|
||||
\fB\-loglevel \fIlevel\fR
|
||||
.
|
||||
The logging level of this package. The logging level must be (in order of
|
||||
decreasing verbosity) one of \fBdebug\fR, \fBinfo\fR, \fBwarn\fR, or
|
||||
\fBerror\fR.
|
||||
.TP
|
||||
\fB\-offline \fIflag\fR
|
||||
.
|
||||
Allows the cookie managment engine to be placed into offline mode. In offline
|
||||
mode, the list of domains is read immediately from the file configured in the
|
||||
\fB\-domainfile\fR option, and the \fB\-domainlist\fR option is not used; it
|
||||
also makes the \fB\-domainrefresh\fR option be effectively ignored.
|
||||
.TP
|
||||
\fB\-purgeold \fIintervalMilliseconds\fR
|
||||
.
|
||||
The number of milliseconds between checks of the database for expired
|
||||
cookies; expired cookies are deleted.
|
||||
.TP
|
||||
\fB\-retain \fIcookieCount\fR
|
||||
.
|
||||
The maximum number of cookies to retain in the database.
|
||||
.TP
|
||||
\fB\-vacuumtrigger \fIdeletionCount\fR
|
||||
.
|
||||
A count of the number of persistent cookie deletions to go between vacuuming
|
||||
the database.
|
||||
.RE
|
||||
.PP
|
||||
Cookie jar instances may be made with any of the standard TclOO instance
|
||||
creation methods (\fBcreate\fR or \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:
|
||||
+194
-80
@@ -34,7 +34,11 @@ either the \fIdefScript\fR argument or by the \fIsubcommand\fR and following
|
||||
\fIarg\fR arguments; when the second is present, it is exactly as if all the
|
||||
arguments from \fIsubcommand\fR onwards are made into a list and that list is
|
||||
used as the \fIdefScript\fR argument.
|
||||
.SS "CONFIGURING CLASSES"
|
||||
.PP
|
||||
Note that the constructor for \fBoo::class\fR will call \fBoo::define\fR on
|
||||
the script argument that it is provided. This is a convenient way to create
|
||||
and define a class in one step.
|
||||
.SH "CONFIGURING CLASSES"
|
||||
.PP
|
||||
The following commands are supported in the \fIdefScript\fR for
|
||||
\fBoo::define\fR, each of which may also be used in the \fIsubcommand\fR form:
|
||||
@@ -48,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
|
||||
@@ -70,13 +74,11 @@ namespace of the constructor will be a namespace that is unique to the object
|
||||
being constructed. Within the constructor, the \fBnext\fR command should be
|
||||
used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
|
||||
string, the constructor will be deleted.
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR?
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from a class. The methods
|
||||
must have previously existed in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified).
|
||||
.RS
|
||||
.PP
|
||||
Classes do not need to have a constructor defined. If none is specified, the
|
||||
superclass's constructor will be used instead.
|
||||
.RE
|
||||
.TP
|
||||
\fBdestructor\fI bodyScript\fR
|
||||
.
|
||||
@@ -102,16 +104,6 @@ class being defined. Note that the methods themselves may be actually defined
|
||||
by a superclass; subclass exports override superclass visibility, and may in
|
||||
turn be overridden by instances.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether
|
||||
method call to instances of the class may be called and what the method's
|
||||
results are. Each \fImethodName\fR names a single filtering method (which may
|
||||
be exposed or not exposed); it is not an error for a non-existent method to be
|
||||
named since they may be defined by subclasses.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBforward\fI name cmdName \fR?\fIarg ...\fR?
|
||||
.
|
||||
This creates or updates a forwarded method called \fIname\fR. The method is
|
||||
@@ -140,7 +132,7 @@ where the current namespace is the instance namespace of the class object
|
||||
itself. This is useful for setting up, e.g., class-scoped variables.
|
||||
.VE TIP478
|
||||
.TP
|
||||
\fBmethod\fI name argList bodyScript\fR
|
||||
\fBmethod\fI name \fR?\fIoption\fR? \fIargList bodyScript\fR
|
||||
.
|
||||
This creates or updates a method that is implemented as a procedure-like
|
||||
script. The name of the method is \fIname\fR, the formal arguments to the
|
||||
@@ -150,23 +142,20 @@ the body of the method is evaluated, the current namespace of the method will
|
||||
be a namespace that is unique to the current object. The method will be
|
||||
exported if \fIname\fR starts with a lower-case letter, and non-exported
|
||||
otherwise; this behavior can be overridden via \fBexport\fR and
|
||||
\fBunexport\fR.
|
||||
\fBunexport\fR
|
||||
.VS TIP519
|
||||
or by specifying \fB\-export\fR, \fB\-private\fR or \fB\-unexport\fR in the
|
||||
optional parameter \fIoption\fR.
|
||||
.VE TIP519
|
||||
.RS
|
||||
.PP
|
||||
.VS TIP500
|
||||
If in a private definition context (see the \fBprivate\fR definition command,
|
||||
below), this command creates private procedure-like methods.
|
||||
below) or if the \fB\-private\fR flag is given for \fIoption\fR, this command
|
||||
creates private procedure-like methods.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.TP
|
||||
\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of additional classes that are to be mixed into
|
||||
all the instances of the class being defined. Each \fIclassName\fR argument
|
||||
names a single class that is to be mixed in.
|
||||
By default, this slot works by replacement.
|
||||
.TP
|
||||
\fBprivate \fIcmd arg...\fR
|
||||
.TP
|
||||
\fBprivate \fIscript\fR
|
||||
@@ -186,16 +175,6 @@ context.
|
||||
.RE
|
||||
.VE TIP500
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
|
||||
method must have previously existed in the class, and \fItoName\fR must not
|
||||
previously refer to a method in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified). Does
|
||||
not change the export status of the method; if it was exported before, it will
|
||||
be afterwards.
|
||||
.TP
|
||||
\fBself\fI subcommand arg ...\fR
|
||||
.TP
|
||||
\fBself\fI script\fR
|
||||
@@ -269,24 +248,79 @@ namespace has a unique prefix that makes accidental use from other classes
|
||||
extremely unlikely.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.SS "CONFIGURING OBJECTS"
|
||||
.SS "ADVANCED CLASS CONFIGURATION OPTIONS"
|
||||
.PP
|
||||
The following definitions are also supported, but are not required in simple
|
||||
programs:
|
||||
.TP
|
||||
\fBdefinitionnamespace\fR ?\fIkind\fR? \fInamespaceName\fR
|
||||
.VS TIP524
|
||||
This allows control over what namespace will be used by the \fBoo::define\fR
|
||||
and \fBoo::objdefine\fR commands to look up the definition commands they
|
||||
use. When any object has a definition operation applied to it, \fIthe class that
|
||||
it is an instance of\fR (and its superclasses and mixins) is consulted for
|
||||
what definition namespace to use. \fBoo::define\fR gets the class definition
|
||||
namespace, and \fB::oo::objdefine\fR gets the instance definition namespace,
|
||||
but both otherwise use the identical lookup operation.
|
||||
.RS
|
||||
.PP
|
||||
This sets the definition namespace of kind \fIkind\fR provided by the current
|
||||
class to \fInamespaceName\fR. The \fInamespaceName\fR must refer to a
|
||||
currently existing namespace, or must be the empty string (to stop the current
|
||||
class from having such a namespace connected). The \fIkind\fR, if supplied,
|
||||
must be either \fB\-class\fR (the default) or \fB\-instance\fR to specify the
|
||||
whether the namespace for use with \fBoo::define\fR or \fBoo::objdefine\fR
|
||||
respectively is being set.
|
||||
.PP
|
||||
The class \fBoo::object\fR has its instance namespace locked to
|
||||
\fB::oo::objdefine\fR, and the class \fBoo::class\fR has its class namespace
|
||||
locked to \fB::oo::define\fR. A consequence of this is that effective use of
|
||||
this feature for classes requires the definition of a metaclass.
|
||||
.RE
|
||||
.VE TIP524
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR?
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from a class. The methods
|
||||
must have previously existed in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified) or the
|
||||
class object itself.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether
|
||||
method call to instances of the class may be called and what the method's
|
||||
results are. Each \fImethodName\fR names a single filtering method (which may
|
||||
be exposed or not exposed); it is not an error for a non-existent method to be
|
||||
named since they may be defined by subclasses.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of additional classes that are to be mixed into
|
||||
all the instances of the class being defined. Each \fIclassName\fR argument
|
||||
names a single class that is to be mixed in.
|
||||
By default, this slot works by replacement.
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
|
||||
method must have previously existed in the class, and \fItoName\fR must not
|
||||
previously refer to a method in that class. Does not affect the superclasses
|
||||
of the class, nor does it affect the subclasses or instances of the class
|
||||
(except when they have a call chain through the class being modified), 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"
|
||||
.PP
|
||||
The following commands are supported in the \fIdefScript\fR for
|
||||
\fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR
|
||||
form:
|
||||
.TP
|
||||
\fBclass\fI className\fR
|
||||
.
|
||||
This allows the class of an object to be changed after creation. Note that the
|
||||
class's constructors are not called when this is done, and so the object may
|
||||
well be in an inconsistent state unless additional configuration work is done.
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from an object. The methods
|
||||
must have previously existed in that object. Does not affect the classes that
|
||||
the object is an instance of.
|
||||
.TP
|
||||
\fBexport\fI name \fR?\fIname ...\fR?
|
||||
.
|
||||
This arranges for each of the named methods, \fIname\fR, to be exported
|
||||
@@ -294,17 +328,6 @@ This arranges for each of the named methods, \fIname\fR, to be exported
|
||||
being defined. Note that the methods themselves may be actually defined by a
|
||||
class or superclass; object exports override class visibility.
|
||||
.TP
|
||||
\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether a
|
||||
method call to the object may be called and what the method's results are.
|
||||
Each \fImethodName\fR names a single filtering method (which may be exposed or
|
||||
not exposed); it is not an error for a non-existent method to be named. Note
|
||||
that the actual list of filters also depends on the filters set upon any
|
||||
classes that the object is an instance of.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBforward\fI name cmdName \fR?\fIarg ...\fR?
|
||||
.
|
||||
This creates or updates a forwarded object method called \fIname\fR. The
|
||||
@@ -321,7 +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
|
||||
@@ -329,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
|
||||
@@ -363,19 +392,6 @@ difference in behavior when used in a private definition context.
|
||||
.RE
|
||||
.VE TIP500
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in an object to \fItoName\fR.
|
||||
The method must have previously existed in the object, and \fItoName\fR must
|
||||
not previously refer to a method in that object. Does not affect the classes
|
||||
that the object is an instance of. Does not change the export status of the
|
||||
method; if it was exported before, it will be afterwards.
|
||||
.TP
|
||||
\fBself \fR
|
||||
.VS TIP470
|
||||
This gives the name of the object currently being configured.
|
||||
.VE TIP470
|
||||
.TP
|
||||
\fBunexport\fI name \fR?\fIname ...\fR?
|
||||
.
|
||||
This arranges for each of the named methods, \fIname\fR, to be not exported
|
||||
@@ -408,6 +424,50 @@ instance namespace has a unique prefix that makes accidental use from
|
||||
superclass methods extremely unlikely.
|
||||
.VE TIP500
|
||||
.RE
|
||||
.SS "ADVANCED OBJECT CONFIGURATION OPTIONS"
|
||||
.PP
|
||||
The following definitions are also supported, but are not required in simple
|
||||
programs:
|
||||
.TP
|
||||
\fBclass\fI className\fR
|
||||
.
|
||||
This allows the class of an object to be changed after creation. Note that the
|
||||
class's constructors are not called when this is done, and so the object may
|
||||
well be in an inconsistent state unless additional configuration work is done.
|
||||
.TP
|
||||
\fBdeletemethod\fI name\fR ?\fIname ...\fR
|
||||
.
|
||||
This deletes each of the methods called \fIname\fR from an object. The methods
|
||||
must have previously existed in that object (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?
|
||||
.
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
sets or updates the list of method names that are used to guard whether a
|
||||
method call to the object may be called and what the method's results are.
|
||||
Each \fImethodName\fR names a single filtering method (which may be exposed or
|
||||
not exposed); it is not an error for a non-existent method to be named. Note
|
||||
that the actual list of filters also depends on the filters set upon any
|
||||
classes that the object is an instance of.
|
||||
By default, this slot works by appending.
|
||||
.TP
|
||||
\fBrenamemethod\fI fromName toName\fR
|
||||
.
|
||||
This renames the method called \fIfromName\fR in an object to \fItoName\fR.
|
||||
The method must have previously existed in the object, and \fItoName\fR must
|
||||
not previously refer to a method in that object. Does not affect the classes
|
||||
that the object is an instance of 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
|
||||
This gives the name of the object currently being configured.
|
||||
.VE TIP470
|
||||
.SH "PRIVATE METHODS"
|
||||
.VS TIP500
|
||||
When a class or instance has a private method, that private method can only be
|
||||
@@ -659,6 +719,60 @@ $g update "emailaddress=admins"
|
||||
\fI\(-> DB: update row ::oo::Obj125 with emailaddress=admins\fR
|
||||
.CE
|
||||
.VE TIP478
|
||||
.PP
|
||||
.VS TIP524
|
||||
This example shows how to make a custom definition for a class. Note that it
|
||||
explicitly includes delegation to the existing definition commands via
|
||||
\fBnamespace path\fR.
|
||||
.PP
|
||||
.CS
|
||||
namespace eval myDefinitions {
|
||||
# Delegate to existing definitions where not overridden
|
||||
namespace path \fB::oo::define\fR
|
||||
|
||||
# A custom type of method
|
||||
proc exprmethod {name arguments body} {
|
||||
tailcall \fBmethod\fR $name $arguments [list expr $body]
|
||||
}
|
||||
|
||||
# A custom way of building a constructor
|
||||
proc parameters args {
|
||||
uplevel 1 [list \fBvariable\fR {*}$args]
|
||||
set body [join [lmap a $args {
|
||||
string map [list VAR $a] {
|
||||
set [my varname VAR] [expr {double($VAR)}]
|
||||
}
|
||||
}] ";"]
|
||||
tailcall \fBconstructor\fR $args $body
|
||||
}
|
||||
}
|
||||
|
||||
# Bind the namespace into a (very simple) metaclass for use
|
||||
oo::class create exprclass {
|
||||
\fBsuperclass\fR oo::class
|
||||
\fBdefinitionnamespace\fR myDefinitions
|
||||
}
|
||||
|
||||
# Use the custom definitions
|
||||
exprclass create quadratic {
|
||||
parameters a b c
|
||||
exprmethod evaluate {x} {
|
||||
($a * $x**2) + ($b * $x) + $c
|
||||
}
|
||||
}
|
||||
|
||||
# Showing the resulting class and object in action
|
||||
quadratic create quad 1 2 3
|
||||
for {set x 0} {$x <= 4} {incr x} {
|
||||
puts [format "quad(%d) = %.2f" $x [quad evaluate $x]]
|
||||
}
|
||||
\fI\(-> quad(0) = 3.00\fR
|
||||
\fI\(-> quad(1) = 6.00\fR
|
||||
\fI\(-> quad(2) = 11.00\fR
|
||||
\fI\(-> quad(3) = 18.00\fR
|
||||
\fI\(-> quad(4) = 27.00\fR
|
||||
.CE
|
||||
.VE TIP524
|
||||
.SH "SEE ALSO"
|
||||
next(n), oo::class(n), oo::object(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
@@ -59,3 +59,7 @@ while {1} {
|
||||
file(n), open(n), close(n), fblocked(n), Tcl_StandardChannels(3)
|
||||
.SH KEYWORDS
|
||||
channel, end of file
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -49,3 +49,7 @@ if {[catch {main} msg options]} {
|
||||
exec(n)
|
||||
.SH KEYWORDS
|
||||
abort, exit, process
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+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
|
||||
.
|
||||
|
||||
@@ -65,3 +65,7 @@ vwait forever
|
||||
gets(n), open(n), read(n), socket(n), Tcl_StandardChannels(3)
|
||||
.SH KEYWORDS
|
||||
blocking, nonblocking
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -154,3 +154,7 @@ fconfigure(n), gets(n), interp(n), puts(n), read(n), Tcl_StandardChannels(3)
|
||||
.SH KEYWORDS
|
||||
asynchronous I/O, blocking, channel, event handler, nonblocking, readable,
|
||||
script, writable.
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -176,3 +176,7 @@ file(n), glob(n)
|
||||
.SH KEYWORDS
|
||||
current directory, absolute file name, relative file name,
|
||||
volume-relative file name, portability
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -43,3 +43,7 @@ puts "Hello there, $name!"
|
||||
file(n), open(n), socket(n), Tcl_StandardChannels(3)
|
||||
.SH KEYWORDS
|
||||
blocking, buffer, channel, flush, nonblocking, output
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -102,3 +102,7 @@ for(n), while(n), break(n), continue(n)
|
||||
|
||||
.SH KEYWORDS
|
||||
foreach, iteration, list, loop
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -56,3 +56,7 @@ proc accum {string} {
|
||||
namespace(n), upvar(n), variable(n)
|
||||
.SH KEYWORDS
|
||||
global, namespace, procedure, variable
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -100,3 +100,7 @@ the \fBevent\fR operation to retrieve some event,
|
||||
and the \fBadd\fR operation to add it to history and execute it.
|
||||
.SH KEYWORDS
|
||||
event, history, record
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+113
-2
@@ -13,10 +13,10 @@
|
||||
.SH NAME
|
||||
http \- Client-side implementation of the HTTP/1.1 protocol
|
||||
.SH SYNOPSIS
|
||||
\fBpackage require http ?2.8?\fR
|
||||
\fBpackage require http\fI ?\fB2.8\fR?
|
||||
.\" See Also -useragent option documentation in body!
|
||||
.sp
|
||||
\fB::http::config ?\fI\-option value\fR ...?
|
||||
\fB::http::config\fR ?\fI\-option value\fR ...?
|
||||
.sp
|
||||
\fB::http::geturl \fIurl\fR ?\fI\-option value\fR ...?
|
||||
.sp
|
||||
@@ -99,6 +99,15 @@ comma-separated list of mime type patterns that you are
|
||||
willing to receive. For example,
|
||||
.QW "image/gif, image/jpeg, text/*" .
|
||||
.TP
|
||||
\fB\-cookiejar\fR \fIcommand\fR
|
||||
.VS TIP406
|
||||
The cookie store for the package to use to manage HTTP cookies.
|
||||
\fIcommand\fR is a command prefix list; if the empty list (the
|
||||
default value) is used, no cookies will be sent by requests or stored
|
||||
from responses. The command indicated by \fIcommand\fR, if supplied,
|
||||
must obey the \fBCOOKIE JAR PROTOCOL\fR described below.
|
||||
.VE TIP406
|
||||
.TP
|
||||
\fB\-pipeline\fR \fIboolean\fR
|
||||
.
|
||||
Specifies whether HTTP/1.1 transactions on a persistent socket will be
|
||||
@@ -770,6 +779,108 @@ Subsequent GET and HEAD requests in a failed pipeline will also be retried.
|
||||
that the retry is appropriate\fR - specifically, the application must know
|
||||
that if the failed POST successfully modified the state of the server, a repeat POST
|
||||
would have no adverse effect.
|
||||
.VS TIP406
|
||||
.SH "COOKIE JAR PROTOCOL"
|
||||
.PP
|
||||
Cookies are short key-value pairs used to implement sessions within the
|
||||
otherwise-stateless HTTP protocol. (See RFC 6265 for details; Tcl does not
|
||||
implement the Cookie2 protocol as that is rarely seen in the wild.)
|
||||
.PP
|
||||
Cookie storage managment commands \(em
|
||||
.QW "cookie jars"
|
||||
\(em must support these subcommands which form the HTTP cookie storage
|
||||
management protocol. Note that \fIcookieJar\fR below does not have to be a
|
||||
command name; it is properly a command prefix (a Tcl list of words that will
|
||||
be expanded in place) and admits many possible implementations.
|
||||
.PP
|
||||
Though not formally part of the protocol, it is expected that particular
|
||||
values of \fIcookieJar\fR will correspond to sessions; it is up to the caller
|
||||
of \fB::http::config\fR to decide what session applies and to manage the
|
||||
deletion of said sessions when they are no longer desired (which should be
|
||||
when they not configured as the current cookie jar).
|
||||
.TP
|
||||
\fIcookieJar \fBgetCookies \fIprotocol host requestPath\fR
|
||||
.
|
||||
This command asks the cookie jar what cookies should be supplied for a
|
||||
particular request. It should take the \fIprotocol\fR (typically \fBhttp\fR or
|
||||
\fBhttps\fR), \fIhost\fR name and \fIrequestPath\fR (parsed from the \fIurl\fR
|
||||
argument to \fB::http::geturl\fR) and return a list of cookie keys and values
|
||||
that describe the cookies to supply to the remote host. The list must have an
|
||||
even number of elements.
|
||||
.RS
|
||||
.PP
|
||||
There should only ever be at most one cookie with a particular key for any
|
||||
request (typically the one with the most specific \fIhost\fR/domain match and
|
||||
most specific \fIrequestPath\fR/path match), but there may be many cookies
|
||||
with different names in any request.
|
||||
.RE
|
||||
.TP
|
||||
\fIcookieJar \fBstoreCookie \fIcookieDictionary\fR
|
||||
.
|
||||
This command asks the cookie jar to store a particular cookie that was
|
||||
returned by a request; the result of this command is ignored. The cookie
|
||||
(which will have been parsed by the http package) is described by a
|
||||
dictionary, \fIcookieDictionary\fR, that may have the following keys:
|
||||
.RS
|
||||
.TP
|
||||
\fBdomain\fR
|
||||
.
|
||||
This is always present. Its value describes the domain hostname \fIor
|
||||
prefix\fR that the cookie should be returned for. The checking of the domain
|
||||
against the origin (below) should be careful since sites that issue cookies
|
||||
should only do so for domains related to themselves. Cookies that do not obey
|
||||
a relevant origin matching rule should be ignored.
|
||||
.TP
|
||||
\fBexpires\fR
|
||||
.
|
||||
This is optional. If present, the cookie is intended to be a persistent cookie
|
||||
and the value of the option is the Tcl timestamp (in seconds from the same
|
||||
base as \fBclock seconds\fR) of when the cookie expires (which may be in the
|
||||
past, which should result in the cookie being deleted immediately). If absent,
|
||||
the cookie is intended to be a session cookie that should be not persisted
|
||||
beyond the lifetime of the cookie jar.
|
||||
.TP
|
||||
\fBhostonly\fR
|
||||
.
|
||||
This is always present. Its value is a boolean that describes whether the
|
||||
cookie is a single host cookie (true) or a domain-level cookie (false).
|
||||
.TP
|
||||
\fBhttponly\fR
|
||||
.
|
||||
This is always present. Its value is a boolean that is true when the site
|
||||
wishes the cookie to only ever be used with HTTP (or HTTPS) traffic.
|
||||
.TP
|
||||
\fBkey\fR
|
||||
.
|
||||
This is always present. Its value is the \fIkey\fR of the cookie, which is
|
||||
part of the information that must be return when sending this cookie back in a
|
||||
future request.
|
||||
.TP
|
||||
\fBorigin\fR
|
||||
.
|
||||
This is always present. Its value describes where the http package believes it
|
||||
received the cookie from, which may be useful for checking whether the
|
||||
cookie's domain is valid.
|
||||
.TP
|
||||
\fBpath\fR
|
||||
.
|
||||
This is always present. Its value describes the path prefix of requests to the
|
||||
cookie domain where the cookie should be returned.
|
||||
.TP
|
||||
\fBsecure\fR
|
||||
.
|
||||
This is always present. Its value is a boolean that is true when the cookie
|
||||
should only used on requests sent over secure channels (typically HTTPS).
|
||||
.TP
|
||||
\fBvalue\fR
|
||||
.
|
||||
This is always present. Its value is the value of the cookie, which is part of
|
||||
the information that must be return when sending this cookie back in a future
|
||||
request.
|
||||
.PP
|
||||
Other keys may always be ignored; they have no meaning in this protocol.
|
||||
.RE
|
||||
.VE TIP406
|
||||
.SH EXAMPLE
|
||||
.PP
|
||||
This example creates a procedure to copy a URL to a file while printing a
|
||||
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2014-2018 Donal K. Fellows.
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH "idna" n 0.1 http "Tcl Bundled Packages"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
tcl::idna \- Support for normalization of Internationalized Domain Names
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
package require tcl::idna 1.0
|
||||
|
||||
\fBtcl::idna decode\fR \fIhostname\fR
|
||||
\fBtcl::idna encode\fR \fIhostname\fR
|
||||
\fBtcl::idna puny decode\fR \fIstring\fR ?\fIcase\fR?
|
||||
\fBtcl::idna puny encode\fR \fIstring\fR ?\fIcase\fR?
|
||||
\fBtcl::idna version\fR
|
||||
.fi
|
||||
.SH DESCRIPTION
|
||||
This package provides an implementation of the punycode scheme used in
|
||||
Internationalised Domain Names, and some access commands. (See RFC 3492 for a
|
||||
description of punycode.)
|
||||
.TP
|
||||
\fBtcl::idna decode\fR \fIhostname\fR
|
||||
.
|
||||
This command takes the name of a host that potentially contains
|
||||
punycode-encoded character sequences, \fIhostname\fR, and returns the hostname
|
||||
as might be displayed to the user. Note that there are often UNICODE
|
||||
characters that have extremely similar glyphs, so care should be taken with
|
||||
displaying hostnames to users.
|
||||
.TP
|
||||
\fBtcl::idna encode\fR \fIhostname\fR
|
||||
.
|
||||
This command takes the name of a host as might be displayed to the user,
|
||||
\fIhostname\fR, and returns the version of the hostname with characters not
|
||||
permitted in basic hostnames encoded with punycode.
|
||||
.TP
|
||||
\fBtcl::idna puny\fR \fIsubcommand ...\fR
|
||||
.
|
||||
This command provides direct access to the basic punycode encoder and
|
||||
decoder. It supports two \fIsubcommand\fRs:
|
||||
.RS
|
||||
.TP
|
||||
\fBtcl::idna puny decode\fR \fIstring\fR ?\fIcase\fR?
|
||||
.
|
||||
This command decodes the punycode-encoded string, \fIstring\fR, and returns
|
||||
the result. If \fIcase\fR is provided, it is a boolean to make the case be
|
||||
folded to upper case (if \fIcase\fR is true) or lower case (if \fIcase\fR is
|
||||
false) during the decoding process; if omitted, no case transformation is
|
||||
applied.
|
||||
.TP
|
||||
\fBtcl::idna puny encode\fR \fIstring\fR ?\fIcase\fR?
|
||||
.
|
||||
This command encodes the string, \fIstring\fR, and returns the
|
||||
punycode-encoded version of the string. If \fIcase\fR is provided, it is a
|
||||
boolean to make the case be folded to upper case (if \fIcase\fR is true) or
|
||||
lower case (if \fIcase\fR is false) during the encoding process; if omitted,
|
||||
no case transformation is applied.
|
||||
.RE
|
||||
.TP
|
||||
\fBtcl::idna version\fR
|
||||
.
|
||||
This returns the version of the \fBtcl::idna\fR package.
|
||||
.SH "EXAMPLE"
|
||||
.PP
|
||||
This is an example of how punycoding of a string works:
|
||||
.PP
|
||||
.CS
|
||||
package require tcl::idna
|
||||
|
||||
puts [\fBtcl::idna puny encode\fR "abc\(->def"]
|
||||
# prints: \fIabcdef-kn2c\fR
|
||||
puts [\fBtcl::idna puny decode\fR "abcdef-kn2c"]
|
||||
# prints: \fIabc\(->def\fR
|
||||
.CE
|
||||
'\" TODO: show how it handles a real domain name
|
||||
.SH "SEE ALSO"
|
||||
http(n), cookiejar(n)
|
||||
.SH KEYWORDS
|
||||
internet, www
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
+164
-236
@@ -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:
|
||||
@@ -481,6 +391,24 @@ list; the first element is the list of arguments to the method in a form
|
||||
suitable for passing to another call to \fBproc\fR or a method definition, and
|
||||
the second element is the body of the method.
|
||||
.TP
|
||||
\fBinfo class definitionnamespace\fI class\fR ?\fIkind\fR?
|
||||
.VS TIP524
|
||||
This subcommand returns the definition namespace for \fIkind\fR definitions of
|
||||
the class \fIclass\fR; the definition namespace only affects the instances of
|
||||
\fIclass\fR, not \fIclass\fR itself. The \fIkind\fR can be either
|
||||
\fB\-class\fR to return the definition namespace used for \fBoo::define\fR, or
|
||||
\fB\-instance\fR to return the definition namespace used for
|
||||
\fBoo::objdefine\fR; the \fB\-class\fR kind is default (though this is only
|
||||
actually useful on classes that are subclasses of \fBoo::class\fR).
|
||||
.RS
|
||||
.PP
|
||||
If \fIclass\fR does not provide a definition namespace of the 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.
|
||||
.RE
|
||||
.VE TIP524
|
||||
.TP
|
||||
\fBinfo class destructor\fI class\fR
|
||||
.
|
||||
This subcommand returns the body of the destructor of class \fIclass\fR. If no
|
||||
@@ -505,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
|
||||
@@ -582,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"
|
||||
@@ -620,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
|
||||
@@ -689,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
|
||||
@@ -759,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
|
||||
|
||||
+2
-2
@@ -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
|
||||
@@ -236,7 +236,7 @@ attempts are silently ignored. This is needed to maintain the
|
||||
consistency of the underlying interpreter's state.
|
||||
.RE
|
||||
.TP
|
||||
\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
|
||||
\fBinterp\fR \fBdelete \fR?\fIpath ...\fR?
|
||||
.
|
||||
Deletes zero or more interpreters given by the optional \fIpath\fR
|
||||
arguments, and for each interpreter, it also deletes its slaves. The
|
||||
|
||||
@@ -42,3 +42,7 @@ set data {1 {2 3} 4 {5 {6 7} 8}}
|
||||
list(n), lappend(n), split(n)
|
||||
.SH KEYWORDS
|
||||
element, join, list, separator
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
.SH NAME
|
||||
lindex \- Retrieve an element from a list
|
||||
.SH SYNOPSIS
|
||||
\fBlindex \fIlist ?index ...?\fR
|
||||
\fBlindex \fIlist\fR ?\fIindex ...\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
|
||||
@@ -53,3 +53,7 @@ list(n), lappend(n), lindex(n), linsert(n), lsearch(n),
|
||||
lset(n), lsort(n), lrange(n), lreplace(n)
|
||||
.SH KEYWORDS
|
||||
element, list, length
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+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:
|
||||
@@ -76,3 +76,7 @@ lset(n), lreplace(n), lsort(n),
|
||||
string(n)
|
||||
.SH KEYWORDS
|
||||
element, list, range, sublist
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+4
-1
@@ -33,6 +33,9 @@ is identical to \fBlist element ...\fR.
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
list(n), lappend(n), linsert(n), llength(n), lset(n)
|
||||
|
||||
.SH KEYWORDS
|
||||
element, index, list
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+12
-22
@@ -17,7 +17,7 @@ lreplace \- Replace elements in a list with new elements
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fBlreplace\fR returns a new list formed by replacing one or more elements of
|
||||
\fBlreplace\fR returns a new list formed by replacing zero or more elements of
|
||||
\fIlist\fR with the \fIelement\fR arguments.
|
||||
\fIfirst\fR and \fIlast\fR are index values specifying the first and
|
||||
last elements of the range to replace.
|
||||
@@ -27,36 +27,26 @@ supporting simple index arithmetic and indices relative to the
|
||||
end of the list.
|
||||
0 refers to the first element of the
|
||||
list, and \fBend\fR refers to the last element of the list.
|
||||
If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored.
|
||||
.PP
|
||||
If \fIfirst\fR is less than zero, it is considered to refer to before the
|
||||
first element of the list.
|
||||
If either \fIfirst\fR or \fIlast\fR is less than zero, it is considered
|
||||
to refer to before the first element of the list. This allows \fBlreplace\fR
|
||||
to prepend elements to \fIlist\fR.
|
||||
.VS TIP505
|
||||
If \fIfirst\fR indicates a position greater than the index of the last element
|
||||
of the list, it is treated as if it is an index one greater than the last
|
||||
element. This allows this command to append elements to the list.
|
||||
If either \fIfirst\fR or \fIlast\fR indicates a position greater than the
|
||||
index of the last element of the list, it is treated as if it is an
|
||||
index one greater than the last element. This allows \fBlreplace\fR to
|
||||
append elements to \fIlist\fR.
|
||||
.VE TIP505
|
||||
For non-empty lists, the element indicated
|
||||
by \fIfirst\fR must exist, or \fIfirst\fR must indicate before the
|
||||
start of the list.
|
||||
.PP
|
||||
If \fIlast\fR is less than \fIfirst\fR, then any specified elements
|
||||
will be inserted into the list before the point specified by \fIfirst\fR
|
||||
will be inserted into the list before the element specified by \fIfirst\fR
|
||||
with no elements being deleted.
|
||||
.VS TIP505
|
||||
If \fIlast\fR is greater than the index of the last item of the list, it is
|
||||
treated as if it is an index one greater than the last element. This means
|
||||
that if it is also greater than than \fIfirst\fR, all elements from
|
||||
\fIfirst\fR to the end of the list will be replaced, and otherwise the
|
||||
elements will be appended.
|
||||
.VE TIP505
|
||||
.PP
|
||||
The \fIelement\fR arguments specify zero or more new arguments to
|
||||
The \fIelement\fR arguments specify zero or more new elements to
|
||||
be added to the list in place of those that were deleted.
|
||||
Each \fIelement\fR argument will become a separate element of
|
||||
the list. If no \fIelement\fR arguments are specified, then the elements
|
||||
between \fIfirst\fR and \fIlast\fR are simply deleted. If \fIlist\fR
|
||||
is empty, any \fIelement\fR arguments are added to the end of the list.
|
||||
between \fIfirst\fR and \fIlast\fR are simply deleted.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
Replacing an element of a list with another:
|
||||
@@ -93,7 +83,7 @@ proc lremove {listVariable value} {
|
||||
.CE
|
||||
.PP
|
||||
.VS TIP505
|
||||
Adding elements to the end of the list; note that \fBend+2\fR will initially
|
||||
Appending elements to the list; note that \fBend+2\fR will initially
|
||||
be treated as if it is \fB6\fR here, but both that and \fB12345\fR are greater
|
||||
than the index of the final item so they behave identically:
|
||||
.PP
|
||||
|
||||
+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
|
||||
|
||||
@@ -48,3 +48,7 @@ At least one \fB\-load\fR or \fB\-source\fR parameter must be given.
|
||||
package(n)
|
||||
.SH KEYWORDS
|
||||
auto-load, index, package, version
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -43,6 +43,9 @@ close $pipeline
|
||||
|
||||
.SH "SEE ALSO"
|
||||
exec(n), open(n)
|
||||
|
||||
.SH KEYWORDS
|
||||
file, pipeline, process identifier
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
platform \- System identification support code and utilities
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require platform ?1.0.10?\fR
|
||||
\fBpackage require platform\fR ?\fB1.0.10\fR?
|
||||
.sp
|
||||
\fBplatform::generic\fR
|
||||
\fBplatform::identify\fR
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
platform::shell \- System identification support code and utilities
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require platform::shell ?1.1.4?\fR
|
||||
\fBpackage require platform::shell\fR ?\fB1.1.4\fR?
|
||||
.sp
|
||||
\fBplatform::shell::generic \fIshell\fR
|
||||
\fBplatform::shell::identify \fIshell\fR
|
||||
@@ -55,3 +55,7 @@ This command returns the contents of \fBtcl_platform(platform)\fR for
|
||||
the specified Tcl shell.
|
||||
.SH KEYWORDS
|
||||
operating system, cpu architecture, platform, architecture
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+6
-6
@@ -12,9 +12,9 @@
|
||||
tcl::prefix \- facilities for prefix matching
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix match\fR \fI?option ...?\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix all\fR \fItable string\fR
|
||||
\fB::tcl::prefix longest\fR \fItable string\fR
|
||||
\fB::tcl::prefix match\fR ?\fIoption ...\fR? \fItable string\fR
|
||||
.fi
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
@@ -22,17 +22,17 @@ tcl::prefix \- facilities for prefix matching
|
||||
This document describes commands looking up a prefix in a list of strings.
|
||||
The following commands are supported:
|
||||
.TP
|
||||
\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix all\fR \fItable string\fR
|
||||
.
|
||||
Returns a list of all elements in \fItable\fR that begin with the prefix
|
||||
\fIstring\fR.
|
||||
.TP
|
||||
\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix longest\fR \fItable string\fR
|
||||
.
|
||||
Returns the longest common prefix of all elements in \fItable\fR that
|
||||
begin with the prefix \fIstring\fR.
|
||||
.TP
|
||||
\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable\fR \fIstring\fR
|
||||
\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable string\fR
|
||||
.
|
||||
If \fIstring\fR equals one element in \fItable\fR or is a prefix to exactly
|
||||
one element, the matched element is returned. If not, the result depends
|
||||
|
||||
+54
-35
@@ -16,11 +16,31 @@ tcl::process \- Subprocess management
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This command provides a way to manage subprocesses created by the \fBopen\fR
|
||||
and \fBexec\fR commands. The legal \fIoptions\fR (which may be abbreviated) are:
|
||||
and \fBexec\fR commands, as identified by the process identifiers (PIDs) of
|
||||
those subprocesses. The legal \fIoptions\fR (which may be abbreviated) are:
|
||||
.TP
|
||||
\fB::tcl::process autopurge\fR ?\fIflag\fR?
|
||||
.
|
||||
Automatic purge facility. If \fIflag\fR is specified as a boolean value then
|
||||
it activates or deactivate autopurge. In all cases it returns the current
|
||||
status as a boolean value. When autopurge is active,
|
||||
\fBTcl_ReapDetachedProcs\fR is called each time the \fBexec\fR command is
|
||||
executed or a pipe channel created by \fBopen\fR is closed. When autopurge is
|
||||
inactive, \fB::tcl::process\fR purge must be called explicitly. By default
|
||||
autopurge is active.
|
||||
.TP
|
||||
\fB::tcl::process list\fR
|
||||
.
|
||||
Returns the list of subprocess PIDs.
|
||||
Returns the list of subprocess PIDs. This includes all currently executing
|
||||
subprocesses and all terminated subprocesses that have not yet had their
|
||||
corresponding process table entries purged.
|
||||
.TP
|
||||
\fB::tcl::process purge\fR ?\fIpids\fR?
|
||||
.
|
||||
Cleans up all data associated with terminated subprocesses. If \fIpids\fR is
|
||||
specified as a list of PIDs then the command only cleanup data for the matching
|
||||
subprocesses if they exist, and raises an error otherwise. If a process listed is
|
||||
still active, this command does nothing to that process.
|
||||
.TP
|
||||
\fB::tcl::process status\fR ?\fIswitches\fR? ?\fIpids\fR?
|
||||
.
|
||||
@@ -29,62 +49,48 @@ Returns a dictionary mapping subprocess PIDs to their respective status. If
|
||||
status of the matching subprocesses if they exist, and raises an error
|
||||
otherwise. For active processes, the status is an empty value. For terminated
|
||||
processes, the status is a list with the following format:
|
||||
.QW "{code ?\fImsg errorCode\fR?}" ,
|
||||
.QW "\fB{\fIcode\fR ?\fImsg errorCode\fR?\fB}\fR" ,
|
||||
where:
|
||||
.RS
|
||||
.TP
|
||||
\fBcode\fR\0
|
||||
\fIcode\fR\0
|
||||
.
|
||||
is a standard Tcl return code,
|
||||
is a standard Tcl return code, i.e., \fB0\fR for TCL_OK and \fB1\fR
|
||||
for TCL_ERROR,
|
||||
.TP
|
||||
\fBmsg\fR\0
|
||||
\fImsg\fR\0
|
||||
.
|
||||
is the human-readable error message,
|
||||
.TP
|
||||
\fBerrorCode\fR\0
|
||||
\fIerrorCode\fR\0
|
||||
.
|
||||
uses the same format as the \fBerrorCode\fR global variable
|
||||
.RE
|
||||
.PP
|
||||
Note that \fBmsg\fR and \fBerrorCode\fR are only present for abnormally
|
||||
terminated processes (i.e. those where \fBcode\fR is nonzero). Under the hood
|
||||
this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for
|
||||
terminated processes (i.e. those where the \fIcode\fR is nonzero). Under the
|
||||
hood this command calls \fBTcl_WaitPid\fR with the \fBWNOHANG\fR flag set for
|
||||
non-blocking behavior, unless the \fB\-wait\fR switch is set (see below).
|
||||
.RS
|
||||
.PP
|
||||
Additionally, \fB::tcl::process status\fR accepts the following switches:
|
||||
.TP
|
||||
\fB\-wait\fR\0
|
||||
.
|
||||
By default the command returns immediately (the underlying \fBTcl_WaitPid\fR is
|
||||
called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fBpids\fR
|
||||
called with the \fBWNOHANG\fR flag set) unless this switch is set. If \fIpids\fR
|
||||
is specified as a list of PIDs then the command waits until the status of the
|
||||
matching subprocesses are available. If \fBpids\fR is not specified then it
|
||||
waits for all known subprocesses.
|
||||
matching subprocesses are available. If \fIpids\fR was not specified, this
|
||||
command will wait for all known subprocesses.
|
||||
.TP
|
||||
\fB\-\|\-\fR
|
||||
.
|
||||
Marks the end of switches. The argument following this one will
|
||||
be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
|
||||
.RE
|
||||
.TP
|
||||
\fB::tcl::process purge ?\fIpids\fR?
|
||||
.
|
||||
Cleans up all data associated with terminated subprocesses. If \fBpids\fR is
|
||||
specified as a list of PIDs then the command only cleanup data for the matching
|
||||
subprocesses if they exist, and raises an error otherwise. If the process is
|
||||
still active then it does nothing.
|
||||
.TP
|
||||
\fB::tcl::process autopurge ?\fIflag\fR?
|
||||
.
|
||||
Automatic purge facility. If \fBflag\fR is specified as a boolean value then it
|
||||
activates or deactivate autopurge. In all cases it returns the current status as
|
||||
a boolean value. When autopurge is active, \fBTcl_ReapDetachedProcs\fR is called
|
||||
each time the exec command is executed or a pipe channel created by open is
|
||||
closed. When autopurge is inactive, \fB::tcl::process\fR purge must be called
|
||||
explicitly. By default autopurge is active.
|
||||
.RE
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
These show the use of \fB::tcl::process\fR. Some of the results from
|
||||
\fB::tcl::process status\fR are split over multiple lines for readability.
|
||||
.PP
|
||||
.CS
|
||||
\fB::tcl::process autopurge\fR
|
||||
\fI\(-> true\fR
|
||||
@@ -102,7 +108,12 @@ set pid2 [pid $chan]
|
||||
\fI\(-> 123 456 789 1011\fR
|
||||
|
||||
\fB::tcl::process status\fR
|
||||
\fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {}\fR
|
||||
\fI\(-> 123 0
|
||||
456 {1 "child killed: write on pipe with no readers" {
|
||||
CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}}
|
||||
789 {1 "child suspended: background tty read" {
|
||||
CHILDSUSP 789 SIGTTIN "background tty read"}}
|
||||
1011 {}\fR
|
||||
|
||||
\fB::tcl::process status\fR 123
|
||||
\fI\(-> 123 0\fR
|
||||
@@ -111,10 +122,17 @@ set pid2 [pid $chan]
|
||||
\fI\(-> 1011 {}\fR
|
||||
|
||||
\fB::tcl::process status\fR -wait
|
||||
\fI\(-> 123 0 456 {1 "child killed: write on pipe with no readers" {CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}} 789 {1 "child suspended: background tty read" {CHILDSUSP 789 SIGTTIN "background tty read"}} 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR
|
||||
\fI\(-> 123 0
|
||||
456 {1 "child killed: write on pipe with no readers" {
|
||||
CHILDKILLED 456 SIGPIPE "write on pipe with no readers"}}
|
||||
789 {1 "child suspended: background tty read" {
|
||||
CHILDSUSP 789 SIGTTIN "background tty read"}}
|
||||
1011 {1 "child process exited abnormally" {
|
||||
CHILDSTATUS 1011 -1}}\fR
|
||||
|
||||
\fB::tcl::process status\fR 1011
|
||||
\fI\(-> 1011 {1 "child process exited abnormally" {CHILDSTATUS 1011 -1}}\fR
|
||||
\fI\(-> 1011 {1 "child process exited abnormally" {
|
||||
CHILDSTATUS 1011 -1}}\fR
|
||||
|
||||
\fB::tcl::process purge\fR
|
||||
exec command1 1 2 3 &
|
||||
@@ -123,7 +141,8 @@ exec command1 1 2 3 &
|
||||
\fI\(-> 1213\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
exec(n), open(n), Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3)
|
||||
exec(n), open(n), pid(n),
|
||||
Tcl_DetachPids(3), Tcl_WaitPid(3), Tcl_ReapDetachedProcs(3)
|
||||
.SH "KEYWORDS"
|
||||
background, child, detach, process, wait
|
||||
'\" Local Variables:
|
||||
|
||||
@@ -96,3 +96,7 @@ close $chan
|
||||
file(n), fileevent(n), Tcl_StandardChannels(3)
|
||||
.SH KEYWORDS
|
||||
channel, newline, output, write
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -37,3 +37,7 @@ cd $savedDir
|
||||
file(n), cd(n), glob(n), filename(n)
|
||||
.SH KEYWORDS
|
||||
working directory
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -43,3 +43,7 @@ proc ::source args {
|
||||
namespace(n), proc(n)
|
||||
.SH KEYWORDS
|
||||
command, delete, namespace, rename
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -73,3 +73,7 @@ practice instead of doing double-dereferencing):
|
||||
expr(n), global(n), namespace(n), proc(n), trace(n), unset(n), upvar(n), variable(n)
|
||||
.SH KEYWORDS
|
||||
read, write, variable
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -69,3 +69,7 @@ foreach scriptFile {foo.tcl bar.tcl} {
|
||||
file(n), cd(n), encoding(n), info(n)
|
||||
.SH KEYWORDS
|
||||
file, script
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+11
-5
@@ -12,7 +12,7 @@
|
||||
.SH NAME
|
||||
string \- Manipulate strings
|
||||
.SH SYNOPSIS
|
||||
\fBstring \fIoption arg \fR?\fIarg ...?\fR
|
||||
\fBstring \fIoption arg \fR?\fIarg ...\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -20,7 +20,7 @@ Performs one of several string operations, depending on \fIoption\fR.
|
||||
The legal \fIoption\fRs (which may be abbreviated) are:
|
||||
.TP
|
||||
\fBstring cat\fR ?\fIstring1\fR? ?\fIstring2...\fR?
|
||||
.VS 8.6.2
|
||||
.
|
||||
Concatenate the given \fIstring\fRs just like placing them directly
|
||||
next to each other and return the resulting compound string. If no
|
||||
\fIstring\fRs are present, the result is an empty string.
|
||||
@@ -32,7 +32,6 @@ of a concatenation without resorting to \fBreturn\fR \fB\-level 0\fR,
|
||||
and is more efficient than building a list of arguments and using
|
||||
\fBjoin\fR with an empty join string.
|
||||
.RE
|
||||
.VE
|
||||
.TP
|
||||
\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR
|
||||
.
|
||||
@@ -111,17 +110,24 @@ Any character with a value less than \eu0080 (those that are in the
|
||||
Any of the forms allowed to \fBTcl_GetBoolean\fR.
|
||||
.IP \fBcontrol\fR 12
|
||||
Any Unicode control character.
|
||||
.IP \fBdict\fR 12
|
||||
.VS TIP501
|
||||
Any proper dict structure, with optional surrounding whitespace. In
|
||||
case of improper dict structure, 0 is returned and the \fIvarname\fR
|
||||
will contain the index of the
|
||||
.QW element
|
||||
where the dict parsing fails, or \-1 if this cannot be determined.
|
||||
.VE TIP501
|
||||
.IP \fBdigit\fR 12
|
||||
Any Unicode digit character. Note that this includes characters
|
||||
outside of the [0\-9] range.
|
||||
.IP \fBdouble\fR 12
|
||||
Any of the forms allowed to \fBTcl_GetDoubleFromObj\fR.
|
||||
.IP \fBentier\fR 12
|
||||
.VS 8.6
|
||||
.
|
||||
Any of the valid string formats for an integer value of arbitrary size
|
||||
in Tcl, with optional surrounding whitespace. The formats accepted are
|
||||
exactly those accepted by the C routine \fBTcl_GetBignumFromObj\fR.
|
||||
.VE
|
||||
.IP \fBfalse\fR 12
|
||||
Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
|
||||
false.
|
||||
|
||||
+12
-2
@@ -8,7 +8,7 @@
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH "tcltest" n 2.3 tcltest "Tcl Bundled Packages"
|
||||
.TH "tcltest" n 2.5 tcltest "Tcl Bundled Packages"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
@@ -16,7 +16,7 @@
|
||||
tcltest \- Test harness support code and utilities
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fBpackage require tcltest\fR ?\fB2.3\fR?
|
||||
\fBpackage require tcltest\fR ?\fB2.5\fR?
|
||||
|
||||
\fBtcltest::test \fIname description\fR ?\fI\-option value ...\fR?
|
||||
\fBtcltest::test \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
|
||||
@@ -454,6 +454,7 @@ The valid options for \fBtest\fR are summarized:
|
||||
?\fB\-output \fIexpectedOutput\fR?
|
||||
?\fB\-errorOutput \fIexpectedError\fR?
|
||||
?\fB\-returnCodes \fIcodeList\fR?
|
||||
?\fB\-errorCode \fIexpectedErrorCode\fR?
|
||||
?\fB\-match \fImode\fR?
|
||||
.CE
|
||||
.PP
|
||||
@@ -577,6 +578,15 @@ return codes known to \fBreturn\fR, in both numeric and symbolic
|
||||
form, including extended return codes, are acceptable elements in
|
||||
the \fIexpectedCodeList\fR. Default value is
|
||||
.QW "\fBok return\fR" .
|
||||
.TP
|
||||
\fB\-errorCode \fIexpectedErrorCode\fR
|
||||
.
|
||||
The optional \fB\-errorCode\fR attribute supplies \fIexpectedErrorCode\fR,
|
||||
a glob pattern that should match the error code reported from evaluation of the
|
||||
\fB\-body\fR script. If evaluation of the \fB\-body\fR script returns
|
||||
a code not matching \fIexpectedErrorCode\fR, the test fails. Default value is
|
||||
.QW "\fB*\fR" .
|
||||
If \fB\-returnCodes\fR does not include \fBerror\fR it is set to \fBerror\fR.
|
||||
.PP
|
||||
To pass, a test must successfully evaluate its \fB\-setup\fR, \fB\-body\fR,
|
||||
and \fB\-cleanup\fR scripts. The return code of the \fB\-body\fR script and
|
||||
|
||||
@@ -46,3 +46,7 @@ if {[read $chan 6] eq "foobar"} {
|
||||
file(n), open(n), close(n), gets(n), seek(n), Tcl_StandardChannels(3)
|
||||
.SH KEYWORDS
|
||||
access position, channel, seeking
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2005 Sergey Brester aka sebres.
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.TH timerate n "" Tcl "Tcl Built-In Commands"
|
||||
.so man.macros
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
timerate \- Time-related execution resp. performance measurement of a script
|
||||
.SH SYNOPSIS
|
||||
\fBtimerate \fIscript\fR \fI?time ?max-count??\fR
|
||||
.sp
|
||||
\fBtimerate \fI?-direct?\fR \fI?-overhead double?\fR \fIscript\fR \fI?time ?max-count??\fR
|
||||
.sp
|
||||
\fBtimerate \fI?-calibrate?\fR \fI?-direct?\fR \fIscript\fR \fI?time ?max-count??\fR
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The first and second form will evaluate \fIscript\fR until the interval
|
||||
\fItime\fR given in milliseconds elapses, or for 1000 milliseconds (1 second)
|
||||
if \fItime\fR is not specified.
|
||||
.sp
|
||||
The parameter \fImax-count\fR could additionally impose a further restriction
|
||||
by the maximal number of iterations to evaluate the script.
|
||||
If \fImax-count\fR is specified, the evalution will stop either this count of
|
||||
iterations is reached or the time is exceeded.
|
||||
.sp
|
||||
It will then return a canonical tcl-list of the form
|
||||
.PP
|
||||
.CS
|
||||
\fB0.095977 \(mcs/# 52095836 # 10419167 #/sec 5000.000 nett-ms\fR
|
||||
.CE
|
||||
.PP
|
||||
which indicates:
|
||||
.IP \(bu
|
||||
the average amount of time required per iteration, in microseconds ([\fBlindex\fR $result 0])
|
||||
.IP \(bu
|
||||
the count how many times it was executed ([\fBlindex\fR $result 2])
|
||||
.IP \(bu
|
||||
the estimated rate per second ([\fBlindex\fR $result 4])
|
||||
.IP \(bu
|
||||
the estimated real execution time without measurement overhead ([\fBlindex\fR $result 6])
|
||||
.PP
|
||||
Time is measured in elapsed time using the finest timer resolution as possible,
|
||||
not CPU time.
|
||||
This command may be used to provide information as to how well the script or a
|
||||
tcl-command is performing and can help determine bottlenecks and fine-tune
|
||||
application performance.
|
||||
.TP
|
||||
\fI-calibrate\fR
|
||||
.
|
||||
To measure very fast scripts as exact as posible the calibration process
|
||||
may be required.
|
||||
|
||||
The \fI-calibrate\fR option is used to calibrate timerate, calculating the
|
||||
estimated overhead of the given script as the default overhead for future
|
||||
invocations of the \fBtimerate\fR command. If the \fItime\fR parameter is not
|
||||
specified, the calibrate procedure runs for up to 10 seconds.
|
||||
.TP
|
||||
\fI-overhead double\fR
|
||||
.
|
||||
The \fI-overhead\fR parameter supplies an estimate (in microseconds) of the
|
||||
measurement overhead of each iteration of the tested script. This quantity
|
||||
will be subtracted from the measured time prior to reporting results.
|
||||
.TP
|
||||
\fI-direct\fR
|
||||
.
|
||||
The \fI-direct\fR option causes direct execution of the supplied script,
|
||||
without compilation, in a manner similar to the \fBtime\fR command. It can be
|
||||
used to measure the cost of \fBTcl_EvalObjEx\fR, of the invocation of canonical
|
||||
lists, and of the uncompiled versions of bytecoded commands.
|
||||
.PP
|
||||
As opposed to the \fBtime\fR commmand, which runs the tested script for a fixed
|
||||
number of iterations, the timerate command runs it for a fixed time.
|
||||
Additionally, the compiled variant of the script will be used during the entire
|
||||
measurement, as if the script were part of a compiled procedure, if the \fI-direct\fR
|
||||
option is not specified. The fixed time period and possibility of compilation allow
|
||||
for more precise results and prevent very long execution times by slow scripts, making
|
||||
it practical for measuring scripts with highly uncertain execution times.
|
||||
|
||||
.SH EXAMPLE
|
||||
Estimate how fast it takes for a simple Tcl \fBfor\fR loop (including
|
||||
operations on variable \fIi\fR) to count to a ten:
|
||||
.PP
|
||||
.CS
|
||||
# calibrate:
|
||||
timerate -calibrate {}
|
||||
# measure:
|
||||
timerate { for {set i 0} {$i<10} {incr i} {} } 5000
|
||||
.CE
|
||||
.PP
|
||||
Estimate how fast it takes for a simple Tcl \fBfor\fR loop, ignoring the
|
||||
overhead for to perform ten iterations, ignoring the overhead of the management
|
||||
of the variable that controls the loop:
|
||||
.PP
|
||||
.CS
|
||||
# calibrate for overhead of variable operations:
|
||||
set i 0; timerate -calibrate {expr {$i<10}; incr i} 1000
|
||||
# measure:
|
||||
timerate { for {set i 0} {$i<10} {incr i} {} } 5000
|
||||
.CE
|
||||
.PP
|
||||
Estimate the speed of calculating the hour of the day using \fBclock format\fR only,
|
||||
ignoring overhead of the portion of the script that prepares the time for it to
|
||||
calculate:
|
||||
.PP
|
||||
.CS
|
||||
# calibrate:
|
||||
timerate -calibrate {}
|
||||
# estimate overhead:
|
||||
set tm 0
|
||||
set ovh [lindex [timerate { incr tm [expr {24*60*60}] }] 0]
|
||||
# measure using esimated overhead:
|
||||
set tm 0
|
||||
timerate -overhead $ovh {
|
||||
clock format $tm -format %H
|
||||
incr tm [expr {24*60*60}]; # overhead for this is ignored
|
||||
} 5000
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
time(n)
|
||||
.SH KEYWORDS
|
||||
script, timerate, time
|
||||
.\" Local Variables:
|
||||
.\" mode: nroff
|
||||
.\" End:
|
||||
+2
-1
@@ -20,7 +20,8 @@ trace \- Monitor variable accesses, command usages and command executions
|
||||
This command causes Tcl commands to be executed whenever certain operations are
|
||||
invoked. The legal \fIoption\fRs (which may be abbreviated) are:
|
||||
.TP
|
||||
\fBtrace add \fItype name ops ?args?\fR
|
||||
\fBtrace add \fItype name ops\fR ?\fIargs\fR?
|
||||
.
|
||||
Where \fItype\fR is \fBcommand\fR, \fBexecution\fR, or \fBvariable\fR.
|
||||
.RS
|
||||
.TP
|
||||
|
||||
@@ -89,3 +89,7 @@ proc \fBunknown\fR args {
|
||||
info(n), proc(n), interp(n), library(n), namespace(n)
|
||||
.SH KEYWORDS
|
||||
error, non-existent command, unknown
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -63,3 +63,7 @@ while {!$done} {
|
||||
after(n), interp(n)
|
||||
.SH KEYWORDS
|
||||
asynchronous I/O, event, flush, handler, idle, update
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
@@ -63,3 +63,7 @@ set lineCount 0
|
||||
break(n), continue(n), for(n), foreach(n)
|
||||
.SH KEYWORDS
|
||||
boolean, loop, test, while
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" fill-column: 78
|
||||
'\" End:
|
||||
|
||||
+88
-38
@@ -10,61 +10,111 @@
|
||||
.so man.macros
|
||||
.BS
|
||||
.SH NAME
|
||||
TclZipfs_AppHook, Tclzipfs_Mount, Tclzipfs_Unmount, \- handle ZIP files as VFS
|
||||
TclZipfs_AppHook, Tclzipfs_Mount, TclZipfs_MountBuffer, Tclzipfs_Unmount \- handle ZIP files as Tcl virtual filesystems
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
int
|
||||
\fBTclZipfs_AppHook(\fIargcPtr, argvPtr\fR)
|
||||
.sp
|
||||
int
|
||||
\fBTclZipfs_AppHook(\fIint *argc, char ***argv\fR)
|
||||
\fBTclzipfs_Mount\fR(\fIinterp, mountpoint, zipname, password\fR)
|
||||
.sp
|
||||
int
|
||||
\fBTclzipfs_Mount\fR(\fIinterp, mntpt, zipname, passwd\fR)
|
||||
\fBTclZipfs_MountBuffer\fR(\fIinterp, mountpoint, data, dataLen, copy\fR)
|
||||
.sp
|
||||
int
|
||||
\fBTclzipfs_Unmount\fR(\fIinterp, zipname\fR)
|
||||
\fBTclzipfs_Unmount\fR(\fIinterp, mountpoint\fR)
|
||||
.fi
|
||||
.SH ARGUMENTS
|
||||
.AP "int" *argc in
|
||||
Number of command line arguments from main()
|
||||
.AP "char" ***argv in
|
||||
Pointer to an array of strings containing the command
|
||||
line arguments to main()
|
||||
.AS Tcl_Interp **termPtr
|
||||
.AS Tcl_Interp *mountpoint in
|
||||
.AP "int" *argcPtr in
|
||||
Pointer to a variable holding the number of command line arguments from
|
||||
\fBmain\fR().
|
||||
.AP "char" ***argvPtr in
|
||||
Pointer to an array of strings containing the command line arguments to
|
||||
\fBmain\fR().
|
||||
.AP Tcl_Interp *interp in
|
||||
Interpreter in which the zip file system is mounted. The interpreter's result is
|
||||
Interpreter in which the ZIP file system is mounted. The interpreter's result is
|
||||
modified to hold the result or error message from the script.
|
||||
.AP "const char" *zipname in
|
||||
Name of a zipfile.
|
||||
.AP "const char" *mntpt in
|
||||
Name of a mount point.
|
||||
.AP "const char" *passwd in
|
||||
An (optional) password.
|
||||
Name of a ZIP file. Must not be NULL when either mounting or unmounting a ZIP.
|
||||
.AP "const char" *mountpoint in
|
||||
Name of a mount point, which must be a legal Tcl file or directory name. May
|
||||
be NULL to query current mount points.
|
||||
.AP "const char" *password in
|
||||
An (optional) password. Use NULL if no password is wanted to read the file.
|
||||
.AP "unsigned char" *data in
|
||||
A data buffer to mount. The data buffer must hold the contents of a ZIP
|
||||
archive, and must not be NULL.
|
||||
.AP size_t dataLen in
|
||||
The number of bytes in the supplied data buffer argument, \fIdata\fR.
|
||||
.AP int copy in
|
||||
If non-zero, the ZIP archive in the data buffer will be internally copied
|
||||
before mounting, allowing the data buffer to be disposed once
|
||||
\fBTclZipfs_MountBuffer\fR returns. If zero, the caller guarantees that the
|
||||
buffer will be valid to read from for the duration of the mount.
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
\fBTclZipfs_AppHook()\fR is a utility function to perform standard
|
||||
application initialization procedures. If the current application has
|
||||
a mountable zip file system, that file system is mounted under \fIZIPROOT\fR\fB/app\fR.
|
||||
If a file named \fBmain.tcl\fR is located in that file system, it is treated
|
||||
as the startup script for the process. If the file \fIZIPROOT\fR\fB/app/tcl_library/init.tcl\fR
|
||||
is present, \fBtcl_library\fR is set to \fIZIPROOT\fR\fB/app/tcl_library.
|
||||
\fBTclZipfs_AppHook\fR is a utility function to perform standard application
|
||||
initialization procedures, taking into account available ZIP archives as
|
||||
follows:
|
||||
.IP [1]
|
||||
If the current application has a mountable ZIP archive, that archive is
|
||||
mounted under \fIZIPFS_VOLUME\fB/app\fR as a read-only Tcl virtual file
|
||||
system. \fIZIPFS_VOLUME\fR is usually \fB//zipfs:\fR on all platforms, but
|
||||
\fBzipfs:\fR may also be used on Windows (due to differences in the
|
||||
platform's filename parsing).
|
||||
.IP [2]
|
||||
If a file named \fBmain.tcl\fR is located in the root directory of that file
|
||||
system (i.e., at \fIZIPROOT\fB/app/main.tcl\fR after the ZIP archive is
|
||||
mounted as described above) it is treated as the startup script for the
|
||||
process.
|
||||
.IP [3]
|
||||
If the file \fIZIPROOT\fB/app/tcl_library/init.tcl\fR is present, the
|
||||
\fBtcl_library\fR global variable in the initial Tcl interpreter is set to
|
||||
\fIZIPROOT\fB/app/tcl_library\fR.
|
||||
.IP [4]
|
||||
If the directory \fBtcl_library\fR was not found in the main application
|
||||
mount, the system will then search for it as either a VFS attached to the
|
||||
application dynamic library, or as a zip archive named
|
||||
\fBlibtcl_\fImajor\fB_\fIminor\fB_\fIpatchlevel\fB.zip\fR either in the
|
||||
present working directory or in the standard Tcl install location. (For
|
||||
example, the Tcl 8.7.2 release would be searched for in a file
|
||||
\fBlibtcl_8_7_2.zip\fR.) That archive, if located, is also mounted read-only.
|
||||
.PP
|
||||
On Windows, \fBTclZipfs_AppHook()\fR has a slightly different signature, it uses
|
||||
WCHAR in stead of char. As a result, it only works if your application is compiled
|
||||
using -DUNICODE.
|
||||
On Windows, \fBTclZipfs_AppHook\fR has a slightly different signature, since
|
||||
it uses WCHAR in stead of char. As a result, it requires your application to
|
||||
be compiled with the UNICODE preprocessor symbol defined (e.g., via the
|
||||
\fB-DUNICODE\fR compiler flag).
|
||||
.PP
|
||||
If the \fBtcl_library\fR was not found in the application, the system will then search for it
|
||||
as either a VFS attached to the application dynamic library, or as a zip archive named
|
||||
libtcl_\fIMAJOR\fR_\fIMINOR\fR_\fIpatchLevel\fR.zip either in the present working directory
|
||||
or in the standard tcl install location.
|
||||
The result of \fBTclZipfs_AppHook\fR is a Tcl result code (e.g., \fBTCL_OK\fR
|
||||
when the function is successful). The function \fImay\fR modify the variables
|
||||
pointed to by \fIargcPtr\fR and \fIargvPtr\fR to remove arguments; the
|
||||
current implementation does not do so, but callers \fIshould not\fR assume
|
||||
that this will be true in the future.
|
||||
.PP
|
||||
\fBTclzipfs_Mount()\fR mount the ZIP archive \fIzipname\fR on the mount
|
||||
point given in \fImntpt\fR using the optional ZIP password \fIpasswd\fR.
|
||||
Errors during that process are reported in the interpreter \fIinterp\fR.
|
||||
If \fImountpoint\fR is a NULL pointer, information on all currently mounted
|
||||
ZIP file systems is written into \fIinterp\fR's result as a sequence of
|
||||
mount points and ZIP file names.
|
||||
\fBTclzipfs_Mount\fR mounts the ZIP archive \fIzipname\fR on the mount point
|
||||
given in \fImountpoint\fR using the optional ZIP password \fIpassword\fR.
|
||||
Errors during that process are reported in the interpreter \fIinterp\fR. If
|
||||
\fImountpoint\fR is a NULL pointer, information on all currently mounted ZIP
|
||||
file systems is written into \fIinterp\fR's result as a sequence of mount
|
||||
points and ZIP file names. The result of this call is a standard Tcl result
|
||||
code.
|
||||
.PP
|
||||
\fBTclzipfs_Unmount()\fR undoes the effect of \fBTclzipfs_Mount()\fR,
|
||||
i.e. it unmounts the mounted ZIP file system at \fImountpoint\fR. Errors are
|
||||
reported in the interpreter \fIinterp\fR.
|
||||
\fBTclzipfs_MountBuffer\fR mounts the ZIP archive in the buffer pointed to by
|
||||
\fIdata\fR on the mount point given in \fImountpoint\fR. The ZIP archive is
|
||||
assumed to be not password protected. Errors during that process are reported
|
||||
in the interpreter \fIinterp\fR. The \fIcopy\fR argument determines whether
|
||||
the buffer is internally copied before mounting or not. The result of this
|
||||
call is a standard Tcl result code.
|
||||
.PP
|
||||
\fBTclzipfs_Unmount\fR undoes the effect of \fBTclzipfs_Mount\fR, i.e., it
|
||||
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
|
||||
compress, filesystem, zip
|
||||
|
||||
+184
-55
@@ -16,108 +16,237 @@ zipfs \- Mount and work with ZIP files within Tcl
|
||||
.nf
|
||||
\fBpackage require zipfs \fR?\fB1.0\fR?
|
||||
.sp
|
||||
\fBzipfs canonical\fR ?\fImntpnt\fR? \fIfilename\fR ?\fIZIPFS\fR?
|
||||
\fBzipfs exists\fR \fIfilename\fR
|
||||
\fBzipfs find\fR \fIdir\fR
|
||||
\fBzipfs find\fR \fIdirectoryName\fR
|
||||
\fBzipfs info\fR \fIfilename\fR
|
||||
\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
|
||||
\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
|
||||
\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR?
|
||||
\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR?
|
||||
\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR?
|
||||
\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR?
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
|
||||
\fBzipfs mount\fR \fI?mountpoint?\fR \fI?zipfile?\fR \fI?password?\fR
|
||||
\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR?
|
||||
\fBzipfs mount\fR ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR?
|
||||
\fBzipfs root\fR
|
||||
\fBzipfs unmount\fR \fImountpoint\fR
|
||||
.fi
|
||||
'\" The following subcommand is *UNDOCUMENTED*
|
||||
'\" \fBzipfs mount_data\fR ?\fImountpoint\fR? ?\fIdata\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBzipfs\fR package provides tcl with the ability to mount
|
||||
the contents of a zip file as a virtual file system.
|
||||
The \fBzipfs\fR command (the sole public command provided by the built-in
|
||||
package with the same name) provides Tcl with the ability to mount the
|
||||
contents of a ZIP archive file as a virtual file system. ZIP archives support
|
||||
simple encryption, sufficient to prevent casual inspection of their contents
|
||||
but not able to prevent access by even a moderately determined attacker.
|
||||
.TP
|
||||
\fBzipfs canonical\fR ?\fImountpoint\fR? \fIfilename\fR ?\fIinZipfs\fR?
|
||||
.
|
||||
This takes the name of a file, \fIfilename\fR, and produces where it would be
|
||||
mapped into a zipfs mount as its result. If specified, \fImountpoint\fR says
|
||||
within which mount the mapping will be done; if omitted, the main root of the
|
||||
zipfs system is used. The \fIinZipfs\fR argument is a an optional boolean
|
||||
which controls whether to fully canonicalise the name; it defaults to true.
|
||||
.TP
|
||||
\fBzipfs exists\fR \fIfilename\fR
|
||||
.
|
||||
Return 1 if the given filename exists in the mounted zipfs and 0 if it does not.
|
||||
.TP
|
||||
\fBzipfs find\fR \fIdir\fR
|
||||
\fBzipfs find\fR \fIdirectoryName\fR
|
||||
.
|
||||
Recursively lists files including and below the directory \fIdir\fR.
|
||||
The result list consists of relative path names starting from the
|
||||
given directory. This command is also used by the \fBzipfs mkzip\fR
|
||||
and \fBzipfs mkimg\fR commands.
|
||||
Recursively lists files including and below the directory \fIdirectoryName\fR.
|
||||
The result list consists of relative path names starting from the given
|
||||
directory. This command is also used by the \fBzipfs mkzip\fR and \fBzipfs
|
||||
mkimg\fR commands.
|
||||
.TP
|
||||
\fBzipfs info\fR \fIfile\fR
|
||||
.
|
||||
Return information about the given file in the mounted zipfs. The information
|
||||
consists of (1) the name of the ZIP archive file that contains the file,
|
||||
(2) the size of the file after decompressions, (3) the compressed size of
|
||||
the file, and (4) the offset of the compressed data in the ZIP archive file.
|
||||
Return information about the given \fIfile\fR in the mounted zipfs. The
|
||||
information consists of:
|
||||
.RS
|
||||
.IP (1)
|
||||
the name of the ZIP archive file that contains the file,
|
||||
.IP (2)
|
||||
the size of the file after decompressions,
|
||||
.IP (3)
|
||||
the compressed size of the file, and
|
||||
.IP (4)
|
||||
the offset of the compressed data in the ZIP archive file.
|
||||
.PP
|
||||
Note: querying the mount point gives the start of zip data offset in (4),
|
||||
which can be used to truncate the zip info off an executable.
|
||||
Note: querying the mount point gives the start of the zip data as the offset
|
||||
in (4), which can be used to truncate the zip information from an executable.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs list\fR \fB?(-glob|-regexp)?\fR \fI?pattern?\fR
|
||||
\fBzipfs list\fR ?(\fB\-glob\fR|\fB\-regexp\fR)? ?\fIpattern\fR?
|
||||
.
|
||||
Return a list of all files in the mounted zipfs. The order of the names
|
||||
in the list is arbitrary.
|
||||
Return a list of all files in the mounted zipfs, or just those matching
|
||||
\fIpattern\fR (optionally controlled by the option parameters). The order of
|
||||
the names in the list is arbitrary.
|
||||
.TP
|
||||
\fBzipfs mkimg\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR \fI?infile?\fR
|
||||
\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR?
|
||||
.
|
||||
Creates an image (potentially a new executable file) similar to
|
||||
\fBzipfs mkzip\fR. If the \fIinfile\fR parameter is specified,
|
||||
this file is prepended in front of the ZIP archive, otherwise the file
|
||||
returned by \fBTcl_NameOfExecutable(3)\fR (i.e. the executable file of
|
||||
the running process) is used. If the \fIpassword\fR parameter is not empty,
|
||||
an obfuscated version of that password is placed between the image and ZIP
|
||||
chunks of the output file and the contents of the ZIP chunk are protected
|
||||
with that password.
|
||||
The \fBzipfs mount\fR command mounts a ZIP archive file as a Tcl virtual
|
||||
filesystem at \fImountpoint\fR. After this command executes, files contained
|
||||
in \fIzipfile\fR will appear to Tcl to be regular files at the mount point.
|
||||
.RS
|
||||
.PP
|
||||
Caution: highly experimental, not usable on Android, only partially tested
|
||||
on Linux and Windows.
|
||||
With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR. With
|
||||
no \fImountpoint\fR, return all zipfile/mount pairs. If \fImountpoint\fR is
|
||||
specified as an empty string, mount on file path.
|
||||
.PP
|
||||
\fBNB:\fR because the current working directory is a concept maintained by the
|
||||
operating system, using \fBcd\fR into a mounted archive will only work in the
|
||||
current process, and then not entirely consistently (e.g., if a shared library
|
||||
uses direct access to the OS rather than through Tcl's filesystem API, it will
|
||||
not see the current directory as being inside the mount and will not be able
|
||||
to access the files inside the mount).
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
\fBzipfs root\fR
|
||||
.
|
||||
For the clear text \fIpassword\fR argument an obfuscated string version
|
||||
is returned with the same format used in the \fBzipfs mkimg\fR command.
|
||||
Returns a constant string which indicates the mount point for zipfs volumes
|
||||
for the current platform. On Windows, this value is
|
||||
.QW \fBzipfs:/\fR .
|
||||
On Unix, this value is
|
||||
.QW \fB//zipfs:/\fR .
|
||||
.TP
|
||||
\fBzipfs mkzip\fR \fIoutfile\fR \fIindir\fR \fI?strip?\fR \fI?password?\fR
|
||||
\fBzipfs unmount \fImountpoint\fR
|
||||
.
|
||||
Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR.
|
||||
.SS "ZIP CREATION COMMANDS"
|
||||
This package also provides several commands to aid the creation of ZIP
|
||||
archives as Tcl applications.
|
||||
.TP
|
||||
\fBzipfs mkzip\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR?
|
||||
.
|
||||
Creates a ZIP archive file named \fIoutfile\fR from the contents of the input
|
||||
directory \fIindir\fR (contained regular files only) with optional ZIP
|
||||
password \fIpassword\fR. While processing the files below \fIindir\fR the
|
||||
optional file name prefix given in \fIstrip\fR is stripped off the beginning
|
||||
of the respective file name.
|
||||
of the respective file name. When stripping, it is common to remove either
|
||||
the whole source directory name or the name of its parent directory.
|
||||
.RS
|
||||
.PP
|
||||
Caution: the choice of the \fIindir\fR parameter
|
||||
(less the optional stripped prefix) determines the later root name of the
|
||||
archive's content.
|
||||
\fBCaution:\fR the choice of the \fIindir\fR parameter (less the optional
|
||||
stripped prefix) determines the later root name of the archive's content.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs mount ?\fImountpoint\fR? ?\fIzipfile\fR? ?\fIpassword\fR?
|
||||
\fBzipfs mkimg\fR \fIoutfile indir\fR ?\fIstrip\fR? ?\fIpassword\fR? ?\fIinfile\fR?
|
||||
.
|
||||
The \fBzipfs mount\fR command mounts a ZIP archive file as a VFS.
|
||||
After this command executes, files contained in \fIzipfile\fR
|
||||
will appear to Tcl to be regular files at the mount point.
|
||||
Creates an image (potentially a new executable file) similar to \fBzipfs
|
||||
mkzip\fR; see that command for a description of most parameters to this
|
||||
command, as they behave identically here.
|
||||
.RS
|
||||
.PP
|
||||
With no \fIzipfile\fR, returns the zipfile mounted at \fImountpoint\fR.
|
||||
With no \fImountpoint\fR, return all zipfile/mount pairs.
|
||||
If \fImountpoint\fR is specified as an empty string, mount on file path.
|
||||
If the \fIinfile\fR parameter is specified, this file is prepended in front of
|
||||
the ZIP archive, otherwise the file returned by \fBinfo nameofexecutable\fR
|
||||
(i.e., the executable file of the running process) is used. If the
|
||||
\fIpassword\fR parameter is not empty, an obfuscated version of that password
|
||||
(see \fBzipfs mkkey\fR) is placed between the image and ZIP chunks of the
|
||||
output file and the contents of the ZIP chunk are protected with that
|
||||
password.
|
||||
.PP
|
||||
If there is a file, \fBmain.tcl\fR, in the root directory of the resulting
|
||||
archive and the image file that the archive is attached to is a \fBtclsh\fR
|
||||
(or \fBwish\fR) instance (true by default, but depends on your configuration),
|
||||
then the resulting image is an executable that will \fBsource\fR the script in
|
||||
that \fBmain.tcl\fR after mounting the ZIP archive, and will \fBexit\fR once
|
||||
that script has been executed.
|
||||
.PP
|
||||
\fBCaution:\fR highly experimental, not usable on Android, only partially
|
||||
tested on Linux and Windows.
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs root\fR
|
||||
Returns a constant string which indicates the mount point for zipfs volumes
|
||||
for the current platform. On Windows, this value is zipfs:/. On Unux, //zipfs:/
|
||||
.RE
|
||||
.TP
|
||||
\fBzipfs unmount \fImountpoint\fR
|
||||
\fBzipfs mkkey\fR \fIpassword\fR
|
||||
.
|
||||
Unmounts a previously mounted ZIP archive mounted to \fImountpoint\fR.
|
||||
Given the clear text \fIpassword\fR argument, an obfuscated string version is
|
||||
returned with the same format used in the \fBzipfs mkimg\fR command.
|
||||
.TP
|
||||
\fBzipfs lmkimg\fR \fIoutfile inlist\fR ?\fIpassword infile\fR?
|
||||
.
|
||||
This command is like \fBzipfs mkimg\fR, but instead of an input directory,
|
||||
\fIinlist\fR must be a Tcl list where the odd elements are the names of files
|
||||
to be copied into the archive in the image, and the even elements are their
|
||||
respective names within that archive.
|
||||
.TP
|
||||
\fBzipfs lmkzip\fR \fIoutfile inlist\fR ?\fIpassword\fR?
|
||||
.
|
||||
This command is like \fBzipfs mkzip\fR, but instead of an input directory,
|
||||
\fIinlist\fR must be a Tcl list where the odd elements are the names of files
|
||||
to be copied into the archive, and the even elements are their respective
|
||||
names within that archive.
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
Mounting an ZIP archive as an application directory and running code out of it
|
||||
before unmounting it again:
|
||||
.PP
|
||||
.CS
|
||||
set zip myApp.zip
|
||||
set base [file join [\fBzipfs root\fR] myApp]
|
||||
|
||||
\fBzipfs mount\fR $base $zip
|
||||
# $base now has the contents of myApp.zip
|
||||
|
||||
source [file join $base app.tcl]
|
||||
# use the contents, load libraries from it, etc...
|
||||
|
||||
\fBzipfs unmount\fR $zip
|
||||
.CE
|
||||
.PP
|
||||
Creating a ZIP archive, given that a directory exists containing the content
|
||||
to put in the archive. Note that the source directory is given twice, in order
|
||||
to strip the exterior directory name from each filename in the archive.
|
||||
.PP
|
||||
.CS
|
||||
set sourceDirectory [file normalize myApp]
|
||||
set targetZip myApp.zip
|
||||
|
||||
\fBzipfs mkzip\fR $targetZip $sourceDirectory $sourceDirectory
|
||||
.CE
|
||||
.PP
|
||||
Encryption can be applied to ZIP archives by providing a password when
|
||||
building the ZIP and when mounting it.
|
||||
.PP
|
||||
.CS
|
||||
set zip myApp.zip
|
||||
set sourceDir [file normalize myApp]
|
||||
set password "hunter2"
|
||||
set base [file join [\fBzipfs root\fR] myApp]
|
||||
|
||||
# Create with password
|
||||
\fBzipfs mkzip\fR $targetZip $sourceDir $sourceDir $password
|
||||
|
||||
# Mount with password
|
||||
\fBzipfs mount\fR $base $zip $password
|
||||
.CE
|
||||
.PP
|
||||
When creating an executable image with a password, the password is placed
|
||||
within the executable in a shrouded form so that the application can read
|
||||
files inside the embedded ZIP archive yet casual inspection cannot read it.
|
||||
.PP
|
||||
.CS
|
||||
set appDir [file normalize myApp]
|
||||
set img "myApp.bin"
|
||||
set password "hunter2"
|
||||
|
||||
# Create some simple content to define a basic application
|
||||
file mkdir $appDir
|
||||
set f [open $appDir/main.tcl]
|
||||
puts $f {
|
||||
puts "Hi. This is [info script]"
|
||||
}
|
||||
close $f
|
||||
|
||||
# Create the executable
|
||||
\fBzipfs mkimg\fR $img $appDir $appDir $password
|
||||
|
||||
# Launch the executable, printing its output to stdout
|
||||
exec $img >@stdout
|
||||
# prints: \fIHi. This is //zipfs:/app/main.tcl\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
tclsh(1), file(n), zlib(n)
|
||||
tclsh(1), file(n), zipfs(3), zlib(n)
|
||||
.SH "KEYWORDS"
|
||||
compress, filesystem, zip
|
||||
'\" Local Variables:
|
||||
|
||||
+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]);
|
||||
|
||||
+58
-19
@@ -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)
|
||||
}
|
||||
|
||||
@@ -2332,25 +2333,50 @@ declare 631 {
|
||||
|
||||
# TIP #430
|
||||
declare 632 {
|
||||
int TclZipfs_Mount(
|
||||
Tcl_Interp *interp,
|
||||
const char *mntpt,
|
||||
const char *zipname,
|
||||
const char *passwd)
|
||||
int TclZipfs_Mount(Tcl_Interp *interp, const char *mountPoint,
|
||||
const char *zipname, const char *passwd)
|
||||
}
|
||||
declare 633 {
|
||||
int TclZipfs_Unmount(Tcl_Interp *interp, const char *zipname)
|
||||
int TclZipfs_Unmount(Tcl_Interp *interp, const char *mountPoint)
|
||||
}
|
||||
declare 634 {
|
||||
Tcl_Obj *TclZipfs_TclLibrary(void)
|
||||
}
|
||||
declare 635 {
|
||||
int TclZipfs_Mount_Buffer(
|
||||
Tcl_Interp *interp,
|
||||
const char *mntpt,
|
||||
unsigned char *data,
|
||||
size_t datalen,
|
||||
int copy)
|
||||
int TclZipfs_MountBuffer(Tcl_Interp *interp, const char *mountPoint,
|
||||
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 ----- #
|
||||
@@ -2403,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)
|
||||
|
||||
+49
-41
@@ -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)
|
||||
@@ -224,7 +220,7 @@ extern "C" {
|
||||
* to be included in a shared library, then it should have the DLLEXPORT
|
||||
* storage class. If is being declared for use by a module that is going to
|
||||
* link against the shared library, then it should have the DLLIMPORT storage
|
||||
* class. If the symbol is beind declared for a static build or for use from a
|
||||
* class. If the symbol is being declared for a static build or for use from a
|
||||
* stub library, then the storage class should be empty.
|
||||
*
|
||||
* The convention is that a macro called BUILD_xxxx, where xxxx is the name of
|
||||
@@ -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);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -2333,6 +2321,13 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
|
||||
#define TCL_TCPSERVER_REUSEADDR (1<<0)
|
||||
#define TCL_TCPSERVER_REUSEPORT (1<<1)
|
||||
|
||||
/*
|
||||
* Constants for special int-typed values, see TIP #494
|
||||
*/
|
||||
|
||||
#define TCL_IO_FAILURE (-1)
|
||||
#define TCL_AUTO_LENGTH (-1)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* Single public declaration for NRE.
|
||||
@@ -2396,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,
|
||||
@@ -2475,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
|
||||
@@ -2511,7 +2519,7 @@ EXTERN int TclZipfs_AppHook(int *argc, char ***argv);
|
||||
Tcl_DbNewBignumObj(val, __FILE__, __LINE__)
|
||||
# undef Tcl_NewBooleanObj
|
||||
# define Tcl_NewBooleanObj(val) \
|
||||
Tcl_DbNewLongObj((val)!=0, __FILE__, __LINE__)
|
||||
Tcl_DbNewWideIntObj((val)!=0, __FILE__, __LINE__)
|
||||
# undef Tcl_NewByteArrayObj
|
||||
# define Tcl_NewByteArrayObj(bytes, len) \
|
||||
Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
|
||||
|
||||
+3
-3
@@ -274,8 +274,8 @@ TclpAlloc(
|
||||
|
||||
if (numBytes >= MAXMALLOC - OVERHEAD) {
|
||||
if (numBytes <= UINT_MAX - OVERHEAD -sizeof(struct block)) {
|
||||
bigBlockPtr = (struct block *) TclpSysAlloc((unsigned)
|
||||
(sizeof(struct block) + OVERHEAD + numBytes), 0);
|
||||
bigBlockPtr = (struct block *) TclpSysAlloc(
|
||||
sizeof(struct block) + OVERHEAD + numBytes, 0);
|
||||
}
|
||||
if (bigBlockPtr == NULL) {
|
||||
Tcl_MutexUnlock(allocMutexPtr);
|
||||
@@ -604,7 +604,7 @@ TclpRealloc(
|
||||
if (maxSize < numBytes) {
|
||||
numBytes = maxSize;
|
||||
}
|
||||
memcpy(newPtr, oldPtr, (size_t) numBytes);
|
||||
memcpy(newPtr, oldPtr, numBytes);
|
||||
TclpFree(oldPtr);
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
+15
-11
@@ -32,6 +32,7 @@
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclOOInt.h"
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* Structure that represents a range of instructions in the bytecode.
|
||||
@@ -271,15 +272,12 @@ static void CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*,
|
||||
const TalInstDesc*);
|
||||
static int DefineLabel(AssemblyEnv* envPtr, const char* label);
|
||||
static void DeleteMirrorJumpTable(JumptableInfo* jtPtr);
|
||||
static void DupAssembleCodeInternalRep(Tcl_Obj* src,
|
||||
Tcl_Obj* dest);
|
||||
static void FillInJumpOffsets(AssemblyEnv*);
|
||||
static int CreateMirrorJumpTable(AssemblyEnv* assemEnvPtr,
|
||||
Tcl_Obj* jumpTable);
|
||||
static int FindLocalVar(AssemblyEnv* envPtr,
|
||||
Tcl_Token** tokenPtrPtr);
|
||||
static int FinishAssembly(AssemblyEnv*);
|
||||
static void FreeAssembleCodeInternalRep(Tcl_Obj *objPtr);
|
||||
static void FreeAssemblyEnv(AssemblyEnv*);
|
||||
static int GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*);
|
||||
static int GetListIndexOperand(AssemblyEnv*, Tcl_Token**, int*);
|
||||
@@ -318,6 +316,9 @@ static void UnstackExpiredCatches(CompileEnv*, BasicBlock*, int,
|
||||
* Tcl_ObjType that describes bytecode emitted by the assembler.
|
||||
*/
|
||||
|
||||
static Tcl_FreeInternalRepProc FreeAssembleCodeInternalRep;
|
||||
static Tcl_DupInternalRepProc DupAssembleCodeInternalRep;
|
||||
|
||||
static const Tcl_ObjType assembleCodeType = {
|
||||
"assemblecode",
|
||||
FreeAssembleCodeInternalRep, /* freeIntRepProc */
|
||||
@@ -802,7 +803,7 @@ TclNRAssembleObjCmd(
|
||||
Tcl_AddErrorInfo(interp, "\n (\"");
|
||||
Tcl_AppendObjToErrorInfo(interp, objv[0]);
|
||||
Tcl_AddErrorInfo(interp, "\" body, line ");
|
||||
backtrace = Tcl_NewIntObj(Tcl_GetErrorLine(interp));
|
||||
backtrace = Tcl_NewWideIntObj(Tcl_GetErrorLine(interp));
|
||||
Tcl_AppendObjToErrorInfo(interp, backtrace);
|
||||
Tcl_AddErrorInfo(interp, ")");
|
||||
return TCL_ERROR;
|
||||
@@ -847,15 +848,15 @@ CompileAssembleObj(
|
||||
const char* source; /* String representation of the source code */
|
||||
int sourceLen; /* Length of the source code in bytes */
|
||||
|
||||
|
||||
/*
|
||||
* Get the expression ByteCode from the object. If it exists, make sure it
|
||||
* is valid in the current context.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &assembleCodeType) {
|
||||
ByteCodeGetIntRep(objPtr, &assembleCodeType, codePtr);
|
||||
|
||||
if (codePtr) {
|
||||
namespacePtr = iPtr->varFramePtr->nsPtr;
|
||||
codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
if (((Interp *) *codePtr->interpHandle == iPtr)
|
||||
&& (codePtr->compileEpoch == iPtr->compileEpoch)
|
||||
&& (codePtr->nsPtr == namespacePtr)
|
||||
@@ -869,7 +870,7 @@ CompileAssembleObj(
|
||||
* Not valid, so free it and regenerate.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
Tcl_StoreIntRep(objPtr, &assembleCodeType, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2261,7 +2262,7 @@ GetListIndexOperand(
|
||||
* when list size limits grow.
|
||||
*/
|
||||
status = TclIndexEncode(interp, value,
|
||||
TCL_INDEX_BEFORE,TCL_INDEX_BEFORE, result);
|
||||
TCL_INDEX_NONE,TCL_INDEX_NONE, result);
|
||||
|
||||
Tcl_DecrRefCount(value);
|
||||
*tokenPtrPtr = TokenAfter(tokenPtr);
|
||||
@@ -4262,7 +4263,7 @@ AddBasicBlockRangeToErrorInfo(
|
||||
Tcl_Obj* lineNo; /* Line number in the source */
|
||||
|
||||
Tcl_AddErrorInfo(interp, "\n in assembly code between lines ");
|
||||
lineNo = Tcl_NewIntObj(bbPtr->startLine);
|
||||
lineNo = Tcl_NewWideIntObj(bbPtr->startLine);
|
||||
Tcl_IncrRefCount(lineNo);
|
||||
Tcl_AppendObjToErrorInfo(interp, lineNo);
|
||||
Tcl_AddErrorInfo(interp, " and ");
|
||||
@@ -4332,7 +4333,10 @@ static void
|
||||
FreeAssembleCodeInternalRep(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
ByteCode *codePtr;
|
||||
|
||||
ByteCodeGetIntRep(objPtr, &assembleCodeType, codePtr);
|
||||
assert(codePtr != NULL);
|
||||
|
||||
TclReleaseByteCode(codePtr);
|
||||
}
|
||||
|
||||
+255
-82
@@ -105,6 +105,7 @@ TCL_DECLARE_MUTEX(commandTypeLock);
|
||||
* Static functions in this file:
|
||||
*/
|
||||
|
||||
static Tcl_ObjCmdProc BadEnsembleSubcommand;
|
||||
static char * CallCommandTraces(Interp *iPtr, Command *cmdPtr,
|
||||
const char *oldName, const char *newName,
|
||||
int flags);
|
||||
@@ -125,7 +126,6 @@ static Tcl_ObjCmdProc ExprBinaryFunc;
|
||||
static Tcl_ObjCmdProc ExprBoolFunc;
|
||||
static Tcl_ObjCmdProc ExprCeilFunc;
|
||||
static Tcl_ObjCmdProc ExprDoubleFunc;
|
||||
static Tcl_ObjCmdProc ExprEntierFunc;
|
||||
static Tcl_ObjCmdProc ExprFloorFunc;
|
||||
static Tcl_ObjCmdProc ExprIntFunc;
|
||||
static Tcl_ObjCmdProc ExprIsqrtFunc;
|
||||
@@ -206,6 +206,24 @@ typedef struct {
|
||||
* expansion for itself rather than needing the generic layer to take care of
|
||||
* it for it. Defined in tclInt.h. */
|
||||
|
||||
/*
|
||||
* The following struct states that the command it talks about (a subcommand
|
||||
* of one of Tcl's built-in ensembles) is unsafe and must be hidden when an
|
||||
* interpreter is made safe. (TclHideUnsafeCommands accesses an array of these
|
||||
* structs.) Alas, we can't sensibly just store the information directly in
|
||||
* the commands.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const char *ensembleNsName; /* The ensemble's name within ::tcl. NULL for
|
||||
* the end of the list of commands to hide. */
|
||||
const char *commandName; /* The name of the command within the
|
||||
* ensemble. If this is NULL, we want to also
|
||||
* make the overall command be hidden, an ugly
|
||||
* hack because it is expected by security
|
||||
* policies in the wild. */
|
||||
} UnsafeEnsembleInfo;
|
||||
|
||||
/*
|
||||
* The built-in commands, and the functions that implement them:
|
||||
*/
|
||||
@@ -242,6 +260,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"list", Tcl_ListObjCmd, TclCompileListCmd, NULL, CMD_IS_SAFE|CMD_COMPILES_EXPANDED},
|
||||
{"llength", Tcl_LlengthObjCmd, TclCompileLlengthCmd, NULL, CMD_IS_SAFE},
|
||||
{"lmap", Tcl_LmapObjCmd, TclCompileLmapCmd, TclNRLmapCmd, CMD_IS_SAFE},
|
||||
{"lpop", Tcl_LpopObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"lrange", Tcl_LrangeObjCmd, TclCompileLrangeCmd, NULL, CMD_IS_SAFE},
|
||||
{"lrepeat", Tcl_LrepeatObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"lreplace", Tcl_LreplaceObjCmd, TclCompileLreplaceCmd, NULL, CMD_IS_SAFE},
|
||||
@@ -300,12 +319,75 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"source", Tcl_SourceObjCmd, NULL, TclNRSourceObjCmd, 0},
|
||||
{"tell", Tcl_TellObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"time", Tcl_TimeObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"timerate", Tcl_TimeRateObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"unload", Tcl_UnloadObjCmd, NULL, NULL, 0},
|
||||
{"update", Tcl_UpdateObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"vwait", Tcl_VwaitObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Information about which pieces of ensembles to hide when making an
|
||||
* interpreter safe:
|
||||
*/
|
||||
|
||||
static const UnsafeEnsembleInfo unsafeEnsembleCommands[] = {
|
||||
/* [encoding] has two unsafe commands. Assumed by older security policies
|
||||
* to be overall unsafe; it isn't but... */
|
||||
{"encoding", NULL},
|
||||
{"encoding", "dirs"},
|
||||
{"encoding", "system"},
|
||||
/* [file] has MANY unsafe commands! Assumed by older security policies to
|
||||
* be overall unsafe; it isn't but... */
|
||||
{"file", NULL},
|
||||
{"file", "atime"},
|
||||
{"file", "attributes"},
|
||||
{"file", "copy"},
|
||||
{"file", "delete"},
|
||||
{"file", "dirname"},
|
||||
{"file", "executable"},
|
||||
{"file", "exists"},
|
||||
{"file", "extension"},
|
||||
{"file", "isdirectory"},
|
||||
{"file", "isfile"},
|
||||
{"file", "link"},
|
||||
{"file", "lstat"},
|
||||
{"file", "mtime"},
|
||||
{"file", "mkdir"},
|
||||
{"file", "nativename"},
|
||||
{"file", "normalize"},
|
||||
{"file", "owned"},
|
||||
{"file", "readable"},
|
||||
{"file", "readlink"},
|
||||
{"file", "rename"},
|
||||
{"file", "rootname"},
|
||||
{"file", "size"},
|
||||
{"file", "stat"},
|
||||
{"file", "tail"},
|
||||
{"file", "tempfile"},
|
||||
{"file", "type"},
|
||||
{"file", "volumes"},
|
||||
{"file", "writable"},
|
||||
/* [info] has two unsafe commands */
|
||||
{"info", "cmdtype"},
|
||||
{"info", "nameofexecutable"},
|
||||
/* [tcl::process] has ONLY unsafe commands! */
|
||||
{"process", "list"},
|
||||
{"process", "status"},
|
||||
{"process", "purge"},
|
||||
{"process", "autopurge"},
|
||||
/* [zipfs] has MANY unsafe commands! */
|
||||
{"zipfs", "lmkimg"},
|
||||
{"zipfs", "lmkzip"},
|
||||
{"zipfs", "mkimg"},
|
||||
{"zipfs", "mkkey"},
|
||||
{"zipfs", "mkzip"},
|
||||
{"zipfs", "mount"},
|
||||
{"zipfs", "mount_data"},
|
||||
{"zipfs", "unmount"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
/*
|
||||
* Math functions. All are safe.
|
||||
*/
|
||||
@@ -327,7 +409,7 @@ static const BuiltinFuncDef BuiltinFuncTable[] = {
|
||||
{ "cos", ExprUnaryFunc, (ClientData) cos },
|
||||
{ "cosh", ExprUnaryFunc, (ClientData) cosh },
|
||||
{ "double", ExprDoubleFunc, NULL },
|
||||
{ "entier", ExprEntierFunc, NULL },
|
||||
{ "entier", ExprIntFunc, NULL },
|
||||
{ "exp", ExprUnaryFunc, (ClientData) exp },
|
||||
{ "floor", ExprFloorFunc, NULL },
|
||||
{ "fmod", ExprBinaryFunc, (ClientData) fmod },
|
||||
@@ -478,7 +560,7 @@ Tcl_CreateInterp(void)
|
||||
const BuiltinFuncDef *builtinFuncPtr;
|
||||
const OpCmdInfo *opcmdInfoPtr;
|
||||
const CmdInfo *cmdInfoPtr;
|
||||
Tcl_Namespace *mathfuncNSPtr, *mathopNSPtr;
|
||||
Tcl_Namespace *nsPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
int isNew;
|
||||
CancelInfo *cancelInfo;
|
||||
@@ -893,6 +975,13 @@ Tcl_CreateInterp(void)
|
||||
Tcl_NRCreateCommand(interp, "::tcl::unsupported::inject", NULL,
|
||||
NRCoroInjectObjCmd, NULL, NULL);
|
||||
|
||||
/* Export unsupported commands */
|
||||
nsPtr = Tcl_FindNamespace(interp, "::tcl::unsupported", NULL, 0);
|
||||
if (nsPtr) {
|
||||
Tcl_Export(interp, nsPtr, "*", 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_DTRACE
|
||||
/*
|
||||
* Register the tcl::dtrace command.
|
||||
@@ -905,8 +994,8 @@ Tcl_CreateInterp(void)
|
||||
* Register the builtin math functions.
|
||||
*/
|
||||
|
||||
mathfuncNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathfunc", NULL,NULL);
|
||||
if (mathfuncNSPtr == NULL) {
|
||||
nsPtr = Tcl_CreateNamespace(interp, "::tcl::mathfunc", NULL,NULL);
|
||||
if (nsPtr == NULL) {
|
||||
Tcl_Panic("Can't create math function namespace");
|
||||
}
|
||||
#define MATH_FUNC_PREFIX_LEN 17 /* == strlen("::tcl::mathfunc::") */
|
||||
@@ -916,18 +1005,18 @@ Tcl_CreateInterp(void)
|
||||
strcpy(mathFuncName+MATH_FUNC_PREFIX_LEN, builtinFuncPtr->name);
|
||||
Tcl_CreateObjCommand(interp, mathFuncName,
|
||||
builtinFuncPtr->objCmdProc, builtinFuncPtr->clientData, NULL);
|
||||
Tcl_Export(interp, mathfuncNSPtr, builtinFuncPtr->name, 0);
|
||||
Tcl_Export(interp, nsPtr, builtinFuncPtr->name, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Register the mathematical "operator" commands. [TIP #174]
|
||||
*/
|
||||
|
||||
mathopNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathop", NULL, NULL);
|
||||
if (mathopNSPtr == NULL) {
|
||||
nsPtr = Tcl_CreateNamespace(interp, "::tcl::mathop", NULL, NULL);
|
||||
if (nsPtr == NULL) {
|
||||
Tcl_Panic("can't create math operator namespace");
|
||||
}
|
||||
Tcl_Export(interp, mathopNSPtr, "*", 1);
|
||||
Tcl_Export(interp, nsPtr, "*", 1);
|
||||
#define MATH_OP_PREFIX_LEN 15 /* == strlen("::tcl::mathop::") */
|
||||
memcpy(mathFuncName, "::tcl::mathop::", MATH_OP_PREFIX_LEN);
|
||||
for (opcmdInfoPtr=mathOpCmds ; opcmdInfoPtr->name!=NULL ; opcmdInfoPtr++){
|
||||
@@ -977,11 +1066,11 @@ Tcl_CreateInterp(void)
|
||||
TCL_GLOBAL_ONLY);
|
||||
|
||||
Tcl_SetVar2Ex(interp, "tcl_platform", "wordSize",
|
||||
Tcl_NewLongObj((long) sizeof(long)), TCL_GLOBAL_ONLY);
|
||||
Tcl_NewWideIntObj(sizeof(long)), TCL_GLOBAL_ONLY);
|
||||
|
||||
/* TIP #291 */
|
||||
Tcl_SetVar2Ex(interp, "tcl_platform", "pointerSize",
|
||||
Tcl_NewLongObj((long) sizeof(void *)), TCL_GLOBAL_ONLY);
|
||||
Tcl_NewWideIntObj(sizeof(void *)), TCL_GLOBAL_ONLY);
|
||||
|
||||
/*
|
||||
* Set up other variables such as tcl_version and tcl_library
|
||||
@@ -1135,6 +1224,7 @@ TclHideUnsafeCommands(
|
||||
Tcl_Interp *interp) /* Hide commands in this interpreter. */
|
||||
{
|
||||
register const CmdInfo *cmdInfoPtr;
|
||||
register const UnsafeEnsembleInfo *unsafePtr;
|
||||
|
||||
if (interp == NULL) {
|
||||
return TCL_ERROR;
|
||||
@@ -1144,11 +1234,82 @@ TclHideUnsafeCommands(
|
||||
Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
|
||||
}
|
||||
}
|
||||
TclMakeEncodingCommandSafe(interp); /* Ugh! */
|
||||
TclMakeFileCommandSafe(interp); /* Ugh! */
|
||||
|
||||
for (unsafePtr = unsafeEnsembleCommands;
|
||||
unsafePtr->ensembleNsName; unsafePtr++) {
|
||||
if (unsafePtr->commandName) {
|
||||
/*
|
||||
* Hide an ensemble subcommand.
|
||||
*/
|
||||
|
||||
Tcl_Obj *cmdName = Tcl_ObjPrintf("::tcl::%s::%s",
|
||||
unsafePtr->ensembleNsName, unsafePtr->commandName);
|
||||
Tcl_Obj *hideName = Tcl_ObjPrintf("tcl:%s:%s",
|
||||
unsafePtr->ensembleNsName, unsafePtr->commandName);
|
||||
|
||||
if (TclRenameCommand(interp, TclGetString(cmdName),
|
||||
"___tmp") != TCL_OK
|
||||
|| Tcl_HideCommand(interp, "___tmp",
|
||||
TclGetString(hideName)) != TCL_OK) {
|
||||
Tcl_Panic("problem making '%s %s' safe: %s",
|
||||
unsafePtr->ensembleNsName, unsafePtr->commandName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
Tcl_CreateObjCommand(interp, TclGetString(cmdName),
|
||||
BadEnsembleSubcommand, (ClientData) unsafePtr, NULL);
|
||||
TclDecrRefCount(cmdName);
|
||||
TclDecrRefCount(hideName);
|
||||
} else {
|
||||
/*
|
||||
* Hide an ensemble main command (for compatibility).
|
||||
*/
|
||||
|
||||
if (Tcl_HideCommand(interp, unsafePtr->ensembleNsName,
|
||||
unsafePtr->ensembleNsName) != TCL_OK) {
|
||||
Tcl_Panic("problem making '%s' safe: %s",
|
||||
unsafePtr->ensembleNsName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* BadEnsembleSubcommand --
|
||||
*
|
||||
* Command used to act as a backstop implementation when subcommands of
|
||||
* ensembles are unsafe (the real implementations of the subcommands are
|
||||
* hidden). The clientData is description of what was hidden.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result (always a TCL_ERROR).
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
BadEnsembleSubcommand(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
const UnsafeEnsembleInfo *infoPtr = clientData;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"not allowed to invoke subcommand %s of %s",
|
||||
infoPtr->commandName, infoPtr->ensembleNsName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*--------------------------------------------------------------
|
||||
*
|
||||
@@ -2594,7 +2755,7 @@ TclInvokeStringCommand(
|
||||
Command *cmdPtr = clientData;
|
||||
int i, result;
|
||||
const char **argv =
|
||||
TclStackAlloc(interp, (unsigned)(objc + 1) * sizeof(char *));
|
||||
TclStackAlloc(interp, (objc + 1) * sizeof(char *));
|
||||
|
||||
for (i = 0; i < objc; i++) {
|
||||
argv[i] = TclGetString(objv[i]);
|
||||
@@ -2623,7 +2784,7 @@ TclInvokeStringCommand(
|
||||
* in the Command structure.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl string result value.
|
||||
* A standard Tcl result value.
|
||||
*
|
||||
* Side effects:
|
||||
* Besides those side effects of the called Tcl_ObjCmdProc,
|
||||
@@ -2643,7 +2804,7 @@ TclInvokeObjectCommand(
|
||||
Tcl_Obj *objPtr;
|
||||
int i, length, result;
|
||||
Tcl_Obj **objv =
|
||||
TclStackAlloc(interp, (unsigned)(argc * sizeof(Tcl_Obj *)));
|
||||
TclStackAlloc(interp, (argc * sizeof(Tcl_Obj *)));
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
length = strlen(argv[i]);
|
||||
@@ -3715,9 +3876,14 @@ OldMathFuncProc(
|
||||
valuePtr = objv[j];
|
||||
result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((result != TCL_OK) && (valuePtr->typePtr == &tclDoubleType)) {
|
||||
d = valuePtr->internalRep.doubleValue;
|
||||
result = TCL_OK;
|
||||
if (result != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr
|
||||
= TclFetchIntRep(valuePtr, &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d = irPtr->doubleValue;
|
||||
result = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (result != TCL_OK) {
|
||||
@@ -4250,7 +4416,7 @@ Tcl_CancelEval(
|
||||
if (resultObjPtr != NULL) {
|
||||
result = TclGetStringFromObj(resultObjPtr, &cancelInfo->length);
|
||||
cancelInfo->result = ckrealloc(cancelInfo->result,cancelInfo->length);
|
||||
memcpy(cancelInfo->result, result, (size_t) cancelInfo->length);
|
||||
memcpy(cancelInfo->result, result, cancelInfo->length);
|
||||
TclDecrRefCount(resultObjPtr); /* Discard their result object. */
|
||||
} else {
|
||||
cancelInfo->result = NULL;
|
||||
@@ -4818,7 +4984,7 @@ TEOV_NotFound(
|
||||
Tcl_ListObjGetElements(NULL, currNsPtr->unknownHandlerPtr,
|
||||
&handlerObjc, &handlerObjv);
|
||||
newObjc = objc + handlerObjc;
|
||||
newObjv = TclStackAlloc(interp, (int) sizeof(Tcl_Obj *) * newObjc);
|
||||
newObjv = TclStackAlloc(interp, sizeof(Tcl_Obj *) * newObjc);
|
||||
|
||||
/*
|
||||
* Copy command prefix from unknown handler and add on the real command's
|
||||
@@ -4830,7 +4996,7 @@ TEOV_NotFound(
|
||||
newObjv[i] = handlerObjv[i];
|
||||
Tcl_IncrRefCount(newObjv[i]);
|
||||
}
|
||||
memcpy(newObjv+handlerObjc, objv, sizeof(Tcl_Obj *) * (unsigned)objc);
|
||||
memcpy(newObjv+handlerObjc, objv, sizeof(Tcl_Obj *) * objc);
|
||||
|
||||
/*
|
||||
* Look up and invoke the handler (by recursive call to this function). If
|
||||
@@ -5999,7 +6165,7 @@ TclArgumentGet(
|
||||
* up by the caller. It knows better than us.
|
||||
*/
|
||||
|
||||
if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) {
|
||||
if (!TclHasStringRep(obj) || TclListObjIsCanonical(obj)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6620,7 +6786,7 @@ Tcl_ExprLongObj(
|
||||
resultPtr = Tcl_NewBignumObj(&big);
|
||||
/* FALLTHROUGH */
|
||||
}
|
||||
case TCL_NUMBER_WIDE:
|
||||
case TCL_NUMBER_INT:
|
||||
case TCL_NUMBER_BIG:
|
||||
result = TclGetLongFromObj(interp, resultPtr, ptr);
|
||||
break;
|
||||
@@ -6863,7 +7029,7 @@ Tcl_ExprString(
|
||||
* An empty string. Just set the interpreter's result to 0.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
} else {
|
||||
Tcl_Obj *resultPtr, *exprObj = Tcl_NewStringObj(expr, -1);
|
||||
|
||||
@@ -7276,9 +7442,13 @@ ExprCeilFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7312,9 +7482,13 @@ ExprFloorFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7386,7 +7560,7 @@ ExprIsqrtFunc(
|
||||
if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (SIGN(&big) == MP_NEG) {
|
||||
if (big.sign != MP_ZPOS) {
|
||||
mp_clear(&big);
|
||||
goto negarg;
|
||||
}
|
||||
@@ -7448,9 +7622,13 @@ ExprSqrtFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7491,10 +7669,14 @@ ExprUnaryFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
d = objv[1]->internalRep.doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d = irPtr->doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7551,10 +7733,14 @@ ExprBinaryFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[1], &d1);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
|
||||
d1 = objv[1]->internalRep.doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d1 = irPtr->doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7562,10 +7748,14 @@ ExprBinaryFunc(
|
||||
}
|
||||
code = Tcl_GetDoubleFromObj(interp, objv[2], &d2);
|
||||
#ifdef ACCEPT_NAN
|
||||
if ((code != TCL_OK) && (objv[2]->typePtr == &tclDoubleType)) {
|
||||
d2 = objv[2]->internalRep.doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
if (code != TCL_OK) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objv[1], &tclDoubleType);
|
||||
|
||||
if (irPtr) {
|
||||
d2 = irPtr->doubleValue;
|
||||
Tcl_ResetResult(interp);
|
||||
code = TCL_OK;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (code != TCL_OK) {
|
||||
@@ -7596,20 +7786,22 @@ ExprAbsFunc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (type == TCL_NUMBER_WIDE) {
|
||||
if (type == TCL_NUMBER_INT) {
|
||||
Tcl_WideInt l = *((const Tcl_WideInt *) ptr);
|
||||
|
||||
if (l > (Tcl_WideInt)0) {
|
||||
if (l > 0) {
|
||||
goto unChanged;
|
||||
} else if (l == (Tcl_WideInt)0) {
|
||||
const char *string = objv[1]->bytes;
|
||||
if (string) {
|
||||
while (*string != '0') {
|
||||
if (*string == '-') {
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
|
||||
} else if (l == 0) {
|
||||
if (TclHasStringRep(objv[1])) {
|
||||
int numBytes;
|
||||
const char *bytes = TclGetStringFromObj(objv[1], &numBytes);
|
||||
|
||||
while (numBytes) {
|
||||
if (*bytes == '-') {
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
return TCL_OK;
|
||||
}
|
||||
string++;
|
||||
bytes++; numBytes--;
|
||||
}
|
||||
}
|
||||
goto unChanged;
|
||||
@@ -7642,7 +7834,7 @@ ExprAbsFunc(
|
||||
}
|
||||
|
||||
if (type == TCL_NUMBER_BIG) {
|
||||
if (mp_isneg((const mp_int *) ptr)) {
|
||||
if (((const mp_int *) ptr)->sign != MP_ZPOS) {
|
||||
Tcl_GetBignumFromObj(NULL, objv[1], &big);
|
||||
tooLarge:
|
||||
mp_neg(&big, &big);
|
||||
@@ -7705,7 +7897,7 @@ ExprDoubleFunc(
|
||||
}
|
||||
if (Tcl_GetDoubleFromObj(interp, objv[1], &dResult) != TCL_OK) {
|
||||
#ifdef ACCEPT_NAN
|
||||
if (objv[1]->typePtr == &tclDoubleType) {
|
||||
if (TclHasIntRep(objv[1], &tclDoubleType)) {
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -7717,7 +7909,7 @@ ExprDoubleFunc(
|
||||
}
|
||||
|
||||
static int
|
||||
ExprEntierFunc(
|
||||
ExprIntFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
Tcl_Interp *interp, /* The interpreter in which to execute the
|
||||
* function. */
|
||||
@@ -7772,25 +7964,6 @@ ExprEntierFunc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
ExprIntFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
Tcl_Interp *interp, /* The interpreter in which to execute the
|
||||
* function. */
|
||||
int objc, /* Actual parameter count. */
|
||||
Tcl_Obj *const *objv) /* Actual parameter vector. */
|
||||
{
|
||||
Tcl_WideInt wResult;
|
||||
Tcl_Obj *objPtr;
|
||||
if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objPtr = Tcl_GetObjResult(interp);
|
||||
TclGetWideBitsFromObj(NULL, objPtr, &wResult);
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj((long)wResult));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
ExprWideFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
@@ -7801,7 +7974,7 @@ ExprWideFunc(
|
||||
{
|
||||
Tcl_WideInt wResult;
|
||||
|
||||
if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
|
||||
if (ExprIntFunc(NULL, interp, objc, objv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclGetWideBitsFromObj(NULL, Tcl_GetObjResult(interp), &wResult);
|
||||
@@ -7990,7 +8163,7 @@ ExprRoundFunc(
|
||||
|
||||
if (type == TCL_NUMBER_DOUBLE) {
|
||||
double fractPart, intPart;
|
||||
long max = LONG_MAX, min = LONG_MIN;
|
||||
Tcl_WideInt max = WIDE_MAX, min = WIDE_MIN;
|
||||
|
||||
fractPart = modf(*((const double *) ptr), &intPart);
|
||||
if (fractPart <= -0.5) {
|
||||
@@ -8013,14 +8186,14 @@ ExprRoundFunc(
|
||||
Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
|
||||
return TCL_OK;
|
||||
} else {
|
||||
long result = (long)intPart;
|
||||
Tcl_WideInt result = (Tcl_WideInt)intPart;
|
||||
|
||||
if (fractPart <= -0.5) {
|
||||
result--;
|
||||
} else if (fractPart >= 0.5) {
|
||||
result++;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
+164
-102
@@ -15,6 +15,7 @@
|
||||
#include "tommath.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*
|
||||
* The following constants are used by GetFormatSpec to indicate various
|
||||
@@ -56,9 +57,12 @@
|
||||
|
||||
static void DupByteArrayInternalRep(Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *copyPtr);
|
||||
static void DupProperByteArrayInternalRep(Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *copyPtr);
|
||||
static int FormatNumber(Tcl_Interp *interp, int type,
|
||||
Tcl_Obj *src, unsigned char **cursorPtr);
|
||||
static void FreeByteArrayInternalRep(Tcl_Obj *objPtr);
|
||||
static void FreeProperByteArrayInternalRep(Tcl_Obj *objPtr);
|
||||
static int GetFormatSpec(const char **formatPtr, char *cmdPtr,
|
||||
int *countPtr, int *flagsPtr);
|
||||
static Tcl_Obj * ScanNumber(unsigned char *buffer, int type,
|
||||
@@ -246,8 +250,8 @@ static const EnsembleImplMap decodeMap[] = {
|
||||
|
||||
static const Tcl_ObjType properByteArrayType = {
|
||||
"bytearray",
|
||||
FreeByteArrayInternalRep,
|
||||
DupByteArrayInternalRep,
|
||||
FreeProperByteArrayInternalRep,
|
||||
DupProperByteArrayInternalRep,
|
||||
UpdateStringOfByteArray,
|
||||
NULL
|
||||
};
|
||||
@@ -268,9 +272,9 @@ const Tcl_ObjType tclByteArrayType = {
|
||||
*/
|
||||
|
||||
typedef struct ByteArray {
|
||||
int used; /* The number of bytes used in the byte
|
||||
unsigned int used; /* The number of bytes used in the byte
|
||||
* array. */
|
||||
int allocated; /* The amount of space actually allocated
|
||||
unsigned int allocated; /* The amount of space actually allocated
|
||||
* minus 1 byte. */
|
||||
unsigned char bytes[1]; /* The array of bytes. The actual size of this
|
||||
* field depends on the 'allocated' field
|
||||
@@ -279,16 +283,15 @@ typedef struct ByteArray {
|
||||
|
||||
#define BYTEARRAY_SIZE(len) \
|
||||
((unsigned) (TclOffset(ByteArray, bytes) + (len)))
|
||||
#define GET_BYTEARRAY(objPtr) \
|
||||
((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1)
|
||||
#define SET_BYTEARRAY(objPtr, baPtr) \
|
||||
(objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr)
|
||||
#define GET_BYTEARRAY(irPtr) ((ByteArray *) (irPtr)->twoPtrValue.ptr1)
|
||||
#define SET_BYTEARRAY(irPtr, baPtr) \
|
||||
(irPtr)->twoPtrValue.ptr1 = (void *) (baPtr)
|
||||
|
||||
int
|
||||
TclIsPureByteArray(
|
||||
Tcl_Obj * objPtr)
|
||||
{
|
||||
return (objPtr->typePtr == &properByteArrayType);
|
||||
return TclHasIntRep(objPtr, &properByteArrayType);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -403,11 +406,11 @@ Tcl_SetByteArrayObj(
|
||||
be >= 0. */
|
||||
{
|
||||
ByteArray *byteArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayObj");
|
||||
}
|
||||
TclFreeIntRep(objPtr);
|
||||
TclInvalidateStringRep(objPtr);
|
||||
|
||||
if (length < 0) {
|
||||
@@ -418,10 +421,11 @@ Tcl_SetByteArrayObj(
|
||||
byteArrayPtr->allocated = length;
|
||||
|
||||
if ((bytes != NULL) && (length > 0)) {
|
||||
memcpy(byteArrayPtr->bytes, bytes, (size_t) length);
|
||||
memcpy(byteArrayPtr->bytes, bytes, length);
|
||||
}
|
||||
objPtr->typePtr = &properByteArrayType;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
SET_BYTEARRAY(&ir, byteArrayPtr);
|
||||
|
||||
Tcl_StoreIntRep(objPtr, &properByteArrayType, &ir);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -449,17 +453,24 @@ Tcl_GetByteArrayFromObj(
|
||||
* array of bytes in the ByteArray object. */
|
||||
{
|
||||
ByteArray *baPtr;
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
|
||||
if ((objPtr->typePtr != &properByteArrayType)
|
||||
&& (objPtr->typePtr != &tclByteArrayType)) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
}
|
||||
}
|
||||
}
|
||||
baPtr = GET_BYTEARRAY(objPtr);
|
||||
baPtr = GET_BYTEARRAY(irPtr);
|
||||
|
||||
if (lengthPtr != NULL) {
|
||||
*lengthPtr = baPtr->used;
|
||||
}
|
||||
return (unsigned char *) baPtr->bytes;
|
||||
return baPtr->bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -490,23 +501,36 @@ Tcl_SetByteArrayLength(
|
||||
int length) /* New length for internal byte array. */
|
||||
{
|
||||
ByteArray *byteArrayPtr;
|
||||
unsigned newLength;
|
||||
Tcl_ObjIntRep *irPtr;
|
||||
|
||||
assert(length >= 0);
|
||||
newLength = (unsigned int)length;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayLength");
|
||||
}
|
||||
if ((objPtr->typePtr != &properByteArrayType)
|
||||
&& (objPtr->typePtr != &tclByteArrayType)) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byteArrayPtr = GET_BYTEARRAY(objPtr);
|
||||
if (length > byteArrayPtr->allocated) {
|
||||
byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(length));
|
||||
byteArrayPtr->allocated = length;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
byteArrayPtr = GET_BYTEARRAY(irPtr);
|
||||
if (newLength > byteArrayPtr->allocated) {
|
||||
byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(newLength));
|
||||
byteArrayPtr->allocated = newLength;
|
||||
SET_BYTEARRAY(irPtr, byteArrayPtr);
|
||||
}
|
||||
TclInvalidateStringRep(objPtr);
|
||||
byteArrayPtr->used = length;
|
||||
byteArrayPtr->used = newLength;
|
||||
return byteArrayPtr->bytes;
|
||||
}
|
||||
|
||||
@@ -535,13 +559,14 @@ SetByteArrayFromAny(
|
||||
int improper = 0;
|
||||
const char *src, *srcEnd;
|
||||
unsigned char *dst;
|
||||
ByteArray *byteArrayPtr;
|
||||
Tcl_UniChar ch = 0;
|
||||
ByteArray *byteArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
if (objPtr->typePtr == &properByteArrayType) {
|
||||
if (TclHasIntRep(objPtr, &properByteArrayType)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclByteArrayType) {
|
||||
if (TclHasIntRep(objPtr, &tclByteArrayType)) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -559,9 +584,9 @@ SetByteArrayFromAny(
|
||||
byteArrayPtr->used = dst - byteArrayPtr->bytes;
|
||||
byteArrayPtr->allocated = length;
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->typePtr = improper ? &tclByteArrayType : &properByteArrayType;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
SET_BYTEARRAY(&ir, byteArrayPtr);
|
||||
Tcl_StoreIntRep(objPtr,
|
||||
improper ? &tclByteArrayType : &properByteArrayType, &ir);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -586,8 +611,14 @@ static void
|
||||
FreeByteArrayInternalRep(
|
||||
Tcl_Obj *objPtr) /* Object with internal rep to free. */
|
||||
{
|
||||
ckfree(GET_BYTEARRAY(objPtr));
|
||||
objPtr->typePtr = NULL;
|
||||
ckfree(GET_BYTEARRAY(TclFetchIntRep(objPtr, &tclByteArrayType)));
|
||||
}
|
||||
|
||||
static void
|
||||
FreeProperByteArrayInternalRep(
|
||||
Tcl_Obj *objPtr) /* Object with internal rep to free. */
|
||||
{
|
||||
ckfree(GET_BYTEARRAY(TclFetchIntRep(objPtr, &properByteArrayType)));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -612,19 +643,41 @@ DupByteArrayInternalRep(
|
||||
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
|
||||
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
{
|
||||
int length;
|
||||
unsigned int length;
|
||||
ByteArray *srcArrayPtr, *copyArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
srcArrayPtr = GET_BYTEARRAY(srcPtr);
|
||||
srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &tclByteArrayType));
|
||||
length = srcArrayPtr->used;
|
||||
|
||||
copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
|
||||
copyArrayPtr->used = length;
|
||||
copyArrayPtr->allocated = length;
|
||||
memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, (size_t) length);
|
||||
SET_BYTEARRAY(copyPtr, copyArrayPtr);
|
||||
memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length);
|
||||
|
||||
copyPtr->typePtr = srcPtr->typePtr;
|
||||
SET_BYTEARRAY(&ir, copyArrayPtr);
|
||||
Tcl_StoreIntRep(copyPtr, &tclByteArrayType, &ir);
|
||||
}
|
||||
|
||||
static void
|
||||
DupProperByteArrayInternalRep(
|
||||
Tcl_Obj *srcPtr, /* Object with internal rep to copy. */
|
||||
Tcl_Obj *copyPtr) /* Object with internal rep to set. */
|
||||
{
|
||||
unsigned int length;
|
||||
ByteArray *srcArrayPtr, *copyArrayPtr;
|
||||
Tcl_ObjIntRep ir;
|
||||
|
||||
srcArrayPtr = GET_BYTEARRAY(TclFetchIntRep(srcPtr, &properByteArrayType));
|
||||
length = srcArrayPtr->used;
|
||||
|
||||
copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
|
||||
copyArrayPtr->used = length;
|
||||
copyArrayPtr->allocated = length;
|
||||
memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, length);
|
||||
|
||||
SET_BYTEARRAY(&ir, copyArrayPtr);
|
||||
Tcl_StoreIntRep(copyPtr, &properByteArrayType, &ir);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -632,9 +685,7 @@ DupByteArrayInternalRep(
|
||||
*
|
||||
* UpdateStringOfByteArray --
|
||||
*
|
||||
* Update the string representation for a ByteArray data object. Note:
|
||||
* This procedure does not invalidate an existing old string rep so
|
||||
* storage will be lost if this has not already been done.
|
||||
* Update the string representation for a ByteArray data object.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -643,9 +694,6 @@ DupByteArrayInternalRep(
|
||||
* The object's string is set to a valid string that results from the
|
||||
* ByteArray-to-string conversion.
|
||||
*
|
||||
* The object becomes a string object -- the internal rep is discarded
|
||||
* and the typePtr becomes NULL.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -654,41 +702,35 @@ UpdateStringOfByteArray(
|
||||
Tcl_Obj *objPtr) /* ByteArray object whose string rep to
|
||||
* update. */
|
||||
{
|
||||
int i, length, size;
|
||||
unsigned char *src;
|
||||
char *dst;
|
||||
ByteArray *byteArrayPtr;
|
||||
|
||||
byteArrayPtr = GET_BYTEARRAY(objPtr);
|
||||
src = byteArrayPtr->bytes;
|
||||
length = byteArrayPtr->used;
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
ByteArray *byteArrayPtr = GET_BYTEARRAY(irPtr);
|
||||
unsigned char *src = byteArrayPtr->bytes;
|
||||
unsigned int i, length = byteArrayPtr->used;
|
||||
unsigned int size = length;
|
||||
|
||||
/*
|
||||
* How much space will string rep need?
|
||||
*/
|
||||
|
||||
size = length;
|
||||
for (i = 0; i < length && size >= 0; i++) {
|
||||
for (i = 0; i < length && size <= INT_MAX; i++) {
|
||||
if ((src[i] == 0) || (src[i] > 127)) {
|
||||
size++;
|
||||
}
|
||||
}
|
||||
if (size < 0) {
|
||||
if (size > INT_MAX) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
|
||||
dst = ckalloc(size + 1);
|
||||
objPtr->bytes = dst;
|
||||
objPtr->length = size;
|
||||
|
||||
if (size == length) {
|
||||
memcpy(dst, src, (size_t) size);
|
||||
dst[size] = '\0';
|
||||
char *dst = Tcl_InitStringRep(objPtr, (char *)src, size);
|
||||
TclOOM(dst, size);
|
||||
} else {
|
||||
char *dst = Tcl_InitStringRep(objPtr, NULL, size);
|
||||
TclOOM(dst, size);
|
||||
for (i = 0; i < length; i++) {
|
||||
dst += Tcl_UniCharToUtf(src[i], dst);
|
||||
}
|
||||
*dst = '\0';
|
||||
(void)Tcl_InitStringRep(objPtr, NULL, size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,7 +760,8 @@ TclAppendBytesToByteArray(
|
||||
int len)
|
||||
{
|
||||
ByteArray *byteArrayPtr;
|
||||
int needed;
|
||||
unsigned int length, needed;
|
||||
Tcl_ObjIntRep *irPtr;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
|
||||
@@ -731,24 +774,34 @@ TclAppendBytesToByteArray(
|
||||
/* Append zero bytes is a no-op. */
|
||||
return;
|
||||
}
|
||||
if ((objPtr->typePtr != &properByteArrayType)
|
||||
&& (objPtr->typePtr != &tclByteArrayType)) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
}
|
||||
byteArrayPtr = GET_BYTEARRAY(objPtr);
|
||||
|
||||
if (len > INT_MAX - byteArrayPtr->used) {
|
||||
length = (unsigned int)len;
|
||||
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
irPtr = TclFetchIntRep(objPtr, &properByteArrayType);
|
||||
if (irPtr == NULL) {
|
||||
irPtr = TclFetchIntRep(objPtr, &tclByteArrayType);
|
||||
}
|
||||
}
|
||||
}
|
||||
byteArrayPtr = GET_BYTEARRAY(irPtr);
|
||||
|
||||
if (length > INT_MAX - byteArrayPtr->used) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
|
||||
needed = byteArrayPtr->used + len;
|
||||
needed = byteArrayPtr->used + length;
|
||||
/*
|
||||
* If we need to, resize the allocated space in the byte array.
|
||||
*/
|
||||
|
||||
if (needed > byteArrayPtr->allocated) {
|
||||
ByteArray *ptr = NULL;
|
||||
int attempt;
|
||||
unsigned int attempt;
|
||||
|
||||
if (needed <= INT_MAX/2) {
|
||||
/* Try to allocate double the total space that is needed. */
|
||||
@@ -758,7 +811,7 @@ TclAppendBytesToByteArray(
|
||||
if (ptr == NULL) {
|
||||
/* Try to allocate double the increment that is needed (plus). */
|
||||
unsigned int limit = INT_MAX - needed;
|
||||
unsigned int extra = len + TCL_MIN_GROWTH;
|
||||
unsigned int extra = length + TCL_MIN_GROWTH;
|
||||
int growth = (int) ((extra > limit) ? limit : extra);
|
||||
|
||||
attempt = needed + growth;
|
||||
@@ -771,13 +824,13 @@ TclAppendBytesToByteArray(
|
||||
}
|
||||
byteArrayPtr = ptr;
|
||||
byteArrayPtr->allocated = attempt;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
SET_BYTEARRAY(irPtr, byteArrayPtr);
|
||||
}
|
||||
|
||||
if (bytes) {
|
||||
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
|
||||
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, length);
|
||||
}
|
||||
byteArrayPtr->used += len;
|
||||
byteArrayPtr->used += length;
|
||||
TclInvalidateStringRep(objPtr);
|
||||
}
|
||||
|
||||
@@ -1023,7 +1076,7 @@ BinaryFormatCmd(
|
||||
|
||||
resultPtr = Tcl_NewObj();
|
||||
buffer = Tcl_SetByteArrayLength(resultPtr, length);
|
||||
memset(buffer, 0, (size_t) length);
|
||||
memset(buffer, 0, length);
|
||||
|
||||
/*
|
||||
* Pack the data into the result object. Note that we can skip the
|
||||
@@ -1060,10 +1113,10 @@ BinaryFormatCmd(
|
||||
count = 1;
|
||||
}
|
||||
if (length >= count) {
|
||||
memcpy(cursor, bytes, (size_t) count);
|
||||
memcpy(cursor, bytes, count);
|
||||
} else {
|
||||
memcpy(cursor, bytes, (size_t) length);
|
||||
memset(cursor + length, pad, (size_t) (count - length));
|
||||
memcpy(cursor, bytes, length);
|
||||
memset(cursor + length, pad, count - length);
|
||||
}
|
||||
cursor += count;
|
||||
break;
|
||||
@@ -1252,7 +1305,7 @@ BinaryFormatCmd(
|
||||
if (count == BINARY_NOCOUNT) {
|
||||
count = 1;
|
||||
}
|
||||
memset(cursor, 0, (size_t) count);
|
||||
memset(cursor, 0, count);
|
||||
cursor += count;
|
||||
break;
|
||||
case 'X':
|
||||
@@ -1301,7 +1354,7 @@ BinaryFormatCmd(
|
||||
badField:
|
||||
{
|
||||
Tcl_UniChar ch = 0;
|
||||
char buf[TCL_UTF_MAX + 1];
|
||||
char buf[TCL_UTF_MAX + 1] = "";
|
||||
|
||||
TclUtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
@@ -1655,7 +1708,7 @@ BinaryScanCmd(
|
||||
*/
|
||||
|
||||
done:
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(arg - 3));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(arg - 3));
|
||||
DeleteScanNumberCache(numberCachePtr);
|
||||
|
||||
return TCL_OK;
|
||||
@@ -1671,7 +1724,7 @@ BinaryScanCmd(
|
||||
badField:
|
||||
{
|
||||
Tcl_UniChar ch = 0;
|
||||
char buf[TCL_UTF_MAX + 1];
|
||||
char buf[TCL_UTF_MAX + 1] = "";
|
||||
|
||||
TclUtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
@@ -1978,10 +2031,11 @@ FormatNumber(
|
||||
*/
|
||||
|
||||
if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
|
||||
if (src->typePtr != &tclDoubleType) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(src, &tclDoubleType);
|
||||
if (irPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dvalue = src->internalRep.doubleValue;
|
||||
dvalue = irPtr->doubleValue;
|
||||
}
|
||||
CopyNumber(&dvalue, *cursorPtr, sizeof(double), type);
|
||||
*cursorPtr += sizeof(double);
|
||||
@@ -1997,10 +2051,11 @@ FormatNumber(
|
||||
*/
|
||||
|
||||
if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
|
||||
if (src->typePtr != &tclDoubleType) {
|
||||
const Tcl_ObjIntRep *irPtr = TclFetchIntRep(src, &tclDoubleType);
|
||||
if (irPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dvalue = src->internalRep.doubleValue;
|
||||
dvalue = irPtr->doubleValue;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2220,7 +2275,7 @@ ScanNumber(
|
||||
|
||||
returnNumericObject:
|
||||
if (*numberCachePtrPtr == NULL) {
|
||||
return Tcl_NewLongObj(value);
|
||||
return Tcl_NewWideIntObj(value);
|
||||
} else {
|
||||
register Tcl_HashTable *tablePtr = *numberCachePtrPtr;
|
||||
register Tcl_HashEntry *hPtr;
|
||||
@@ -2231,7 +2286,7 @@ ScanNumber(
|
||||
return Tcl_GetHashValue(hPtr);
|
||||
}
|
||||
if (tablePtr->numEntries <= BINARY_SCAN_MAX_CACHE) {
|
||||
register Tcl_Obj *objPtr = Tcl_NewLongObj(value);
|
||||
register Tcl_Obj *objPtr = Tcl_NewWideIntObj(value);
|
||||
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
Tcl_SetHashValue(hPtr, objPtr);
|
||||
@@ -2249,7 +2304,7 @@ ScanNumber(
|
||||
|
||||
DeleteScanNumberCache(tablePtr);
|
||||
*numberCachePtrPtr = NULL;
|
||||
return Tcl_NewLongObj(value);
|
||||
return Tcl_NewWideIntObj(value);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2483,8 +2538,8 @@ BinaryDecodeHex(
|
||||
}
|
||||
|
||||
c = *data++;
|
||||
if (!isxdigit((int) c)) {
|
||||
if (strict || !isspace(c)) {
|
||||
if (!isxdigit(UCHAR(c))) {
|
||||
if (strict || !TclIsSpaceProc(c)) {
|
||||
goto badChar;
|
||||
}
|
||||
i--;
|
||||
@@ -2831,7 +2886,7 @@ BinaryDecodeUu(
|
||||
if (lineLen < 0) {
|
||||
c = *data++;
|
||||
if (c < 32 || c > 96) {
|
||||
if (strict || !isspace(c)) {
|
||||
if (strict || !TclIsSpaceProc(c)) {
|
||||
goto badUu;
|
||||
}
|
||||
i--;
|
||||
@@ -2849,7 +2904,7 @@ BinaryDecodeUu(
|
||||
d[i] = c = *data++;
|
||||
if (c < 32 || c > 96) {
|
||||
if (strict) {
|
||||
if (!isspace(c)) {
|
||||
if (!TclIsSpaceProc(c)) {
|
||||
goto badUu;
|
||||
} else if (c == '\n') {
|
||||
goto shortUu;
|
||||
@@ -2893,7 +2948,7 @@ BinaryDecodeUu(
|
||||
} else if (c >= 32 && c <= 96) {
|
||||
data--;
|
||||
break;
|
||||
} else if (strict || !isspace(c)) {
|
||||
} else if (strict || !TclIsSpaceProc(c)) {
|
||||
goto badUu;
|
||||
}
|
||||
} while (data < dataend);
|
||||
@@ -3003,6 +3058,11 @@ BinaryDecode64(
|
||||
} else if (i > 1) {
|
||||
c = '=';
|
||||
} else {
|
||||
if (strict && i <= 1) {
|
||||
/* single resp. unfulfilled char (each 4th next single char)
|
||||
* is rather bad64 error case in strict mode */
|
||||
goto bad64;
|
||||
}
|
||||
cut += 3;
|
||||
break;
|
||||
}
|
||||
@@ -3018,7 +3078,7 @@ BinaryDecode64(
|
||||
if (c == '=' && i > 1) {
|
||||
value <<= 6;
|
||||
cut++;
|
||||
} else if (!strict && isspace(c)) {
|
||||
} else if (!strict && TclIsSpaceProc(c)) {
|
||||
i--;
|
||||
} else {
|
||||
goto bad64;
|
||||
@@ -3033,10 +3093,12 @@ BinaryDecode64(
|
||||
value = (value << 6) | 0x3e;
|
||||
} else if (c == '/') {
|
||||
value = (value << 6) | 0x3f;
|
||||
} else if (c == '=') {
|
||||
} else if (c == '=' && (
|
||||
!strict || i > 1) /* "=" and "a=" is rather bad64 error case in strict mode */
|
||||
) {
|
||||
value <<= 6;
|
||||
cut++;
|
||||
} else if (strict || !isspace(c)) {
|
||||
if (i) cut++;
|
||||
} else if (strict || !TclIsSpaceProc(c)) {
|
||||
goto bad64;
|
||||
} else {
|
||||
i--;
|
||||
@@ -3057,7 +3119,7 @@ BinaryDecode64(
|
||||
goto bad64;
|
||||
}
|
||||
for (; data < dataend; data++) {
|
||||
if (!isspace(*data)) {
|
||||
if (!TclIsSpaceProc(*data)) {
|
||||
goto bad64;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +405,7 @@ Tcl_DbCkalloc(
|
||||
|
||||
/* Don't let size argument to TclpAlloc overflow */
|
||||
if (size <= UINT_MAX - HIGH_GUARD_SIZE -sizeof(struct mem_header)) {
|
||||
result = (struct mem_header *) TclpAlloc((unsigned)size +
|
||||
result = (struct mem_header *) TclpAlloc(size +
|
||||
sizeof(struct mem_header) + HIGH_GUARD_SIZE);
|
||||
}
|
||||
if (result == NULL) {
|
||||
@@ -495,7 +495,7 @@ Tcl_AttemptDbCkalloc(
|
||||
|
||||
/* Don't let size argument to TclpAlloc overflow */
|
||||
if (size <= UINT_MAX - HIGH_GUARD_SIZE - sizeof(struct mem_header)) {
|
||||
result = (struct mem_header *) TclpAlloc((unsigned)size +
|
||||
result = (struct mem_header *) TclpAlloc(size +
|
||||
sizeof(struct mem_header) + HIGH_GUARD_SIZE);
|
||||
}
|
||||
if (result == NULL) {
|
||||
@@ -691,7 +691,7 @@ Tcl_DbCkrealloc(
|
||||
copySize = memp->length;
|
||||
}
|
||||
newPtr = Tcl_DbCkalloc(size, file, line);
|
||||
memcpy(newPtr, ptr, (size_t) copySize);
|
||||
memcpy(newPtr, ptr, copySize);
|
||||
Tcl_DbCkfree(ptr, file, line);
|
||||
return newPtr;
|
||||
}
|
||||
@@ -725,7 +725,7 @@ Tcl_AttemptDbCkrealloc(
|
||||
if (newPtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
memcpy(newPtr, ptr, (size_t) copySize);
|
||||
memcpy(newPtr, ptr, copySize);
|
||||
Tcl_DbCkfree(ptr, file, line);
|
||||
return newPtr;
|
||||
}
|
||||
|
||||
+15
-20
@@ -452,7 +452,7 @@ ClockGetdatefieldsObjCmd(
|
||||
* that it isn't.
|
||||
*/
|
||||
|
||||
if (objv[1]->typePtr == &tclBignumType) {
|
||||
if (TclHasIntRep(objv[1], &tclBignumType)) {
|
||||
Tcl_SetObjResult(interp, literals[LIT_INTEGER_VALUE_TOO_LARGE]);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -488,27 +488,27 @@ ClockGetdatefieldsObjCmd(
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_TZNAME], fields.tzName);
|
||||
Tcl_DecrRefCount(fields.tzName);
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_TZOFFSET],
|
||||
Tcl_NewIntObj(fields.tzOffset));
|
||||
Tcl_NewWideIntObj(fields.tzOffset));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_JULIANDAY],
|
||||
Tcl_NewIntObj(fields.julianDay));
|
||||
Tcl_NewWideIntObj(fields.julianDay));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_GREGORIAN],
|
||||
Tcl_NewIntObj(fields.gregorian));
|
||||
Tcl_NewWideIntObj(fields.gregorian));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_ERA],
|
||||
literals[fields.era ? LIT_BCE : LIT_CE]);
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_YEAR],
|
||||
Tcl_NewIntObj(fields.year));
|
||||
Tcl_NewWideIntObj(fields.year));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFYEAR],
|
||||
Tcl_NewIntObj(fields.dayOfYear));
|
||||
Tcl_NewWideIntObj(fields.dayOfYear));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_MONTH],
|
||||
Tcl_NewIntObj(fields.month));
|
||||
Tcl_NewWideIntObj(fields.month));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFMONTH],
|
||||
Tcl_NewIntObj(fields.dayOfMonth));
|
||||
Tcl_NewWideIntObj(fields.dayOfMonth));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601YEAR],
|
||||
Tcl_NewIntObj(fields.iso8601Year));
|
||||
Tcl_NewWideIntObj(fields.iso8601Year));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601WEEK],
|
||||
Tcl_NewIntObj(fields.iso8601Week));
|
||||
Tcl_NewWideIntObj(fields.iso8601Week));
|
||||
Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFWEEK],
|
||||
Tcl_NewIntObj(fields.dayOfWeek));
|
||||
Tcl_NewWideIntObj(fields.dayOfWeek));
|
||||
Tcl_SetObjResult(interp, dict);
|
||||
|
||||
return TCL_OK;
|
||||
@@ -628,7 +628,7 @@ ClockGetjuliandayfromerayearmonthdayObjCmd(
|
||||
copied = 1;
|
||||
}
|
||||
status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
|
||||
Tcl_NewIntObj(fields.julianDay));
|
||||
Tcl_NewWideIntObj(fields.julianDay));
|
||||
if (status == TCL_OK) {
|
||||
Tcl_SetObjResult(interp, dict);
|
||||
}
|
||||
@@ -712,7 +712,7 @@ ClockGetjuliandayfromerayearweekdayObjCmd(
|
||||
copied = 1;
|
||||
}
|
||||
status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
|
||||
Tcl_NewIntObj(fields.julianDay));
|
||||
Tcl_NewWideIntObj(fields.julianDay));
|
||||
if (status == TCL_OK) {
|
||||
Tcl_SetObjResult(interp, dict);
|
||||
}
|
||||
@@ -1772,8 +1772,7 @@ ClockClicksObjCmd(
|
||||
#endif
|
||||
break;
|
||||
case CLICKS_MICROS:
|
||||
Tcl_GetTime(&now);
|
||||
clicks = ((Tcl_WideInt) now.sec * 1000000) + now.usec;
|
||||
clicks = TclpGetMicroseconds();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1843,15 +1842,11 @@ ClockMicrosecondsObjCmd(
|
||||
int objc, /* Parameter count */
|
||||
Tcl_Obj *const *objv) /* Parameter values */
|
||||
{
|
||||
Tcl_Time now;
|
||||
|
||||
if (objc != 1) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_GetTime(&now);
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
|
||||
((Tcl_WideInt) now.sec * 1000000) + now.usec));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclpGetMicroseconds()));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
+46
-292
@@ -46,9 +46,6 @@ struct ForeachState {
|
||||
|
||||
static int CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr,
|
||||
int mode);
|
||||
static int BadEncodingSubcommand(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int EncodingConvertfromObjCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -84,7 +81,6 @@ static Tcl_NRPostProc ForPostNextCallback;
|
||||
static Tcl_NRPostProc ForeachLoopStep;
|
||||
static Tcl_NRPostProc EvalCmdErrMsg;
|
||||
|
||||
static Tcl_ObjCmdProc BadFileSubcommand;
|
||||
static Tcl_ObjCmdProc FileAttrAccessTimeCmd;
|
||||
static Tcl_ObjCmdProc FileAttrIsDirectoryCmd;
|
||||
static Tcl_ObjCmdProc FileAttrIsExecutableCmd;
|
||||
@@ -386,7 +382,7 @@ CatchObjCmdCallback(
|
||||
}
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(result));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -536,122 +532,15 @@ TclInitEncodingCmd(
|
||||
static const EnsembleImplMap encodingImplMap[] = {
|
||||
{"convertfrom", EncodingConvertfromObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"convertto", EncodingConverttoObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"dirs", EncodingDirsObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
|
||||
{"names", EncodingNamesObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"system", EncodingSystemObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
return TclMakeEnsemble(interp, "encoding", encodingImplMap);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* TclMakeEncodingCommandSafe --
|
||||
*
|
||||
* This function hides the unsafe 'dirs' and 'system' subcommands of
|
||||
* the "encoding" Tcl command ensemble. It must be called only from
|
||||
* TclHideUnsafeCommands.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result
|
||||
*
|
||||
* Side effects:
|
||||
* Adds commands to the table of hidden commands.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclMakeEncodingCommandSafe(
|
||||
Tcl_Interp* interp) /* Tcl interpreter */
|
||||
{
|
||||
static const struct {
|
||||
const char *cmdName;
|
||||
int unsafe;
|
||||
} unsafeInfo[] = {
|
||||
{"convertfrom", 0},
|
||||
{"convertto", 0},
|
||||
{"dirs", 1},
|
||||
{"names", 0},
|
||||
{"system", 0},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
int i;
|
||||
Tcl_DString oldBuf, newBuf;
|
||||
|
||||
Tcl_DStringInit(&oldBuf);
|
||||
TclDStringAppendLiteral(&oldBuf, "::tcl::encoding::");
|
||||
Tcl_DStringInit(&newBuf);
|
||||
TclDStringAppendLiteral(&newBuf, "tcl:encoding:");
|
||||
for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
|
||||
if (unsafeInfo[i].unsafe) {
|
||||
const char *oldName, *newName;
|
||||
|
||||
Tcl_DStringSetLength(&oldBuf, 17);
|
||||
oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1);
|
||||
Tcl_DStringSetLength(&newBuf, 13);
|
||||
newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1);
|
||||
if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK
|
||||
|| Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) {
|
||||
Tcl_Panic("problem making 'encoding %s' safe: %s",
|
||||
unsafeInfo[i].cmdName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
Tcl_CreateObjCommand(interp, oldName, BadEncodingSubcommand,
|
||||
(ClientData) unsafeInfo[i].cmdName, NULL);
|
||||
}
|
||||
}
|
||||
Tcl_DStringFree(&oldBuf);
|
||||
Tcl_DStringFree(&newBuf);
|
||||
|
||||
/*
|
||||
* Ugh. The [encoding] command is now actually safe, but it is assumed by
|
||||
* scripts that it is not, which messes up security policies.
|
||||
*/
|
||||
|
||||
if (Tcl_HideCommand(interp, "encoding", "encoding") != TCL_OK) {
|
||||
Tcl_Panic("problem making 'encoding' safe: %s",
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* BadEncodingSubcommand --
|
||||
*
|
||||
* Command used to act as a backstop implementation when subcommands of
|
||||
* "encoding" are unsafe (the real implementations of the subcommands are
|
||||
* hidden). The clientData is always the full official subcommand name.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result (always a TCL_ERROR).
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
BadEncodingSubcommand(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
const char *subcommandName = (const char *) clientData;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"not allowed to invoke subcommand %s of encoding", subcommandName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1043,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?");
|
||||
@@ -1052,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! */
|
||||
}
|
||||
@@ -1174,180 +1063,45 @@ TclInitFileCmd(
|
||||
*/
|
||||
|
||||
static const EnsembleImplMap initMap[] = {
|
||||
{"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
|
||||
{"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 1},
|
||||
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 1},
|
||||
{"channels", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
|
||||
{"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 1},
|
||||
{"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1},
|
||||
{"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"join", PathJoinCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
|
||||
{"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
|
||||
{"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 1},
|
||||
{"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1},
|
||||
{"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 1},
|
||||
{"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1},
|
||||
{"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"pathtype", PathTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
|
||||
{"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 1},
|
||||
{"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 1},
|
||||
{"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
|
||||
{"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 1},
|
||||
{"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1},
|
||||
{"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 1},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
return TclMakeEnsemble(interp, "file", initMap);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclMakeFileCommandSafe --
|
||||
*
|
||||
* This function hides the unsafe subcommands of the "file" Tcl command
|
||||
* ensemble. It must only be called from TclHideUnsafeCommands.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Adds commands to the table of hidden commands.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclMakeFileCommandSafe(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
static const struct {
|
||||
const char *cmdName;
|
||||
int unsafe;
|
||||
} unsafeInfo[] = {
|
||||
{"atime", 1},
|
||||
{"attributes", 1},
|
||||
{"channels", 0},
|
||||
{"copy", 1},
|
||||
{"delete", 1},
|
||||
{"dirname", 1},
|
||||
{"executable", 1},
|
||||
{"exists", 1},
|
||||
{"extension", 1},
|
||||
{"isdirectory", 1},
|
||||
{"isfile", 1},
|
||||
{"join", 0},
|
||||
{"link", 1},
|
||||
{"lstat", 1},
|
||||
{"mtime", 1},
|
||||
{"mkdir", 1},
|
||||
{"nativename", 1},
|
||||
{"normalize", 1},
|
||||
{"owned", 1},
|
||||
{"pathtype", 0},
|
||||
{"readable", 1},
|
||||
{"readlink", 1},
|
||||
{"rename", 1},
|
||||
{"rootname", 1},
|
||||
{"separator", 0},
|
||||
{"size", 1},
|
||||
{"split", 0},
|
||||
{"stat", 1},
|
||||
{"system", 0},
|
||||
{"tail", 1},
|
||||
{"tempfile", 1},
|
||||
{"type", 1},
|
||||
{"volumes", 1},
|
||||
{"writable", 1},
|
||||
{NULL, 0}
|
||||
};
|
||||
int i;
|
||||
Tcl_DString oldBuf, newBuf;
|
||||
|
||||
Tcl_DStringInit(&oldBuf);
|
||||
TclDStringAppendLiteral(&oldBuf, "::tcl::file::");
|
||||
Tcl_DStringInit(&newBuf);
|
||||
TclDStringAppendLiteral(&newBuf, "tcl:file:");
|
||||
for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
|
||||
if (unsafeInfo[i].unsafe) {
|
||||
const char *oldName, *newName;
|
||||
|
||||
Tcl_DStringSetLength(&oldBuf, 13);
|
||||
oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1);
|
||||
Tcl_DStringSetLength(&newBuf, 9);
|
||||
newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1);
|
||||
if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK
|
||||
|| Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) {
|
||||
Tcl_Panic("problem making 'file %s' safe: %s",
|
||||
unsafeInfo[i].cmdName,
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
Tcl_CreateObjCommand(interp, oldName, BadFileSubcommand,
|
||||
(ClientData) unsafeInfo[i].cmdName, NULL);
|
||||
}
|
||||
}
|
||||
Tcl_DStringFree(&oldBuf);
|
||||
Tcl_DStringFree(&newBuf);
|
||||
|
||||
/*
|
||||
* Ugh. The [file] command is now actually safe, but it is assumed by
|
||||
* scripts that it is not, which messes up security policies. [Bug
|
||||
* 3211758]
|
||||
*/
|
||||
|
||||
if (Tcl_HideCommand(interp, "file", "file") != TCL_OK) {
|
||||
Tcl_Panic("problem making 'file' safe: %s",
|
||||
Tcl_GetString(Tcl_GetObjResult(interp)));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* BadFileSubcommand --
|
||||
*
|
||||
* Command used to act as a backstop implementation when subcommands of
|
||||
* "file" are unsafe (the real implementations of the subcommands are
|
||||
* hidden). The clientData is always the full official subcommand name.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result (always a TCL_ERROR).
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
BadFileSubcommand(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
const char *subcommandName = (const char *) clientData;
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"not allowed to invoke subcommand %s of file", subcommandName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1425,7 +1179,7 @@ FileAttrAccessTimeCmd(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_atime));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((long) buf.st_atime));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1505,7 +1259,7 @@ FileAttrModifyTimeCmd(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_mtime));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj((long) buf.st_mtime));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2128,7 +1882,7 @@ PathJoinCmd(
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1));
|
||||
Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1, 0));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2524,23 +2278,23 @@ StoreStatData(
|
||||
* cast might fail when there isn't a real arithmetic 'long long' type...
|
||||
*/
|
||||
|
||||
STORE_ARY("dev", Tcl_NewLongObj((long)statPtr->st_dev));
|
||||
STORE_ARY("dev", Tcl_NewWideIntObj((long)statPtr->st_dev));
|
||||
STORE_ARY("ino", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_ino));
|
||||
STORE_ARY("nlink", Tcl_NewLongObj((long)statPtr->st_nlink));
|
||||
STORE_ARY("uid", Tcl_NewLongObj((long)statPtr->st_uid));
|
||||
STORE_ARY("gid", Tcl_NewLongObj((long)statPtr->st_gid));
|
||||
STORE_ARY("nlink", Tcl_NewWideIntObj((long)statPtr->st_nlink));
|
||||
STORE_ARY("uid", Tcl_NewWideIntObj((long)statPtr->st_uid));
|
||||
STORE_ARY("gid", Tcl_NewWideIntObj((long)statPtr->st_gid));
|
||||
STORE_ARY("size", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_size));
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
|
||||
STORE_ARY("blocks", Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_blocks));
|
||||
#endif
|
||||
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
|
||||
STORE_ARY("blksize", Tcl_NewLongObj((long)statPtr->st_blksize));
|
||||
STORE_ARY("blksize", Tcl_NewWideIntObj((long)statPtr->st_blksize));
|
||||
#endif
|
||||
STORE_ARY("atime", Tcl_NewLongObj((long)statPtr->st_atime));
|
||||
STORE_ARY("mtime", Tcl_NewLongObj((long)statPtr->st_mtime));
|
||||
STORE_ARY("ctime", Tcl_NewLongObj((long)statPtr->st_ctime));
|
||||
STORE_ARY("atime", Tcl_NewWideIntObj((long)statPtr->st_atime));
|
||||
STORE_ARY("mtime", Tcl_NewWideIntObj((long)statPtr->st_mtime));
|
||||
STORE_ARY("ctime", Tcl_NewWideIntObj((long)statPtr->st_ctime));
|
||||
mode = (unsigned short) statPtr->st_mode;
|
||||
STORE_ARY("mode", Tcl_NewIntObj(mode));
|
||||
STORE_ARY("mode", Tcl_NewWideIntObj(mode));
|
||||
STORE_ARY("type", Tcl_NewStringObj(GetTypeFromMode(mode), -1));
|
||||
#undef STORE_ARY
|
||||
|
||||
|
||||
+133
-47
@@ -173,7 +173,7 @@ static const EnsembleImplMap defaultInfoMap[] = {
|
||||
{"library", InfoLibraryCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"loaded", InfoLoadedCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"locals", TclInfoLocalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1},
|
||||
{"patchlevel", InfoPatchLevelCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"procs", InfoProcsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
@@ -404,7 +404,7 @@ Tcl_IncrObjCmd(
|
||||
if (objc == 3) {
|
||||
incrPtr = objv[2];
|
||||
} else {
|
||||
incrPtr = Tcl_NewIntObj(1);
|
||||
incrPtr = Tcl_NewWideIntObj(1);
|
||||
}
|
||||
Tcl_IncrRefCount(incrPtr);
|
||||
newValuePtr = TclIncrObjVar2(interp, objv[1], NULL,
|
||||
@@ -539,9 +539,9 @@ InfoBodyCmd(
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
register Interp *iPtr = (Interp *) interp;
|
||||
const char *name;
|
||||
const char *name, *bytes;
|
||||
Proc *procPtr;
|
||||
Tcl_Obj *bodyPtr, *resultPtr;
|
||||
int numBytes;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "procname");
|
||||
@@ -566,18 +566,8 @@ InfoBodyCmd(
|
||||
* the object do not invalidate the internal rep.
|
||||
*/
|
||||
|
||||
bodyPtr = procPtr->bodyPtr;
|
||||
if (bodyPtr->bytes == NULL) {
|
||||
/*
|
||||
* The string rep might not be valid if the procedure has never been
|
||||
* run before. [Bug #545644]
|
||||
*/
|
||||
|
||||
TclGetString(bodyPtr);
|
||||
}
|
||||
resultPtr = Tcl_NewStringObj(bodyPtr->bytes, bodyPtr->length);
|
||||
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
bytes = Tcl_GetStringFromObj(procPtr->bodyPtr, &numBytes);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(bytes, numBytes));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -616,7 +606,7 @@ InfoCmdCountCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->cmdCount));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iPtr->cmdCount));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -998,7 +988,7 @@ InfoDefaultCmd(
|
||||
if (valueObjPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(1));
|
||||
} else {
|
||||
Tcl_Obj *nullObjPtr = Tcl_NewObj();
|
||||
|
||||
@@ -1007,7 +997,7 @@ InfoDefaultCmd(
|
||||
if (valueObjPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1181,7 +1171,7 @@ InfoFrameCmd(
|
||||
* Just "info frame".
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(topLevel));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(topLevel));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1303,9 +1293,9 @@ TclInfoFrame(
|
||||
|
||||
ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
|
||||
if (framePtr->line) {
|
||||
ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(framePtr->line[0]));
|
||||
} else {
|
||||
ADD_PAIR("line", Tcl_NewIntObj(1));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(1));
|
||||
}
|
||||
ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
|
||||
break;
|
||||
@@ -1342,7 +1332,7 @@ TclInfoFrame(
|
||||
|
||||
ADD_PAIR("type", Tcl_NewStringObj(typeString[fPtr->type], -1));
|
||||
if (fPtr->line) {
|
||||
ADD_PAIR("line", Tcl_NewIntObj(fPtr->line[0]));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(fPtr->line[0]));
|
||||
}
|
||||
|
||||
if (fPtr->type == TCL_LOCATION_SOURCE) {
|
||||
@@ -1369,7 +1359,7 @@ TclInfoFrame(
|
||||
*/
|
||||
|
||||
ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
|
||||
ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
|
||||
ADD_PAIR("line", Tcl_NewWideIntObj(framePtr->line[0]));
|
||||
ADD_PAIR("file", framePtr->data.eval.path);
|
||||
|
||||
/*
|
||||
@@ -1440,7 +1430,7 @@ TclInfoFrame(
|
||||
int c = framePtr->framePtr->level;
|
||||
int t = iPtr->varFramePtr->level;
|
||||
|
||||
ADD_PAIR("level", Tcl_NewIntObj(t - c));
|
||||
ADD_PAIR("level", Tcl_NewWideIntObj(t - c));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1595,7 +1585,7 @@ InfoLevelCmd(
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
|
||||
if (objc == 1) { /* Just "info level" */
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(iPtr->varFramePtr->level));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2564,7 +2554,97 @@ Tcl_LlengthObjCmd(
|
||||
* length.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(listLen));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(listLen));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_LpopObjCmd --
|
||||
*
|
||||
* This procedure is invoked to process the "lpop" Tcl command. See the
|
||||
* user documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl object result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Tcl_LpopObjCmd(
|
||||
ClientData notUsed, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
register Tcl_Obj *const objv[])
|
||||
/* Argument objects. */
|
||||
{
|
||||
int listLen, result;
|
||||
Tcl_Obj *elemPtr;
|
||||
Tcl_Obj *listPtr, **elemPtrs;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "listvar ?index?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
listPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
|
||||
if (listPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
result = TclListObjGetElements(interp, listPtr, &listLen, &elemPtrs);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* First, extract the element to be returned.
|
||||
* TclLindexFlat adds a ref count which is handled.
|
||||
*/
|
||||
|
||||
if (objc == 2) {
|
||||
elemPtr = elemPtrs[listLen - 1];
|
||||
Tcl_IncrRefCount(elemPtr);
|
||||
} else {
|
||||
elemPtr = TclLindexFlat(interp, listPtr, objc-2, objv+2);
|
||||
|
||||
if (elemPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, elemPtr);
|
||||
Tcl_DecrRefCount(elemPtr);
|
||||
|
||||
/*
|
||||
* Second, remove the element.
|
||||
*/
|
||||
|
||||
if (objc == 2) {
|
||||
if (Tcl_IsShared(listPtr)) {
|
||||
listPtr = TclListObjCopy(NULL, listPtr);
|
||||
}
|
||||
result = Tcl_ListObjReplace(interp, listPtr, listLen - 1, 1, 0, NULL);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
listPtr = TclLsetFlat(interp, listPtr, objc-2, objv+2, NULL);
|
||||
|
||||
if (listPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
listPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, listPtr, TCL_LEAVE_ERR_MSG);
|
||||
if (listPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3159,12 +3239,11 @@ Tcl_LsearchObjCmd(
|
||||
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
int encoded = 0;
|
||||
if (TclIndexEncode(interp, indices[j], TCL_INDEX_BEFORE,
|
||||
TCL_INDEX_AFTER, &encoded) != TCL_OK) {
|
||||
if (TclIndexEncode(interp, indices[j], TCL_INDEX_NONE,
|
||||
TCL_INDEX_NONE, &encoded) != TCL_OK) {
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if ((encoded == TCL_INDEX_BEFORE)
|
||||
|| (encoded == TCL_INDEX_AFTER)) {
|
||||
if (encoded == TCL_INDEX_NONE) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"index \"%s\" cannot select an element "
|
||||
"from any list", Tcl_GetString(indices[j])));
|
||||
@@ -3310,7 +3389,7 @@ Tcl_LsearchObjCmd(
|
||||
if (allMatches || inlineReturn) {
|
||||
Tcl_ResetResult(interp);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-1));
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
@@ -3599,14 +3678,14 @@ Tcl_LsearchObjCmd(
|
||||
} else if (returnSubindices) {
|
||||
int j;
|
||||
|
||||
itemPtr = Tcl_NewIntObj(i+groupOffset);
|
||||
itemPtr = Tcl_NewWideIntObj(i+groupOffset);
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewWideIntObj(
|
||||
TclIndexDecode(sortInfo.indexv[j], listc)));
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
|
||||
} else {
|
||||
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i));
|
||||
Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewWideIntObj(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3621,14 +3700,14 @@ Tcl_LsearchObjCmd(
|
||||
if (returnSubindices) {
|
||||
int j;
|
||||
|
||||
itemPtr = Tcl_NewIntObj(index+groupOffset);
|
||||
itemPtr = Tcl_NewWideIntObj(index+groupOffset);
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewWideIntObj(
|
||||
TclIndexDecode(sortInfo.indexv[j], listc)));
|
||||
}
|
||||
Tcl_SetObjResult(interp, itemPtr);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
|
||||
}
|
||||
} else if (index < 0) {
|
||||
/*
|
||||
@@ -3879,10 +3958,9 @@ Tcl_LsortObjCmd(
|
||||
for (j=0 ; j<indexc ; j++) {
|
||||
int encoded = 0;
|
||||
int result = TclIndexEncode(interp, indexv[j],
|
||||
TCL_INDEX_BEFORE, TCL_INDEX_AFTER, &encoded);
|
||||
TCL_INDEX_NONE, TCL_INDEX_NONE, &encoded);
|
||||
|
||||
if ((result == TCL_OK) && ((encoded == TCL_INDEX_BEFORE)
|
||||
|| (encoded == TCL_INDEX_AFTER))) {
|
||||
if ((result == TCL_OK) && (encoded == TCL_INDEX_NONE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"index \"%s\" cannot select an element "
|
||||
"from any list", Tcl_GetString(indexv[j])));
|
||||
@@ -3971,7 +4049,8 @@ Tcl_LsortObjCmd(
|
||||
}
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
/* Prescreened values, no errors or out of range possible */
|
||||
TclIndexEncode(NULL, indexv[j], 0, 0, &sortInfo.indexv[j]);
|
||||
TclIndexEncode(NULL, indexv[j], TCL_INDEX_NONE,
|
||||
TCL_INDEX_NONE, &sortInfo.indexv[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4197,7 +4276,7 @@ Tcl_LsortObjCmd(
|
||||
idx = elementPtr->payload.index;
|
||||
for (j = 0; j < groupSize; j++) {
|
||||
if (indices) {
|
||||
objPtr = Tcl_NewIntObj(idx + j - groupOffset);
|
||||
objPtr = Tcl_NewWideIntObj(idx + j - groupOffset);
|
||||
newArray[i++] = objPtr;
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
} else {
|
||||
@@ -4209,7 +4288,7 @@ Tcl_LsortObjCmd(
|
||||
}
|
||||
} else if (indices) {
|
||||
for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) {
|
||||
objPtr = Tcl_NewIntObj(elementPtr->payload.index);
|
||||
objPtr = Tcl_NewWideIntObj(elementPtr->payload.index);
|
||||
newArray[i++] = objPtr;
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
}
|
||||
@@ -4641,9 +4720,16 @@ SelectObjFromSublist(
|
||||
return NULL;
|
||||
}
|
||||
if (currentObj == NULL) {
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element %d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
if (index == TCL_INDEX_NONE) {
|
||||
index = TCL_INDEX_END - infoPtr->indexv[i];
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element end-%d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
} else {
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element %d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
}
|
||||
Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
|
||||
"INDEXFAILED", NULL);
|
||||
infoPtr->resultCode = TCL_ERROR;
|
||||
|
||||
+498
-61
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclRegexp.h"
|
||||
#include "tclStringTrim.h"
|
||||
|
||||
@@ -258,7 +259,7 @@ Tcl_RegexpObjCmd(
|
||||
stringLength = Tcl_GetCharLength(objPtr);
|
||||
|
||||
if (startIndex) {
|
||||
TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
|
||||
TclGetIntForIndexM(interp, startIndex, stringLength, &offset);
|
||||
Tcl_DecrRefCount(startIndex);
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
@@ -335,7 +336,7 @@ Tcl_RegexpObjCmd(
|
||||
*/
|
||||
|
||||
if (!doinline) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -388,8 +389,8 @@ Tcl_RegexpObjCmd(
|
||||
end = -1;
|
||||
}
|
||||
|
||||
objs[0] = Tcl_NewLongObj(start);
|
||||
objs[1] = Tcl_NewLongObj(end);
|
||||
objs[0] = Tcl_NewWideIntObj(start);
|
||||
objs[1] = Tcl_NewWideIntObj(end);
|
||||
|
||||
newPtr = Tcl_NewListObj(2, objs);
|
||||
} else {
|
||||
@@ -457,7 +458,7 @@ Tcl_RegexpObjCmd(
|
||||
if (doinline) {
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(all ? all-1 : 1));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(all ? all-1 : 1));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -582,7 +583,7 @@ Tcl_RegsubObjCmd(
|
||||
if (startIndex) {
|
||||
int stringLength = Tcl_GetCharLength(objv[1]);
|
||||
|
||||
TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
|
||||
TclGetIntForIndexM(interp, startIndex, stringLength, &offset);
|
||||
Tcl_DecrRefCount(startIndex);
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
@@ -959,7 +960,7 @@ Tcl_RegsubObjCmd(
|
||||
* holding the number of matches.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(numMatches));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(numMatches));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -1216,13 +1217,13 @@ Tcl_SplitObjCmd(
|
||||
Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
|
||||
|
||||
for ( ; stringPtr < end; stringPtr += len) {
|
||||
int fullchar;
|
||||
int fullchar;
|
||||
len = TclUtfToUniChar(stringPtr, &ch);
|
||||
fullchar = ch;
|
||||
|
||||
#if TCL_UTF_MAX <= 4
|
||||
if (!len) {
|
||||
len += TclUtfToUniChar(stringPtr, &ch);
|
||||
if ((ch >= 0xD800) && (len < 3)) {
|
||||
len += TclUtfToUniChar(stringPtr + len, &ch);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
@@ -1336,7 +1337,7 @@ StringFirstCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFirst(objv[1],
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclStringFirst(objv[1],
|
||||
objv[2], start)));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1381,7 +1382,7 @@ StringLastCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringLast(objv[1],
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(TclStringLast(objv[1],
|
||||
objv[2], last)));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1444,11 +1445,11 @@ StringIndexCmd(
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1));
|
||||
} else {
|
||||
char buf[4];
|
||||
char buf[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));
|
||||
}
|
||||
@@ -1490,19 +1491,19 @@ StringIsCmd(
|
||||
|
||||
static const char *const isClasses[] = {
|
||||
"alnum", "alpha", "ascii", "control",
|
||||
"boolean", "digit", "double", "entier",
|
||||
"false", "graph", "integer", "list",
|
||||
"lower", "print", "punct", "space",
|
||||
"true", "upper", "wideinteger", "wordchar",
|
||||
"xdigit", NULL
|
||||
"boolean", "dict", "digit", "double",
|
||||
"entier", "false", "graph", "integer",
|
||||
"list", "lower", "print", "punct",
|
||||
"space", "true", "upper", "wideinteger",
|
||||
"wordchar", "xdigit", NULL
|
||||
};
|
||||
enum isClasses {
|
||||
STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
|
||||
STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
|
||||
STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST,
|
||||
STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE,
|
||||
STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD,
|
||||
STR_IS_XDIGIT
|
||||
STR_IS_BOOL, STR_IS_DICT, STR_IS_DIGIT, STR_IS_DOUBLE,
|
||||
STR_IS_ENTIER, STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT,
|
||||
STR_IS_LIST, STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT,
|
||||
STR_IS_SPACE, STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE,
|
||||
STR_IS_WORD, STR_IS_XDIGIT
|
||||
};
|
||||
static const char *const isOptions[] = {
|
||||
"-strict", "-failindex", NULL
|
||||
@@ -1571,7 +1572,7 @@ StringIsCmd(
|
||||
case STR_IS_BOOL:
|
||||
case STR_IS_TRUE:
|
||||
case STR_IS_FALSE:
|
||||
if ((objPtr->typePtr != &tclBooleanType)
|
||||
if (!TclHasIntRep(objPtr, &tclBooleanType)
|
||||
&& (TCL_OK != TclSetBooleanFromAny(NULL, objPtr))) {
|
||||
if (strict) {
|
||||
result = 0;
|
||||
@@ -1589,13 +1590,61 @@ StringIsCmd(
|
||||
case STR_IS_CONTROL:
|
||||
chcomp = Tcl_UniCharIsControl;
|
||||
break;
|
||||
case STR_IS_DICT: {
|
||||
int dresult, dsize;
|
||||
|
||||
dresult = Tcl_DictObjSize(interp, objPtr, &dsize);
|
||||
Tcl_ResetResult(interp);
|
||||
result = (dresult == TCL_OK) ? 1 : 0;
|
||||
if (dresult != TCL_OK && failVarObj != NULL) {
|
||||
/*
|
||||
* Need to figure out where the list parsing failed, which is
|
||||
* fairly expensive. This is adapted from the core of
|
||||
* SetDictFromAny().
|
||||
*/
|
||||
|
||||
const char *elemStart, *nextElem;
|
||||
int lenRemain, elemSize;
|
||||
register const char *p;
|
||||
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
end = string1 + length1;
|
||||
failat = -1;
|
||||
for (p=string1, lenRemain=length1; lenRemain > 0;
|
||||
p=nextElem, lenRemain=end-nextElem) {
|
||||
if (TCL_ERROR == TclFindElement(NULL, p, lenRemain,
|
||||
&elemStart, &nextElem, &elemSize, NULL)) {
|
||||
Tcl_Obj *tmpStr;
|
||||
|
||||
/*
|
||||
* This is the simplest way of getting the number of
|
||||
* characters parsed. Note that this is not the same as
|
||||
* the number of bytes when parsing strings with non-ASCII
|
||||
* characters in them.
|
||||
*
|
||||
* Skip leading spaces first. This is only really an issue
|
||||
* if it is the first "element" that has the failure.
|
||||
*/
|
||||
|
||||
while (TclIsSpaceProc(*p)) {
|
||||
p++;
|
||||
}
|
||||
TclNewStringObj(tmpStr, string1, p-string1);
|
||||
failat = Tcl_GetCharLength(tmpStr);
|
||||
TclDecrRefCount(tmpStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STR_IS_DIGIT:
|
||||
chcomp = Tcl_UniCharIsDigit;
|
||||
break;
|
||||
case STR_IS_DOUBLE: {
|
||||
if ((objPtr->typePtr == &tclDoubleType) ||
|
||||
(objPtr->typePtr == &tclIntType) ||
|
||||
(objPtr->typePtr == &tclBignumType)) {
|
||||
if (TclHasIntRep(objPtr, &tclDoubleType) ||
|
||||
TclHasIntRep(objPtr, &tclIntType) ||
|
||||
TclHasIntRep(objPtr, &tclBignumType)) {
|
||||
break;
|
||||
}
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
@@ -1623,13 +1672,9 @@ StringIsCmd(
|
||||
chcomp = Tcl_UniCharIsGraph;
|
||||
break;
|
||||
case STR_IS_INT:
|
||||
if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) {
|
||||
break;
|
||||
}
|
||||
goto failedIntParse;
|
||||
case STR_IS_ENTIER:
|
||||
if ((objPtr->typePtr == &tclIntType) ||
|
||||
(objPtr->typePtr == &tclBignumType)) {
|
||||
if (TclHasIntRep(objPtr, &tclIntType) ||
|
||||
TclHasIntRep(objPtr, &tclBignumType)) {
|
||||
break;
|
||||
}
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
@@ -1674,7 +1719,6 @@ StringIsCmd(
|
||||
break;
|
||||
}
|
||||
|
||||
failedIntParse:
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
if (length1 == 0) {
|
||||
if (strict) {
|
||||
@@ -1811,8 +1855,8 @@ StringIsCmd(
|
||||
length2 = TclUtfToUniChar(string1, &ch);
|
||||
fullchar = ch;
|
||||
#if TCL_UTF_MAX <= 4
|
||||
if (!length2) {
|
||||
length2 = TclUtfToUniChar(string1, &ch);
|
||||
if ((ch >= 0xD800) && (length2 < 3)) {
|
||||
length2 += TclUtfToUniChar(string1 + length2, &ch);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
@@ -1830,7 +1874,7 @@ StringIsCmd(
|
||||
|
||||
str_is_done:
|
||||
if ((result == 0) && (failVarObj != NULL) &&
|
||||
Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewIntObj(failat),
|
||||
Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewWideIntObj(failat),
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1849,7 +1893,7 @@ static int
|
||||
UniCharIsHexDigit(
|
||||
int character)
|
||||
{
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(character);
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(UCHAR(character));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1892,7 +1936,7 @@ StringMapCmd(
|
||||
const char *string = TclGetStringFromObj(objv[1], &length2);
|
||||
|
||||
if ((length2 > 1) &&
|
||||
strncmp(string, "-nocase", (size_t) length2) == 0) {
|
||||
strncmp(string, "-nocase", length2) == 0) {
|
||||
nocase = 1;
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
@@ -1908,7 +1952,8 @@ StringMapCmd(
|
||||
* inconsistencies (see test string-10.20.1 for illustration why!)
|
||||
*/
|
||||
|
||||
if (objv[objc-2]->typePtr == &tclDictType && objv[objc-2]->bytes == NULL){
|
||||
if (!TclHasStringRep(objv[objc-2])
|
||||
&& TclHasIntRep(objv[objc-2], &tclDictType)){
|
||||
int i, done;
|
||||
Tcl_DictSearch search;
|
||||
|
||||
@@ -2070,7 +2115,7 @@ StringMapCmd(
|
||||
(Tcl_UniCharToLower(*ustring1) == u2lc[index/2]))) &&
|
||||
/* Restrict max compare length. */
|
||||
(end-ustring1 >= length2) && ((length2 == 1) ||
|
||||
!strCmpFn(ustring2, ustring1, (unsigned) length2))) {
|
||||
!strCmpFn(ustring2, ustring1, length2))) {
|
||||
if (p != ustring1) {
|
||||
/*
|
||||
* Put the skipped chars onto the result first.
|
||||
@@ -2159,7 +2204,7 @@ StringMatchCmd(
|
||||
const char *string = TclGetStringFromObj(objv[1], &length);
|
||||
|
||||
if ((length > 1) &&
|
||||
strncmp(string, "-nocase", (size_t) length) == 0) {
|
||||
strncmp(string, "-nocase", length) == 0) {
|
||||
nocase = TCL_MATCH_NOCASE;
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
@@ -2452,7 +2497,7 @@ StringStartCmd(
|
||||
cur += 1;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2514,7 +2559,7 @@ StringEndCmd(
|
||||
} else {
|
||||
cur = numChars;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(cur));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2561,10 +2606,10 @@ StringEqualCmd(
|
||||
|
||||
for (i = 1; i < objc-2; i++) {
|
||||
string2 = TclGetStringFromObj(objv[i], &length);
|
||||
if ((length > 1) && !strncmp(string2, "-nocase", (size_t)length)) {
|
||||
if ((length > 1) && !strncmp(string2, "-nocase", length)) {
|
||||
nocase = 1;
|
||||
} else if ((length > 1)
|
||||
&& !strncmp(string2, "-length", (size_t)length)) {
|
||||
&& !strncmp(string2, "-length", length)) {
|
||||
if (i+1 >= objc-2) {
|
||||
goto str_cmp_args;
|
||||
}
|
||||
@@ -2588,9 +2633,7 @@ StringEqualCmd(
|
||||
*/
|
||||
|
||||
objv += objc-2;
|
||||
|
||||
match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -2635,11 +2678,12 @@ StringCmpCmd(
|
||||
|
||||
objv += objc-2;
|
||||
match = TclStringCmp(objv[0], objv[1], 0, nocase, reqlength);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(match));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int TclStringCmpOpts(
|
||||
int
|
||||
TclStringCmpOpts(
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[], /* Argument objects. */
|
||||
@@ -2660,10 +2704,10 @@ int TclStringCmpOpts(
|
||||
|
||||
for (i = 1; i < objc-2; i++) {
|
||||
string = TclGetStringFromObj(objv[i], &length);
|
||||
if ((length > 1) && !strncmp(string, "-nocase", (size_t)length)) {
|
||||
if ((length > 1) && !strncmp(string, "-nocase", length)) {
|
||||
*nocase = 1;
|
||||
} else if ((length > 1)
|
||||
&& !strncmp(string, "-length", (size_t)length)) {
|
||||
&& !strncmp(string, "-length", length)) {
|
||||
if (i+1 >= objc-2) {
|
||||
goto str_cmp_args;
|
||||
}
|
||||
@@ -2760,7 +2804,7 @@ StringBytesCmd(
|
||||
}
|
||||
|
||||
(void) TclGetStringFromObj(objv[1], &length);
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(length));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(length));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2794,7 +2838,7 @@ StringLenCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_GetCharLength(objv[1])));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tcl_GetCharLength(objv[1])));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3683,10 +3727,10 @@ TclNRSwitchObjCmd(
|
||||
Tcl_Obj *rangeObjAry[2];
|
||||
|
||||
if (info.matches[j].end > 0) {
|
||||
rangeObjAry[0] = Tcl_NewLongObj(info.matches[j].start);
|
||||
rangeObjAry[1] = Tcl_NewLongObj(info.matches[j].end-1);
|
||||
rangeObjAry[0] = Tcl_NewWideIntObj(info.matches[j].start);
|
||||
rangeObjAry[1] = Tcl_NewWideIntObj(info.matches[j].end-1);
|
||||
} else {
|
||||
rangeObjAry[0] = rangeObjAry[1] = Tcl_NewIntObj(-1);
|
||||
rangeObjAry[0] = rangeObjAry[1] = Tcl_NewWideIntObj(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3987,7 +4031,7 @@ Tcl_TimeObjCmd(
|
||||
start = TclpGetWideClicks();
|
||||
#endif
|
||||
while (i-- > 0) {
|
||||
result = Tcl_EvalObjEx(interp, objPtr, 0);
|
||||
result = TclEvalObjEx(interp, objPtr, 0, NULL, 0);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
@@ -4006,7 +4050,7 @@ Tcl_TimeObjCmd(
|
||||
* Use int obj since we know time is not fractional. [Bug 1202178]
|
||||
*/
|
||||
|
||||
objs[0] = Tcl_NewIntObj((count <= 0) ? 0 : (int) totalMicroSec);
|
||||
objs[0] = Tcl_NewWideIntObj((count <= 0) ? 0 : (Tcl_WideInt)totalMicroSec);
|
||||
} else {
|
||||
objs[0] = Tcl_NewDoubleObj(totalMicroSec/count);
|
||||
}
|
||||
@@ -4024,6 +4068,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 {
|
||||
/*
|
||||
|
||||
+41
-35
@@ -461,7 +461,7 @@ TclCompileStringIsCmd(
|
||||
Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
static const char *const isClasses[] = {
|
||||
"alnum", "alpha", "ascii", "control",
|
||||
"boolean", "digit", "double", "entier",
|
||||
"boolean", "dict", "digit", "double", "entier",
|
||||
"false", "graph", "integer", "list",
|
||||
"lower", "print", "punct", "space",
|
||||
"true", "upper", "wideinteger", "wordchar",
|
||||
@@ -469,7 +469,7 @@ TclCompileStringIsCmd(
|
||||
};
|
||||
enum isClasses {
|
||||
STR_IS_ALNUM, STR_IS_ALPHA, STR_IS_ASCII, STR_IS_CONTROL,
|
||||
STR_IS_BOOL, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
|
||||
STR_IS_BOOL, STR_IS_DICT, STR_IS_DIGIT, STR_IS_DOUBLE, STR_IS_ENTIER,
|
||||
STR_IS_FALSE, STR_IS_GRAPH, STR_IS_INT, STR_IS_LIST,
|
||||
STR_IS_LOWER, STR_IS_PRINT, STR_IS_PUNCT, STR_IS_SPACE,
|
||||
STR_IS_TRUE, STR_IS_UPPER, STR_IS_WIDE, STR_IS_WORD,
|
||||
@@ -691,14 +691,11 @@ TclCompileStringIsCmd(
|
||||
}
|
||||
|
||||
switch (t) {
|
||||
case STR_IS_INT:
|
||||
PUSH( "1");
|
||||
OP( EQ);
|
||||
break;
|
||||
case STR_IS_WIDE:
|
||||
PUSH( "2");
|
||||
OP( LE);
|
||||
break;
|
||||
case STR_IS_INT:
|
||||
case STR_IS_ENTIER:
|
||||
PUSH( "3");
|
||||
OP( LE);
|
||||
@@ -706,7 +703,19 @@ TclCompileStringIsCmd(
|
||||
}
|
||||
FIXJUMP1( end);
|
||||
return TCL_OK;
|
||||
|
||||
case STR_IS_DICT:
|
||||
range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
|
||||
OP4( BEGIN_CATCH4, range);
|
||||
ExceptionRangeStarts(envPtr, range);
|
||||
OP( DUP);
|
||||
OP( DICT_VERIFY);
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
ExceptionRangeTarget(envPtr, range, catchOffset);
|
||||
OP( POP);
|
||||
OP( PUSH_RETURN_CODE);
|
||||
OP( END_CATCH);
|
||||
OP( LNOT);
|
||||
return TCL_OK;
|
||||
case STR_IS_LIST:
|
||||
range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
|
||||
OP4( BEGIN_CATCH4, range);
|
||||
@@ -937,7 +946,7 @@ TclCompileStringRangeCmd(
|
||||
* Parse the two indices.
|
||||
*/
|
||||
|
||||
if (TclGetIndexFromToken(fromTokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
if (TclGetIndexFromToken(fromTokenPtr, TCL_INDEX_START, TCL_INDEX_NONE,
|
||||
&idx1) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
@@ -946,14 +955,14 @@ TclCompileStringRangeCmd(
|
||||
* the string the same as the start of the string.
|
||||
*/
|
||||
|
||||
if (idx1 == TCL_INDEX_AFTER) {
|
||||
if (idx1 == TCL_INDEX_NONE) {
|
||||
/* [string range $s end+1 $last] must be empty string */
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (TclGetIndexFromToken(toTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
if (TclGetIndexFromToken(toTokenPtr, TCL_INDEX_NONE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
@@ -961,7 +970,7 @@ TclCompileStringRangeCmd(
|
||||
* Token parsed as an index expression. We treat all indices after
|
||||
* the string the same as the end of the string.
|
||||
*/
|
||||
if (idx2 == TCL_INDEX_BEFORE) {
|
||||
if (idx2 == TCL_INDEX_NONE) {
|
||||
/* [string range $s $first -1] must be empty string */
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
@@ -1011,7 +1020,7 @@ TclCompileStringReplaceCmd(
|
||||
* Check for first index known and useful at compile time.
|
||||
*/
|
||||
tokenPtr = TokenAfter(valueTokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_NONE,
|
||||
&first) != TCL_OK) {
|
||||
goto genericReplace;
|
||||
}
|
||||
@@ -1020,7 +1029,7 @@ TclCompileStringReplaceCmd(
|
||||
* Check for last index known and useful at compile time.
|
||||
*/
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_AFTER,
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_NONE, TCL_INDEX_END,
|
||||
&last) != TCL_OK) {
|
||||
goto genericReplace;
|
||||
}
|
||||
@@ -1039,8 +1048,8 @@ TclCompileStringReplaceCmd(
|
||||
* compile direct to bytecode implementing the no-op.
|
||||
*/
|
||||
|
||||
if ((last == TCL_INDEX_BEFORE) /* Know (last < 0) */
|
||||
|| (first == TCL_INDEX_AFTER) /* Know (first > end) */
|
||||
if ((last == TCL_INDEX_NONE) /* Know (last < 0) */
|
||||
|| (first == TCL_INDEX_NONE) /* Know (first > end) */
|
||||
|
||||
/*
|
||||
* Tricky to determine when runtime (last < first) can be
|
||||
@@ -1048,20 +1057,17 @@ TclCompileStringReplaceCmd(
|
||||
* cases...
|
||||
*
|
||||
* (first <= TCL_INDEX_END) &&
|
||||
* (last == TCL_INDEX_AFTER) => cannot tell REJECT
|
||||
* (last <= TCL_INDEX END) && (last < first) => ACCEPT
|
||||
* else => cannot tell REJECT
|
||||
*/
|
||||
|| ((first <= TCL_INDEX_END) && (last <= TCL_INDEX_END)
|
||||
&& (last < first)) /* Know (last < first) */
|
||||
/*
|
||||
* (first == TCL_INDEX_BEFORE) &&
|
||||
* (last == TCL_INDEX_AFTER) => (first < last) REJECT
|
||||
* (first == TCL_INDEX_NONE) &&
|
||||
* (last <= TCL_INDEX_END) => cannot tell REJECT
|
||||
* else => (first < last) REJECT
|
||||
*
|
||||
* else [[first >= TCL_INDEX_START]] &&
|
||||
* (last == TCL_INDEX_AFTER) => cannot tell REJECT
|
||||
* (last <= TCL_INDEX_END) => cannot tell REJECT
|
||||
* else [[last >= TCL_INDEX START]] && (last < first) => ACCEPT
|
||||
*/
|
||||
@@ -1094,34 +1100,34 @@ TclCompileStringReplaceCmd(
|
||||
* (first <= end)
|
||||
*
|
||||
* The encoded indices (first <= TCL_INDEX END) and
|
||||
* (first == TCL_INDEX_BEFORE) always meets this condition, but
|
||||
* (first == TCL_INDEX_NONE) always meets this condition, but
|
||||
* any other encoded first index has some list for which it fails.
|
||||
*
|
||||
* We also need, second:
|
||||
*
|
||||
* (last >= 0)
|
||||
*
|
||||
* The encoded indices (last >= TCL_INDEX_START) and
|
||||
* (last == TCL_INDEX_AFTER) always meet this condition but any
|
||||
* other encoded last index has some list for which it fails.
|
||||
* The encoded index (last >= TCL_INDEX_START) always meet this
|
||||
* condition but any other encoded last index has some list for
|
||||
* which it fails.
|
||||
*
|
||||
* Finally we need, third:
|
||||
*
|
||||
* (first <= last)
|
||||
*
|
||||
* Considered in combination with the constraints we already have,
|
||||
* we see that we can proceed when (first == TCL_INDEX_BEFORE)
|
||||
* or (last == TCL_INDEX_AFTER). These also permit simplification
|
||||
* of the prefix|replace|suffix construction. The other constraints,
|
||||
* though, interfere with getting a guarantee that first <= last.
|
||||
* we see that we can proceed when (first == TCL_INDEX_NONE).
|
||||
* These also permit simplification of the prefix|replace|suffix
|
||||
* construction. The other constraints, though, interfere with
|
||||
* getting a guarantee that first <= last.
|
||||
*/
|
||||
|
||||
if ((first == TCL_INDEX_BEFORE) && (last >= TCL_INDEX_START)) {
|
||||
if ((first == TCL_INDEX_START) && (last >= TCL_INDEX_START)) {
|
||||
/* empty prefix */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
OP4( REVERSE, 2);
|
||||
if (last == TCL_INDEX_AFTER) {
|
||||
if (last == INT_MAX) {
|
||||
OP( POP); /* Pop original */
|
||||
} else {
|
||||
OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END);
|
||||
@@ -1130,7 +1136,7 @@ TclCompileStringReplaceCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if ((last == TCL_INDEX_AFTER) && (first <= TCL_INDEX_END)) {
|
||||
if ((last == TCL_INDEX_NONE) && (first <= TCL_INDEX_END)) {
|
||||
OP44( STR_RANGE_IMM, 0, first-1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 4);
|
||||
@@ -1147,10 +1153,10 @@ TclCompileStringReplaceCmd(
|
||||
* are harmless when they are replaced by another empty string.
|
||||
*/
|
||||
|
||||
if ((first == TCL_INDEX_BEFORE) || (first == TCL_INDEX_START)) {
|
||||
if (first == TCL_INDEX_START) {
|
||||
/* empty prefix - build suffix only */
|
||||
|
||||
if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) {
|
||||
if (last == TCL_INDEX_END) {
|
||||
/* empty suffix too => empty result */
|
||||
OP( POP); /* Pop original */
|
||||
PUSH ( "");
|
||||
@@ -1159,7 +1165,7 @@ TclCompileStringReplaceCmd(
|
||||
OP44( STR_RANGE_IMM, last + 1, TCL_INDEX_END);
|
||||
return TCL_OK;
|
||||
} else {
|
||||
if ((last == TCL_INDEX_END) || (last == TCL_INDEX_AFTER)) {
|
||||
if (last == TCL_INDEX_END) {
|
||||
/* empty suffix - build prefix only */
|
||||
OP44( STR_RANGE_IMM, 0, first-1);
|
||||
return TCL_OK;
|
||||
@@ -1353,7 +1359,7 @@ static int
|
||||
UniCharIsHexDigit(
|
||||
int character)
|
||||
{
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(character);
|
||||
return (character >= 0) && (character < 0x80) && isxdigit(UCHAR(character));
|
||||
}
|
||||
|
||||
StringClassDesc const tclStringClassTable[] = {
|
||||
@@ -1496,7 +1502,7 @@ TclSubstCompile(
|
||||
for (endTokenPtr = tokenPtr + parse.numTokens;
|
||||
tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
|
||||
int length, literal, catchRange, breakJump;
|
||||
char buf[TCL_UTF_MAX];
|
||||
char buf[4] = "";
|
||||
JumpFixup startFixup, okFixup, returnFixup, breakFixup;
|
||||
JumpFixup continueFixup, otherFixup, endFixup;
|
||||
|
||||
|
||||
@@ -1759,7 +1759,7 @@ ConvertTreeToTokens(
|
||||
|
||||
/*
|
||||
* All the Tcl_Tokens allocated and filled belong to
|
||||
* this subexpresion. The first token is the leading
|
||||
* this subexpression. The first token is the leading
|
||||
* TCL_TOKEN_SUB_EXPR token, and all the rest (one fewer)
|
||||
* are its components.
|
||||
*/
|
||||
@@ -2027,7 +2027,7 @@ ParseLexeme(
|
||||
* Example: Inf + luence + () becomes a valid function call.
|
||||
* [Bug 3401704]
|
||||
*/
|
||||
if (literal->typePtr == &tclDoubleType) {
|
||||
if (TclHasIntRep(literal, &tclDoubleType)) {
|
||||
const char *p = start;
|
||||
|
||||
while (p < end) {
|
||||
@@ -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++;
|
||||
|
||||
+19
-2
@@ -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
|
||||
@@ -1473,7 +1490,7 @@ MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
#endif
|
||||
|
||||
#define TclGetInt4AtPtr(p) \
|
||||
(((int) TclGetInt1AtPtr(p) << 24) | \
|
||||
(((int) (TclGetUInt1AtPtr(p) << 24)) | \
|
||||
(*((p)+1) << 16) | \
|
||||
(*((p)+2) << 8) | \
|
||||
(*((p)+3)))
|
||||
|
||||
+954
-954
File diff suppressed because it is too large
Load Diff
+77
-26
@@ -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);
|
||||
@@ -1863,17 +1865,38 @@ EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp,
|
||||
Tcl_TcpAcceptProc *acceptProc,
|
||||
ClientData callbackData);
|
||||
/* 632 */
|
||||
EXTERN int TclZipfs_Mount(Tcl_Interp *interp, const char *mntpt,
|
||||
const char *zipname, const char *passwd);
|
||||
EXTERN int TclZipfs_Mount(Tcl_Interp *interp,
|
||||
const char *mountPoint, const char *zipname,
|
||||
const char *passwd);
|
||||
/* 633 */
|
||||
EXTERN int TclZipfs_Unmount(Tcl_Interp *interp,
|
||||
const char *zipname);
|
||||
const char *mountPoint);
|
||||
/* 634 */
|
||||
EXTERN Tcl_Obj * TclZipfs_TclLibrary(void);
|
||||
/* 635 */
|
||||
EXTERN int TclZipfs_Mount_Buffer(Tcl_Interp *interp,
|
||||
const char *mntpt, unsigned char *data,
|
||||
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;
|
||||
@@ -1931,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 */
|
||||
@@ -1977,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 */
|
||||
@@ -2045,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 */
|
||||
@@ -2139,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 */
|
||||
@@ -2153,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 */
|
||||
@@ -2428,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 */
|
||||
@@ -2541,10 +2564,18 @@ typedef struct TclStubs {
|
||||
int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */
|
||||
void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */
|
||||
Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 631 */
|
||||
int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mntpt, const char *zipname, const char *passwd); /* 632 */
|
||||
int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *zipname); /* 633 */
|
||||
int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *mountPoint, const char *zipname, const char *passwd); /* 632 */
|
||||
int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *mountPoint); /* 633 */
|
||||
Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */
|
||||
int (*tclZipfs_Mount_Buffer) (Tcl_Interp *interp, const char *mntpt, unsigned char *data, size_t datalen, int copy); /* 635 */
|
||||
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;
|
||||
@@ -2631,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 \
|
||||
@@ -3845,8 +3876,24 @@ extern const TclStubs *tclStubsPtr;
|
||||
(tclStubsPtr->tclZipfs_Unmount) /* 633 */
|
||||
#define TclZipfs_TclLibrary \
|
||||
(tclStubsPtr->tclZipfs_TclLibrary) /* 634 */
|
||||
#define TclZipfs_Mount_Buffer \
|
||||
(tclStubsPtr->tclZipfs_Mount_Buffer) /* 635 */
|
||||
#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) */
|
||||
|
||||
@@ -3858,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
|
||||
@@ -3897,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)
|
||||
@@ -4025,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);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user