Compare commits
820
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ddabb17f9 | ||
|
|
a3babfe12a | ||
|
|
b6fecacc22 | ||
|
|
360b5c41ee | ||
|
|
5a6443d00e | ||
|
|
7134cd9399 | ||
|
|
1a92fb378c | ||
|
|
ef6f1ba2c3 | ||
|
|
b0078c8129 | ||
|
|
49e7d0262b | ||
|
|
2cbec4bf44 | ||
|
|
7ac39417f1 | ||
|
|
3faf4cc3b8 | ||
|
|
9f699d22a2 | ||
|
|
13667e8096 | ||
|
|
51f7688e96 | ||
|
|
f6d6b394eb | ||
|
|
7e44dabec3 | ||
|
|
cfefe7127b | ||
|
|
2613112a13 | ||
|
|
18131f9c09 | ||
|
|
baf649278a | ||
|
|
88ec3c9772 | ||
|
|
ad19550909 | ||
|
|
aed72bee30 | ||
|
|
f65cb994d8 | ||
|
|
893c9c7302 | ||
|
|
24817641b1 | ||
|
|
89e6a65411 | ||
|
|
f664d633e6 | ||
|
|
d56e61b246 | ||
|
|
8dd58baa04 | ||
|
|
559113cc4c | ||
|
|
5dafefe112 | ||
|
|
955507f635 | ||
|
|
e942227f6e | ||
|
|
68b5780dde | ||
|
|
3b7664e77f | ||
|
|
b47b88af9b | ||
|
|
d7a9d63520 | ||
|
|
f716d8815b | ||
|
|
4e0313afe2 | ||
|
|
d9b30b94b8 | ||
|
|
2f8ea1be7c | ||
|
|
59cb45cc16 | ||
|
|
ee5c231ff5 | ||
|
|
604faa265f | ||
|
|
8e80c62f6f | ||
|
|
a417c667a5 | ||
|
|
26326004c6 | ||
|
|
0318c256ed | ||
|
|
704532c57a | ||
|
|
2d415cbf59 | ||
|
|
916f1716f3 | ||
|
|
d297273a13 | ||
|
|
b27238fbbb | ||
|
|
7466351c90 | ||
|
|
58bde2cb77 | ||
|
|
40420634aa | ||
|
|
b52476a5cd | ||
|
|
bc8ffb3922 | ||
|
|
bfb321eb38 | ||
|
|
5c1b9fefdf | ||
|
|
6d936db4a3 | ||
|
|
dd4c175c81 | ||
|
|
29b10229de | ||
|
|
bff00baca2 | ||
|
|
7dfd9c5a96 | ||
|
|
05971adca4 | ||
|
|
2f3edeea43 | ||
|
|
0c0be35710 | ||
|
|
137e142be2 | ||
|
|
8694763c10 | ||
|
|
58cd08bb7d | ||
|
|
730a9a132c | ||
|
|
d7cf041bab | ||
|
|
03f0d60f88 | ||
|
|
92402afe21 | ||
|
|
d9465a5be2 | ||
|
|
52bcb866e5 | ||
|
|
7f5ddf43ee | ||
|
|
484de8b987 | ||
|
|
2b3e403550 | ||
|
|
fa8d5668aa | ||
|
|
24d57ad4ff | ||
|
|
3185389da2 | ||
|
|
164250cf86 | ||
|
|
9c2149012b | ||
|
|
6e056b1e14 | ||
|
|
99ee3e86d7 | ||
|
|
3bbc2317b3 | ||
|
|
7d10d699c7 | ||
|
|
620cf6fa02 | ||
|
|
98e4ac55d2 | ||
|
|
eb64ed3cf0 | ||
|
|
5e0d1d6bc5 | ||
|
|
7565b9ff1e | ||
|
|
10dc783c93 | ||
|
|
0c027bb706 | ||
|
|
c658976cc3 | ||
|
|
1db5ff8c2c | ||
|
|
fbba7d0b1e | ||
|
|
559b8ab9de | ||
|
|
60ef43cb8c | ||
|
|
5c6717b7d5 | ||
|
|
2f8dae1cec | ||
|
|
dac552ac0b | ||
|
|
53ae611583 | ||
|
|
57de194b09 | ||
|
|
5204910c12 | ||
|
|
71d27bd9c6 | ||
|
|
3fa4ffc77a | ||
|
|
d2b69b306e | ||
|
|
db9946ccc3 | ||
|
|
cb0895755d | ||
|
|
b14c2f49d2 | ||
|
|
48ab03f3cd | ||
|
|
de82a1a99e | ||
|
|
7ec17e20d3 | ||
|
|
d95273cf0e | ||
|
|
f87735c127 | ||
|
|
1e769e4b57 | ||
|
|
a8dc863399 | ||
|
|
476a68cbe5 | ||
|
|
54d2883694 | ||
|
|
5a9b116846 | ||
|
|
df4391e23f | ||
|
|
717a98747d | ||
|
|
915359ddce | ||
|
|
999c88ea06 | ||
|
|
790fed46bb | ||
|
|
da01ebeabe | ||
|
|
91d5ac9d0b | ||
|
|
adff5bc1c6 | ||
|
|
eee56ee95a | ||
|
|
9cf7e2a336 | ||
|
|
93082a74a2 | ||
|
|
9f2c3815f7 | ||
|
|
592ab670f3 | ||
|
|
c0e8db49d5 | ||
|
|
d7604e5728 | ||
|
|
8e5b3b87a5 | ||
|
|
d31d858702 | ||
|
|
1234267c92 | ||
|
|
59491ce8ca | ||
|
|
ef89704696 | ||
|
|
1ce240e90f | ||
|
|
c132978e4b | ||
|
|
59f2031ac5 | ||
|
|
f85490f4e1 | ||
|
|
c2be2a28e0 | ||
|
|
4977df535f | ||
|
|
182bace1e3 | ||
|
|
1f33c7ae12 | ||
|
|
78c2c1cedf | ||
|
|
186ecf8003 | ||
|
|
56c0b11912 | ||
|
|
1df1505d69 | ||
|
|
1a08ae6fb4 | ||
|
|
891a0ade43 | ||
|
|
29d06499aa | ||
|
|
ea97de415f | ||
|
|
b327c90dcc | ||
|
|
cd1372b52d | ||
|
|
3b4cf982e3 | ||
|
|
7c4da917a7 | ||
|
|
e36d384130 | ||
|
|
5e53c4c296 | ||
|
|
78fcaa3580 | ||
|
|
11db57d058 | ||
|
|
822a2b50f7 | ||
|
|
fc21aee814 | ||
|
|
d06897f3ea | ||
|
|
1598658a83 | ||
|
|
192fa71096 | ||
|
|
76db7c5c04 | ||
|
|
85f3786d9c | ||
|
|
5e0835667d | ||
|
|
26fe5fff38 | ||
|
|
d75135cca1 | ||
|
|
a5dd225e78 | ||
|
|
5f9519213f | ||
|
|
7bce68fe3b | ||
|
|
600ace1c4b | ||
|
|
62004c9fb4 | ||
|
|
976c48a7f1 | ||
|
|
a3b501f125 | ||
|
|
13d8cae724 | ||
|
|
303cced03d | ||
|
|
3f8809d6ec | ||
|
|
b47df5123e | ||
|
|
996c102b1f | ||
|
|
a024a52335 | ||
|
|
2e4f40528b | ||
|
|
8964b0101f | ||
|
|
6d02d4e9dc | ||
|
|
2e512ffbe8 | ||
|
|
6e00c594ea | ||
|
|
77e18bafa5 | ||
|
|
bcdc8e8a6d | ||
|
|
7cd4eb1657 | ||
|
|
a562752936 | ||
|
|
46346effdc | ||
|
|
6c10f6324b | ||
|
|
ae0f801eaf | ||
|
|
a9c6d78680 | ||
|
|
dbacb46d52 | ||
|
|
7ab1ebdc32 | ||
|
|
3ca10397cf | ||
|
|
13e336e4cd | ||
|
|
80604a93c1 | ||
|
|
aa8f4d27ac | ||
|
|
b08dc28c80 | ||
|
|
92f9aca55f | ||
|
|
ce04ed5ad3 | ||
|
|
eda831ff7e | ||
|
|
bc9dca8ca6 | ||
|
|
f8a968fdb8 | ||
|
|
72fee4f1c7 | ||
|
|
71f6f450b2 | ||
|
|
f2225b9dc1 | ||
|
|
344b547cd4 | ||
|
|
60125626dc | ||
|
|
36c74f5033 | ||
|
|
02b159d09e | ||
|
|
d5113635d3 | ||
|
|
7cfbfdffd3 | ||
|
|
a0e133cb07 | ||
|
|
e4a9f37030 | ||
|
|
459724f70a | ||
|
|
7f8321b616 | ||
|
|
ac5fa7c959 | ||
|
|
8c3d28816c | ||
|
|
13828f74ee | ||
|
|
822b0d469e | ||
|
|
8755613114 | ||
|
|
c93483448e | ||
|
|
582c164dc3 | ||
|
|
91b9c5690e | ||
|
|
d544f36344 | ||
|
|
796e087b9c | ||
|
|
76e87312ed | ||
|
|
5863c1e1b9 | ||
|
|
50f00c62f2 | ||
|
|
2918630e90 | ||
|
|
00ee522067 | ||
|
|
87724ab09f | ||
|
|
43aaaf34e5 | ||
|
|
67fcf44a82 | ||
|
|
239374cbb8 | ||
|
|
aa2667b729 | ||
|
|
25860d9071 | ||
|
|
1cecac9cad | ||
|
|
23b2b428b6 | ||
|
|
9c45b517dc | ||
|
|
f70b625cf3 | ||
|
|
592bd0b065 | ||
|
|
f4f511dbae | ||
|
|
a3cfa0d708 | ||
|
|
6563197fa8 | ||
|
|
08c2327777 | ||
|
|
0b7630c23f | ||
|
|
b425d2c241 | ||
|
|
bd2e4fe97f | ||
|
|
bed95cfaf7 | ||
|
|
a745e85067 | ||
|
|
232336fbee | ||
|
|
c62d8b25aa | ||
|
|
179c36fd48 | ||
|
|
5191ece516 | ||
|
|
f1e1a92d13 | ||
|
|
6c55284908 | ||
|
|
fd5a54c8dd | ||
|
|
d9ab63098e | ||
|
|
2cbe892d48 | ||
|
|
cfb0ea03ec | ||
|
|
5ec61dacf7 | ||
|
|
c6eb718dfd | ||
|
|
a1bd6bc434 | ||
|
|
51be2107ea | ||
|
|
cf106cdda6 | ||
|
|
e98326383b | ||
|
|
1db9d005b6 | ||
|
|
3eb6318d9b | ||
|
|
19d6bd367d | ||
|
|
7f4563705c | ||
|
|
b627af851c | ||
|
|
ef647d7ccd | ||
|
|
0a9367fbc9 | ||
|
|
841ecebfa5 | ||
|
|
b3bdbd342b | ||
|
|
bfe912517c | ||
|
|
97d74c549d | ||
|
|
595290e064 | ||
|
|
631849ea86 | ||
|
|
213c040089 | ||
|
|
0bc839ec64 | ||
|
|
72c15c0c4e | ||
|
|
df7b610caf | ||
|
|
2ad2aba317 | ||
|
|
5eaa219754 | ||
|
|
2c10c359b5 | ||
|
|
bfab4c718b | ||
|
|
d19b7190cb | ||
|
|
97d610fbfe | ||
|
|
4e4b5a7e53 | ||
|
|
6cd3ffa246 | ||
|
|
d2d54ff3de | ||
|
|
eaf423b505 | ||
|
|
f345a78f27 | ||
|
|
5203cce0e0 | ||
|
|
f07fe1c911 | ||
|
|
7571df843a | ||
|
|
f7c255fa17 | ||
|
|
07d1de7a4f | ||
|
|
d586b47d44 | ||
|
|
b58f928be5 | ||
|
|
6f05041d3f | ||
|
|
0d27a4b905 | ||
|
|
4870917293 | ||
|
|
1797998aed | ||
|
|
0fac79a0fb | ||
|
|
8825fb59d7 | ||
|
|
5af71fcbff | ||
|
|
431189b805 | ||
|
|
4822b65c03 | ||
|
|
b58baa4ff6 | ||
|
|
0a0d095f20 | ||
|
|
dbed3f8089 | ||
|
|
d6605e9057 | ||
|
|
0992240c65 | ||
|
|
0e96637923 | ||
|
|
8fd7a48012 | ||
|
|
b406c00842 | ||
|
|
31eb3eebb7 | ||
|
|
b81d871afb | ||
|
|
cf1f2fb61e | ||
|
|
61f8119019 | ||
|
|
a072994389 | ||
|
|
da31ff7eb8 | ||
|
|
d5ffff6214 | ||
|
|
e1b54e0e11 | ||
|
|
53df9e36da | ||
|
|
8d68951021 | ||
|
|
4b4b642fe6 | ||
|
|
0cf246c174 | ||
|
|
0bab3624a9 | ||
|
|
ee896008d0 | ||
|
|
6bc046c0bc | ||
|
|
58f92b6316 | ||
|
|
ddeb3ab35c | ||
|
|
0d9a8edf22 | ||
|
|
6ab9c80ea1 | ||
|
|
aa6f0b1cab | ||
|
|
c7510fa5b9 | ||
|
|
efcc225259 | ||
|
|
24b0f264c3 | ||
|
|
3cd11c535e | ||
|
|
f326f97897 | ||
|
|
7834f2fe96 | ||
|
|
7bde946742 | ||
|
|
fce6982a3e | ||
|
|
52af4f6df3 | ||
|
|
908fc261b6 | ||
|
|
eab2f47c2c | ||
|
|
ab6933ef6b | ||
|
|
c20374dfa6 | ||
|
|
5f82234293 | ||
|
|
17751a998c | ||
|
|
08d9096362 | ||
|
|
2621d5a21a | ||
|
|
4e3fe86fc2 | ||
|
|
86b84b6d21 | ||
|
|
6a99b9a546 | ||
|
|
e5104aa3dc | ||
|
|
fae85d1af5 | ||
|
|
bb40f1cd2c | ||
|
|
bb4c894bca | ||
|
|
b4cc0cbac8 | ||
|
|
16b3c54eb0 | ||
|
|
3eb959fc93 | ||
|
|
ba7b49d9c4 | ||
|
|
45fd54872f | ||
|
|
cb1e14e0eb | ||
|
|
3189f48d19 | ||
|
|
6a91e192f8 | ||
|
|
3334cf2103 | ||
|
|
518ffe037f | ||
|
|
2691f4b9a9 | ||
|
|
93b55b0dc4 | ||
|
|
1e37d8beb0 | ||
|
|
10caa9b482 | ||
|
|
6c7e545b80 | ||
|
|
004361c91d | ||
|
|
744e7bfe51 | ||
|
|
9b701fdae7 | ||
|
|
1f197f004a | ||
|
|
312e71eff4 | ||
|
|
3dcb02dc07 | ||
|
|
78bb5378e9 | ||
|
|
bf498960d9 | ||
|
|
329c85106b | ||
|
|
334ffdfa50 | ||
|
|
4b98569f89 | ||
|
|
0fe50b37a2 | ||
|
|
c08a9df4d6 | ||
|
|
a60da763ba | ||
|
|
88ab76b3b8 | ||
|
|
5f8f27387d | ||
|
|
ceae73bd28 | ||
|
|
a74fb9ea31 | ||
|
|
cc63d97f54 | ||
|
|
461b9f3322 | ||
|
|
47089ed2b3 | ||
|
|
ff04f434c4 | ||
|
|
e55620ed06 | ||
|
|
052f13167e | ||
|
|
6fb8bfc715 | ||
|
|
f19d7ab302 | ||
|
|
3eb4868d33 | ||
|
|
090475cc9c | ||
|
|
7f2205461c | ||
|
|
b1576079b7 | ||
|
|
125a9f8a25 | ||
|
|
5b5dffa386 | ||
|
|
48b8a3755c | ||
|
|
94d4975fa2 | ||
|
|
604007076c | ||
|
|
3afefe3d81 | ||
|
|
5db8831fb0 | ||
|
|
28721acb58 | ||
|
|
6a8b9ef2d6 | ||
|
|
4715d60689 | ||
|
|
539adc9f7f | ||
|
|
5e1812e37c | ||
|
|
158ab27221 | ||
|
|
edb5d20cbf | ||
|
|
47912a0cab | ||
|
|
d32b2d8171 | ||
|
|
61f362f9a4 | ||
|
|
b4ca74a562 | ||
|
|
8eb9237e4a | ||
|
|
c6cd29b3f9 | ||
|
|
3bb92ad005 | ||
|
|
eccb17258f | ||
|
|
f57343eb42 | ||
|
|
e55ee4d6cc | ||
|
|
2e71d669fe | ||
|
|
07f07faf4b | ||
|
|
63543e9ad0 | ||
|
|
73ccc4ba86 | ||
|
|
9265507b2c | ||
|
|
7974460313 | ||
|
|
5fedb4d01b | ||
|
|
29055898b0 | ||
|
|
7156085860 | ||
|
|
5d76c6e6c0 | ||
|
|
a4eef46453 | ||
|
|
73f53667ed | ||
|
|
fbb32b908c | ||
|
|
1b7b5e839c | ||
|
|
643d4e096b | ||
|
|
8b4cb6f5d9 | ||
|
|
54a7fb1431 | ||
|
|
d7461d07ad | ||
|
|
f4401162e8 | ||
|
|
a84b51c1b4 | ||
|
|
e538095963 | ||
|
|
99a5afc6e0 | ||
|
|
61c463f55f | ||
|
|
2ff193dc57 | ||
|
|
7d850a310d | ||
|
|
95eec569fd | ||
|
|
fa53de3d90 | ||
|
|
f1ace09e64 | ||
|
|
f54edc88cf | ||
|
|
04fbce15ca | ||
|
|
e083b8e9bb | ||
|
|
65baa666b5 | ||
|
|
22c5cd91eb | ||
|
|
48ecb1a2ee | ||
|
|
75e37a235a | ||
|
|
e29e8eee24 | ||
|
|
84a26717ef | ||
|
|
643b20e2b2 | ||
|
|
68f4187dd1 | ||
|
|
01ccb9ccaa | ||
|
|
3fd76e6ba7 | ||
|
|
7218e5967c | ||
|
|
cc1b3e8ddc | ||
|
|
c4669a8b0c | ||
|
|
a0d540327f | ||
|
|
2d6278c829 | ||
|
|
ba89a15d53 | ||
|
|
d8b36a0216 | ||
|
|
b8c001575a | ||
|
|
681e50da88 | ||
|
|
b04c31eecb | ||
|
|
acdf0e593a | ||
|
|
3c51a58c1e | ||
|
|
acce1f902b | ||
|
|
9888275261 | ||
|
|
01f9f84db5 | ||
|
|
9bed70dea4 | ||
|
|
3ab2f65ec6 | ||
|
|
322ea4d71d | ||
|
|
fd83709b45 | ||
|
|
c09e2ded08 | ||
|
|
8e5e88f4db | ||
|
|
d3c1978e07 | ||
|
|
fb36ca1b18 | ||
|
|
27ce96cd71 | ||
|
|
abd9269a04 | ||
|
|
aacc275d30 | ||
|
|
0b7940e00e | ||
|
|
183a28c109 | ||
|
|
c4f8c1063c | ||
|
|
438b6b5009 | ||
|
|
a95f198d2e | ||
|
|
87d82b22e7 | ||
|
|
e0c1d41f5e | ||
|
|
1a41595e06 | ||
|
|
2d4cef6d56 | ||
|
|
f8ff5f9f13 | ||
|
|
210aa9605a | ||
|
|
19292d74bf | ||
|
|
ab5b2feda0 | ||
|
|
35a41cd0d6 | ||
|
|
9873314d0d | ||
|
|
f3f494358f | ||
|
|
0c9e9be9e5 | ||
|
|
e024894c53 | ||
|
|
e3220aa631 | ||
|
|
47d1451282 | ||
|
|
5f636c9b81 | ||
|
|
45659eebd2 | ||
|
|
3ec273770b | ||
|
|
c69e73e183 | ||
|
|
fa12c3782d | ||
|
|
af15fe284a | ||
|
|
d7f092d1cf | ||
|
|
fea67060de | ||
|
|
ea20dfbaae | ||
|
|
da22d54b77 | ||
|
|
e4bf3a0afd | ||
|
|
473f2fb8dd | ||
|
|
29d26aa2c1 | ||
|
|
fecf0d5e64 | ||
|
|
b70fbe851c | ||
|
|
747725c1fc | ||
|
|
f60122dc91 | ||
|
|
dfb3ea8358 | ||
|
|
da5348ec0f | ||
|
|
322bd5dd1f | ||
|
|
9f8bc994a9 | ||
|
|
a7101c49af | ||
|
|
ea3c325aa5 | ||
|
|
9915e77374 | ||
|
|
9db9d4ff84 | ||
|
|
335591836a | ||
|
|
e9e54156fa | ||
|
|
f91d3dd584 | ||
|
|
88d357a99c | ||
|
|
c97d829e0c | ||
|
|
be0324597a | ||
|
|
fcca5df8d6 | ||
|
|
7284ed46fb | ||
|
|
5b2fb22633 | ||
|
|
16c608178f | ||
|
|
924739ac23 | ||
|
|
fdcd434e12 | ||
|
|
5d9aef7a4e | ||
|
|
b497ad4e53 | ||
|
|
a95a8e4a9c | ||
|
|
d10806530d | ||
|
|
c867dfd034 | ||
|
|
601ecb35c8 | ||
|
|
87fc10a8da | ||
|
|
32d3c7b2a1 | ||
|
|
42143bf4e9 | ||
|
|
a7350e3489 | ||
|
|
8a33c02a15 | ||
|
|
1abf8e4ad8 | ||
|
|
e92b34ab12 | ||
|
|
59e40535f5 | ||
|
|
3d4fa09102 | ||
|
|
5e96fb5ee1 | ||
|
|
d0e001a334 | ||
|
|
8bf9869083 | ||
|
|
269a88ebaf | ||
|
|
9757dd7eba | ||
|
|
9365e418f3 | ||
|
|
ebb15ded42 | ||
|
|
2f51a2e128 | ||
|
|
a5f9898e34 | ||
|
|
e2c7cfecc1 | ||
|
|
c736ad3e88 | ||
|
|
3d1b611f4c | ||
|
|
6cfae752ff | ||
|
|
253440c377 | ||
|
|
61e5f733e5 | ||
|
|
77a33cf2ff | ||
|
|
3756d27b06 | ||
|
|
551a220b1f | ||
|
|
a529e32955 | ||
|
|
2e6d32b5a8 | ||
|
|
9bc964b5bb | ||
|
|
daa585d846 | ||
|
|
bc5c5261e5 | ||
|
|
a2e8fa6c52 | ||
|
|
4fa18eaa12 | ||
|
|
f9c41b4bcc | ||
|
|
8655555eb4 | ||
|
|
2a5a3323cb | ||
|
|
2d315899eb | ||
|
|
6ac66b5476 | ||
|
|
2b096d89a3 | ||
|
|
4252a9c191 | ||
|
|
52fe1455a7 | ||
|
|
4c46afc6f5 | ||
|
|
1673f7d67a | ||
|
|
c6eeda71be | ||
|
|
15df01c93d | ||
|
|
1408478f56 | ||
|
|
021c7456ff | ||
|
|
6eb3a60712 | ||
|
|
8837ed8935 | ||
|
|
e5b53212a8 | ||
|
|
97ef11cb6e | ||
|
|
71680aec07 | ||
|
|
4d2bb24e84 | ||
|
|
56214ea49a | ||
|
|
88cddf0b80 | ||
|
|
183b5fd257 | ||
|
|
ff8fef8c8d | ||
|
|
2a7cf86d30 | ||
|
|
0530d01b63 | ||
|
|
e9bb48106a | ||
|
|
c6fabad70e | ||
|
|
88abf586de | ||
|
|
16dcfe4b5f | ||
|
|
bce5a2ae75 | ||
|
|
cb2a1e4c13 | ||
|
|
a62fd8466e | ||
|
|
c7a7120587 | ||
|
|
02d7d5af4c | ||
|
|
3e8c032e35 | ||
|
|
b9409ecdff | ||
|
|
912913c340 | ||
|
|
ac3233bf36 | ||
|
|
934c12d4a4 | ||
|
|
d1f0a7b5f7 | ||
|
|
ee1a8aed63 | ||
|
|
2a00313c29 | ||
|
|
b896860fbf | ||
|
|
6c5d496711 | ||
|
|
66cf21eaaf | ||
|
|
47b0512591 | ||
|
|
080aa64c3d | ||
|
|
f8cfd0ecd0 | ||
|
|
ee4aa52d42 | ||
|
|
ca31b05c9d | ||
|
|
baf55bba6a | ||
|
|
75cae59053 | ||
|
|
10a9e13e5d | ||
|
|
3bb727a3c7 | ||
|
|
e02a90c10d | ||
|
|
5de4bf8981 | ||
|
|
12a4d297b9 | ||
|
|
bef17eed6a | ||
|
|
6bcc85f28e | ||
|
|
61e8875498 | ||
|
|
5350ed1efe | ||
|
|
d08f5c564c | ||
|
|
f5cb50339f | ||
|
|
f3343892a7 | ||
|
|
886199711d | ||
|
|
57182d5ef3 | ||
|
|
5fe3c1fbee | ||
|
|
bfa93a894c | ||
|
|
6ddf4c01d5 | ||
|
|
e5f7fb59c4 | ||
|
|
fa81506a01 | ||
|
|
74ed570183 | ||
|
|
3183209237 | ||
|
|
5bef69e253 | ||
|
|
3f6201e538 | ||
|
|
596cd02dba | ||
|
|
ecec9dacef | ||
|
|
ece5f1377f | ||
|
|
c98d055207 | ||
|
|
45f1f60132 | ||
|
|
ff27c27a27 | ||
|
|
3e6fc11b81 | ||
|
|
e622e61b3a | ||
|
|
2f73d6810c | ||
|
|
378008089c | ||
|
|
8f2742b2f5 | ||
|
|
4a58d3c00a | ||
|
|
4840e7dbb4 | ||
|
|
e31901dcd5 | ||
|
|
2207a65968 | ||
|
|
282de06cab | ||
|
|
8f14151916 | ||
|
|
e8e909f1cd | ||
|
|
6733e57835 | ||
|
|
6978c989d7 | ||
|
|
d888a526f4 | ||
|
|
ada7d66e9f | ||
|
|
1a8dc819d6 | ||
|
|
b3bfa3ee1d | ||
|
|
b6212a88b3 | ||
|
|
01eab1e2cd | ||
|
|
90725c211b | ||
|
|
90d3294572 | ||
|
|
6e09fe5ab9 | ||
|
|
fa1ab4f740 | ||
|
|
3ac01c586f | ||
|
|
c65342141a | ||
|
|
0e8e132aca | ||
|
|
d4cb991846 | ||
|
|
e51a0bd096 | ||
|
|
521821debf | ||
|
|
06a0036a49 | ||
|
|
c91f173c8b | ||
|
|
ec145024fd | ||
|
|
47f1107ebc | ||
|
|
78bbf020ea | ||
|
|
342aec6684 | ||
|
|
f0882154a8 | ||
|
|
89583a6623 | ||
|
|
0258413bde | ||
|
|
c0726f8f4f | ||
|
|
39ddd8c91b | ||
|
|
d69c1d382b | ||
|
|
e175773277 | ||
|
|
b6ae0212a1 | ||
|
|
5ff110b484 | ||
|
|
438b687249 | ||
|
|
8c3bcfe950 | ||
|
|
cacb796441 | ||
|
|
cad363e97d | ||
|
|
f54081e9e5 | ||
|
|
40094302e0 | ||
|
|
c7569e1c35 | ||
|
|
ae659fdb12 | ||
|
|
fc5e6debde | ||
|
|
876dd3ac96 | ||
|
|
8c665116c9 | ||
|
|
1eb2dfe0fc | ||
|
|
f53e4a7a0e | ||
|
|
14b32b82e1 | ||
|
|
5be047220d | ||
|
|
510244810f | ||
|
|
9f92115d2d | ||
|
|
3f60452ac2 | ||
|
|
ad8e3dcb0a | ||
|
|
f77ffeb9b2 | ||
|
|
c574af192d | ||
|
|
fd4bc0f106 | ||
|
|
e12cc95f12 | ||
|
|
beb8c62dff | ||
|
|
684c2c9051 | ||
|
|
767efbf478 | ||
|
|
b4b95b976a | ||
|
|
2c59046c95 | ||
|
|
f11f5780e0 | ||
|
|
c00d7aa9b9 | ||
|
|
050c8a639f | ||
|
|
248247d828 | ||
|
|
42f972d403 | ||
|
|
a92cc7b340 | ||
|
|
b6ac569a5d | ||
|
|
2c00f457ae | ||
|
|
4a8456e406 | ||
|
|
63d77c0046 | ||
|
|
cc6eaf6308 | ||
|
|
c53002fe3b | ||
|
|
2c2a7d737a | ||
|
|
d250eba26d | ||
|
|
2585021472 | ||
|
|
518e457db3 | ||
|
|
7afa150e2f | ||
|
|
490384e3e7 | ||
|
|
4e83fe1049 | ||
|
|
5d9939831c | ||
|
|
d7803bcb41 | ||
|
|
c25181bd7d | ||
|
|
2ceb7a6077 | ||
|
|
e3bde55a0f | ||
|
|
834d5da992 | ||
|
|
2be298f89d | ||
|
|
477af49f88 | ||
|
|
e99699b008 | ||
|
|
72fa9a96c8 | ||
|
|
8fc4750efc | ||
|
|
78b4196767 | ||
|
|
1e9a5591d9 | ||
|
|
a994cc42f5 | ||
|
|
75b361386e | ||
|
|
48459b2357 | ||
|
|
c8e62b1cfa | ||
|
|
2a15c7082e | ||
|
|
9901b732cc | ||
|
|
f3dba34e63 | ||
|
|
36a7db47de | ||
|
|
97323cd8a0 | ||
|
|
8fa124afba | ||
|
|
df623b6abe | ||
|
|
3ef97fba38 | ||
|
|
a261f7d413 | ||
|
|
50cc521ee3 | ||
|
|
48205fa50d | ||
|
|
9fb06ec1c9 | ||
|
|
f9e188bad3 | ||
|
|
6b65756937 | ||
|
|
a74538b064 | ||
|
|
55787f4f08 | ||
|
|
0d59c187fe | ||
|
|
4d2add8f0f |
@@ -1,5 +1,5 @@
|
||||
README: Tcl
|
||||
This is the Tcl 8.6.1 source distribution.
|
||||
This is the Tcl 8.6.3 source distribution.
|
||||
http://sourceforge.net/projects/tcl/files/Tcl/
|
||||
You can get any source release of Tcl from the URL above.
|
||||
|
||||
|
||||
@@ -8274,7 +8274,7 @@ Dropped support for OS X versions less than 10.4 (Tiger) (fellows)
|
||||
2013-08-01 (bug fix)[1905562] RE recursion limit increased to support
|
||||
reported usage of large expressions (porter)
|
||||
|
||||
2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows)2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows)
|
||||
2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows)
|
||||
|
||||
2013-08-03 (enhancement)[3611643] [auto_mkindex] support TclOO (fellows)
|
||||
|
||||
@@ -8303,4 +8303,193 @@ reported usage of large expressions (porter)
|
||||
|
||||
Many optmizations, improvements, and tightened stack management in bytecode.
|
||||
|
||||
--- Released 8.6.1, Septemer 20, 2013 --- http://core.tcl.tk/tcl/ for details
|
||||
--- Released 8.6.1, September 20, 2013 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2013-09-27 (enhancement) improved ::env synchronization (fellows)
|
||||
|
||||
2013-10-20 (bug fix)[2835313] segfault from
|
||||
[apply {{} {while 1 {a {*}[return -level 0 -code continue]}}}] (fellows)
|
||||
|
||||
2013-10-22 (bug fix)[3556215] [scan %E%G%X] support (fellows)
|
||||
|
||||
2013-10-25 (bug fix)[3eb2ec1] upper case scheme names in url. (nijtmans)
|
||||
=> http 2.8.8
|
||||
|
||||
2013-10-29 (bug fix)[414d103] HP-UX: restore [exec] in threaded Tcl (nijtmans)
|
||||
|
||||
2013-11-04 (bug fix) C++ friendly stubs struct declarations (nijtmans)
|
||||
|
||||
2013-11-05 (bug fix)[426679e] OpenBSD man page rendering (nijtmans)
|
||||
|
||||
2013-11-12 (bug fix)[5425f2c] [fconfigure -error] breaks [socket -async]
|
||||
|
||||
2013-11-20 (bug fix) Improved environment variable management (nijtmans)
|
||||
=> tcltest 2.3.7
|
||||
|
||||
2013-11-21 (platforms) Support for Windows 8.1 (nijtmans)
|
||||
|
||||
2013-12-06 (RFE) improved [foreach] bytecode (fellows)
|
||||
|
||||
2013-12-10 (RFE) improved [lmap] bytecode (sofer)
|
||||
|
||||
2013-12-11 (RFE) improved [catch] bytecode (sofer)
|
||||
|
||||
2013-12-18 (bug fix)[0b874c3] SEGV [coroutine X coroutine Y info frame] (porter)
|
||||
|
||||
2013-12-20 (RFE) reduced numeric conversion in bytecode (sofer)
|
||||
|
||||
2014-01-07 (RFE) compilers for [concat], [linsert], [namespace origin],
|
||||
[next], [string replace], [string tolower], [string totitle], [string toupper],
|
||||
[string trim], [string trimleft], [string trimright] (fellows)
|
||||
|
||||
2014-01-22 (RFE) compilers for [nextto], [yieldto] (fellows)
|
||||
|
||||
2014-02-02 (RFE) compiler for [string is] (fellows)
|
||||
|
||||
2014-02-06 (bug fix)[a4494e2] panic in test namespace-13.2 (porter)
|
||||
|
||||
2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans)
|
||||
|
||||
2014-03-26 (RFE)[b42b208] Cygwin: [file attr -readonly -archive -hidden -system]
|
||||
(nijtmans)
|
||||
|
||||
2014-03-27 (bug fix) segfault iocmd-23.11 (porter)
|
||||
|
||||
2014-04-02 (bug fix)[581937a] Win: readable event on async connect failure
|
||||
|
||||
2014-04-04 (bug fix)[581937a,97069ea] async socket connect fail (oehlmann)
|
||||
|
||||
2014-04-10 (bug fix)[792641f] Win: no \ in normalized path (nijtmans)
|
||||
|
||||
2014-04-11 (bug fix)[3118489] protect NUL in filenames (nijtmans)
|
||||
|
||||
2014-04-15 (bug fix)[88aef05] segfault iocmd-21.20 (porter)
|
||||
|
||||
2014-04-16 (update) Win: use Winsock 2.2 (nijtmans)
|
||||
|
||||
2014-04-16 (bug fix)[d19a30d] segfault clock-67.[23] (sebres)
|
||||
|
||||
2014-04-21 (bug fix) segfault iocmd-21.2[12] (porter)
|
||||
|
||||
2014-04-22 (bug fix) segfault iogt-2.4 (porter)
|
||||
|
||||
2014-04-23 (bug fix)[3493120] memleak in thread exit
|
||||
|
||||
2014-05-08 refactoring of core I/O functions (porter)
|
||||
|
||||
2014-05-09 (bug fix)[3389978] Win: extended paths support (nijtmans)
|
||||
|
||||
2014-05-09 (bug fix) segfault iocmd-32.1 (porter)
|
||||
|
||||
2014-05-11 (bug fix)[6d2f249] nested ensemble compile failure (fellows)
|
||||
|
||||
2014-05-17 (RFE)[47d6625] wideint support in [lsearch -integer] [lsort -integer] (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2014-05-20 (bug fix) Stop eof and blocked state leaking thru stacks (porter)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2014-05-20 (bug fix)[13d3af3] Win: socket -async tried only first IP address
|
||||
|
||||
2014-05-28 (platforms) work around systems that fail when a shared library
|
||||
is deleted after it is [load]ed (kupries)
|
||||
|
||||
2014-05-31 (bug fix) chan events on pipes must be on proper ends (porter)
|
||||
|
||||
2014-06-04 (bug fix) socket-2.12 (porter)
|
||||
|
||||
2014-06-05 (bug fix) io-12.6 (kupries,porter)
|
||||
|
||||
2014-06-15 (RFE)[1b0266d] [dict replace|remove] return canonical dict (fellows)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2014-06-16 (bug fix) socket-2.13 workaround broken select() (porter)
|
||||
|
||||
2014-06-20 (bug fix)[b47b176] iortrans.tf-11.0 (porter)
|
||||
|
||||
2014-06-22 (RFE)[2f9df4c] -cleanup scripts before -out compare (nijtmans)
|
||||
|
||||
2014-07-04 (update) Update Unicode data to 7.0 (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2014-07-08 (bug) [chan push] converts blocked writes to error (aspect,porter)
|
||||
|
||||
2014-07-10 (bug fix)[7368d2] memleak Tcl_SetVar2(..,TCL_APPEND_VALUE) (porter)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2014-07-11 (bug) leaks in SetFsPathFromAny, [info frame] (porter)
|
||||
|
||||
2014-07-15 (bug) compress dict leak in zlib xform channel close (porter)
|
||||
|
||||
2014-07-17 (bug fix)[9969cf8] leak trace data in coroutine deletion (porter)
|
||||
|
||||
2014-07-18 (RFE)[b43f2b4] fix [lappend] multi performance collapse (fellows)
|
||||
|
||||
2014-07-19 (bug fix)[75b8433] memleak managing oo instance lists (porter)
|
||||
|
||||
2014-07-21 (bug fix)[e6477e1] memleak in AtForkChild() (porter)
|
||||
|
||||
2014-07-22 (bug fix)[12b0997] memleak in iocmd.tf-32.0 (porter)
|
||||
|
||||
2014-07-28 (RFE) Optimized binary [chan copy] by moving buffers (porter)
|
||||
|
||||
2014-07-30 (enhancement) use refcounts, not Tcl_Preserve to manage lifetime
|
||||
of Tcl_Channel (porter)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2014-07-31 (bug fix)[a84a720] double free in oo chain deletion (porter)
|
||||
|
||||
2014-08-01 (bug fix)[e75faba] SEGV [apply {{} {namespace upvar a b [x]}}] (porter)
|
||||
|
||||
2014-08-01 (update) "macosx*-i386-x86_64" "macosx-universal" no longer compatible (kupries)
|
||||
=> platform 1.0.13
|
||||
|
||||
2014-08-12 tzdata updated to Olson's tzdata2014f (kenny)
|
||||
|
||||
2014-08-17 (bug fix)[7d52e11] [info class subclasses oo::object] should
|
||||
include ::oo::class (fellows)
|
||||
|
||||
2014-08-25 (TIP 429) New command [string cat] (leitgeb,ferrieux)
|
||||
|
||||
--- Released 8.6.2, August 27, 2014 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2014-08-28 (bug)[b9e1a3] Correct Method Search Order (nadkarni,fellows)
|
||||
=> TclOO 1.0.3
|
||||
|
||||
2014-09-05 (bug)[ccc2c2] Regression [lreplace {} 1 1] (bron,fellows)
|
||||
|
||||
2014-09-08 (bug)<oo-1.18.2> Crash regression in [oo::class destroy] (porter)
|
||||
|
||||
2014-09-09 (bug)[84af11] Regress [regsub -all {\(.*} a(b) {}] (fellows)
|
||||
|
||||
2014-09-10 (bug)[cee90e] [try {} on ok {} - on return {} {}] panic (porter)
|
||||
|
||||
2014-09-20 (feature) [tcl::unsupported::getbytecode] disassember (fellows)
|
||||
|
||||
2014-09-27 (enhancement) [string cat] bytecode optimization (leitgeb,ferrieux)
|
||||
|
||||
2014-09-27 (bug)[82521b] segfault in mangled bytecode (ogilvie,sofer)
|
||||
|
||||
2014-10-02 (bug)[bc5b79] Hang in some [read]s of limited size (rogers,porter)
|
||||
|
||||
2014-10-03 (bug)[bc1a96] segfault in [array set] of traced array (tab,porter)
|
||||
|
||||
2014-10-08 (bug)[59a2e7] MSVC14 compile support (dower,nijtmans)
|
||||
|
||||
2014-10-10 (bug)[ed29c4] [fcopy] treats [blocked] as error (rowen,porter)
|
||||
|
||||
2014-10-10 (bug)[bf7135] regression in Tcl_Write() interface (porter)
|
||||
|
||||
2014-10-18 (bug)[10dc6d] fix [gets] on non-blocking channels (fassel,porter)
|
||||
|
||||
2014-10-26 Support for Windows 10 (nijtmans)
|
||||
|
||||
2014-10-31 (bug)[dcc034] restore [open comX: r+] (lll,nijtmans)
|
||||
|
||||
2014-11-05 (bug)[214cc0] Restore [lappend v] return value (sayers,porter)
|
||||
|
||||
2014-11-06 (bug)[5adc35] Stop forcing EOF to be permanent (porter)
|
||||
|
||||
--- Released 8.6.3, November 12, 2014 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2014-12-17 (TIP 427) [fconfigure $h -connecting, -peername, -sockname] (oehlmann,rmax)
|
||||
|
||||
Regular → Executable
Regular → Executable
Executable → Regular
Executable → Regular
+4
-1
@@ -293,6 +293,7 @@ of \fBTcl_Format\fR with functionality equivalent to:
|
||||
Tcl_Obj *newPtr = \fBTcl_Format\fR(interp, format, objc, objv);
|
||||
if (newPtr == NULL) return TCL_ERROR;
|
||||
\fBTcl_AppendObjToObj\fR(objPtr, newPtr);
|
||||
\fBTcl_DecrRefCount\fR(newPtr);
|
||||
return TCL_OK;
|
||||
.CE
|
||||
.PP
|
||||
@@ -337,7 +338,9 @@ Compile-time protection may be provided by some compilers.
|
||||
of \fBTcl_ObjPrintf\fR with functionality equivalent to
|
||||
.PP
|
||||
.CS
|
||||
\fBTcl_AppendObjToObj\fR(objPtr, \fBTcl_ObjPrintf\fR(format, ...));
|
||||
Tcl_Obj *newPtr = \fBTcl_ObjPrintf\fR(format, ...);
|
||||
\fBTcl_AppendObjToObj\fR(objPtr, newPtr);
|
||||
\fBTcl_DecrRefCount\fR(newPtr);
|
||||
.CE
|
||||
.PP
|
||||
but with greater convenience and efficiency when the appending
|
||||
|
||||
+10
-23
@@ -86,11 +86,14 @@ operation is being performed on the command. The bit
|
||||
\fBTCL_TRACE_DESTROYED\fR will be set in \fIflags\fR if the trace is about
|
||||
to be destroyed; this information may be useful to \fIproc\fR so that
|
||||
it can clean up its own internal data structures (see the section
|
||||
\fBTCL_TRACE_DESTROYED\fR below for more details). Lastly, the bit
|
||||
\fBTCL_INTERP_DESTROYED\fR will be set if the entire interpreter is being
|
||||
destroyed. When this bit is set, \fIproc\fR must be especially
|
||||
careful in the things it does (see the section \fBTCL_INTERP_DESTROYED\fR
|
||||
below).
|
||||
\fBTCL_TRACE_DESTROYED\fR below for more details). Because the
|
||||
deletion of commands can take place as part of the deletion of the interp
|
||||
that contains them, \fIproc\fR must be careful about checking what
|
||||
the passed in \fIinterp\fR value can be called upon to do.
|
||||
The routine \fBTcl_InterpDeleted\fR is an important tool for this.
|
||||
When \fBTcl_InterpDeleted\fR returns 1, \fIproc\fR will not be able
|
||||
to invoke any scripts in \fIinterp\fR. The function of \fIproc\fR
|
||||
in that circumstance is limited to the cleanup of its own data structures.
|
||||
.PP
|
||||
\fBTcl_UntraceCommand\fR may be used to remove a trace. If the
|
||||
command specified by \fIinterp\fR, \fIcmdName\fR, and \fIflags\fR has
|
||||
@@ -123,7 +126,8 @@ traces for a given command that have the same \fIproc\fR.
|
||||
.PP
|
||||
During rename traces, the command being renamed is visible with both
|
||||
names simultaneously, and the command still exists during delete
|
||||
traces (if \fBTCL_INTERP_DESTROYED\fR is not set). However, there is no
|
||||
traces, unless the interp that contains it is being deleted.
|
||||
However, there is no
|
||||
mechanism for signaling that an error occurred in a trace procedure,
|
||||
so great care should be taken that errors do not get silently lost.
|
||||
.SH "MULTIPLE TRACES"
|
||||
@@ -142,22 +146,5 @@ rename the command, the last renaming takes precedence.
|
||||
In a delete callback to \fIproc\fR, the \fBTCL_TRACE_DESTROYED\fR bit
|
||||
is set in \fIflags\fR.
|
||||
.\" Perhaps need some more comments here? - DKF
|
||||
.SH "TCL_INTERP_DESTROYED"
|
||||
.PP
|
||||
When an interpreter is destroyed, unset traces are called for
|
||||
all of its commands.
|
||||
The \fBTCL_INTERP_DESTROYED\fR bit will be set in the \fIflags\fR
|
||||
argument passed to the trace procedures.
|
||||
Trace procedures must be extremely careful in what they do if
|
||||
the \fBTCL_INTERP_DESTROYED\fR bit is set.
|
||||
It is not safe for the procedures to invoke any Tcl procedures
|
||||
on the interpreter, since its state is partially deleted.
|
||||
All that trace procedures should do under these circumstances is
|
||||
to clean up and free their own internal data structures.
|
||||
.SH BUGS
|
||||
.PP
|
||||
Tcl does not do any error checking to prevent trace procedures
|
||||
from misusing the interpreter during traces with \fBTCL_INTERP_DESTROYED\fR
|
||||
set.
|
||||
.SH KEYWORDS
|
||||
clientData, trace, command
|
||||
|
||||
+3
-2
@@ -637,8 +637,9 @@ On output, produces a locale-dependent time of day representation on a
|
||||
12-hour clock. On input, accepts whatever \fB%r\fR produces.
|
||||
.TP
|
||||
\fB%R\fR
|
||||
On output, produces a locale-dependent time of day representation on a
|
||||
24-hour clock. On input, accepts whatever \fB%R\fR produces.
|
||||
On output, the time in 24-hour notation (%H:%M). For a version
|
||||
including the seconds, see \fB%T\fR below. On input, accepts whatever
|
||||
\fB%R\fR produces.
|
||||
.TP
|
||||
\fB%s\fR
|
||||
On output, simply formats the \fItimeVal\fR argument as a decimal
|
||||
|
||||
+15
-11
@@ -25,11 +25,12 @@ below for a description), depending on \fIoption\fR. The legal
|
||||
This appends the given string (or strings) to the value that the given
|
||||
key maps to in the dictionary value contained in the given variable,
|
||||
writing the resulting dictionary value back to that variable.
|
||||
Non-existent keys are treated as if they map to an empty string.
|
||||
Non-existent keys are treated as if they map to an empty string. The
|
||||
updated dictionary value is returned.
|
||||
.TP
|
||||
\fBdict create \fR?\fIkey value ...\fR?
|
||||
.
|
||||
Create a new dictionary that contains each of the key/value mappings
|
||||
Return a new dictionary that contains each of the key/value mappings
|
||||
listed as arguments (keys and values alternating, with each key being
|
||||
followed by its associated value.)
|
||||
.TP
|
||||
@@ -53,10 +54,10 @@ The key rule only matches those key/value pairs whose keys match any
|
||||
of the given patterns (in the style of \fBstring match\fR.)
|
||||
.VE 8.6
|
||||
.TP
|
||||
\fBdict filter \fIdictionaryValue \fBscript {\fIkeyVar valueVar\fB} \fIscript\fR
|
||||
\fBdict filter \fIdictionaryValue \fBscript {\fIkeyVariable valueVariable\fB} \fIscript\fR
|
||||
.
|
||||
The script rule tests for matching by assigning the key to the
|
||||
\fIkeyVar\fR and the value to the \fIvalueVar\fR, and then evaluating
|
||||
\fIkeyVariable\fR and the value to the \fIvalueVariable\fR, and then evaluating
|
||||
the given script which should return a boolean value (with the
|
||||
key/value pair only being included in the result of the \fBdict
|
||||
filter\fR when a true value is returned.) Note that the first
|
||||
@@ -74,7 +75,7 @@ of the given patterns (in the style of \fBstring match\fR.)
|
||||
.VE 8.6
|
||||
.RE
|
||||
.TP
|
||||
\fBdict for {\fIkeyVar valueVar\fB} \fIdictionaryValue body\fR
|
||||
\fBdict for {\fIkeyVariable valueVariable\fB} \fIdictionaryValue body\fR
|
||||
.
|
||||
This command takes three arguments, the first a two-element list of
|
||||
variable names (for the key and value respectively of each mapping in
|
||||
@@ -121,7 +122,8 @@ not specified) to the value that the given key maps to in the
|
||||
dictionary value contained in the given variable, writing the
|
||||
resulting dictionary value back to that variable. Non-existent keys
|
||||
are treated as if they map to 0. It is an error to increment a value
|
||||
for an existing key if that value is not an integer.
|
||||
for an existing key if that value is not an integer. The updated
|
||||
dictionary value is returned.
|
||||
.TP
|
||||
\fBdict info \fIdictionaryValue\fR
|
||||
.
|
||||
@@ -145,9 +147,10 @@ to in the dictionary value contained in the given variable, writing
|
||||
the resulting dictionary value back to that variable. Non-existent
|
||||
keys are treated as if they map to an empty list, and it is legal for
|
||||
there to be no items to append to the list. It is an error for the
|
||||
value that the key maps to to not be representable as a list.
|
||||
value that the key maps to to not be representable as a list. The
|
||||
updated dictionary value is returned.
|
||||
.TP
|
||||
\fBdict map \fR{\fIkeyVar valueVar\fR} \fIdictionaryValue body\fR
|
||||
\fBdict map \fR{\fIkeyVariable valueVariable\fR} \fIdictionaryValue body\fR
|
||||
.
|
||||
This command applies a transformation to each element of a dictionary,
|
||||
returning a new dictionary. It takes three arguments: the first is a
|
||||
@@ -157,7 +160,7 @@ and the third a script to be evaluated for each mapping with the key and value
|
||||
variables set appropriately (in the manner of \fBlmap\fR). In an iteration
|
||||
where the evaluated script completes normally (\fBTCL_OK\fR, as opposed to an
|
||||
\fBerror\fR, etc.) the result of the script is put into an accumulator
|
||||
dictionary using the key that is the current contents of the \fIkeyVar\fR
|
||||
dictionary using the key that is the current contents of the \fIkeyVariable\fR
|
||||
variable at that point. The result of the \fBdict map\fR command is the
|
||||
accumulator dictionary after all keys have been iterated over.
|
||||
.RS
|
||||
@@ -202,7 +205,7 @@ This operation takes the name of a variable containing a dictionary
|
||||
value and places an updated dictionary value in that variable
|
||||
containing a mapping from the given key to the given value. When
|
||||
multiple keys are present, this operation creates or updates a chain
|
||||
of nested dictionaries.
|
||||
of nested dictionaries. The updated dictionary value is returned.
|
||||
.TP
|
||||
\fBdict size \fIdictionaryValue\fR
|
||||
.
|
||||
@@ -216,7 +219,8 @@ dictionary value in that variable that does not contain a mapping for
|
||||
the given key. Where multiple keys are present, this describes a path
|
||||
through nested dictionaries to the mapping to remove. At least one key
|
||||
must be specified, but the last key on the key-path need not exist.
|
||||
All other components on the path must exist.
|
||||
All other components on the path must exist. The updated dictionary
|
||||
value is returned.
|
||||
.TP
|
||||
\fBdict update \fIdictionaryVariable key varName \fR?\fIkey varName ...\fR? \fIbody\fR
|
||||
.
|
||||
|
||||
+27
-7
@@ -14,10 +14,21 @@ encoding \- Manipulate encodings
|
||||
.BE
|
||||
.SH INTRODUCTION
|
||||
.PP
|
||||
Strings in Tcl are encoded using 16-bit Unicode characters. Different
|
||||
operating system interfaces or applications may generate strings in
|
||||
other encodings such as Shift-JIS. The \fBencoding\fR command helps
|
||||
to bridge the gap between Unicode and these other formats.
|
||||
Strings in Tcl are logically a sequence of 16-bit Unicode characters.
|
||||
These strings are represented in memory as a sequence of bytes that
|
||||
may be in one of several encodings: modified UTF\-8 (which uses 1 to 3
|
||||
bytes per character), 16-bit
|
||||
.QW Unicode
|
||||
(which uses 2 bytes per character, with an endianness that is
|
||||
dependent on the host architecture), and binary (which uses a single
|
||||
byte per character but only handles a restricted range of characters).
|
||||
Tcl does not guarantee to always use the same encoding for the same
|
||||
string.
|
||||
.PP
|
||||
Different operating system interfaces or applications may generate
|
||||
strings in other encodings such as Shift\-JIS. The \fBencoding\fR
|
||||
command helps to bridge the gap between Unicode and these other
|
||||
formats.
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Performs one of several encoding related operations, depending on
|
||||
@@ -37,8 +48,9 @@ system encoding is used.
|
||||
Convert \fIstring\fR from Unicode to the specified \fIencoding\fR.
|
||||
The result is a sequence of bytes that represents the converted
|
||||
string. Each byte is stored in the lower 8-bits of a Unicode
|
||||
character. If \fIencoding\fR is not specified, the current
|
||||
system encoding is used.
|
||||
character (indeed, the resulting string is a binary string as far as
|
||||
Tcl is concerned, at least initially). If \fIencoding\fR is not
|
||||
specified, the current system encoding is used.
|
||||
.TP
|
||||
\fBencoding dirs\fR ?\fIdirectoryList\fR?
|
||||
.
|
||||
@@ -56,6 +68,11 @@ searchable directory, that element is ignored.
|
||||
.
|
||||
Returns a list containing the names of all of the encodings that are
|
||||
currently available.
|
||||
The encodings
|
||||
.QW utf-8
|
||||
and
|
||||
.QW iso8859-1
|
||||
are guaranteed to be present in the list.
|
||||
.TP
|
||||
\fBencoding system\fR ?\fIencoding\fR?
|
||||
.
|
||||
@@ -73,7 +90,7 @@ However, because the \fBsource\fR command always reads files using the
|
||||
current system encoding, Tcl will only source such files correctly
|
||||
when the encoding used to write the file is the same. This tends not
|
||||
to be true in an internationalized setting. For example, if such a
|
||||
file was sourced in North America (where the ISO8859-1 is normally
|
||||
file was sourced in North America (where the ISO8859\-1 is normally
|
||||
used), each byte in the file would be treated as a separate character
|
||||
that maps to the 00 page in Unicode. The resulting Tcl strings will
|
||||
not contain the expected Japanese characters. Instead, they will
|
||||
@@ -93,3 +110,6 @@ which is the Hiragana letter HA.
|
||||
Tcl_GetEncoding(3)
|
||||
.SH KEYWORDS
|
||||
encoding, unicode
|
||||
.\" Local Variables:
|
||||
.\" mode: nroff
|
||||
.\" End:
|
||||
|
||||
+24
-3
@@ -46,8 +46,11 @@ non-blocking mode; the \fBfcopy\fR command takes care of that automatically.
|
||||
However, it is necessary to enter the event loop by using
|
||||
the \fBvwait\fR command or by using Tk.
|
||||
.PP
|
||||
You are not allowed to do other I/O operations with
|
||||
\fIinchan\fR or \fIoutchan\fR during a background \fBfcopy\fR.
|
||||
You are not allowed to do other input operations with \fIinchan\fR, or
|
||||
output operations with \fIoutchan\fR, during a background
|
||||
\fBfcopy\fR. The converse is entirely legitimate, as exhibited by the
|
||||
bidirectional fcopy example below.
|
||||
.PP
|
||||
If either \fIinchan\fR or \fIoutchan\fR get closed
|
||||
while the copy is in progress, the current copy is stopped
|
||||
and the command callback is \fInot\fR made.
|
||||
@@ -57,7 +60,7 @@ then all data already queued for \fIoutchan\fR is written out.
|
||||
Note that \fIinchan\fR can become readable during a background copy.
|
||||
You should turn off any \fBfileevent\fR handlers during a background
|
||||
copy so those handlers do not interfere with the copy.
|
||||
Any I/O attempted by a \fBfileevent\fR handler will get a
|
||||
Any wrong-sided I/O attempted (by a \fBfileevent\fR handler or otherwise) will get a
|
||||
.QW "channel busy"
|
||||
error.
|
||||
.PP
|
||||
@@ -149,6 +152,24 @@ set total 0
|
||||
-command [list CopyMore $in $out $chunk]
|
||||
vwait done
|
||||
.CE
|
||||
.PP
|
||||
The fourth example starts an asynchronous, bidirectional fcopy between
|
||||
two sockets. Those could also be pipes from two [open "|hal 9000" r+]
|
||||
(though their conversation would remain secret to the script, since
|
||||
all four fileevent slots are busy).
|
||||
.PP
|
||||
.CS
|
||||
set flows 2
|
||||
proc Done {dir args} {
|
||||
global flows done
|
||||
puts "$dir is over."
|
||||
incr flows -1
|
||||
if {$flows<=0} {set done 1}
|
||||
}
|
||||
\fBfcopy\fR $sok1 $sok2 -command [list Done UP]
|
||||
\fBfcopy\fR $sok2 $sok1 -command [list Done DOWN]
|
||||
vwait done
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
eof(n), fblocked(n), fconfigure(n), file(n)
|
||||
.SH KEYWORDS
|
||||
|
||||
+2
-1
@@ -210,7 +210,8 @@ proc httpHandlerCallback {socket token} {
|
||||
.TP
|
||||
\fB\-headers\fR \fIkeyvaluelist\fR
|
||||
.
|
||||
This option is used to add extra headers to the HTTP request. The
|
||||
This option is used to add headers not already specified
|
||||
by \fB::http::config\fR to the HTTP request. The
|
||||
\fIkeyvaluelist\fR argument must be a list with an even number of
|
||||
elements that alternate between keys and values. The keys become
|
||||
header field names. Newlines are stripped from the values so the
|
||||
|
||||
Executable → Regular
+13
-48
@@ -361,18 +361,17 @@ may cause this error.
|
||||
A BREAK condition has been detected by your UART (see above).
|
||||
.SH "PORTABILITY ISSUES"
|
||||
.TP
|
||||
\fBWindows \fR(all versions)
|
||||
\fBWindows \fR
|
||||
.
|
||||
Valid values for \fIfileName\fR to open a serial port are of the form
|
||||
\fBcom\fIX\fB:\fR, where \fIX\fR is a number, generally from 1 to 4.
|
||||
This notation only works for serial ports from 1 to 9, if the system
|
||||
happens to have more than four. An attempt to open a serial port that
|
||||
\fBcom\fIX\fB\fR, where \fIX\fR is a number, generally from 1 to 9.
|
||||
A legacy form accepted as well is \fBcom\fIX\fB:\fR. This notation only
|
||||
works for serial ports from 1 to 9. An attempt to open a serial port that
|
||||
does not exist or has a number greater than 9 will fail. An alternate
|
||||
form of opening serial ports is to use the filename \fB\e\e.\ecomX\fR,
|
||||
where X is any number that corresponds to a serial port; please note
|
||||
that this method is considerably slower on Windows 95 and Windows 98.
|
||||
.TP
|
||||
\fBWindows NT\fR
|
||||
form of opening serial ports is to use the filename \fB//./comX\fR,
|
||||
where X is any number that corresponds to a serial port.
|
||||
.RS
|
||||
.PP
|
||||
.
|
||||
When running Tcl interactively, there may be some strange interactions
|
||||
between the real console, if one is present, and a command pipeline that uses
|
||||
@@ -380,45 +379,11 @@ standard input or output. If a command pipeline is opened for reading, some
|
||||
of the lines entered at the console will be sent to the command pipeline and
|
||||
some will be sent to the Tcl evaluator. If a command pipeline is opened for
|
||||
writing, keystrokes entered into the console are not visible until the
|
||||
pipe is closed. This behavior occurs whether the command pipeline is
|
||||
executing 16-bit or 32-bit applications. These problems only occur because
|
||||
both Tcl and the child application are competing for the console at
|
||||
the same time. If the command pipeline is started from a script, so that Tcl
|
||||
is not accessing the console, or if the command pipeline does not use
|
||||
standard input or output, but is redirected from or to a file, then the
|
||||
above problems do not occur.
|
||||
.TP
|
||||
\fBWindows 95\fR
|
||||
.
|
||||
A command pipeline that executes a 16-bit DOS application cannot be opened
|
||||
for both reading and writing, since 16-bit DOS applications that receive
|
||||
standard input from a pipe and send standard output to a pipe run
|
||||
synchronously. Command pipelines that do not execute 16-bit DOS
|
||||
applications run asynchronously and can be opened for both reading and
|
||||
writing.
|
||||
.RS
|
||||
.PP
|
||||
When running Tcl interactively, there may be some strange interactions
|
||||
between the real console, if one is present, and a command pipeline that uses
|
||||
standard input or output. If a command pipeline is opened for reading from
|
||||
a 32-bit application, some of the keystrokes entered at the console will be
|
||||
sent to the command pipeline and some will be sent to the Tcl evaluator. If
|
||||
a command pipeline is opened for writing to a 32-bit application, no output
|
||||
is visible on the console until the pipe is closed. These problems only
|
||||
occur because both Tcl and the child application are competing for the
|
||||
console at the same time. If the command pipeline is started from a script,
|
||||
so that Tcl is not accessing the console, or if the command pipeline does
|
||||
not use standard input or output, but is redirected from or to a file, then
|
||||
the above problems do not occur.
|
||||
.PP
|
||||
Whether or not Tcl is running interactively, if a command pipeline is opened
|
||||
for reading from a 16-bit DOS application, the call to \fBopen\fR will not
|
||||
return until end-of-file has been received from the command pipeline's
|
||||
standard output. If a command pipeline is opened for writing to a 16-bit DOS
|
||||
application, no data will be sent to the command pipeline's standard output
|
||||
until the pipe is actually closed. This problem occurs because 16-bit DOS
|
||||
applications are run synchronously, as described above.
|
||||
.RE
|
||||
pipe is closed. These problems only occur because both Tcl and the child
|
||||
application are competing for the console at the same time. If the command
|
||||
pipeline is started from a script, so that Tcl is not accessing the console,
|
||||
or if the command pipeline does not use standard input or output, but is
|
||||
redirected from or to a file, then the above problems do not occur.
|
||||
.TP
|
||||
\fBUnix\fR\0\0\0\0\0\0\0
|
||||
.
|
||||
|
||||
@@ -97,6 +97,10 @@ writable channel event on the socket to get notified when the
|
||||
asynchronous connection has succeeded or failed. See the \fBvwait\fR
|
||||
and the \fBchan\fR commands for more details on the event loop and
|
||||
channel events.
|
||||
.PP
|
||||
The \fBchan configure\fR option \fB-connecting\fR may be used to check if the connect is still running. To verify a successful connect, the option \fB-error\fR may be checked when \fB-connecting\fR returned 0.
|
||||
.PP
|
||||
Operation without the event queue requires at the moment calls to \fBchan configure\fR to advance the internal state machine.
|
||||
.RE
|
||||
.SH "SERVER SOCKETS"
|
||||
.PP
|
||||
@@ -186,6 +190,11 @@ sockets, this option returns a list of three elements; these are the
|
||||
address, the host name and the port to which the peer socket is connected
|
||||
or bound. If the host name cannot be computed, the second element of the
|
||||
list is identical to the address, its first element.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-connecting\fR
|
||||
.
|
||||
This option is not supported by server sockets. For client sockets, this option returns 1 if an asyncroneous connect is still in progress, 0 otherwise.
|
||||
.PP
|
||||
.SH "EXAMPLES"
|
||||
.PP
|
||||
|
||||
+42
-6
@@ -19,6 +19,21 @@ string \- Manipulate strings
|
||||
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.
|
||||
.RS
|
||||
.PP
|
||||
This primitive is occasionally handier than juxtaposition of strings
|
||||
when mixed quoting is wanted, or when the aim is to return the result
|
||||
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
|
||||
.
|
||||
Perform a character-by-character comparison of strings \fIstring1\fR
|
||||
@@ -131,8 +146,9 @@ Any Unicode printing character, including space.
|
||||
.IP \fBpunct\fR 12
|
||||
Any Unicode punctuation character.
|
||||
.IP \fBspace\fR 12
|
||||
Any Unicode whitespace character, zero width space (U+200b),
|
||||
word joiner (U+2060) and zero width no-break space (U+feff) (=BOM).
|
||||
Any Unicode whitespace character, mongolian vowel separator
|
||||
(U+180e), zero width space (U+200b), word joiner (U+2060) or
|
||||
zero width no-break space (U+feff) (=BOM).
|
||||
.IP \fBtrue\fR 12
|
||||
Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
|
||||
true.
|
||||
@@ -343,10 +359,13 @@ misleading.
|
||||
\fBstring bytelength \fIstring\fR
|
||||
.
|
||||
Returns a decimal string giving the number of bytes used to represent
|
||||
\fIstring\fR in memory. Because UTF\-8 uses one to three bytes to
|
||||
represent Unicode characters, the byte length will not be the same as
|
||||
the character length in general. The cases where a script cares about
|
||||
the byte length are rare.
|
||||
\fIstring\fR in memory when encoded as Tcl's internal modified UTF\-8;
|
||||
Tcl may use other encodings for \fIstring\fR as well, and does not
|
||||
guarantee to only use a single encoding for a particular \fIstring\fR.
|
||||
Because UTF\-8 uses a variable number of bytes to represent Unicode
|
||||
characters, the byte length will not be the same as the character
|
||||
length in general. The cases where a script cares about the byte
|
||||
length are rare.
|
||||
.RS
|
||||
.PP
|
||||
In almost all cases, you should use the
|
||||
@@ -354,10 +373,27 @@ In almost all cases, you should use the
|
||||
Tcl byte array value). Refer to the \fBTcl_NumUtfChars\fR manual
|
||||
entry for more details on the UTF\-8 representation.
|
||||
.PP
|
||||
Formally, the \fBstring bytelength\fR operation returns the content of
|
||||
the \fIlength\fR field of the \fBTcl_Obj\fR structure, after calling
|
||||
\fBTcl_GetString\fR to ensure that the \fIbytes\fR field is populated.
|
||||
This is highly unlikely to be useful to Tcl scripts, as Tcl's internal
|
||||
encoding is not strict UTF\-8, but rather a modified CESU\-8 with a
|
||||
denormalized NUL (identical to that used in a number of places by
|
||||
Java's serialization mechanism) to enable basic processing with
|
||||
non-Unicode-aware C functions. As this representation should only
|
||||
ever be used by Tcl's implementation, the number of bytes used to
|
||||
store the representation is of very low value (except to C extension
|
||||
code, which has direct access for the purpose of memory management,
|
||||
etc.)
|
||||
.PP
|
||||
\fICompatibility note:\fR it is likely that this subcommand will be
|
||||
withdrawn in a future version of Tcl. It is better to use the
|
||||
\fBencoding convertto\fR command to convert a string to a known
|
||||
encoding and then apply \fBstring length\fR to that.
|
||||
.PP
|
||||
.CS
|
||||
\fBstring length\fR [encoding convertto utf-8 $theString]
|
||||
.CE
|
||||
.RE
|
||||
.TP
|
||||
\fBstring wordend \fIstring charIndex\fR
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceEval, tcl_wordchars, tcl_version \- Variables used by Tcl
|
||||
argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceExec, tcl_wordchars, tcl_version \- Variables used by Tcl
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -347,8 +347,8 @@ was compiled with threads enabled.
|
||||
.
|
||||
This identifies the
|
||||
current user based on the login information available on the platform.
|
||||
This comes from the USER or LOGNAME environment variable on Unix,
|
||||
and the value from GetUserName on Windows.
|
||||
This value comes from the getuid() and getpwuid() system calls on Unix,
|
||||
and the value from the GetUserName() system call on Windows.
|
||||
.TP
|
||||
\fBwordSize\fR
|
||||
.
|
||||
|
||||
+340
-297
@@ -137,97 +137,107 @@ static const crange alphaRangeTable[] = {
|
||||
{0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6},
|
||||
{0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374},
|
||||
{0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5},
|
||||
{0x3f7, 0x481}, {0x48a, 0x527}, {0x531, 0x556}, {0x561, 0x587},
|
||||
{0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
|
||||
{0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
|
||||
{0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
|
||||
{0x800, 0x815}, {0x840, 0x858}, {0x8a2, 0x8ac}, {0x904, 0x939},
|
||||
{0x958, 0x961}, {0x971, 0x977}, {0x979, 0x97f}, {0x985, 0x98c},
|
||||
{0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1},
|
||||
{0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c},
|
||||
{0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
|
||||
{0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28},
|
||||
{0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a},
|
||||
{0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
|
||||
{0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc33},
|
||||
{0xc35, 0xc39}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8},
|
||||
{0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
|
||||
{0xd12, 0xd3a}, {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, 0x13f4},
|
||||
{0x1401, 0x166c}, {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea},
|
||||
{0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751},
|
||||
{0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877},
|
||||
{0x1880, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191c}, {0x1950, 0x196d},
|
||||
{0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19c1, 0x19c7}, {0x1a00, 0x1a16},
|
||||
{0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0},
|
||||
{0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d},
|
||||
{0x1ce9, 0x1cec}, {0x1cee, 0x1cf1}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15},
|
||||
{0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57},
|
||||
{0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4},
|
||||
{0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec},
|
||||
{0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113},
|
||||
{0x2119, 0x211d}, {0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f},
|
||||
{0x2145, 0x2149}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4},
|
||||
{0x2ceb, 0x2cee}, {0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96},
|
||||
{0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe},
|
||||
{0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde},
|
||||
{0x3031, 0x3035}, {0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa},
|
||||
{0x30fc, 0x30ff}, {0x3105, 0x312d}, {0x3131, 0x318e}, {0x31a0, 0x31ba},
|
||||
{0x31f0, 0x31ff}, {0x3400, 0x4db5}, {0x4e00, 0x9fcc}, {0xa000, 0xa48c},
|
||||
{0xa4d0, 0xa4fd}, {0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e},
|
||||
{0xa67f, 0xa697}, {0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788},
|
||||
{0xa78b, 0xa78e}, {0xa790, 0xa793}, {0xa7a0, 0xa7aa}, {0xa7f8, 0xa801},
|
||||
{0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822}, {0xa840, 0xa873},
|
||||
{0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925}, {0xa930, 0xa946},
|
||||
{0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xaa00, 0xaa28}, {0xaa40, 0xaa42},
|
||||
{0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa80, 0xaaaf}, {0xaab9, 0xaabd},
|
||||
{0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, {0xab01, 0xab06},
|
||||
{0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
|
||||
{0xabc0, 0xabe2}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
|
||||
{0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
|
||||
{0xfb1f, 0xfb28}, {0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1},
|
||||
{0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb},
|
||||
{0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a},
|
||||
{0xff66, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7},
|
||||
{0xffda, 0xffdc}
|
||||
{0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b2}, {0x904, 0x939},
|
||||
{0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c}, {0x993, 0x9a8},
|
||||
{0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1}, {0xa05, 0xa0a},
|
||||
{0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c}, {0xa72, 0xa74},
|
||||
{0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
|
||||
{0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
|
||||
{0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a}, {0xb8e, 0xb90},
|
||||
{0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xc05, 0xc0c},
|
||||
{0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc85, 0xc8c},
|
||||
{0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9},
|
||||
{0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a}, {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, 0x13f4}, {0x1401, 0x166c}, {0x166f, 0x167f},
|
||||
{0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8}, {0x1700, 0x170c},
|
||||
{0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751}, {0x1760, 0x176c},
|
||||
{0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877}, {0x1880, 0x18a8},
|
||||
{0x18b0, 0x18f5}, {0x1900, 0x191e}, {0x1950, 0x196d}, {0x1970, 0x1974},
|
||||
{0x1980, 0x19ab}, {0x19c1, 0x19c7}, {0x1a00, 0x1a16}, {0x1a20, 0x1a54},
|
||||
{0x1b05, 0x1b33}, {0x1b45, 0x1b4b}, {0x1b83, 0x1ba0}, {0x1bba, 0x1be5},
|
||||
{0x1c00, 0x1c23}, {0x1c4d, 0x1c4f}, {0x1c5a, 0x1c7d}, {0x1ce9, 0x1cec},
|
||||
{0x1cee, 0x1cf1}, {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d},
|
||||
{0x1f20, 0x1f45}, {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d},
|
||||
{0x1f80, 0x1fb4}, {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc},
|
||||
{0x1fd0, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4},
|
||||
{0x1ff6, 0x1ffc}, {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d},
|
||||
{0x212a, 0x212d}, {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149},
|
||||
{0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee},
|
||||
{0x2d00, 0x2d25}, {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6},
|
||||
{0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
|
||||
{0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035},
|
||||
{0x3041, 0x3096}, {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff},
|
||||
{0x3105, 0x312d}, {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff},
|
||||
{0x3400, 0x4db5}, {0x4e00, 0x9fcc}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd},
|
||||
{0xa500, 0xa60c}, {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d},
|
||||
{0xa6a0, 0xa6e5}, {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa78e},
|
||||
{0xa790, 0xa7ad}, {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, 0xab5f}, {0xabc0, 0xabe2},
|
||||
{0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d},
|
||||
{0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28},
|
||||
{0xfb2a, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d},
|
||||
{0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74},
|
||||
{0xfe76, 0xfefc}, {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe},
|
||||
{0xffc2, 0xffc7}, {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
|
||||
{0x10300, 0x1031e}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10380, 0x1039d},
|
||||
{0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d}, {0x10800, 0x10805},
|
||||
{0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10900, 0x10915}, {0x10920, 0x10939},
|
||||
{0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
|
||||
{0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d},
|
||||
{0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
|
||||
{0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
|
||||
{0x10860, 0x10876}, {0x10880, 0x1089e}, {0x10900, 0x10915}, {0x10920, 0x10939},
|
||||
{0x10980, 0x109b7}, {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33},
|
||||
{0x10a60, 0x10a7c}, {0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72},
|
||||
{0x10a60, 0x10a7c}, {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4},
|
||||
{0x10b00, 0x10b35}, {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91},
|
||||
{0x10c00, 0x10c48}, {0x11003, 0x11037}, {0x11083, 0x110af}, {0x110d0, 0x110e8},
|
||||
{0x11103, 0x11126}, {0x11183, 0x111b2}, {0x111c1, 0x111c4}, {0x11680, 0x116aa},
|
||||
{0x12000, 0x1236e}, {0x13000, 0x1342e}, {0x16800, 0x16a38}, {0x16f00, 0x16f44},
|
||||
{0x16f93, 0x16f9f}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
|
||||
{0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2}, {0x111c1, 0x111c4},
|
||||
{0x11200, 0x11211}, {0x11213, 0x1122b}, {0x112b0, 0x112de}, {0x11305, 0x1130c},
|
||||
{0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1135d, 0x11361},
|
||||
{0x11480, 0x114af}, {0x11580, 0x115ae}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
|
||||
{0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x12000, 0x12398}, {0x13000, 0x1342e},
|
||||
{0x16800, 0x16a38}, {0x16a40, 0x16a5e}, {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f},
|
||||
{0x16b40, 0x16b43}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44},
|
||||
{0x16f93, 0x16f9f}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
|
||||
{0x1bc90, 0x1bc99}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
|
||||
{0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
|
||||
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0},
|
||||
{0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734},
|
||||
{0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8},
|
||||
{0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {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}, {0x2f800, 0x2fa1d}
|
||||
{0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {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},
|
||||
{0x2f800, 0x2fa1d}
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
|
||||
|
||||
static const chr alphaCharTable[] = {
|
||||
0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x386, 0x38c,
|
||||
0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef, 0x6ff,
|
||||
0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828, 0x8a0,
|
||||
0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x37f, 0x386,
|
||||
0x38c, 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef,
|
||||
0x6ff, 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828,
|
||||
0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd,
|
||||
0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38,
|
||||
0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xb0f,
|
||||
@@ -241,14 +251,16 @@ static const chr alphaCharTable[] = {
|
||||
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, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5,
|
||||
0xaab6, 0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
|
||||
0x303b, 0x303c, 0xa62a, 0xa62b, 0xa7b0, 0xa7b1, 0xa8fb, 0xa9cf, 0xaa7a,
|
||||
0xaab1, 0xaab5, 0xaab6, 0xaac0, 0xaac2, 0xab64, 0xab65, 0xfb1d, 0xfb3e,
|
||||
0xfb40, 0xfb41, 0xfb43, 0xfb44
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x109be, 0x109bf, 0x10a00,
|
||||
0x16f50, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
|
||||
0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47,
|
||||
0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d,
|
||||
0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
|
||||
0x11176, 0x111da, 0x1130f, 0x11310, 0x11332, 0x11333, 0x1133d, 0x114c4, 0x114c5,
|
||||
0x114c7, 0x11644, 0x118ff, 0x16f50, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2,
|
||||
0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39,
|
||||
0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57,
|
||||
0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -259,11 +271,12 @@ static const chr alphaCharTable[] = {
|
||||
*/
|
||||
|
||||
static const crange controlRangeTable[] = {
|
||||
{0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x604}, {0x200b, 0x200f},
|
||||
{0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x605}, {0x200b, 0x200f},
|
||||
{0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
|
||||
{0xfff9, 0xfffb}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd}, {0x100000, 0x10fffd}
|
||||
,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd},
|
||||
{0x100000, 0x10fffd}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -286,15 +299,18 @@ static const crange digitRangeTable[] = {
|
||||
{0x30, 0x39}, {0x660, 0x669}, {0x6f0, 0x6f9}, {0x7c0, 0x7c9},
|
||||
{0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, {0xae6, 0xaef},
|
||||
{0xb66, 0xb6f}, {0xbe6, 0xbef}, {0xc66, 0xc6f}, {0xce6, 0xcef},
|
||||
{0xd66, 0xd6f}, {0xe50, 0xe59}, {0xed0, 0xed9}, {0xf20, 0xf29},
|
||||
{0x1040, 0x1049}, {0x1090, 0x1099}, {0x17e0, 0x17e9}, {0x1810, 0x1819},
|
||||
{0x1946, 0x194f}, {0x19d0, 0x19d9}, {0x1a80, 0x1a89}, {0x1a90, 0x1a99},
|
||||
{0x1b50, 0x1b59}, {0x1bb0, 0x1bb9}, {0x1c40, 0x1c49}, {0x1c50, 0x1c59},
|
||||
{0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909}, {0xa9d0, 0xa9d9},
|
||||
{0xaa50, 0xaa59}, {0xabf0, 0xabf9}, {0xff10, 0xff19}
|
||||
{0xd66, 0xd6f}, {0xde6, 0xdef}, {0xe50, 0xe59}, {0xed0, 0xed9},
|
||||
{0xf20, 0xf29}, {0x1040, 0x1049}, {0x1090, 0x1099}, {0x17e0, 0x17e9},
|
||||
{0x1810, 0x1819}, {0x1946, 0x194f}, {0x19d0, 0x19d9}, {0x1a80, 0x1a89},
|
||||
{0x1a90, 0x1a99}, {0x1b50, 0x1b59}, {0x1bb0, 0x1bb9}, {0x1c40, 0x1c49},
|
||||
{0x1c50, 0x1c59}, {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909},
|
||||
{0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9},
|
||||
{0xff10, 0xff19}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
|
||||
{0x111d0, 0x111d9}, {0x116c0, 0x116c9}, {0x1d7ce, 0x1d7ff}
|
||||
{0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x114d0, 0x114d9}, {0x11650, 0x11659},
|
||||
{0x116c0, 0x116c9}, {0x118e0, 0x118e9}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59},
|
||||
{0x1d7ce, 0x1d7ff}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -317,15 +333,17 @@ 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, 0x2e3b},
|
||||
{0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e42},
|
||||
{0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
|
||||
{0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
|
||||
{0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
|
||||
{0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d},
|
||||
{0xff5f, 0xff65}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10b39, 0x10b3f}, {0x11047, 0x1104d},
|
||||
{0x110be, 0x110c1}, {0x11140, 0x11143}, {0x111c5, 0x111c8}, {0x12470, 0x12473}
|
||||
,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
|
||||
{0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
|
||||
{0x111c5, 0x111c8}, {0x11238, 0x1123d}, {0x115c1, 0x115c9}, {0x11641, 0x11643},
|
||||
{0x12470, 0x12474}, {0x16b37, 0x16b3b}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -345,7 +363,8 @@ static const chr punctCharTable[] = {
|
||||
0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, 0xfe6a, 0xfe6b,
|
||||
0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1039f, 0x103d0, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc
|
||||
,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
|
||||
0x11174, 0x11175, 0x111cd, 0x114c6, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -383,15 +402,16 @@ 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}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xff41, 0xff5a}
|
||||
{0xa771, 0xa778}, {0xa793, 0xa795}, {0xab30, 0xab5a}, {0xfb00, 0xfb06},
|
||||
{0xfb13, 0xfb17}, {0xff41, 0xff5a}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10428, 0x1044f}, {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467},
|
||||
{0x1d482, 0x1d49b}, {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf},
|
||||
{0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f},
|
||||
{0x1d5ba, 0x1d5d3}, {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f},
|
||||
{0x1d68a, 0x1d6a5}, {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714},
|
||||
{0x1d716, 0x1d71b}, {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788},
|
||||
{0x1d78a, 0x1d78f}, {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}
|
||||
,{0x10428, 0x1044f}, {0x118c0, 0x118df}, {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454},
|
||||
{0x1d456, 0x1d467}, {0x1d482, 0x1d49b}, {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3},
|
||||
{0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503}, {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b},
|
||||
{0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3}, {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b},
|
||||
{0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5}, {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1},
|
||||
{0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b}, {0x1d736, 0x1d74e}, {0x1d750, 0x1d755},
|
||||
{0x1d770, 0x1d788}, {0x1d78a, 0x1d78f}, {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -427,39 +447,41 @@ static const chr lowerCharTable[] = {
|
||||
0x4f1, 0x4f3, 0x4f5, 0x4f7, 0x4f9, 0x4fb, 0x4fd, 0x4ff, 0x501,
|
||||
0x503, 0x505, 0x507, 0x509, 0x50b, 0x50d, 0x50f, 0x511, 0x513,
|
||||
0x515, 0x517, 0x519, 0x51b, 0x51d, 0x51f, 0x521, 0x523, 0x525,
|
||||
0x527, 0x1e01, 0x1e03, 0x1e05, 0x1e07, 0x1e09, 0x1e0b, 0x1e0d, 0x1e0f,
|
||||
0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19, 0x1e1b, 0x1e1d, 0x1e1f, 0x1e21,
|
||||
0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b, 0x1e2d, 0x1e2f, 0x1e31, 0x1e33,
|
||||
0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d, 0x1e3f, 0x1e41, 0x1e43, 0x1e45,
|
||||
0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f, 0x1e51, 0x1e53, 0x1e55, 0x1e57,
|
||||
0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61, 0x1e63, 0x1e65, 0x1e67, 0x1e69,
|
||||
0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73, 0x1e75, 0x1e77, 0x1e79, 0x1e7b,
|
||||
0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85, 0x1e87, 0x1e89, 0x1e8b, 0x1e8d,
|
||||
0x1e8f, 0x1e91, 0x1e93, 0x1e9f, 0x1ea1, 0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9,
|
||||
0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb,
|
||||
0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd,
|
||||
0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7, 0x1ed9, 0x1edb, 0x1edd, 0x1edf,
|
||||
0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9, 0x1eeb, 0x1eed, 0x1eef, 0x1ef1,
|
||||
0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb, 0x1efd, 0x1fb6, 0x1fb7, 0x1fbe,
|
||||
0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6, 0x1ff7, 0x210a, 0x210e, 0x210f,
|
||||
0x2113, 0x212f, 0x2134, 0x2139, 0x213c, 0x213d, 0x214e, 0x2184, 0x2c61,
|
||||
0x2c65, 0x2c66, 0x2c68, 0x2c6a, 0x2c6c, 0x2c71, 0x2c73, 0x2c74, 0x2c81,
|
||||
0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b, 0x2c8d, 0x2c8f, 0x2c91, 0x2c93,
|
||||
0x2c95, 0x2c97, 0x2c99, 0x2c9b, 0x2c9d, 0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5,
|
||||
0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 0x2caf, 0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7,
|
||||
0x2cb9, 0x2cbb, 0x2cbd, 0x2cbf, 0x2cc1, 0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9,
|
||||
0x2ccb, 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3, 0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb,
|
||||
0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce4, 0x2cec, 0x2cee, 0x2cf3, 0x2d27,
|
||||
0x2d2d, 0xa641, 0xa643, 0xa645, 0xa647, 0xa649, 0xa64b, 0xa64d, 0xa64f,
|
||||
0xa651, 0xa653, 0xa655, 0xa657, 0xa659, 0xa65b, 0xa65d, 0xa65f, 0xa661,
|
||||
0xa663, 0xa665, 0xa667, 0xa669, 0xa66b, 0xa66d, 0xa681, 0xa683, 0xa685,
|
||||
0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f, 0xa691, 0xa693, 0xa695, 0xa697,
|
||||
0xa723, 0xa725, 0xa727, 0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737,
|
||||
0xa739, 0xa73b, 0xa73d, 0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749,
|
||||
0xa74b, 0xa74d, 0xa74f, 0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b,
|
||||
0xa75d, 0xa75f, 0xa761, 0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d,
|
||||
0xa76f, 0xa77a, 0xa77c, 0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c,
|
||||
0xa78e, 0xa791, 0xa793, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9, 0xa7fa
|
||||
0x527, 0x529, 0x52b, 0x52d, 0x52f, 0x1e01, 0x1e03, 0x1e05, 0x1e07,
|
||||
0x1e09, 0x1e0b, 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19,
|
||||
0x1e1b, 0x1e1d, 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b,
|
||||
0x1e2d, 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d,
|
||||
0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f,
|
||||
0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61,
|
||||
0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73,
|
||||
0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85,
|
||||
0x1e87, 0x1e89, 0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1e9f, 0x1ea1,
|
||||
0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3,
|
||||
0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5,
|
||||
0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7,
|
||||
0x1ed9, 0x1edb, 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9,
|
||||
0x1eeb, 0x1eed, 0x1eef, 0x1ef1, 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb,
|
||||
0x1efd, 0x1fb6, 0x1fb7, 0x1fbe, 0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6,
|
||||
0x1ff7, 0x210a, 0x210e, 0x210f, 0x2113, 0x212f, 0x2134, 0x2139, 0x213c,
|
||||
0x213d, 0x214e, 0x2184, 0x2c61, 0x2c65, 0x2c66, 0x2c68, 0x2c6a, 0x2c6c,
|
||||
0x2c71, 0x2c73, 0x2c74, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b,
|
||||
0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, 0x2c9d,
|
||||
0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 0x2caf,
|
||||
0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, 0x2cbd, 0x2cbf, 0x2cc1,
|
||||
0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3,
|
||||
0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce4,
|
||||
0x2cec, 0x2cee, 0x2cf3, 0x2d27, 0x2d2d, 0xa641, 0xa643, 0xa645, 0xa647,
|
||||
0xa649, 0xa64b, 0xa64d, 0xa64f, 0xa651, 0xa653, 0xa655, 0xa657, 0xa659,
|
||||
0xa65b, 0xa65d, 0xa65f, 0xa661, 0xa663, 0xa665, 0xa667, 0xa669, 0xa66b,
|
||||
0xa66d, 0xa681, 0xa683, 0xa685, 0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f,
|
||||
0xa691, 0xa693, 0xa695, 0xa697, 0xa699, 0xa69b, 0xa723, 0xa725, 0xa727,
|
||||
0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737, 0xa739, 0xa73b, 0xa73d,
|
||||
0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749, 0xa74b, 0xa74d, 0xa74f,
|
||||
0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b, 0xa75d, 0xa75f, 0xa761,
|
||||
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,
|
||||
0xa7fa, 0xab64, 0xab65
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1d4bb, 0x1d7cb
|
||||
#endif
|
||||
@@ -481,14 +503,15 @@ static const crange upperRangeTable[] = {
|
||||
{0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb}, {0x210b, 0x210d},
|
||||
{0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d}, {0x2130, 0x2133},
|
||||
{0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70}, {0x2c7e, 0x2c80},
|
||||
{0xff21, 0xff3a}
|
||||
{0xa7aa, 0xa7ad}, {0xff21, 0xff3a}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10400, 0x10427}, {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481},
|
||||
{0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a},
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544},
|
||||
{0x1d54a, 0x1d550}, {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed},
|
||||
{0x1d608, 0x1d621}, {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0},
|
||||
{0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}
|
||||
,{0x10400, 0x10427}, {0x118a0, 0x118bf}, {0x1d400, 0x1d419}, {0x1d434, 0x1d44d},
|
||||
{0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9},
|
||||
{0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e},
|
||||
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9},
|
||||
{0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621}, {0x1d63c, 0x1d655}, {0x1d670, 0x1d689},
|
||||
{0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa}, {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e},
|
||||
{0x1d790, 0x1d7a8}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -511,52 +534,54 @@ static const chr upperCharTable[] = {
|
||||
0x20c, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x218, 0x21a, 0x21c,
|
||||
0x21e, 0x220, 0x222, 0x224, 0x226, 0x228, 0x22a, 0x22c, 0x22e,
|
||||
0x230, 0x232, 0x23a, 0x23b, 0x23d, 0x23e, 0x241, 0x248, 0x24a,
|
||||
0x24c, 0x24e, 0x370, 0x372, 0x376, 0x386, 0x38c, 0x38e, 0x38f,
|
||||
0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4, 0x3e6,
|
||||
0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x3f4, 0x3f7, 0x3f9, 0x3fa, 0x460,
|
||||
0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470, 0x472,
|
||||
0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480, 0x48a, 0x48c,
|
||||
0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c, 0x49e,
|
||||
0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae, 0x4b0,
|
||||
0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c0, 0x4c1,
|
||||
0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4d0, 0x4d2, 0x4d4,
|
||||
0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4, 0x4e6,
|
||||
0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6, 0x4f8,
|
||||
0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508, 0x50a,
|
||||
0x50c, 0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a, 0x51c,
|
||||
0x51e, 0x520, 0x522, 0x524, 0x526, 0x10c7, 0x10cd, 0x1e00, 0x1e02,
|
||||
0x1e04, 0x1e06, 0x1e08, 0x1e0a, 0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14,
|
||||
0x1e16, 0x1e18, 0x1e1a, 0x1e1c, 0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26,
|
||||
0x1e28, 0x1e2a, 0x1e2c, 0x1e2e, 0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38,
|
||||
0x1e3a, 0x1e3c, 0x1e3e, 0x1e40, 0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a,
|
||||
0x1e4c, 0x1e4e, 0x1e50, 0x1e52, 0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c,
|
||||
0x1e5e, 0x1e60, 0x1e62, 0x1e64, 0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e,
|
||||
0x1e70, 0x1e72, 0x1e74, 0x1e76, 0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80,
|
||||
0x1e82, 0x1e84, 0x1e86, 0x1e88, 0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92,
|
||||
0x1e94, 0x1e9e, 0x1ea0, 0x1ea2, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac,
|
||||
0x1eae, 0x1eb0, 0x1eb2, 0x1eb4, 0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe,
|
||||
0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0,
|
||||
0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2,
|
||||
0x1ee4, 0x1ee6, 0x1ee8, 0x1eea, 0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4,
|
||||
0x1ef6, 0x1ef8, 0x1efa, 0x1efc, 0x1efe, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f,
|
||||
0x2102, 0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x213e, 0x213f, 0x2145,
|
||||
0x2183, 0x2c60, 0x2c67, 0x2c69, 0x2c6b, 0x2c72, 0x2c75, 0x2c82, 0x2c84,
|
||||
0x2c86, 0x2c88, 0x2c8a, 0x2c8c, 0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96,
|
||||
0x2c98, 0x2c9a, 0x2c9c, 0x2c9e, 0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8,
|
||||
0x2caa, 0x2cac, 0x2cae, 0x2cb0, 0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba,
|
||||
0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2, 0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc,
|
||||
0x2cce, 0x2cd0, 0x2cd2, 0x2cd4, 0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde,
|
||||
0x2ce0, 0x2ce2, 0x2ceb, 0x2ced, 0x2cf2, 0xa640, 0xa642, 0xa644, 0xa646,
|
||||
0xa648, 0xa64a, 0xa64c, 0xa64e, 0xa650, 0xa652, 0xa654, 0xa656, 0xa658,
|
||||
0xa65a, 0xa65c, 0xa65e, 0xa660, 0xa662, 0xa664, 0xa666, 0xa668, 0xa66a,
|
||||
0xa66c, 0xa680, 0xa682, 0xa684, 0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e,
|
||||
0xa690, 0xa692, 0xa694, 0xa696, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a,
|
||||
0xa72c, 0xa72e, 0xa732, 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e,
|
||||
0xa740, 0xa742, 0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750,
|
||||
0xa752, 0xa754, 0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762,
|
||||
0xa764, 0xa766, 0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d,
|
||||
0xa77e, 0xa780, 0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792,
|
||||
0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7aa
|
||||
0x24c, 0x24e, 0x370, 0x372, 0x376, 0x37f, 0x386, 0x38c, 0x38e,
|
||||
0x38f, 0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4,
|
||||
0x3e6, 0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x3f4, 0x3f7, 0x3f9, 0x3fa,
|
||||
0x460, 0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470,
|
||||
0x472, 0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480, 0x48a,
|
||||
0x48c, 0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c,
|
||||
0x49e, 0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae,
|
||||
0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c0,
|
||||
0x4c1, 0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4d0, 0x4d2,
|
||||
0x4d4, 0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4,
|
||||
0x4e6, 0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6,
|
||||
0x4f8, 0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508,
|
||||
0x50a, 0x50c, 0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a,
|
||||
0x51c, 0x51e, 0x520, 0x522, 0x524, 0x526, 0x528, 0x52a, 0x52c,
|
||||
0x52e, 0x10c7, 0x10cd, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a,
|
||||
0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a, 0x1e1c,
|
||||
0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e,
|
||||
0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40,
|
||||
0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50, 0x1e52,
|
||||
0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62, 0x1e64,
|
||||
0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74, 0x1e76,
|
||||
0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86, 0x1e88,
|
||||
0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1e9e, 0x1ea0, 0x1ea2,
|
||||
0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4,
|
||||
0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6,
|
||||
0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8,
|
||||
0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea,
|
||||
0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1efa, 0x1efc,
|
||||
0x1efe, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x2102, 0x2107, 0x2115, 0x2124,
|
||||
0x2126, 0x2128, 0x213e, 0x213f, 0x2145, 0x2183, 0x2c60, 0x2c67, 0x2c69,
|
||||
0x2c6b, 0x2c72, 0x2c75, 0x2c82, 0x2c84, 0x2c86, 0x2c88, 0x2c8a, 0x2c8c,
|
||||
0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96, 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e,
|
||||
0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8, 0x2caa, 0x2cac, 0x2cae, 0x2cb0,
|
||||
0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba, 0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2,
|
||||
0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, 0x2cce, 0x2cd0, 0x2cd2, 0x2cd4,
|
||||
0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, 0x2ce0, 0x2ce2, 0x2ceb, 0x2ced,
|
||||
0x2cf2, 0xa640, 0xa642, 0xa644, 0xa646, 0xa648, 0xa64a, 0xa64c, 0xa64e,
|
||||
0xa650, 0xa652, 0xa654, 0xa656, 0xa658, 0xa65a, 0xa65c, 0xa65e, 0xa660,
|
||||
0xa662, 0xa664, 0xa666, 0xa668, 0xa66a, 0xa66c, 0xa680, 0xa682, 0xa684,
|
||||
0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694, 0xa696,
|
||||
0xa698, 0xa69a, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e,
|
||||
0xa732, 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742,
|
||||
0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754,
|
||||
0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766,
|
||||
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, 0xa7b0,
|
||||
0xa7b1
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
|
||||
0x1d539, 0x1d546, 0x1d7ca
|
||||
@@ -570,34 +595,34 @@ static const chr upperCharTable[] = {
|
||||
*/
|
||||
|
||||
static const crange graphRangeTable[] = {
|
||||
{0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37e},
|
||||
{0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x527}, {0x531, 0x556},
|
||||
{0x559, 0x55f}, {0x561, 0x587}, {0x591, 0x5c7}, {0x5d0, 0x5ea},
|
||||
{0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc}, {0x6de, 0x70d},
|
||||
{0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa}, {0x800, 0x82d},
|
||||
{0x830, 0x83e}, {0x840, 0x85b}, {0x8a2, 0x8ac}, {0x8e4, 0x8fe},
|
||||
{0x900, 0x977}, {0x979, 0x97f}, {0x981, 0x983}, {0x985, 0x98c},
|
||||
{0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
|
||||
{0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03},
|
||||
{0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
|
||||
{0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, {0xa81, 0xa83},
|
||||
{0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
|
||||
{0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
|
||||
{0xae0, 0xae3}, {0xae6, 0xaf1}, {0xb01, 0xb03}, {0xb05, 0xb0c},
|
||||
{0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb3c, 0xb44},
|
||||
{0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, {0xb85, 0xb8a},
|
||||
{0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
|
||||
{0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, {0xbe6, 0xbfa},
|
||||
{0xc01, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
|
||||
{0xc2a, 0xc33}, {0xc35, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48},
|
||||
{0xc4a, 0xc4d}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc7f},
|
||||
{0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
|
||||
{0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd},
|
||||
{0xce0, 0xce3}, {0xce6, 0xcef}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
|
||||
{0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e},
|
||||
{0xd60, 0xd63}, {0xd66, 0xd75}, {0xd79, 0xd7f}, {0xd85, 0xd96},
|
||||
{0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4},
|
||||
{0xdd8, 0xddf}, {0xdf2, 0xdf4}, {0xe01, 0xe3a}, {0xe3f, 0xe5b},
|
||||
{0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37f},
|
||||
{0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x52f}, {0x531, 0x556},
|
||||
{0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7},
|
||||
{0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
|
||||
{0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
|
||||
{0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x8a0, 0x8b2},
|
||||
{0x8e4, 0x983}, {0x985, 0x98c}, {0x993, 0x9a8}, {0x9aa, 0x9b0},
|
||||
{0x9b6, 0x9b9}, {0x9bc, 0x9c4}, {0x9cb, 0x9ce}, {0x9df, 0x9e3},
|
||||
{0x9e6, 0x9fb}, {0xa01, 0xa03}, {0xa05, 0xa0a}, {0xa13, 0xa28},
|
||||
{0xa2a, 0xa30}, {0xa3e, 0xa42}, {0xa4b, 0xa4d}, {0xa59, 0xa5c},
|
||||
{0xa66, 0xa75}, {0xa81, 0xa83}, {0xa85, 0xa8d}, {0xa8f, 0xa91},
|
||||
{0xa93, 0xaa8}, {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xabc, 0xac5},
|
||||
{0xac7, 0xac9}, {0xacb, 0xacd}, {0xae0, 0xae3}, {0xae6, 0xaf1},
|
||||
{0xb01, 0xb03}, {0xb05, 0xb0c}, {0xb13, 0xb28}, {0xb2a, 0xb30},
|
||||
{0xb35, 0xb39}, {0xb3c, 0xb44}, {0xb4b, 0xb4d}, {0xb5f, 0xb63},
|
||||
{0xb66, 0xb77}, {0xb85, 0xb8a}, {0xb8e, 0xb90}, {0xb92, 0xb95},
|
||||
{0xba8, 0xbaa}, {0xbae, 0xbb9}, {0xbbe, 0xbc2}, {0xbc6, 0xbc8},
|
||||
{0xbca, 0xbcd}, {0xbe6, 0xbfa}, {0xc00, 0xc03}, {0xc05, 0xc0c},
|
||||
{0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39}, {0xc3d, 0xc44},
|
||||
{0xc46, 0xc48}, {0xc4a, 0xc4d}, {0xc60, 0xc63}, {0xc66, 0xc6f},
|
||||
{0xc78, 0xc7f}, {0xc81, 0xc83}, {0xc85, 0xc8c}, {0xc8e, 0xc90},
|
||||
{0xc92, 0xca8}, {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xcbc, 0xcc4},
|
||||
{0xcc6, 0xcc8}, {0xcca, 0xccd}, {0xce0, 0xce3}, {0xce6, 0xcef},
|
||||
{0xd01, 0xd03}, {0xd05, 0xd0c}, {0xd0e, 0xd10}, {0xd12, 0xd3a},
|
||||
{0xd3d, 0xd44}, {0xd46, 0xd48}, {0xd4a, 0xd4e}, {0xd60, 0xd63},
|
||||
{0xd66, 0xd75}, {0xd79, 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},
|
||||
@@ -606,105 +631,123 @@ static const crange graphRangeTable[] = {
|
||||
{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, 0x13f4}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f0},
|
||||
{0x13a0, 0x13f4}, {0x1400, 0x167f}, {0x1681, 0x169c}, {0x16a0, 0x16f8},
|
||||
{0x1700, 0x170c}, {0x170e, 0x1714}, {0x1720, 0x1736}, {0x1740, 0x1753},
|
||||
{0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17dd}, {0x17e0, 0x17e9},
|
||||
{0x17f0, 0x17f9}, {0x1800, 0x180d}, {0x1810, 0x1819}, {0x1820, 0x1877},
|
||||
{0x1880, 0x18aa}, {0x18b0, 0x18f5}, {0x1900, 0x191c}, {0x1920, 0x192b},
|
||||
{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},
|
||||
{0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37},
|
||||
{0x1c3b, 0x1c49}, {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6},
|
||||
{0x1d00, 0x1de6}, {0x1dfc, 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, 0x20ba}, {0x20d0, 0x20f0},
|
||||
{0x2100, 0x2189}, {0x2190, 0x23f3}, {0x2400, 0x2426}, {0x2440, 0x244a},
|
||||
{0x2460, 0x26ff}, {0x2701, 0x2b4c}, {0x2b50, 0x2b59}, {0x2c00, 0x2c2e},
|
||||
{0x2c30, 0x2c5e}, {0x2c60, 0x2cf3}, {0x2cf9, 0x2d25}, {0x2d30, 0x2d67},
|
||||
{0x2d7f, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6},
|
||||
{0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6},
|
||||
{0x2dd8, 0x2dde}, {0x2de0, 0x2e3b}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3},
|
||||
{0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb}, {0x3001, 0x303f}, {0x3041, 0x3096},
|
||||
{0x3099, 0x30ff}, {0x3105, 0x312d}, {0x3131, 0x318e}, {0x3190, 0x31ba},
|
||||
{0x31c0, 0x31e3}, {0x31f0, 0x321e}, {0x3220, 0x32fe}, {0x3300, 0x4db5},
|
||||
{0x4dc0, 0x9fcc}, {0xa000, 0xa48c}, {0xa490, 0xa4c6}, {0xa4d0, 0xa62b},
|
||||
{0xa640, 0xa697}, {0xa69f, 0xa6f7}, {0xa700, 0xa78e}, {0xa790, 0xa793},
|
||||
{0xa7a0, 0xa7aa}, {0xa7f8, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
|
||||
{0xa880, 0xa8c4}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fb}, {0xa900, 0xa953},
|
||||
{0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xaa00, 0xaa36},
|
||||
{0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaa7b}, {0xaa80, 0xaac2},
|
||||
{0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
|
||||
{0xab20, 0xab26}, {0xab28, 0xab2e}, {0xabc0, 0xabed}, {0xabf0, 0xabf9},
|
||||
{0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xf900, 0xfa6d},
|
||||
{0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1d, 0xfb36},
|
||||
{0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f}, {0xfd50, 0xfd8f},
|
||||
{0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19}, {0xfe20, 0xfe26},
|
||||
{0xfe30, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74},
|
||||
{0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
|
||||
{0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
|
||||
{0x1ab0, 0x1abe}, {0x1b00, 0x1b4b}, {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3},
|
||||
{0x1bfc, 0x1c37}, {0x1c3b, 0x1c49}, {0x1c4d, 0x1c7f}, {0x1cc0, 0x1cc7},
|
||||
{0x1cd0, 0x1cf6}, {0x1d00, 0x1df5}, {0x1dfc, 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, 0x20bd},
|
||||
{0x20d0, 0x20f0}, {0x2100, 0x2189}, {0x2190, 0x23fa}, {0x2400, 0x2426},
|
||||
{0x2440, 0x244a}, {0x2460, 0x2b73}, {0x2b76, 0x2b95}, {0x2b98, 0x2bb9},
|
||||
{0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e},
|
||||
{0x2c60, 0x2cf3}, {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96},
|
||||
{0x2da0, 0x2da6}, {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe},
|
||||
{0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde},
|
||||
{0x2de0, 0x2e42}, {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5},
|
||||
{0x2ff0, 0x2ffb}, {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff},
|
||||
{0x3105, 0x312d}, {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3},
|
||||
{0x31f0, 0x321e}, {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fcc},
|
||||
{0xa000, 0xa48c}, {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa69d},
|
||||
{0xa69f, 0xa6f7}, {0xa700, 0xa78e}, {0xa790, 0xa7ad}, {0xa7f7, 0xa82b},
|
||||
{0xa830, 0xa839}, {0xa840, 0xa877}, {0xa880, 0xa8c4}, {0xa8ce, 0xa8d9},
|
||||
{0xa8e0, 0xa8fb}, {0xa900, 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, 0xab5f}, {0xabc0, 0xabed}, {0xabf0, 0xabf9}, {0xac00, 0xd7a3},
|
||||
{0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e},
|
||||
{0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe},
|
||||
{0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e},
|
||||
{0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
|
||||
{0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f},
|
||||
{0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19},
|
||||
{0xfe20, 0xfe2d}, {0xfe30, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b},
|
||||
{0xfe70, 0xfe74}, {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7},
|
||||
{0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6},
|
||||
{0xffe8, 0xffee}
|
||||
#if TCL_UTF_MAX > 4
|
||||
,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
|
||||
{0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
|
||||
{0x10137, 0x1018a}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
|
||||
{0x102a0, 0x102d0}, {0x10300, 0x1031e}, {0x10320, 0x10323}, {0x10330, 0x1034a},
|
||||
{0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5}, {0x10400, 0x1049d},
|
||||
{0x104a0, 0x104a9}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
|
||||
{0x10857, 0x1085f}, {0x10900, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7},
|
||||
{0x10a00, 0x10a03}, {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33},
|
||||
{0x10a38, 0x10a3a}, {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a7f},
|
||||
{0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72}, {0x10b78, 0x10b7f},
|
||||
{0x10c00, 0x10c48}, {0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f},
|
||||
{0x11080, 0x110bc}, {0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9},
|
||||
{0x11100, 0x11134}, {0x11136, 0x11143}, {0x11180, 0x111c8}, {0x111d0, 0x111d9},
|
||||
{0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x12000, 0x1236e}, {0x12400, 0x12462},
|
||||
{0x12470, 0x12473}, {0x13000, 0x1342e}, {0x16800, 0x16a38}, {0x16f00, 0x16f44},
|
||||
{0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126},
|
||||
{0x1d129, 0x1d172}, {0x1d17b, 0x1d1dd}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356},
|
||||
{0x1d360, 0x1d371}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
|
||||
{0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
|
||||
{0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
|
||||
{0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
|
||||
{0x1d7ce, 0x1d7ff}, {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, 0x1f0be}, {0x1f0c1, 0x1f0cf},
|
||||
{0x1f0d1, 0x1f0df}, {0x1f100, 0x1f10a}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b},
|
||||
{0x1f170, 0x1f19a}, {0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248},
|
||||
{0x1f300, 0x1f320}, {0x1f330, 0x1f335}, {0x1f337, 0x1f37c}, {0x1f380, 0x1f393},
|
||||
{0x1f3a0, 0x1f3c4}, {0x1f3c6, 0x1f3ca}, {0x1f3e0, 0x1f3f0}, {0x1f400, 0x1f43e},
|
||||
{0x1f442, 0x1f4f7}, {0x1f4f9, 0x1f4fc}, {0x1f500, 0x1f53d}, {0x1f540, 0x1f543},
|
||||
{0x1f550, 0x1f567}, {0x1f5fb, 0x1f640}, {0x1f645, 0x1f64f}, {0x1f680, 0x1f6c5},
|
||||
{0x1f700, 0x1f773}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734}, {0x2b740, 0x2b81d},
|
||||
{0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
|
||||
{0x10137, 0x1018c}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
|
||||
{0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a},
|
||||
{0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5},
|
||||
{0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x10500, 0x10527}, {0x10530, 0x10563},
|
||||
{0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
|
||||
{0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10857, 0x1089e}, {0x108a7, 0x108af},
|
||||
{0x10900, 0x1091b}, {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x10a00, 0x10a03},
|
||||
{0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a},
|
||||
{0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
|
||||
{0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
|
||||
{0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
|
||||
{0x10e60, 0x10e7e}, {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc},
|
||||
{0x110be, 0x110c1}, {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134},
|
||||
{0x11136, 0x11143}, {0x11150, 0x11176}, {0x11180, 0x111c8}, {0x111d0, 0x111da},
|
||||
{0x111e1, 0x111f4}, {0x11200, 0x11211}, {0x11213, 0x1123d}, {0x112b0, 0x112ea},
|
||||
{0x112f0, 0x112f9}, {0x11301, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328},
|
||||
{0x1132a, 0x11330}, {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d},
|
||||
{0x1135d, 0x11363}, {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11480, 0x114c7},
|
||||
{0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115c9}, {0x11600, 0x11644},
|
||||
{0x11650, 0x11659}, {0x11680, 0x116b7}, {0x116c0, 0x116c9}, {0x118a0, 0x118f2},
|
||||
{0x11ac0, 0x11af8}, {0x12000, 0x12398}, {0x12400, 0x1246e}, {0x12470, 0x12474},
|
||||
{0x13000, 0x1342e}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e}, {0x16a60, 0x16a69},
|
||||
{0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45}, {0x16b50, 0x16b59},
|
||||
{0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44},
|
||||
{0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c},
|
||||
{0x1bc80, 0x1bc88}, {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5},
|
||||
{0x1d100, 0x1d126}, {0x1d129, 0x1d172}, {0x1d17b, 0x1d1dd}, {0x1d200, 0x1d245},
|
||||
{0x1d300, 0x1d356}, {0x1d360, 0x1d371}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c},
|
||||
{0x1d4a9, 0x1d4ac}, {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505},
|
||||
{0x1d507, 0x1d50a}, {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539},
|
||||
{0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5},
|
||||
{0x1d6a8, 0x1d7cb}, {0x1d7ce, 0x1d7ff}, {0x1e800, 0x1e8c4}, {0x1e8c7, 0x1e8d6},
|
||||
{0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
|
||||
{0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
|
||||
{0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
|
||||
{0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093},
|
||||
{0x1f0a0, 0x1f0ae}, {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5},
|
||||
{0x1f100, 0x1f10c}, {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f19a},
|
||||
{0x1f1e6, 0x1f202}, {0x1f210, 0x1f23a}, {0x1f240, 0x1f248}, {0x1f300, 0x1f32c},
|
||||
{0x1f330, 0x1f37d}, {0x1f380, 0x1f3ce}, {0x1f3d4, 0x1f3f7}, {0x1f400, 0x1f4fe},
|
||||
{0x1f500, 0x1f54a}, {0x1f550, 0x1f579}, {0x1f57b, 0x1f5a3}, {0x1f5a5, 0x1f642},
|
||||
{0x1f645, 0x1f6cf}, {0x1f6e0, 0x1f6ec}, {0x1f6f0, 0x1f6f3}, {0x1f700, 0x1f773},
|
||||
{0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b}, {0x1f810, 0x1f847}, {0x1f850, 0x1f859},
|
||||
{0x1f860, 0x1f887}, {0x1f890, 0x1f8ad}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
|
||||
{0x2b740, 0x2b81d}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
|
||||
#endif
|
||||
};
|
||||
|
||||
#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
|
||||
|
||||
static const chr graphCharTable[] = {
|
||||
0x38c, 0x589, 0x58a, 0x58f, 0x85e, 0x8a0, 0x98f, 0x990, 0x9b2,
|
||||
0x9c7, 0x9c8, 0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33,
|
||||
0xa35, 0xa36, 0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e,
|
||||
0xab2, 0xab3, 0xad0, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48,
|
||||
0xb56, 0xb57, 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c,
|
||||
0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xc58,
|
||||
0xc59, 0xc82, 0xc83, 0xcd5, 0xcd6, 0xcde, 0xcf1, 0xcf2, 0xd02,
|
||||
0xd03, 0xd57, 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, 0xa9de,
|
||||
0xa9df, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
|
||||
0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8,
|
||||
0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
|
||||
0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3,
|
||||
0xad0, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56, 0xb57,
|
||||
0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f,
|
||||
0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xc58, 0xc59, 0xcd5,
|
||||
0xcd6, 0xcde, 0xcf1, 0xcf2, 0xd57, 0xd82, 0xd83, 0xdbd, 0xdca,
|
||||
0xdd6, 0xe81, 0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5,
|
||||
0xea7, 0xeaa, 0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772,
|
||||
0x1773, 0x1940, 0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071,
|
||||
0x2d27, 0x2d2d, 0x2d6f, 0x2d70, 0xa7b0, 0xa7b1, 0xab64, 0xab65, 0xfb3e,
|
||||
0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
|
||||
#if TCL_UTF_MAX > 4
|
||||
,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x1093f, 0x109be, 0x109bf,
|
||||
0x10a05, 0x10a06, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6,
|
||||
0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
|
||||
0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
|
||||
0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250,
|
||||
0x1f251, 0x1f440
|
||||
,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x1093f,
|
||||
0x109be, 0x109bf, 0x10a05, 0x10a06, 0x111cd, 0x1130f, 0x11310, 0x11332, 0x11333,
|
||||
0x11347, 0x11348, 0x11357, 0x118ff, 0x16a6e, 0x16a6f, 0x1b000, 0x1b001, 0x1d49e,
|
||||
0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24,
|
||||
0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52,
|
||||
0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64,
|
||||
0x1ee7e, 0x1eef0, 0x1eef1, 0x1f250, 0x1f251
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -1345,7 +1345,7 @@ fixempties(
|
||||
for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
|
||||
nexts = s->next;
|
||||
/* Ensure tmp fields are clear for next step */
|
||||
assert(s->tmp = NULL);
|
||||
assert(s->tmp == NULL);
|
||||
if (s->flag || s->nins != 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+42
-22
@@ -56,10 +56,10 @@ extern "C" {
|
||||
#define TCL_MAJOR_VERSION 8
|
||||
#define TCL_MINOR_VERSION 6
|
||||
#define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
|
||||
#define TCL_RELEASE_SERIAL 1
|
||||
#define TCL_RELEASE_SERIAL 3
|
||||
|
||||
#define TCL_VERSION "8.6"
|
||||
#define TCL_PATCH_LEVEL "8.6.1"
|
||||
#define TCL_PATCH_LEVEL "8.6.3"
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -67,15 +67,12 @@ extern "C" {
|
||||
* We use this method because there is no autoconf equivalent.
|
||||
*/
|
||||
|
||||
#ifndef __WIN32__
|
||||
# if defined(_WIN32) || defined(WIN32) || defined(__MINGW32__) || defined(__BORLANDC__) || (defined(__WATCOMC__) && defined(__WINDOWS_386__))
|
||||
#ifdef _WIN32
|
||||
# ifndef __WIN32__
|
||||
# define __WIN32__
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
# ifndef _WIN32
|
||||
# define _WIN32
|
||||
# endif
|
||||
# endif
|
||||
# ifndef WIN32
|
||||
# define WIN32
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -83,11 +80,11 @@ extern "C" {
|
||||
* STRICT: See MSDN Article Q83456
|
||||
*/
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
# ifndef STRICT
|
||||
# define STRICT
|
||||
# endif
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
* Utility macros: STRINGIFY takes an argument and wraps it in "" (double
|
||||
@@ -191,7 +188,7 @@ extern "C" {
|
||||
* MSVCRT.
|
||||
*/
|
||||
|
||||
#if (defined(__WIN32__) && (defined(_MSC_VER) || (__BORLANDC__ >= 0x0550) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec))))
|
||||
#if (defined(_WIN32) && (defined(_MSC_VER) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0550)) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec))))
|
||||
# define HAVE_DECLSPEC 1
|
||||
# ifdef STATIC_BUILD
|
||||
# define DLLIMPORT
|
||||
@@ -315,14 +312,14 @@ extern "C" {
|
||||
* VOID. This block is skipped under Cygwin and Mingw.
|
||||
*/
|
||||
|
||||
#if defined(__WIN32__) && !defined(HAVE_WINNT_IGNORE_VOID)
|
||||
#if defined(_WIN32) && !defined(HAVE_WINNT_IGNORE_VOID)
|
||||
#ifndef VOID
|
||||
#define VOID void
|
||||
typedef char CHAR;
|
||||
typedef short SHORT;
|
||||
typedef long LONG;
|
||||
#endif
|
||||
#endif /* __WIN32__ && !HAVE_WINNT_IGNORE_VOID */
|
||||
#endif /* _WIN32 && !HAVE_WINNT_IGNORE_VOID */
|
||||
|
||||
/*
|
||||
* Macro to use instead of "void" for arguments that must have type "void *"
|
||||
@@ -390,7 +387,7 @@ typedef long LONG;
|
||||
*/
|
||||
|
||||
#if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
|
||||
# if defined(__WIN32__)
|
||||
# if defined(_WIN32)
|
||||
# define TCL_WIDE_INT_TYPE __int64
|
||||
# ifdef __BORLANDC__
|
||||
# define TCL_LL_MODIFIER "L"
|
||||
@@ -400,7 +397,7 @@ typedef long LONG;
|
||||
# elif defined(__GNUC__)
|
||||
# define TCL_WIDE_INT_TYPE long long
|
||||
# define TCL_LL_MODIFIER "ll"
|
||||
# else /* ! __WIN32__ && ! __GNUC__ */
|
||||
# else /* ! _WIN32 && ! __GNUC__ */
|
||||
/*
|
||||
* Don't know what platform it is and configure hasn't discovered what is
|
||||
* going on for us. Try to guess...
|
||||
@@ -415,7 +412,7 @@ typedef long LONG;
|
||||
# define TCL_WIDE_INT_TYPE long long
|
||||
# endif
|
||||
# endif /* NO_LIMITS_H */
|
||||
# endif /* __WIN32__ */
|
||||
# endif /* _WIN32 */
|
||||
#endif /* !TCL_WIDE_INT_TYPE & !TCL_WIDE_INT_IS_LONG */
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
# undef TCL_WIDE_INT_TYPE
|
||||
@@ -447,7 +444,7 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
|
||||
# define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val)))
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#if defined(_WIN32)
|
||||
# ifdef __BORLANDC__
|
||||
typedef struct stati64 Tcl_StatBuf;
|
||||
# elif defined(_WIN64)
|
||||
@@ -562,7 +559,7 @@ typedef struct Tcl_ZLibStream_ *Tcl_ZlibStream;
|
||||
* will be called as the main fuction of the new thread created by that call.
|
||||
*/
|
||||
|
||||
#if defined __WIN32__
|
||||
#if defined _WIN32
|
||||
typedef unsigned (__stdcall Tcl_ThreadCreateProc) (ClientData clientData);
|
||||
#else
|
||||
typedef void (Tcl_ThreadCreateProc) (ClientData clientData);
|
||||
@@ -574,7 +571,7 @@ typedef void (Tcl_ThreadCreateProc) (ClientData clientData);
|
||||
* in generic/tclThreadTest.c for it's usage.
|
||||
*/
|
||||
|
||||
#if defined __WIN32__
|
||||
#if defined _WIN32
|
||||
# define Tcl_ThreadCreateType unsigned __stdcall
|
||||
# define TCL_THREAD_CREATE_RETURN return 0
|
||||
#else
|
||||
@@ -2147,11 +2144,28 @@ typedef struct Tcl_EncodingType {
|
||||
* substituting one or more "close" characters in
|
||||
* the destination buffer and then continue to
|
||||
* convert the source.
|
||||
* TCL_ENCODING_NO_TERMINATE - If set, Tcl_ExternalToUtf will not append a
|
||||
* terminating NUL byte. Knowing that it will
|
||||
* not need space to do so, it will fill all
|
||||
* dstLen bytes with encoded UTF-8 content, as
|
||||
* other circumstances permit. If clear, the
|
||||
* default behavior is to reserve a byte in
|
||||
* the dst space for NUL termination, and to
|
||||
* append the NUL byte.
|
||||
* TCL_ENCODING_CHAR_LIMIT - If set and dstCharsPtr is not NULL, then
|
||||
* Tcl_ExternalToUtf takes the initial value
|
||||
* of *dstCharsPtr is taken as a limit of the
|
||||
* maximum number of chars to produce in the
|
||||
* encoded UTF-8 content. Otherwise, the
|
||||
* number of chars produced is controlled only
|
||||
* by other limiting factors.
|
||||
*/
|
||||
|
||||
#define TCL_ENCODING_START 0x01
|
||||
#define TCL_ENCODING_END 0x02
|
||||
#define TCL_ENCODING_STOPONERROR 0x04
|
||||
#define TCL_ENCODING_NO_TERMINATE 0x08
|
||||
#define TCL_ENCODING_CHAR_LIMIT 0x10
|
||||
|
||||
/*
|
||||
* The following definitions are the error codes returned by the conversion
|
||||
@@ -2436,9 +2450,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
|
||||
/*
|
||||
* Include platform specific public function declarations that are accessible
|
||||
* via the stubs table.
|
||||
* via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only
|
||||
* has effect on building it as a shared library). See ticket [3010352].
|
||||
*/
|
||||
|
||||
#if defined(BUILD_tcl)
|
||||
# undef TCLAPI
|
||||
# define TCLAPI MODULE_SCOPE
|
||||
#endif
|
||||
|
||||
#include "tclPlatDecls.h"
|
||||
|
||||
/*
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@
|
||||
* until Tcl uses config.h properly.
|
||||
*/
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__BORLANDC__)
|
||||
#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__)
|
||||
typedef unsigned long caddr_t;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ typedef enum BasicBlockCatchState {
|
||||
BBCS_UNKNOWN = 0, /* Catch context has not yet been identified */
|
||||
BBCS_NONE, /* Block is outside of any catch */
|
||||
BBCS_INCATCH, /* Block is within a catch context */
|
||||
BBCS_CAUGHT, /* Block is within a catch context and
|
||||
BBCS_CAUGHT /* Block is within a catch context and
|
||||
* may be executed after an exception fires */
|
||||
} BasicBlockCatchState;
|
||||
|
||||
@@ -121,7 +121,7 @@ enum BasicBlockFlags {
|
||||
* marking it as the start of a 'catch'
|
||||
* sequence. The 'jumpTarget' is the exception
|
||||
* exit from the catch block. */
|
||||
BB_ENDCATCH = (1 << 5), /* Block ends with an 'endCatch' instruction,
|
||||
BB_ENDCATCH = (1 << 5) /* Block ends with an 'endCatch' instruction,
|
||||
* unwinding the catch from the exception
|
||||
* stack. */
|
||||
};
|
||||
@@ -184,7 +184,7 @@ typedef enum TalInstType {
|
||||
* produces N */
|
||||
ASSEM_SINT1, /* One 1-byte signed-integer operand
|
||||
* (INCR_STK_IMM) */
|
||||
ASSEM_SINT4_LVT4, /* Signed 4-byte integer operand followed by
|
||||
ASSEM_SINT4_LVT4 /* Signed 4-byte integer operand followed by
|
||||
* LVT entry. Fixed arity */
|
||||
} TalInstType;
|
||||
|
||||
@@ -410,6 +410,10 @@ static const TalInstDesc TalInstructionTable[] = {
|
||||
{"lappendArray", ASSEM_LVT, (INST_LAPPEND_ARRAY1<<8
|
||||
| INST_LAPPEND_ARRAY4),2, 1},
|
||||
{"lappendArrayStk", ASSEM_1BYTE, INST_LAPPEND_ARRAY_STK, 3, 1},
|
||||
{"lappendList", ASSEM_LVT4, INST_LAPPEND_LIST, 1, 1},
|
||||
{"lappendListArray",ASSEM_LVT4, INST_LAPPEND_LIST_ARRAY,2, 1},
|
||||
{"lappendListArrayStk", ASSEM_1BYTE,INST_LAPPEND_LIST_ARRAY_STK, 3, 1},
|
||||
{"lappendListStk", ASSEM_1BYTE, INST_LAPPEND_LIST_STK, 2, 1},
|
||||
{"lappendStk", ASSEM_1BYTE, INST_LAPPEND_STK, 2, 1},
|
||||
{"le", ASSEM_1BYTE, INST_LE, 2, 1},
|
||||
{"lindexMulti", ASSEM_LINDEX_MULTI,
|
||||
|
||||
+32
-11
@@ -840,7 +840,9 @@ Tcl_CreateInterp(void)
|
||||
*/
|
||||
|
||||
Tcl_CreateObjCommand(interp, "::tcl::unsupported::disassemble",
|
||||
Tcl_DisassembleObjCmd, NULL, NULL);
|
||||
Tcl_DisassembleObjCmd, INT2PTR(0), NULL);
|
||||
Tcl_CreateObjCommand(interp, "::tcl::unsupported::getbytecode",
|
||||
Tcl_DisassembleObjCmd, INT2PTR(1), NULL);
|
||||
Tcl_CreateObjCommand(interp, "::tcl::unsupported::representation",
|
||||
Tcl_RepresentationCmd, NULL, NULL);
|
||||
|
||||
@@ -2085,10 +2087,19 @@ Tcl_CreateCommand(
|
||||
*/
|
||||
|
||||
cmdPtr = Tcl_GetHashValue(hPtr);
|
||||
oldRefPtr = cmdPtr->importRefPtr;
|
||||
cmdPtr->importRefPtr = NULL;
|
||||
cmdPtr->refCount++;
|
||||
if (cmdPtr->importRefPtr) {
|
||||
cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
|
||||
}
|
||||
|
||||
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
|
||||
|
||||
if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
|
||||
oldRefPtr = cmdPtr->importRefPtr;
|
||||
cmdPtr->importRefPtr = NULL;
|
||||
}
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
if (!isNew) {
|
||||
/*
|
||||
@@ -2272,10 +2283,19 @@ Tcl_CreateObjCommand(
|
||||
* intact.
|
||||
*/
|
||||
|
||||
oldRefPtr = cmdPtr->importRefPtr;
|
||||
cmdPtr->importRefPtr = NULL;
|
||||
cmdPtr->refCount++;
|
||||
if (cmdPtr->importRefPtr) {
|
||||
cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
|
||||
}
|
||||
|
||||
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
|
||||
|
||||
if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
|
||||
oldRefPtr = cmdPtr->importRefPtr;
|
||||
cmdPtr->importRefPtr = NULL;
|
||||
}
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
if (!isNew) {
|
||||
/*
|
||||
@@ -3117,12 +3137,13 @@ Tcl_DeleteCommandFromToken(
|
||||
* commands were created that refer back to this command. Delete these
|
||||
* imported commands now.
|
||||
*/
|
||||
|
||||
for (refPtr = cmdPtr->importRefPtr; refPtr != NULL;
|
||||
refPtr = nextRefPtr) {
|
||||
nextRefPtr = refPtr->nextPtr;
|
||||
importCmd = (Tcl_Command) refPtr->importedCmdPtr;
|
||||
Tcl_DeleteCommandFromToken(interp, importCmd);
|
||||
if (!(cmdPtr->flags & CMD_REDEF_IN_PROGRESS)) {
|
||||
for (refPtr = cmdPtr->importRefPtr; refPtr != NULL;
|
||||
refPtr = nextRefPtr) {
|
||||
nextRefPtr = refPtr->nextPtr;
|
||||
importCmd = (Tcl_Command) refPtr->importedCmdPtr;
|
||||
Tcl_DeleteCommandFromToken(interp, importCmd);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+33
-41
@@ -610,9 +610,7 @@ UpdateStringOfByteArray(
|
||||
*
|
||||
* This function appends an array of bytes to a byte array object. Note
|
||||
* that the object *must* be unshared, and the array of bytes *must not*
|
||||
* refer to the object being appended to. Also the caller must have
|
||||
* already checked that the final length of the bytearray after the
|
||||
* append operations is complete will not overflow the int range.
|
||||
* refer to the object being appended to.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -631,6 +629,7 @@ TclAppendBytesToByteArray(
|
||||
int len)
|
||||
{
|
||||
ByteArray *byteArrayPtr;
|
||||
int needed;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
|
||||
@@ -639,64 +638,57 @@ TclAppendBytesToByteArray(
|
||||
Tcl_Panic("%s must be called with definite number of bytes to append",
|
||||
"TclAppendBytesToByteArray");
|
||||
}
|
||||
if (len == 0) {
|
||||
/* Append zero bytes is a no-op. */
|
||||
return;
|
||||
}
|
||||
if (objPtr->typePtr != &tclByteArrayType) {
|
||||
SetByteArrayFromAny(NULL, objPtr);
|
||||
}
|
||||
byteArrayPtr = GET_BYTEARRAY(objPtr);
|
||||
|
||||
if (len > INT_MAX - byteArrayPtr->used) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
|
||||
needed = byteArrayPtr->used + len;
|
||||
/*
|
||||
* If we need to, resize the allocated space in the byte array.
|
||||
*/
|
||||
|
||||
if (byteArrayPtr->used + len > byteArrayPtr->allocated) {
|
||||
unsigned int attempt, used = byteArrayPtr->used;
|
||||
ByteArray *tmpByteArrayPtr = NULL;
|
||||
if (needed > byteArrayPtr->allocated) {
|
||||
ByteArray *ptr = NULL;
|
||||
int attempt;
|
||||
|
||||
attempt = byteArrayPtr->allocated;
|
||||
if (attempt < 1) {
|
||||
/*
|
||||
* No allocated bytes, so must be none used too. We use this
|
||||
* method to calculate how many bytes to allocate because we can
|
||||
* end up with a zero-length buffer otherwise, when doubling can
|
||||
* cause trouble. [Bug 3067036]
|
||||
*/
|
||||
|
||||
attempt = len + 1;
|
||||
} else {
|
||||
do {
|
||||
attempt *= 2;
|
||||
} while (attempt < used+len);
|
||||
if (needed <= INT_MAX/2) {
|
||||
/* Try to allocate double the total space that is needed. */
|
||||
attempt = 2 * needed;
|
||||
ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
|
||||
}
|
||||
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;
|
||||
int growth = (int) ((extra > limit) ? limit : extra);
|
||||
|
||||
if (BYTEARRAY_SIZE(attempt) > BYTEARRAY_SIZE(used)) {
|
||||
tmpByteArrayPtr = attemptckrealloc(byteArrayPtr,
|
||||
BYTEARRAY_SIZE(attempt));
|
||||
attempt = needed + growth;
|
||||
ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
|
||||
}
|
||||
|
||||
if (tmpByteArrayPtr == NULL) {
|
||||
attempt = used + len;
|
||||
if (BYTEARRAY_SIZE(attempt) < BYTEARRAY_SIZE(used)) {
|
||||
Tcl_Panic("attempt to allocate a bigger buffer than we can handle");
|
||||
}
|
||||
tmpByteArrayPtr = ckrealloc(byteArrayPtr,
|
||||
BYTEARRAY_SIZE(attempt));
|
||||
if (ptr == NULL) {
|
||||
/* Last chance: Try to allocate exactly what is needed. */
|
||||
attempt = needed;
|
||||
ptr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
|
||||
}
|
||||
|
||||
byteArrayPtr = tmpByteArrayPtr;
|
||||
byteArrayPtr = ptr;
|
||||
byteArrayPtr->allocated = attempt;
|
||||
byteArrayPtr->used = used;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the append if there's any point.
|
||||
*/
|
||||
|
||||
if (len > 0) {
|
||||
if (bytes) {
|
||||
memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
|
||||
byteArrayPtr->used += len;
|
||||
TclInvalidateStringRep(objPtr);
|
||||
}
|
||||
byteArrayPtr->used += len;
|
||||
TclInvalidateStringRep(objPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+58
-30
@@ -19,7 +19,7 @@
|
||||
* Windows has mktime. The configurators do not check.
|
||||
*/
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
#define HAVE_MKTIME 1
|
||||
#endif
|
||||
|
||||
@@ -521,6 +521,46 @@ ClockGetdatefieldsObjCmd(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
FetchEraField(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *dict,
|
||||
Tcl_Obj *key,
|
||||
int *storePtr)
|
||||
{
|
||||
Tcl_Obj *value = NULL;
|
||||
|
||||
if (Tcl_DictObjGet(interp, dict, key, &value) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (value == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"expected key(s) not found in dictionary", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return Tcl_GetIndexFromObj(interp, value, eras, "era", TCL_EXACT, storePtr);
|
||||
}
|
||||
|
||||
static int
|
||||
FetchIntField(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *dict,
|
||||
Tcl_Obj *key,
|
||||
int *storePtr)
|
||||
{
|
||||
Tcl_Obj *value = NULL;
|
||||
|
||||
if (Tcl_DictObjGet(interp, dict, key, &value) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (value == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"expected key(s) not found in dictionary", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TclGetIntFromObj(interp, value, storePtr);
|
||||
}
|
||||
|
||||
static int
|
||||
ClockGetjuliandayfromerayearmonthdayObjCmd(
|
||||
ClientData clientData, /* Opaque pointer to literal pool, etc. */
|
||||
@@ -532,7 +572,6 @@ ClockGetjuliandayfromerayearmonthdayObjCmd(
|
||||
Tcl_Obj *dict;
|
||||
ClockClientData *data = clientData;
|
||||
Tcl_Obj *const *literals = data->literals;
|
||||
Tcl_Obj *fieldPtr;
|
||||
int changeover;
|
||||
int copied = 0;
|
||||
int status;
|
||||
@@ -547,18 +586,13 @@ ClockGetjuliandayfromerayearmonthdayObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dict = objv[1];
|
||||
if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
|
||||
|| Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
|
||||
&era) != TCL_OK
|
||||
|| Tcl_DictObjGet(interp, dict, literals[LIT_YEAR],
|
||||
&fieldPtr) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, fieldPtr, &fields.year) != TCL_OK
|
||||
|| Tcl_DictObjGet(interp, dict, literals[LIT_MONTH],
|
||||
&fieldPtr) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, fieldPtr, &fields.month) != TCL_OK
|
||||
|| Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFMONTH],
|
||||
&fieldPtr) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, fieldPtr, &fields.dayOfMonth)!=TCL_OK
|
||||
if (FetchEraField(interp, dict, literals[LIT_ERA], &era) != TCL_OK
|
||||
|| FetchIntField(interp, dict, literals[LIT_YEAR], &fields.year)
|
||||
!= TCL_OK
|
||||
|| FetchIntField(interp, dict, literals[LIT_MONTH], &fields.month)
|
||||
!= TCL_OK
|
||||
|| FetchIntField(interp, dict, literals[LIT_DAYOFMONTH],
|
||||
&fields.dayOfMonth) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -622,7 +656,6 @@ ClockGetjuliandayfromerayearweekdayObjCmd(
|
||||
Tcl_Obj *dict;
|
||||
ClockClientData *data = clientData;
|
||||
Tcl_Obj *const *literals = data->literals;
|
||||
Tcl_Obj *fieldPtr;
|
||||
int changeover;
|
||||
int copied = 0;
|
||||
int status;
|
||||
@@ -637,18 +670,13 @@ ClockGetjuliandayfromerayearweekdayObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dict = objv[1];
|
||||
if (Tcl_DictObjGet(interp, dict, literals[LIT_ERA], &fieldPtr) != TCL_OK
|
||||
|| Tcl_GetIndexFromObj(interp, fieldPtr, eras, "era", TCL_EXACT,
|
||||
&era) != TCL_OK
|
||||
|| Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601YEAR],
|
||||
&fieldPtr) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, fieldPtr, &fields.iso8601Year)!=TCL_OK
|
||||
|| Tcl_DictObjGet(interp, dict, literals[LIT_ISO8601WEEK],
|
||||
&fieldPtr) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, fieldPtr, &fields.iso8601Week)!=TCL_OK
|
||||
|| Tcl_DictObjGet(interp, dict, literals[LIT_DAYOFWEEK],
|
||||
&fieldPtr) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, fieldPtr, &fields.dayOfWeek) != TCL_OK
|
||||
if (FetchEraField(interp, dict, literals[LIT_ERA], &era) != TCL_OK
|
||||
|| FetchIntField(interp, dict, literals[LIT_ISO8601YEAR],
|
||||
&fields.iso8601Year) != TCL_OK
|
||||
|| FetchIntField(interp, dict, literals[LIT_ISO8601WEEK],
|
||||
&fields.iso8601Week) != TCL_OK
|
||||
|| FetchIntField(interp, dict, literals[LIT_DAYOFWEEK],
|
||||
&fields.dayOfWeek) != TCL_OK
|
||||
|| TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1697,7 +1725,7 @@ ClockClicksObjCmd(
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "switch", 0,
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "option", 0,
|
||||
&index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1867,9 +1895,9 @@ ClockParseformatargsObjCmd(
|
||||
localeObj = litPtr[LIT_C];
|
||||
timezoneObj = litPtr[LIT__NIL];
|
||||
for (i = 2; i < objc; i+=2) {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", 0,
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
|
||||
&optionIndex) != TCL_OK) {
|
||||
Tcl_SetErrorCode(interp, "CLOCK", "badSwitch",
|
||||
Tcl_SetErrorCode(interp, "CLOCK", "badOption",
|
||||
Tcl_GetString(objv[i]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+1
-1
@@ -1590,7 +1590,7 @@ FileAttrIsOwnedCmd(
|
||||
* test for equivalence to the current user.
|
||||
*/
|
||||
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__)
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
value = 1;
|
||||
#else
|
||||
value = (geteuid() == buf.st_uid);
|
||||
|
||||
+25
-16
@@ -29,7 +29,7 @@
|
||||
typedef struct SortElement {
|
||||
union { /* The value that we sorting by. */
|
||||
const char *strValuePtr;
|
||||
long intValue;
|
||||
Tcl_WideInt wideValue;
|
||||
double doubleValue;
|
||||
Tcl_Obj *objValuePtr;
|
||||
} collationKey;
|
||||
@@ -1287,6 +1287,7 @@ TclInfoFrame(
|
||||
"eval", "eval", "eval", "precompiled", "source", "proc"
|
||||
};
|
||||
Proc *procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL;
|
||||
int needsFree = -1;
|
||||
|
||||
/*
|
||||
* Pull the information and construct the dictionary to return, as list.
|
||||
@@ -1360,6 +1361,9 @@ TclInfoFrame(
|
||||
}
|
||||
|
||||
ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL));
|
||||
if (fPtr->cmdObj && framePtr->cmdObj == NULL) {
|
||||
needsFree = lc - 1;
|
||||
}
|
||||
TclStackFree(interp, fPtr);
|
||||
break;
|
||||
}
|
||||
@@ -1447,7 +1451,11 @@ TclInfoFrame(
|
||||
}
|
||||
}
|
||||
|
||||
return Tcl_NewListObj(lc, lv);
|
||||
tmpObj = Tcl_NewListObj(lc, lv);
|
||||
if (needsFree >= 0) {
|
||||
Tcl_DecrRefCount(lv[needsFree]);
|
||||
}
|
||||
return tmpObj;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2655,7 +2663,7 @@ Tcl_LrepeatObjCmd(
|
||||
* number of times.
|
||||
*/
|
||||
|
||||
CLANG_ASSERT(dataArray);
|
||||
CLANG_ASSERT(dataArray || totalElems == 0 );
|
||||
if (objc == 1) {
|
||||
register Tcl_Obj *tmpPtr = objv[0];
|
||||
|
||||
@@ -2893,7 +2901,8 @@ Tcl_LsearchObjCmd(
|
||||
{
|
||||
const char *bytes, *patternBytes;
|
||||
int i, match, index, result, listc, length, elemLen, bisect;
|
||||
int dataType, isIncreasing, lower, upper, patInt, objInt, offset;
|
||||
int dataType, isIncreasing, lower, upper, offset;
|
||||
Tcl_WideInt patWide, objWide;
|
||||
int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
|
||||
double patDouble, objDouble;
|
||||
SortInfo sortInfo;
|
||||
@@ -3212,7 +3221,7 @@ Tcl_LsearchObjCmd(
|
||||
patternBytes = TclGetStringFromObj(patObj, &length);
|
||||
break;
|
||||
case INTEGER:
|
||||
result = TclGetIntFromObj(interp, patObj, &patInt);
|
||||
result = TclGetWideIntFromObj(interp, patObj, &patWide);
|
||||
if (result != TCL_OK) {
|
||||
goto done;
|
||||
}
|
||||
@@ -3281,13 +3290,13 @@ Tcl_LsearchObjCmd(
|
||||
match = DictionaryCompare(patternBytes, bytes);
|
||||
break;
|
||||
case INTEGER:
|
||||
result = TclGetIntFromObj(interp, itemPtr, &objInt);
|
||||
result = TclGetWideIntFromObj(interp, itemPtr, &objWide);
|
||||
if (result != TCL_OK) {
|
||||
goto done;
|
||||
}
|
||||
if (patInt == objInt) {
|
||||
if (patWide == objWide) {
|
||||
match = 0;
|
||||
} else if (patInt < objInt) {
|
||||
} else if (patWide < objWide) {
|
||||
match = -1;
|
||||
} else {
|
||||
match = 1;
|
||||
@@ -3400,14 +3409,14 @@ Tcl_LsearchObjCmd(
|
||||
break;
|
||||
|
||||
case INTEGER:
|
||||
result = TclGetIntFromObj(interp, itemPtr, &objInt);
|
||||
result = TclGetWideIntFromObj(interp, itemPtr, &objWide);
|
||||
if (result != TCL_OK) {
|
||||
if (listPtr != NULL) {
|
||||
Tcl_DecrRefCount(listPtr);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
match = (objInt == patInt);
|
||||
match = (objWide == patWide);
|
||||
break;
|
||||
|
||||
case REAL:
|
||||
@@ -3971,13 +3980,13 @@ Tcl_LsortObjCmd(
|
||||
if (sortMode == SORTMODE_ASCII) {
|
||||
elementArray[i].collationKey.strValuePtr = TclGetString(indexPtr);
|
||||
} else if (sortMode == SORTMODE_INTEGER) {
|
||||
long a;
|
||||
Tcl_WideInt a;
|
||||
|
||||
if (TclGetLongFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
|
||||
if (TclGetWideIntFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done1;
|
||||
}
|
||||
elementArray[i].collationKey.intValue = a;
|
||||
elementArray[i].collationKey.wideValue = a;
|
||||
} else if (sortMode == SORTMODE_REAL) {
|
||||
double a;
|
||||
|
||||
@@ -4226,10 +4235,10 @@ SortCompare(
|
||||
order = DictionaryCompare(elemPtr1->collationKey.strValuePtr,
|
||||
elemPtr2->collationKey.strValuePtr);
|
||||
} else if (infoPtr->sortMode == SORTMODE_INTEGER) {
|
||||
long a, b;
|
||||
Tcl_WideInt a, b;
|
||||
|
||||
a = elemPtr1->collationKey.intValue;
|
||||
b = elemPtr2->collationKey.intValue;
|
||||
a = elemPtr1->collationKey.wideValue;
|
||||
b = elemPtr2->collationKey.wideValue;
|
||||
order = ((a >= b) - (a <= b));
|
||||
} else if (infoPtr->sortMode == SORTMODE_REAL) {
|
||||
double a, b;
|
||||
|
||||
+102
-13
@@ -32,6 +32,39 @@ static int TryPostHandler(ClientData data[], Tcl_Interp *interp,
|
||||
int result);
|
||||
static int UniCharIsAscii(int character);
|
||||
static int UniCharIsHexDigit(int character);
|
||||
|
||||
/*
|
||||
* Default set of characters to trim in [string trim] and friends. This is a
|
||||
* UTF-8 literal string containing all Unicode space characters [TIP #413]
|
||||
*/
|
||||
|
||||
const char tclDefaultTrimSet[] =
|
||||
"\x09\x0a\x0b\x0c\x0d " /* ASCII */
|
||||
"\xc0\x80" /* nul (U+0000) */
|
||||
"\xc2\x85" /* next line (U+0085) */
|
||||
"\xc2\xa0" /* non-breaking space (U+00a0) */
|
||||
"\xe1\x9a\x80" /* ogham space mark (U+1680) */
|
||||
"\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */
|
||||
"\xe2\x80\x80" /* en quad (U+2000) */
|
||||
"\xe2\x80\x81" /* em quad (U+2001) */
|
||||
"\xe2\x80\x82" /* en space (U+2002) */
|
||||
"\xe2\x80\x83" /* em space (U+2003) */
|
||||
"\xe2\x80\x84" /* three-per-em space (U+2004) */
|
||||
"\xe2\x80\x85" /* four-per-em space (U+2005) */
|
||||
"\xe2\x80\x86" /* six-per-em space (U+2006) */
|
||||
"\xe2\x80\x87" /* figure space (U+2007) */
|
||||
"\xe2\x80\x88" /* punctuation space (U+2008) */
|
||||
"\xe2\x80\x89" /* thin space (U+2009) */
|
||||
"\xe2\x80\x8a" /* hair space (U+200a) */
|
||||
"\xe2\x80\x8b" /* zero width space (U+200b) */
|
||||
"\xe2\x80\xa8" /* line separator (U+2028) */
|
||||
"\xe2\x80\xa9" /* paragraph separator (U+2029) */
|
||||
"\xe2\x80\xaf" /* narrow no-break space (U+202f) */
|
||||
"\xe2\x81\x9f" /* medium mathematical space (U+205f) */
|
||||
"\xe2\x81\xa0" /* word joiner (U+2060) */
|
||||
"\xe3\x80\x80" /* ideographic space (U+3000) */
|
||||
"\xef\xbb\xbf" /* zero width no-break space (U+feff) */
|
||||
;
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -128,7 +161,7 @@ Tcl_RegexpObjCmd(
|
||||
if (name[0] != '-') {
|
||||
break;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", TCL_EXACT,
|
||||
&index) != TCL_OK) {
|
||||
goto optionError;
|
||||
}
|
||||
@@ -184,7 +217,7 @@ Tcl_RegexpObjCmd(
|
||||
endOfForLoop:
|
||||
if ((objc - i) < (2 - about)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"?-switch ...? exp string ?matchVar? ?subMatchVar ...?");
|
||||
"?-option ...? exp string ?matchVar? ?subMatchVar ...?");
|
||||
goto optionError;
|
||||
}
|
||||
objc -= i;
|
||||
@@ -198,6 +231,8 @@ Tcl_RegexpObjCmd(
|
||||
if (doinline && ((objc - 2) != 0)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"regexp match variables not allowed when using -inline", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "REGEXP",
|
||||
"MIX_VAR_INLINE", NULL);
|
||||
goto optionError;
|
||||
}
|
||||
|
||||
@@ -486,7 +521,7 @@ Tcl_RegsubObjCmd(
|
||||
if (name[0] != '-') {
|
||||
break;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[idx], options, "switch",
|
||||
if (Tcl_GetIndexFromObj(interp, objv[idx], options, "option",
|
||||
TCL_EXACT, &index) != TCL_OK) {
|
||||
goto optionError;
|
||||
}
|
||||
@@ -533,7 +568,7 @@ Tcl_RegsubObjCmd(
|
||||
endOfForLoop:
|
||||
if (objc-idx < 3 || objc-idx > 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"?-switch ...? exp string subSpec ?varName?");
|
||||
"?-option ...? exp string subSpec ?varName?");
|
||||
optionError:
|
||||
if (startIndex) {
|
||||
Tcl_DecrRefCount(startIndex);
|
||||
@@ -2800,6 +2835,59 @@ StringCmpCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* StringCatCmd --
|
||||
*
|
||||
* This procedure is invoked to process the "string cat" Tcl command.
|
||||
* See the user documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
StringCatCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
int i;
|
||||
Tcl_Obj *objResultPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
/*
|
||||
* If there are no args, the result is an empty object.
|
||||
* Just leave the preset empty interp result.
|
||||
*/
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objc == 2) {
|
||||
/*
|
||||
* Other trivial case, single arg, just return it.
|
||||
*/
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
objResultPtr = objv[1];
|
||||
if (Tcl_IsShared(objResultPtr)) {
|
||||
objResultPtr = Tcl_DuplicateObj(objResultPtr);
|
||||
}
|
||||
for(i = 2;i < objc;i++) {
|
||||
Tcl_AppendObjToObj(objResultPtr, objv[i]);
|
||||
}
|
||||
Tcl_SetObjResult(interp, objResultPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -3158,8 +3246,8 @@ StringTrimCmd(
|
||||
if (objc == 3) {
|
||||
string2 = TclGetStringFromObj(objv[2], &length2);
|
||||
} else if (objc == 2) {
|
||||
string2 = DEFAULT_TRIM_SET;
|
||||
length2 = strlen(DEFAULT_TRIM_SET);
|
||||
string2 = tclDefaultTrimSet;
|
||||
length2 = strlen(tclDefaultTrimSet);
|
||||
} else {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
|
||||
return TCL_ERROR;
|
||||
@@ -3206,8 +3294,8 @@ StringTrimLCmd(
|
||||
if (objc == 3) {
|
||||
string2 = TclGetStringFromObj(objv[2], &length2);
|
||||
} else if (objc == 2) {
|
||||
string2 = DEFAULT_TRIM_SET;
|
||||
length2 = strlen(DEFAULT_TRIM_SET);
|
||||
string2 = tclDefaultTrimSet;
|
||||
length2 = strlen(tclDefaultTrimSet);
|
||||
} else {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
|
||||
return TCL_ERROR;
|
||||
@@ -3252,8 +3340,8 @@ StringTrimRCmd(
|
||||
if (objc == 3) {
|
||||
string2 = TclGetStringFromObj(objv[2], &length2);
|
||||
} else if (objc == 2) {
|
||||
string2 = DEFAULT_TRIM_SET;
|
||||
length2 = strlen(DEFAULT_TRIM_SET);
|
||||
string2 = tclDefaultTrimSet;
|
||||
length2 = strlen(tclDefaultTrimSet);
|
||||
} else {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
|
||||
return TCL_ERROR;
|
||||
@@ -3295,6 +3383,7 @@ TclInitStringCmd(
|
||||
{
|
||||
static const EnsembleImplMap stringImplMap[] = {
|
||||
{"bytelength", StringBytesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"cat", StringCatCmd, TclCompileStringCatCmd, NULL, NULL, 0},
|
||||
{"compare", StringCmpCmd, TclCompileStringCmpCmd, NULL, NULL, 0},
|
||||
{"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0},
|
||||
{"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0},
|
||||
@@ -3358,7 +3447,7 @@ TclSubstOptions(
|
||||
for (i = 0; i < numOpts; i++) {
|
||||
int optionIndex;
|
||||
|
||||
if (Tcl_GetIndexFromObj(interp, opts[i], substOptions, "switch", 0,
|
||||
if (Tcl_GetIndexFromObj(interp, opts[i], substOptions, "option", 0,
|
||||
&optionIndex) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3558,7 +3647,7 @@ TclNRSwitchObjCmd(
|
||||
finishedOptions:
|
||||
if (objc - i < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"?-switch ...? string ?pattern body ...? ?default body?");
|
||||
"?-option ...? string ?pattern body ...? ?default body?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (indexVarObj != NULL && mode != OPT_REGEXP) {
|
||||
@@ -3605,7 +3694,7 @@ TclNRSwitchObjCmd(
|
||||
|
||||
if (objc < 1) {
|
||||
Tcl_WrongNumArgs(interp, 1, savedObjv,
|
||||
"?-switch ...? string {?pattern body ...? ?default body?}");
|
||||
"?-option ...? string {?pattern body ...? ?default body?}");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objv = listv;
|
||||
|
||||
+228
-109
@@ -26,14 +26,23 @@ static void FreeDictUpdateInfo(ClientData clientData);
|
||||
static void PrintDictUpdateInfo(ClientData clientData,
|
||||
Tcl_Obj *appendObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static void DisassembleDictUpdateInfo(ClientData clientData,
|
||||
Tcl_Obj *dictObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static ClientData DupForeachInfo(ClientData clientData);
|
||||
static void FreeForeachInfo(ClientData clientData);
|
||||
static void PrintForeachInfo(ClientData clientData,
|
||||
Tcl_Obj *appendObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static void DisassembleForeachInfo(ClientData clientData,
|
||||
Tcl_Obj *dictObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static void PrintNewForeachInfo(ClientData clientData,
|
||||
Tcl_Obj *appendObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static void DisassembleNewForeachInfo(ClientData clientData,
|
||||
Tcl_Obj *dictObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static int CompileEachloopCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
CompileEnv *envPtr, int collect);
|
||||
@@ -49,21 +58,24 @@ const AuxDataType tclForeachInfoType = {
|
||||
"ForeachInfo", /* name */
|
||||
DupForeachInfo, /* dupProc */
|
||||
FreeForeachInfo, /* freeProc */
|
||||
PrintForeachInfo /* printProc */
|
||||
PrintForeachInfo, /* printProc */
|
||||
DisassembleForeachInfo /* disassembleProc */
|
||||
};
|
||||
|
||||
const AuxDataType tclNewForeachInfoType = {
|
||||
"NewForeachInfo", /* name */
|
||||
DupForeachInfo, /* dupProc */
|
||||
FreeForeachInfo, /* freeProc */
|
||||
PrintNewForeachInfo /* printProc */
|
||||
PrintNewForeachInfo, /* printProc */
|
||||
DisassembleNewForeachInfo /* disassembleProc */
|
||||
};
|
||||
|
||||
const AuxDataType tclDictUpdateInfoType = {
|
||||
"DictUpdateInfo", /* name */
|
||||
DupDictUpdateInfo, /* dupProc */
|
||||
FreeDictUpdateInfo, /* freeProc */
|
||||
PrintDictUpdateInfo /* printProc */
|
||||
PrintDictUpdateInfo, /* printProc */
|
||||
DisassembleDictUpdateInfo /* disassembleProc */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -165,9 +177,9 @@ TclCompileAppendCmd(
|
||||
*/
|
||||
|
||||
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT,
|
||||
&localIndex, &isScalar, 1);
|
||||
if (!isScalar || localIndex < 0) {
|
||||
|
||||
localIndex = LocalScalarFromToken(varTokenPtr, envPtr);
|
||||
if (localIndex < 0) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -289,7 +301,8 @@ TclCompileArraySetCmd(
|
||||
* a proc, we cannot do a better compile than generic.
|
||||
*/
|
||||
|
||||
if (envPtr->procPtr == NULL && !(isDataEven && len == 0)) {
|
||||
if ((varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) ||
|
||||
(envPtr->procPtr == NULL && !(isDataEven && len == 0))) {
|
||||
code = TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
|
||||
goto done;
|
||||
}
|
||||
@@ -330,8 +343,9 @@ TclCompileArraySetCmd(
|
||||
* a non-local variable: upvar from a local one! This consumes the
|
||||
* variable name that was left at stacktop.
|
||||
*/
|
||||
|
||||
localIndex = AnonymousLocal(envPtr);
|
||||
|
||||
localIndex = TclFindCompiledLocal(varTokenPtr->start,
|
||||
varTokenPtr->size, 1, envPtr);
|
||||
PushStringLiteral(envPtr, "0");
|
||||
TclEmitInstInt4(INST_REVERSE, 2, envPtr);
|
||||
TclEmitInstInt4(INST_UPVAR, localIndex, envPtr);
|
||||
@@ -2084,11 +2098,13 @@ TclCompileDictWithCmd(
|
||||
* DupDictUpdateInfo: a copy of the auxiliary data
|
||||
* FreeDictUpdateInfo: none
|
||||
* PrintDictUpdateInfo: none
|
||||
* DisassembleDictUpdateInfo: none
|
||||
*
|
||||
* Side effects:
|
||||
* DupDictUpdateInfo: allocates memory
|
||||
* FreeDictUpdateInfo: releases memory
|
||||
* PrintDictUpdateInfo: none
|
||||
* DisassembleDictUpdateInfo: none
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -2131,6 +2147,25 @@ PrintDictUpdateInfo(
|
||||
Tcl_AppendPrintfToObj(appendObj, "%%v%u", duiPtr->varIndices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DisassembleDictUpdateInfo(
|
||||
ClientData clientData,
|
||||
Tcl_Obj *dictObj,
|
||||
ByteCode *codePtr,
|
||||
unsigned int pcOffset)
|
||||
{
|
||||
DictUpdateInfo *duiPtr = clientData;
|
||||
int i;
|
||||
Tcl_Obj *variables = Tcl_NewObj();
|
||||
|
||||
for (i=0 ; i<duiPtr->length ; i++) {
|
||||
Tcl_ListObjAppendElement(NULL, variables,
|
||||
Tcl_NewIntObj(duiPtr->varIndices[i]));
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("variables", -1),
|
||||
variables);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2368,7 +2403,6 @@ TclCompileForCmd(
|
||||
|
||||
SetLineInformation(2);
|
||||
TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
|
||||
TclClearNumConversion(envPtr);
|
||||
|
||||
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
|
||||
if (jumpDist > 127) {
|
||||
@@ -2493,24 +2527,16 @@ CompileEachloopCmd(
|
||||
* (TCL_EACH_*) */
|
||||
{
|
||||
Proc *procPtr = envPtr->procPtr;
|
||||
ForeachInfo *infoPtr; /* Points to the structure describing this
|
||||
ForeachInfo *infoPtr=NULL; /* Points to the structure describing this
|
||||
* foreach command. Stored in a AuxData
|
||||
* record in the ByteCode. */
|
||||
|
||||
Tcl_Token *tokenPtr, *bodyTokenPtr;
|
||||
int jumpBackOffset, infoIndex, range;
|
||||
int numWords, numLists, numVars, loopIndex, i, j, code;
|
||||
int numWords, numLists, i, j, code = TCL_OK;
|
||||
Tcl_Obj *varListObj = NULL;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
|
||||
/*
|
||||
* We parse the variable list argument words and create two arrays:
|
||||
* varcList[i] is number of variables in i-th var list.
|
||||
* varvList[i] points to array of var names in i-th var list.
|
||||
*/
|
||||
|
||||
int *varcList;
|
||||
const char ***varvList;
|
||||
|
||||
/*
|
||||
* If the foreach command isn't in a procedure, don't compile it inline:
|
||||
* the payoff is too small.
|
||||
@@ -2539,105 +2565,73 @@ CompileEachloopCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate storage for the varcList and varvList arrays if necessary.
|
||||
* Create and initialize the ForeachInfo and ForeachVarList data
|
||||
* structures describing this command. Then create a AuxData record
|
||||
* pointing to the ForeachInfo structure.
|
||||
*/
|
||||
|
||||
numLists = (numWords - 2)/2;
|
||||
varcList = TclStackAlloc(interp, numLists * sizeof(int));
|
||||
memset(varcList, 0, numLists * sizeof(int));
|
||||
varvList = (const char ***) TclStackAlloc(interp,
|
||||
numLists * sizeof(const char **));
|
||||
memset((char*) varvList, 0, numLists * sizeof(const char **));
|
||||
infoPtr = ckalloc(sizeof(ForeachInfo)
|
||||
+ (numLists - 1) * sizeof(ForeachVarList *));
|
||||
infoPtr->numLists = 0; /* Count this up as we go */
|
||||
|
||||
/*
|
||||
* Break up each var list and set the varcList and varvList arrays. Don't
|
||||
* Parse each var list into sequence of var names. Don't
|
||||
* compile the foreach inline if any var name needs substitutions or isn't
|
||||
* a scalar, or if any var list needs substitutions.
|
||||
*/
|
||||
|
||||
loopIndex = 0;
|
||||
varListObj = Tcl_NewObj();
|
||||
for (i = 0, tokenPtr = parsePtr->tokenPtr;
|
||||
i < numWords-1;
|
||||
i++, tokenPtr = TokenAfter(tokenPtr)) {
|
||||
Tcl_DString varList;
|
||||
ForeachVarList *varListPtr;
|
||||
int numVars;
|
||||
|
||||
if (i%2 != 1) {
|
||||
continue;
|
||||
}
|
||||
if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lots of copying going on here. Need a ListObj wizard to show a
|
||||
* better way.
|
||||
*/
|
||||
|
||||
Tcl_DStringInit(&varList);
|
||||
TclDStringAppendToken(&varList, &tokenPtr[1]);
|
||||
code = Tcl_SplitList(NULL, Tcl_DStringValue(&varList),
|
||||
&varcList[loopIndex], &varvList[loopIndex]);
|
||||
Tcl_DStringFree(&varList);
|
||||
if (code != TCL_OK) {
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
numVars = varcList[loopIndex];
|
||||
|
||||
/*
|
||||
* If the variable list is empty, we can enter an infinite loop when
|
||||
* the interpreted version would not. Take care to ensure this does
|
||||
* not happen. [Bug 1671138]
|
||||
* the interpreted version would not. Take care to ensure this does
|
||||
* not happen. [Bug 1671138]
|
||||
*/
|
||||
|
||||
if (numVars == 0) {
|
||||
if (!TclWordKnownAtCompileTime(tokenPtr, varListObj) ||
|
||||
TCL_OK != Tcl_ListObjLength(NULL, varListObj, &numVars) ||
|
||||
numVars == 0) {
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (j = 0; j < numVars; j++) {
|
||||
const char *varName = varvList[loopIndex][j];
|
||||
varListPtr = ckalloc(sizeof(ForeachVarList)
|
||||
+ (numVars - 1) * sizeof(int));
|
||||
varListPtr->numVars = numVars;
|
||||
infoPtr->varLists[i/2] = varListPtr;
|
||||
infoPtr->numLists++;
|
||||
|
||||
if (!TclIsLocalScalar(varName, (int) strlen(varName))) {
|
||||
for (j = 0; j < numVars; j++) {
|
||||
Tcl_Obj *varNameObj;
|
||||
const char *bytes;
|
||||
int numBytes, varIndex;
|
||||
|
||||
Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj);
|
||||
bytes = Tcl_GetStringFromObj(varNameObj, &numBytes);
|
||||
varIndex = LocalScalar(bytes, numBytes, envPtr);
|
||||
if (varIndex < 0) {
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
varListPtr->varIndexes[j] = varIndex;
|
||||
}
|
||||
loopIndex++;
|
||||
Tcl_SetObjLength(varListObj, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We will compile the foreach command.
|
||||
*/
|
||||
|
||||
code = TCL_OK;
|
||||
|
||||
/*
|
||||
* Create and initialize the ForeachInfo and ForeachVarList data
|
||||
* structures describing this command. Then create a AuxData record
|
||||
* pointing to the ForeachInfo structure.
|
||||
*/
|
||||
|
||||
infoPtr = ckalloc(sizeof(ForeachInfo)
|
||||
+ (numLists - 1) * sizeof(ForeachVarList *));
|
||||
infoPtr->numLists = numLists;
|
||||
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
|
||||
ForeachVarList *varListPtr;
|
||||
|
||||
numVars = varcList[loopIndex];
|
||||
varListPtr = ckalloc(sizeof(ForeachVarList)
|
||||
+ (numVars - 1) * sizeof(int));
|
||||
varListPtr->numVars = numVars;
|
||||
for (j = 0; j < numVars; j++) {
|
||||
const char *varName = varvList[loopIndex][j];
|
||||
int nameChars = strlen(varName);
|
||||
|
||||
varListPtr->varIndexes[j] = TclFindCompiledLocal(varName,
|
||||
nameChars, /*create*/ 1, envPtr);
|
||||
}
|
||||
infoPtr->varLists[loopIndex] = varListPtr;
|
||||
}
|
||||
infoIndex = TclCreateAuxData(infoPtr, &tclNewForeachInfoType, envPtr);
|
||||
|
||||
/*
|
||||
@@ -2709,13 +2703,14 @@ CompileEachloopCmd(
|
||||
}
|
||||
|
||||
done:
|
||||
for (loopIndex = 0; loopIndex < numLists; loopIndex++) {
|
||||
if (varvList[loopIndex] != NULL) {
|
||||
ckfree(varvList[loopIndex]);
|
||||
if (code == TCL_ERROR) {
|
||||
if (infoPtr) {
|
||||
FreeForeachInfo(infoPtr);
|
||||
}
|
||||
}
|
||||
TclStackFree(interp, (void *)varvList);
|
||||
TclStackFree(interp, varcList);
|
||||
if (varListObj) {
|
||||
Tcl_DecrRefCount(varListObj);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
@@ -2809,10 +2804,10 @@ FreeForeachInfo(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* PrintForeachInfo --
|
||||
* PrintForeachInfo, DisassembleForeachInfo --
|
||||
*
|
||||
* Function to write a human-readable representation of a ForeachInfo
|
||||
* structure to stdout for debugging.
|
||||
* Functions to write a human-readable or script-readablerepresentation
|
||||
* of a ForeachInfo structure to a Tcl_Obj for debugging.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -2892,6 +2887,89 @@ PrintNewForeachInfo(
|
||||
Tcl_AppendToObj(appendObj, "]", -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DisassembleForeachInfo(
|
||||
ClientData clientData,
|
||||
Tcl_Obj *dictObj,
|
||||
ByteCode *codePtr,
|
||||
unsigned int pcOffset)
|
||||
{
|
||||
register ForeachInfo *infoPtr = clientData;
|
||||
register ForeachVarList *varsPtr;
|
||||
int i, j;
|
||||
Tcl_Obj *objPtr, *innerPtr;
|
||||
|
||||
/*
|
||||
* Data stores.
|
||||
*/
|
||||
|
||||
objPtr = Tcl_NewObj();
|
||||
for (i=0 ; i<infoPtr->numLists ; i++) {
|
||||
Tcl_ListObjAppendElement(NULL, objPtr,
|
||||
Tcl_NewIntObj(infoPtr->firstValueTemp + i));
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("data", -1), objPtr);
|
||||
|
||||
/*
|
||||
* Loop counter.
|
||||
*/
|
||||
|
||||
Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("loop", -1),
|
||||
Tcl_NewIntObj(infoPtr->loopCtTemp));
|
||||
|
||||
/*
|
||||
* Assignment targets.
|
||||
*/
|
||||
|
||||
objPtr = Tcl_NewObj();
|
||||
for (i=0 ; i<infoPtr->numLists ; i++) {
|
||||
innerPtr = Tcl_NewObj();
|
||||
varsPtr = infoPtr->varLists[i];
|
||||
for (j=0 ; j<varsPtr->numVars ; j++) {
|
||||
Tcl_ListObjAppendElement(NULL, innerPtr,
|
||||
Tcl_NewIntObj(varsPtr->varIndexes[j]));
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, objPtr, innerPtr);
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("assign", -1), objPtr);
|
||||
}
|
||||
|
||||
static void
|
||||
DisassembleNewForeachInfo(
|
||||
ClientData clientData,
|
||||
Tcl_Obj *dictObj,
|
||||
ByteCode *codePtr,
|
||||
unsigned int pcOffset)
|
||||
{
|
||||
register ForeachInfo *infoPtr = clientData;
|
||||
register ForeachVarList *varsPtr;
|
||||
int i, j;
|
||||
Tcl_Obj *objPtr, *innerPtr;
|
||||
|
||||
/*
|
||||
* Jump offset.
|
||||
*/
|
||||
|
||||
Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("jumpOffset", -1),
|
||||
Tcl_NewIntObj(infoPtr->loopCtTemp));
|
||||
|
||||
/*
|
||||
* Assignment targets.
|
||||
*/
|
||||
|
||||
objPtr = Tcl_NewObj();
|
||||
for (i=0 ; i<infoPtr->numLists ; i++) {
|
||||
innerPtr = Tcl_NewObj();
|
||||
varsPtr = infoPtr->varLists[i];
|
||||
for (j=0 ; j<varsPtr->numVars ; j++) {
|
||||
Tcl_ListObjAppendElement(NULL, innerPtr,
|
||||
Tcl_NewIntObj(varsPtr->varIndexes[j]));
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, objPtr, innerPtr);
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("assign", -1), objPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -3114,6 +3192,54 @@ TclCompileFormatCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclLocalScalarFromToken --
|
||||
*
|
||||
* Get the index into the table of compiled locals that corresponds
|
||||
* to a local scalar variable name.
|
||||
*
|
||||
* Results:
|
||||
* Returns the non-negative integer index value into the table of
|
||||
* compiled locals corresponding to a local scalar variable name.
|
||||
* If the arguments passed in do not identify a local scalar variable
|
||||
* then return -1.
|
||||
*
|
||||
* Side effects:
|
||||
* May add an entery into the table of compiled locals.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclLocalScalarFromToken(
|
||||
Tcl_Token *tokenPtr,
|
||||
CompileEnv *envPtr)
|
||||
{
|
||||
int isScalar, index;
|
||||
|
||||
TclPushVarName(NULL, tokenPtr, envPtr, TCL_NO_ELEMENT, &index, &isScalar);
|
||||
if (!isScalar) {
|
||||
index = -1;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
int
|
||||
TclLocalScalar(
|
||||
const char *bytes,
|
||||
int numBytes,
|
||||
CompileEnv *envPtr)
|
||||
{
|
||||
Tcl_Token token[2] = {{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1},
|
||||
{TCL_TOKEN_TEXT, NULL, 0, 0}};
|
||||
|
||||
token[1].start = bytes;
|
||||
token[1].size = numBytes;
|
||||
return TclLocalScalarFromToken(token, envPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -3172,16 +3298,7 @@ TclPushVarName(
|
||||
nameChars = elNameChars = 0;
|
||||
localIndex = -1;
|
||||
|
||||
/*
|
||||
* Check not only that the type is TCL_TOKEN_SIMPLE_WORD, but whether
|
||||
* curly braces surround the variable name. This really matters for array
|
||||
* elements to handle things like
|
||||
* set {x($foo)} 5
|
||||
* which raises an undefined var error if we are not careful here.
|
||||
*/
|
||||
|
||||
if ((varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) &&
|
||||
(varTokenPtr->start[0] != '{')) {
|
||||
if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
|
||||
/*
|
||||
* A simple variable name. Divide it up into "name" and "elName"
|
||||
* strings. If it is not a local variable, look it up at runtime.
|
||||
@@ -3205,7 +3322,7 @@ TclPushVarName(
|
||||
}
|
||||
}
|
||||
|
||||
if ((elName != NULL) && elNameChars) {
|
||||
if (!(flags & TCL_NO_ELEMENT) && (elName != NULL) && elNameChars) {
|
||||
/*
|
||||
* An array element, the element name is a simple string:
|
||||
* assemble the corresponding token.
|
||||
@@ -3220,7 +3337,7 @@ TclPushVarName(
|
||||
elemTokenCount = 1;
|
||||
}
|
||||
}
|
||||
} else if (((n = varTokenPtr->numComponents) > 1)
|
||||
} 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] == ')')) {
|
||||
@@ -3256,9 +3373,10 @@ TclPushVarName(
|
||||
nameChars = p - varTokenPtr[1].start;
|
||||
elName = p + 1;
|
||||
remainingChars = (varTokenPtr[2].start - p) - 1;
|
||||
elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 2;
|
||||
elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1;
|
||||
|
||||
if (remainingChars) {
|
||||
if (!(flags & TCL_NO_ELEMENT)) {
|
||||
if (remainingChars) {
|
||||
/*
|
||||
* Make a first token with the extra characters in the first
|
||||
* token.
|
||||
@@ -3278,13 +3396,14 @@ TclPushVarName(
|
||||
|
||||
memcpy(elemTokenPtr+1, varTokenPtr+2,
|
||||
(n-1) * sizeof(Tcl_Token));
|
||||
} else {
|
||||
} else {
|
||||
/*
|
||||
* Use the already available tokens.
|
||||
*/
|
||||
|
||||
elemTokenPtr = &varTokenPtr[2];
|
||||
elemTokenCount = n - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3319,7 +3438,7 @@ TclPushVarName(
|
||||
localIndex = -1;
|
||||
}
|
||||
}
|
||||
if (localIndex < 0) {
|
||||
if (interp && localIndex < 0) {
|
||||
PushLiteral(envPtr, name, nameChars);
|
||||
}
|
||||
|
||||
@@ -3336,7 +3455,7 @@ TclPushVarName(
|
||||
PushStringLiteral(envPtr, "");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (interp) {
|
||||
/*
|
||||
* The var name isn't simple: compile and push it.
|
||||
*/
|
||||
|
||||
+41
-60
@@ -281,7 +281,6 @@ TclCompileIfCmd(
|
||||
SetLineInformation(wordIdx);
|
||||
Tcl_ResetResult(interp);
|
||||
TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
|
||||
TclClearNumConversion(envPtr);
|
||||
if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
|
||||
TclExpandJumpFixupArray(&jumpFalseFixupArray);
|
||||
}
|
||||
@@ -531,7 +530,6 @@ TclCompileIncrCmd(
|
||||
} else {
|
||||
SetLineInformation(2);
|
||||
CompileTokens(envPtr, incrTokenPtr, interp);
|
||||
TclClearNumConversion(envPtr);
|
||||
}
|
||||
} else { /* No incr amount given so use 1. */
|
||||
haveImmValue = 1;
|
||||
@@ -868,28 +866,16 @@ TclCompileLappendCmd(
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *varTokenPtr, *valueTokenPtr;
|
||||
int isScalar, localIndex, numWords, i, fwd, offsetFwd;
|
||||
int isScalar, localIndex, numWords, i;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
|
||||
/*
|
||||
* If we're not in a procedure, don't compile.
|
||||
*/
|
||||
|
||||
if (envPtr->procPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* TODO: Consider support for compiling expanded args. */
|
||||
numWords = parsePtr->numWords;
|
||||
if (numWords == 1) {
|
||||
if (numWords < 3) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (numWords != 3) {
|
||||
/*
|
||||
* LAPPEND instructions currently only handle one value, but we can
|
||||
* handle some multi-value cases by stringing them together.
|
||||
*/
|
||||
|
||||
if (numWords != 3 || envPtr->procPtr == NULL) {
|
||||
goto lappendMultiple;
|
||||
}
|
||||
|
||||
@@ -943,42 +929,28 @@ TclCompileLappendCmd(
|
||||
return TCL_OK;
|
||||
|
||||
lappendMultiple:
|
||||
/*
|
||||
* Can only handle the case where we are appending to a local scalar when
|
||||
* there are multiple values to append. Fortunately, this is common.
|
||||
*/
|
||||
|
||||
if (envPtr->procPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT,
|
||||
PushVarNameWord(interp, varTokenPtr, envPtr, 0,
|
||||
&localIndex, &isScalar, 1);
|
||||
if (!isScalar || localIndex < 0) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Definitely appending to a local scalar; generate the words and append
|
||||
* them.
|
||||
*/
|
||||
|
||||
valueTokenPtr = TokenAfter(varTokenPtr);
|
||||
for (i = 2 ; i < numWords ; i++) {
|
||||
CompileWord(envPtr, valueTokenPtr, interp, i);
|
||||
valueTokenPtr = TokenAfter(valueTokenPtr);
|
||||
}
|
||||
TclEmitInstInt4( INST_LIST, numWords-2, envPtr);
|
||||
TclEmitInstInt4( INST_EXIST_SCALAR, localIndex, envPtr);
|
||||
offsetFwd = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr);
|
||||
Emit14Inst( INST_LOAD_SCALAR, localIndex, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
fwd = CurrentOffset(envPtr) - offsetFwd;
|
||||
TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1);
|
||||
Emit14Inst( INST_STORE_SCALAR, localIndex, envPtr);
|
||||
|
||||
TclEmitInstInt4( INST_LIST, numWords-2, envPtr);
|
||||
if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode( INST_LAPPEND_LIST_STK, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4(INST_LAPPEND_LIST, localIndex, envPtr);
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
TclEmitOpcode( INST_LAPPEND_LIST_ARRAY_STK, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4(INST_LAPPEND_LIST_ARRAY, localIndex,envPtr);
|
||||
}
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1506,7 +1478,7 @@ TclCompileLreplaceCmd(
|
||||
Tcl_Token *tokenPtr, *listTokenPtr;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Obj *tmpObj;
|
||||
int idx1, idx2, i, offset;
|
||||
int idx1, idx2, i, offset, offset2;
|
||||
|
||||
if (parsePtr->numWords < 4) {
|
||||
return TCL_ERROR;
|
||||
@@ -1612,12 +1584,18 @@ TclCompileLreplaceCmd(
|
||||
TclEmitOpcode( INST_GT, envPtr);
|
||||
offset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
offset2 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr);
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
|
||||
"list doesn't contain element %d", idx1), NULL), envPtr);
|
||||
CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
|
||||
Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
|
||||
envPtr->codeStart + offset + 1);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
|
||||
envPtr->codeStart + offset2 + 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
@@ -1662,12 +1640,18 @@ TclCompileLreplaceCmd(
|
||||
TclEmitOpcode( INST_GT, envPtr);
|
||||
offset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
offset2 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
|
||||
"list doesn't contain element %d", idx1), NULL), envPtr);
|
||||
CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
|
||||
Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
|
||||
envPtr->codeStart + offset + 1);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
|
||||
envPtr->codeStart + offset2 + 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
@@ -2060,7 +2044,7 @@ TclCompileNamespaceUpvarCmd(
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
|
||||
int isScalar, localIndex, numWords, i;
|
||||
int localIndex, numWords, i;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
|
||||
if (envPtr->procPtr == NULL) {
|
||||
@@ -2095,10 +2079,8 @@ TclCompileNamespaceUpvarCmd(
|
||||
localTokenPtr = TokenAfter(otherTokenPtr);
|
||||
|
||||
CompileWord(envPtr, otherTokenPtr, interp, i);
|
||||
PushVarNameWord(interp, localTokenPtr, envPtr, 0,
|
||||
&localIndex, &isScalar, i+1);
|
||||
|
||||
if ((localIndex < 0) || !isScalar) {
|
||||
localIndex = LocalScalarFromToken(localTokenPtr, envPtr);
|
||||
if (localIndex < 0) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclEmitInstInt4( INST_NSUPVAR, localIndex, envPtr);
|
||||
@@ -2284,7 +2266,7 @@ TclCompileRegexpCmd(
|
||||
* converted pattern as a literal.
|
||||
*/
|
||||
|
||||
if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact)
|
||||
if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact, NULL)
|
||||
== TCL_OK) {
|
||||
simple = 1;
|
||||
PushLiteral(envPtr, Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
|
||||
@@ -2376,7 +2358,7 @@ TclCompileRegsubCmd(
|
||||
Tcl_Obj *patternObj = NULL, *replacementObj = NULL;
|
||||
Tcl_DString pattern;
|
||||
const char *bytes;
|
||||
int len, exact, result = TCL_ERROR;
|
||||
int len, exact, quantified, result = TCL_ERROR;
|
||||
|
||||
if (parsePtr->numWords < 5 || parsePtr->numWords > 6) {
|
||||
return TCL_ERROR;
|
||||
@@ -2436,7 +2418,8 @@ TclCompileRegsubCmd(
|
||||
*/
|
||||
|
||||
bytes = Tcl_GetStringFromObj(patternObj, &len);
|
||||
if (TclReToGlob(NULL, bytes, len, &pattern, &exact) != TCL_OK || exact) {
|
||||
if (TclReToGlob(NULL, bytes, len, &pattern, &exact, &quantified)
|
||||
!= TCL_OK || exact || quantified) {
|
||||
goto done;
|
||||
}
|
||||
bytes = Tcl_DStringValue(&pattern);
|
||||
@@ -2778,7 +2761,7 @@ TclCompileUpvarCmd(
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
|
||||
int isScalar, localIndex, numWords, i;
|
||||
int localIndex, numWords, i;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
@@ -2841,10 +2824,8 @@ TclCompileUpvarCmd(
|
||||
localTokenPtr = TokenAfter(otherTokenPtr);
|
||||
|
||||
CompileWord(envPtr, otherTokenPtr, interp, i);
|
||||
PushVarNameWord(interp, localTokenPtr, envPtr, 0,
|
||||
&localIndex, &isScalar, i+1);
|
||||
|
||||
if ((localIndex < 0) || !isScalar) {
|
||||
localIndex = LocalScalarFromToken(localTokenPtr, envPtr);
|
||||
if (localIndex < 0) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclEmitInstInt4( INST_UPVAR, localIndex, envPtr);
|
||||
|
||||
+108
-6
@@ -28,6 +28,9 @@ static void FreeJumptableInfo(ClientData clientData);
|
||||
static void PrintJumptableInfo(ClientData clientData,
|
||||
Tcl_Obj *appendObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static void DisassembleJumptableInfo(ClientData clientData,
|
||||
Tcl_Obj *dictObj, ByteCode *codePtr,
|
||||
unsigned int pcOffset);
|
||||
static int CompileAssociativeBinaryOpCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, const char *identity,
|
||||
int instruction, CompileEnv *envPtr);
|
||||
@@ -72,7 +75,8 @@ const AuxDataType tclJumptableInfoType = {
|
||||
"JumptableInfo", /* name */
|
||||
DupJumptableInfo, /* dupProc */
|
||||
FreeJumptableInfo, /* freeProc */
|
||||
PrintJumptableInfo /* printProc */
|
||||
PrintJumptableInfo, /* printProc */
|
||||
DisassembleJumptableInfo /* disassembleProc */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -268,6 +272,78 @@ TclCompileSetCmd(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileStringCatCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
Tcl_Parse *parsePtr, /* Points to a parse structure for the command
|
||||
* created by Tcl_ParseCommand. */
|
||||
Command *cmdPtr, /* Points to defintion of command being
|
||||
* compiled. */
|
||||
CompileEnv *envPtr) /* Holds resulting instructions. */
|
||||
{
|
||||
int i, numWords = parsePtr->numWords, numArgs;
|
||||
Tcl_Token *wordTokenPtr;
|
||||
Tcl_Obj *obj, *folded;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
|
||||
/* Trivial case, no arg */
|
||||
|
||||
if (numWords<2) {
|
||||
PushStringLiteral(envPtr, "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/* General case: issue CONCAT1's (by chunks of 254 if needed), folding
|
||||
contiguous constants along the way */
|
||||
|
||||
numArgs = 0;
|
||||
folded = NULL;
|
||||
wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
for (i = 1; i < numWords; i++) {
|
||||
obj = Tcl_NewObj();
|
||||
if (TclWordKnownAtCompileTime(wordTokenPtr, obj)) {
|
||||
if (folded) {
|
||||
Tcl_AppendObjToObj(folded, obj);
|
||||
Tcl_DecrRefCount(obj);
|
||||
} else {
|
||||
folded = obj;
|
||||
}
|
||||
} else {
|
||||
Tcl_DecrRefCount(obj);
|
||||
if (folded) {
|
||||
int len;
|
||||
const char *bytes = Tcl_GetStringFromObj(folded, &len);
|
||||
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
Tcl_DecrRefCount(folded);
|
||||
folded = NULL;
|
||||
numArgs ++;
|
||||
}
|
||||
CompileWord(envPtr, wordTokenPtr, interp, i);
|
||||
numArgs ++;
|
||||
if (numArgs >= 254) { /* 254 to take care of the possible +1 of "folded" above */
|
||||
TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
|
||||
numArgs = 1; /* concat pushes 1 obj, the result */
|
||||
}
|
||||
}
|
||||
wordTokenPtr = TokenAfter(wordTokenPtr);
|
||||
}
|
||||
if (folded) {
|
||||
int len;
|
||||
const char *bytes = Tcl_GetStringFromObj(folded, &len);
|
||||
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
Tcl_DecrRefCount(folded);
|
||||
folded = NULL;
|
||||
numArgs ++;
|
||||
}
|
||||
if (numArgs > 1) {
|
||||
TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringCmpCmd(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -1088,7 +1164,7 @@ TclCompileStringTrimLCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET));
|
||||
PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
|
||||
}
|
||||
OP( STR_TRIM_LEFT);
|
||||
return TCL_OK;
|
||||
@@ -1116,7 +1192,7 @@ TclCompileStringTrimRCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET));
|
||||
PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
|
||||
}
|
||||
OP( STR_TRIM_RIGHT);
|
||||
return TCL_OK;
|
||||
@@ -1144,7 +1220,7 @@ TclCompileStringTrimCmd(
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET));
|
||||
PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
|
||||
}
|
||||
OP( STR_TRIM);
|
||||
return TCL_OK;
|
||||
@@ -2019,7 +2095,7 @@ IssueSwitchChainedTests(
|
||||
*/
|
||||
|
||||
if (TclReToGlob(NULL, bodyToken[i]->start,
|
||||
bodyToken[i]->size, &ds, &exact) == TCL_OK) {
|
||||
bodyToken[i]->size, &ds, &exact, NULL) == TCL_OK){
|
||||
simple = 1;
|
||||
PushLiteral(envPtr, Tcl_DStringValue(&ds),
|
||||
Tcl_DStringLength(&ds));
|
||||
@@ -2369,11 +2445,13 @@ IssueSwitchJumpTable(
|
||||
* DupJumptableInfo: a copy of the jump-table
|
||||
* FreeJumptableInfo: none
|
||||
* PrintJumptableInfo: none
|
||||
* DisassembleJumptableInfo: none
|
||||
*
|
||||
* Side effects:
|
||||
* DupJumptableInfo: allocates memory
|
||||
* FreeJumptableInfo: releases memory
|
||||
* PrintJumptableInfo: none
|
||||
* DisassembleJumptableInfo: none
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -2436,6 +2514,30 @@ PrintJumptableInfo(
|
||||
keyPtr, pcOffset + offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
DisassembleJumptableInfo(
|
||||
ClientData clientData,
|
||||
Tcl_Obj *dictObj,
|
||||
ByteCode *codePtr,
|
||||
unsigned int pcOffset)
|
||||
{
|
||||
register JumptableInfo *jtPtr = clientData;
|
||||
Tcl_Obj *mapping = Tcl_NewObj();
|
||||
Tcl_HashEntry *hPtr;
|
||||
Tcl_HashSearch search;
|
||||
const char *keyPtr;
|
||||
int offset;
|
||||
|
||||
hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search);
|
||||
for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) {
|
||||
keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr);
|
||||
offset = PTR2INT(Tcl_GetHashValue(hPtr));
|
||||
Tcl_DictObjPut(NULL, mapping, Tcl_NewStringObj(keyPtr, -1),
|
||||
Tcl_NewIntObj(offset));
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("mapping", -1), mapping);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2966,6 +3068,7 @@ IssueTryClausesInstructions(
|
||||
if (!handlerTokens[i]) {
|
||||
forwardsNeedFixing = 1;
|
||||
JUMP4( JUMP, forwardsToFix[i]);
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
} else {
|
||||
int dontChangeOptions;
|
||||
|
||||
@@ -3679,7 +3782,6 @@ TclCompileWhileCmd(
|
||||
}
|
||||
SetLineInformation(1);
|
||||
TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
|
||||
TclClearNumConversion(envPtr);
|
||||
|
||||
jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
|
||||
if (jumpDist > 127) {
|
||||
|
||||
+40
-43
@@ -365,7 +365,7 @@ static const unsigned char prec[] = {
|
||||
0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
/* Unary operator lexemes */
|
||||
PREC_UNARY, /* UNARY_PLUS */
|
||||
PREC_UNARY, /* UNARY_MINUS */
|
||||
@@ -420,7 +420,7 @@ static const unsigned char instruction[] = {
|
||||
0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0,
|
||||
/* Unary operator lexemes */
|
||||
INST_UPLUS, /* UNARY_PLUS */
|
||||
INST_UMINUS, /* UNARY_MINUS */
|
||||
@@ -488,7 +488,7 @@ static const unsigned char Lexeme[] = {
|
||||
|
||||
typedef struct JumpList {
|
||||
JumpFixup jump; /* Pass this argument to matching calls of
|
||||
* TclEmitForwardJump() and
|
||||
* TclEmitForwardJump() and
|
||||
* TclFixupForwardJump(). */
|
||||
struct JumpList *next; /* Point to next item on the stack */
|
||||
} JumpList;
|
||||
@@ -838,7 +838,7 @@ ParseExpr(
|
||||
|
||||
switch (lexeme) {
|
||||
case NUMBER:
|
||||
case BOOLEAN:
|
||||
case BOOLEAN:
|
||||
/*
|
||||
* TODO: Consider using a dict or hash to collapse all
|
||||
* duplicate literals into a single representative value.
|
||||
@@ -861,7 +861,7 @@ ParseExpr(
|
||||
start += scanned;
|
||||
numBytes -= scanned;
|
||||
continue;
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1324,7 +1324,7 @@ ParseExpr(
|
||||
nodePtr->mark = MARK_LEFT;
|
||||
nodePtr->left = complete;
|
||||
|
||||
/*
|
||||
/*
|
||||
* The COMMA operator cannot be optimized, since the function
|
||||
* needs all of its arguments, and optimization would reduce the
|
||||
* number. Other binary operators root constant expressions when
|
||||
@@ -1546,7 +1546,7 @@ ConvertTreeToTokens(
|
||||
* Tcl_ParseExpr() we do not change them now. Internally, we can
|
||||
* do better.
|
||||
*/
|
||||
|
||||
|
||||
int toCopy = tokenPtr->numComponents + 1;
|
||||
|
||||
if (tokenPtr->numComponents == tokenPtr[1].numComponents + 1) {
|
||||
@@ -1562,7 +1562,7 @@ ConvertTreeToTokens(
|
||||
subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
|
||||
parsePtr->numTokens += toCopy;
|
||||
} else {
|
||||
/*
|
||||
/*
|
||||
* Multiple element word. Create a TCL_TOKEN_SUB_EXPR token to
|
||||
* lead, with fields initialized from the leading token, then
|
||||
* copy entire set of word tokens.
|
||||
@@ -1611,7 +1611,7 @@ ConvertTreeToTokens(
|
||||
case COMMA:
|
||||
case COLON:
|
||||
|
||||
/*
|
||||
/*
|
||||
* Historical practice has been to have no Tcl_Tokens for
|
||||
* these operators.
|
||||
*/
|
||||
@@ -1747,7 +1747,7 @@ ConvertTreeToTokens(
|
||||
/*
|
||||
* Before we leave this node/operator/subexpression for the
|
||||
* last time, finish up its tokens....
|
||||
*
|
||||
*
|
||||
* Our current position scanning the string is where the
|
||||
* substring for the subexpression ends.
|
||||
*/
|
||||
@@ -1967,7 +1967,7 @@ ParseLexeme(
|
||||
|
||||
case 'i':
|
||||
if ((numBytes > 1) && (start[1] == 'n')
|
||||
&& ((numBytes == 2) || !isalpha(UCHAR(start[2])))) {
|
||||
&& ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
|
||||
/*
|
||||
* Must make this check so we can tell the difference between the
|
||||
* "in" operator and the "int" function name and the "infinity"
|
||||
@@ -1981,14 +1981,15 @@ ParseLexeme(
|
||||
|
||||
case 'e':
|
||||
if ((numBytes > 1) && (start[1] == 'q')
|
||||
&& ((numBytes == 2) || !isalpha(UCHAR(start[2])))) {
|
||||
&& ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
|
||||
*lexemePtr = STREQ;
|
||||
return 2;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
if ((numBytes > 1) && ((numBytes == 2) || !isalpha(UCHAR(start[2])))) {
|
||||
if ((numBytes > 1)
|
||||
&& ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
|
||||
switch (start[1]) {
|
||||
case 'e':
|
||||
*lexemePtr = STRNEQ;
|
||||
@@ -2003,9 +2004,8 @@ ParseLexeme(
|
||||
literal = Tcl_NewObj();
|
||||
if (TclParseNumber(NULL, literal, NULL, start, numBytes, &end,
|
||||
TCL_PARSE_NO_WHITESPACE) == TCL_OK) {
|
||||
if (end < start + numBytes && !isalnum(UCHAR(*end))
|
||||
&& UCHAR(*end) != '_') {
|
||||
|
||||
if (end < start + numBytes && !TclIsBareword(*end)) {
|
||||
|
||||
number:
|
||||
TclInitStringRep(literal, start, end-start);
|
||||
*lexemePtr = NUMBER;
|
||||
@@ -2029,9 +2029,9 @@ ParseLexeme(
|
||||
const char *p = start;
|
||||
|
||||
while (p < end) {
|
||||
if (!isalnum(UCHAR(*p++))) {
|
||||
if (!TclIsBareword(*p++)) {
|
||||
/*
|
||||
* The number has non-bareword characters, so we
|
||||
* The number has non-bareword characters, so we
|
||||
* must treat it as a number.
|
||||
*/
|
||||
goto number;
|
||||
@@ -2054,33 +2054,30 @@ ParseLexeme(
|
||||
}
|
||||
}
|
||||
|
||||
if (Tcl_UtfCharComplete(start, numBytes)) {
|
||||
scanned = Tcl_UtfToUniChar(start, &ch);
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
/*
|
||||
* We reject leading underscores in bareword. No sensible reason why.
|
||||
* Might be inspired by reserved identifier rules in C, which of course
|
||||
* have no direct relevance here.
|
||||
*/
|
||||
|
||||
memcpy(utfBytes, start, (size_t) numBytes);
|
||||
utfBytes[numBytes] = '\0';
|
||||
scanned = Tcl_UtfToUniChar(utfBytes, &ch);
|
||||
}
|
||||
if (!isalnum(UCHAR(ch))) {
|
||||
if (!TclIsBareword(*start) || *start == '_') {
|
||||
if (Tcl_UtfCharComplete(start, numBytes)) {
|
||||
scanned = Tcl_UtfToUniChar(start, &ch);
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
|
||||
memcpy(utfBytes, start, (size_t) numBytes);
|
||||
utfBytes[numBytes] = '\0';
|
||||
scanned = Tcl_UtfToUniChar(utfBytes, &ch);
|
||||
}
|
||||
*lexemePtr = INVALID;
|
||||
Tcl_DecrRefCount(literal);
|
||||
return scanned;
|
||||
}
|
||||
end = start;
|
||||
while (isalnum(UCHAR(ch)) || (UCHAR(ch) == '_')) {
|
||||
end += scanned;
|
||||
numBytes -= scanned;
|
||||
if (Tcl_UtfCharComplete(end, numBytes)) {
|
||||
scanned = Tcl_UtfToUniChar(end, &ch);
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
|
||||
memcpy(utfBytes, end, (size_t) numBytes);
|
||||
utfBytes[numBytes] = '\0';
|
||||
scanned = Tcl_UtfToUniChar(utfBytes, &ch);
|
||||
}
|
||||
while (numBytes && TclIsBareword(*end)) {
|
||||
end += 1;
|
||||
numBytes -= 1;
|
||||
}
|
||||
*lexemePtr = BAREWORD;
|
||||
if (literalPtr) {
|
||||
@@ -2098,7 +2095,7 @@ ParseLexeme(
|
||||
* TclCompileExpr --
|
||||
*
|
||||
* This procedure compiles a string containing a Tcl expression into Tcl
|
||||
* bytecodes.
|
||||
* bytecodes.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -2333,7 +2330,7 @@ CompileExprTree(
|
||||
* Use the numWords count we've kept to invoke the function
|
||||
* command with the correct number of arguments.
|
||||
*/
|
||||
|
||||
|
||||
if (numWords < 255) {
|
||||
TclEmitInvoke(envPtr, INST_INVOKE_STK1, numWords);
|
||||
} else {
|
||||
@@ -2427,7 +2424,7 @@ CompileExprTree(
|
||||
const char *bytes = TclGetStringFromObj(literal, &length);
|
||||
int index = TclRegisterNewLiteral(envPtr, bytes, length);
|
||||
Tcl_Obj *objPtr = TclFetchLiteral(envPtr, index);
|
||||
|
||||
|
||||
if ((objPtr->typePtr == NULL) && (literal->typePtr != NULL)) {
|
||||
/*
|
||||
* Would like to do this:
|
||||
@@ -2570,7 +2567,7 @@ TclSingleOpCmd(
|
||||
*
|
||||
* TclSortingOpCmd --
|
||||
* Implements the commands:
|
||||
* <, <=, >, >=, ==, eq
|
||||
* <, <=, >, >=, ==, eq
|
||||
* in the ::tcl::mathop namespace. These commands are defined for
|
||||
* arbitrary number of arguments by computing the AND of the base
|
||||
* operator applied to all neighbor argument pairs.
|
||||
|
||||
+24
-800
@@ -55,9 +55,9 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
/* Name Bytes stackEffect #Opnds Operand types */
|
||||
{"done", 1, -1, 0, {OPERAND_NONE}},
|
||||
/* Finish ByteCode execution and return stktop (top stack item) */
|
||||
{"push1", 2, +1, 1, {OPERAND_UINT1}},
|
||||
{"push1", 2, +1, 1, {OPERAND_LIT1}},
|
||||
/* Push object at ByteCode objArray[op1] */
|
||||
{"push4", 5, +1, 1, {OPERAND_UINT4}},
|
||||
{"push4", 5, +1, 1, {OPERAND_LIT4}},
|
||||
/* Push object at ByteCode objArray[op4] */
|
||||
{"pop", 1, -1, 0, {OPERAND_NONE}},
|
||||
/* Pop the topmost stack object */
|
||||
@@ -125,17 +125,17 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
{"incrStkImm", 2, 0, 1, {OPERAND_INT1}},
|
||||
/* Incr general variable; unparsed name is top, amount is op1 */
|
||||
|
||||
{"jump1", 2, 0, 1, {OPERAND_INT1}},
|
||||
{"jump1", 2, 0, 1, {OPERAND_OFFSET1}},
|
||||
/* Jump relative to (pc + op1) */
|
||||
{"jump4", 5, 0, 1, {OPERAND_INT4}},
|
||||
{"jump4", 5, 0, 1, {OPERAND_OFFSET4}},
|
||||
/* Jump relative to (pc + op4) */
|
||||
{"jumpTrue1", 2, -1, 1, {OPERAND_INT1}},
|
||||
{"jumpTrue1", 2, -1, 1, {OPERAND_OFFSET1}},
|
||||
/* Jump relative to (pc + op1) if stktop expr object is true */
|
||||
{"jumpTrue4", 5, -1, 1, {OPERAND_INT4}},
|
||||
{"jumpTrue4", 5, -1, 1, {OPERAND_OFFSET4}},
|
||||
/* Jump relative to (pc + op4) if stktop expr object is true */
|
||||
{"jumpFalse1", 2, -1, 1, {OPERAND_INT1}},
|
||||
{"jumpFalse1", 2, -1, 1, {OPERAND_OFFSET1}},
|
||||
/* Jump relative to (pc + op1) if stktop expr object is false */
|
||||
{"jumpFalse4", 5, -1, 1, {OPERAND_INT4}},
|
||||
{"jumpFalse4", 5, -1, 1, {OPERAND_OFFSET4}},
|
||||
/* Jump relative to (pc + op4) if stktop expr object is false */
|
||||
|
||||
{"lor", 1, -1, 0, {OPERAND_NONE}},
|
||||
@@ -298,7 +298,7 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
/* List Index: push (lindex stktop op4) */
|
||||
{"listRangeImm", 9, 0, 2, {OPERAND_IDX4, OPERAND_IDX4}},
|
||||
/* List Range: push (lrange stktop op4 op4) */
|
||||
{"startCommand", 9, 0, 2, {OPERAND_INT4,OPERAND_UINT4}},
|
||||
{"startCommand", 9, 0, 2, {OPERAND_OFFSET4, OPERAND_UINT4}},
|
||||
/* Start of bytecoded command: op is the length of the cmd's code, op2
|
||||
* is number of commands here */
|
||||
|
||||
@@ -650,6 +650,19 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
* satisfy the class check (standard definition of "all").
|
||||
* Stack: ... stringValue => ... boolean */
|
||||
|
||||
{"lappendList", 5, 0, 1, {OPERAND_LVT4}},
|
||||
/* Lappend list to scalar variable at op4 in frame.
|
||||
* Stack: ... list => ... listVarContents */
|
||||
{"lappendListArray", 5, -1, 1, {OPERAND_LVT4}},
|
||||
/* Lappend list to array element; array at op4.
|
||||
* Stack: ... elem list => ... listVarContents */
|
||||
{"lappendListArrayStk", 1, -2, 0, {OPERAND_NONE}},
|
||||
/* Lappend list to array element.
|
||||
* Stack: ... arrayName elem list => ... listVarContents */
|
||||
{"lappendListStk", 1, -1, 0, {OPERAND_NONE}},
|
||||
/* Lappend list to general variable.
|
||||
* Stack: ... varName list => ... listVarContents */
|
||||
|
||||
{NULL, 0, 0, 0, {OPERAND_NONE}}
|
||||
};
|
||||
|
||||
@@ -679,11 +692,6 @@ static void RegisterAuxDataType(const AuxDataType *typePtr);
|
||||
static int SetByteCodeFromAny(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
static void StartExpanding(CompileEnv *envPtr);
|
||||
static int FormatInstruction(ByteCode *codePtr,
|
||||
const unsigned char *pc, Tcl_Obj *bufferObj);
|
||||
static void PrintSourceToObj(Tcl_Obj *appendObj,
|
||||
const char *stringPtr, int maxChars);
|
||||
static void UpdateStringOfInstName(Tcl_Obj *objPtr);
|
||||
|
||||
/*
|
||||
* TIP #280: Helper for building the per-word line information of all compiled
|
||||
@@ -721,19 +729,6 @@ static const Tcl_ObjType substCodeType = {
|
||||
NULL, /* setFromAnyProc */
|
||||
};
|
||||
|
||||
/*
|
||||
* The structure below defines an instruction name Tcl object to allow
|
||||
* reporting of inner contexts in errorstack without string allocation.
|
||||
*/
|
||||
|
||||
static const Tcl_ObjType tclInstNameType = {
|
||||
"instname", /* name */
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
UpdateStringOfInstName, /* updateStringProc */
|
||||
NULL, /* setFromAnyProc */
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper macros.
|
||||
*/
|
||||
@@ -4347,10 +4342,11 @@ TclInitAuxDataTypeTable(void)
|
||||
Tcl_InitHashTable(&auxDataTypeTable, TCL_STRING_KEYS);
|
||||
|
||||
/*
|
||||
* There are only three AuxData types at this time, so register them here.
|
||||
* There are only four AuxData types at this time, so register them here.
|
||||
*/
|
||||
|
||||
RegisterAuxDataType(&tclForeachInfoType);
|
||||
RegisterAuxDataType(&tclNewForeachInfoType);
|
||||
RegisterAuxDataType(&tclJumptableInfoType);
|
||||
RegisterAuxDataType(&tclDictUpdateInfoType);
|
||||
}
|
||||
@@ -4583,778 +4579,6 @@ EncodeCmdLocMap(
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPrintByteCodeObj --
|
||||
*
|
||||
* This procedure prints ("disassembles") the instructions of a bytecode
|
||||
* object to stdout.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TclPrintByteCodeObj(
|
||||
Tcl_Interp *interp, /* Used only for Tcl_GetStringFromObj. */
|
||||
Tcl_Obj *objPtr) /* The bytecode object to disassemble. */
|
||||
{
|
||||
Tcl_Obj *bufPtr = TclDisassembleByteCodeObj(objPtr);
|
||||
|
||||
fprintf(stdout, "\n%s", TclGetString(bufPtr));
|
||||
Tcl_DecrRefCount(bufPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPrintInstruction --
|
||||
*
|
||||
* This procedure prints ("disassembles") one instruction from a bytecode
|
||||
* object to stdout.
|
||||
*
|
||||
* Results:
|
||||
* Returns the length in bytes of the current instruiction.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclPrintInstruction(
|
||||
ByteCode *codePtr, /* Bytecode containing the instruction. */
|
||||
const unsigned char *pc) /* Points to first byte of instruction. */
|
||||
{
|
||||
Tcl_Obj *bufferObj;
|
||||
int numBytes;
|
||||
|
||||
TclNewObj(bufferObj);
|
||||
numBytes = FormatInstruction(codePtr, pc, bufferObj);
|
||||
fprintf(stdout, "%s", TclGetString(bufferObj));
|
||||
Tcl_DecrRefCount(bufferObj);
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPrintObject --
|
||||
*
|
||||
* This procedure prints up to a specified number of characters from the
|
||||
* argument Tcl object's string representation to a specified file.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Outputs characters to the specified file.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TclPrintObject(
|
||||
FILE *outFile, /* The file to print the source to. */
|
||||
Tcl_Obj *objPtr, /* Points to the Tcl object whose string
|
||||
* representation should be printed. */
|
||||
int maxChars) /* Maximum number of chars to print. */
|
||||
{
|
||||
char *bytes;
|
||||
int length;
|
||||
|
||||
bytes = Tcl_GetStringFromObj(objPtr, &length);
|
||||
TclPrintSource(outFile, bytes, TclMin(length, maxChars));
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclPrintSource --
|
||||
*
|
||||
* This procedure prints up to a specified number of characters from the
|
||||
* argument string to a specified file. It tries to produce legible
|
||||
* output by adding backslashes as necessary.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Outputs characters to the specified file.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TclPrintSource(
|
||||
FILE *outFile, /* The file to print the source to. */
|
||||
const char *stringPtr, /* The string to print. */
|
||||
int maxChars) /* Maximum number of chars to print. */
|
||||
{
|
||||
Tcl_Obj *bufferObj;
|
||||
|
||||
TclNewObj(bufferObj);
|
||||
PrintSourceToObj(bufferObj, stringPtr, maxChars);
|
||||
fprintf(outFile, "%s", TclGetString(bufferObj));
|
||||
Tcl_DecrRefCount(bufferObj);
|
||||
}
|
||||
#endif /* TCL_COMPILE_DEBUG */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclDisassembleByteCodeObj --
|
||||
*
|
||||
* Given an object which is of bytecode type, return a disassembled
|
||||
* version of the bytecode (in a new refcount 0 object). No guarantees
|
||||
* are made about the details of the contents of the result.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *
|
||||
TclDisassembleByteCodeObj(
|
||||
Tcl_Obj *objPtr) /* The bytecode object to disassemble. */
|
||||
{
|
||||
ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
unsigned char *codeStart, *codeLimit, *pc;
|
||||
unsigned char *codeDeltaNext, *codeLengthNext;
|
||||
unsigned char *srcDeltaNext, *srcLengthNext;
|
||||
int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i;
|
||||
Interp *iPtr = (Interp *) *codePtr->interpHandle;
|
||||
Tcl_Obj *bufferObj;
|
||||
char ptrBuf1[20], ptrBuf2[20];
|
||||
|
||||
TclNewObj(bufferObj);
|
||||
if (codePtr->refCount <= 0) {
|
||||
return bufferObj; /* Already freed. */
|
||||
}
|
||||
|
||||
codeStart = codePtr->codeStart;
|
||||
codeLimit = codeStart + codePtr->numCodeBytes;
|
||||
numCmds = codePtr->numCommands;
|
||||
|
||||
/*
|
||||
* Print header lines describing the ByteCode.
|
||||
*/
|
||||
|
||||
sprintf(ptrBuf1, "%p", codePtr);
|
||||
sprintf(ptrBuf2, "%p", iPtr);
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
"ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n",
|
||||
ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2,
|
||||
iPtr->compileEpoch);
|
||||
Tcl_AppendToObj(bufferObj, " Source ", -1);
|
||||
PrintSourceToObj(bufferObj, codePtr->source,
|
||||
TclMin(codePtr->numSrcBytes, 55));
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
"\n Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n",
|
||||
numCmds, codePtr->numSrcBytes, codePtr->numCodeBytes,
|
||||
codePtr->numLitObjects, codePtr->numAuxDataItems,
|
||||
codePtr->maxStackDepth,
|
||||
#ifdef TCL_COMPILE_STATS
|
||||
codePtr->numSrcBytes?
|
||||
codePtr->structureSize/(float)codePtr->numSrcBytes :
|
||||
#endif
|
||||
0.0);
|
||||
|
||||
#ifdef TCL_COMPILE_STATS
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
" Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n",
|
||||
(unsigned long) codePtr->structureSize,
|
||||
(unsigned long) (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time)),
|
||||
codePtr->numCodeBytes,
|
||||
(unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)),
|
||||
(unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)),
|
||||
(unsigned long) (codePtr->numAuxDataItems * sizeof(AuxData)),
|
||||
codePtr->numCmdLocBytes);
|
||||
#endif /* TCL_COMPILE_STATS */
|
||||
|
||||
/*
|
||||
* If the ByteCode is the compiled body of a Tcl procedure, print
|
||||
* information about that procedure. Note that we don't know the
|
||||
* procedure's name since ByteCode's can be shared among procedures.
|
||||
*/
|
||||
|
||||
if (codePtr->procPtr != NULL) {
|
||||
Proc *procPtr = codePtr->procPtr;
|
||||
int numCompiledLocals = procPtr->numCompiledLocals;
|
||||
|
||||
sprintf(ptrBuf1, "%p", procPtr);
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
" Proc 0x%s, refCt %d, args %d, compiled locals %d\n",
|
||||
ptrBuf1, procPtr->refCount, procPtr->numArgs,
|
||||
numCompiledLocals);
|
||||
if (numCompiledLocals > 0) {
|
||||
CompiledLocal *localPtr = procPtr->firstLocalPtr;
|
||||
|
||||
for (i = 0; i < numCompiledLocals; i++) {
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
" slot %d%s%s%s%s%s%s", i,
|
||||
(localPtr->flags & (VAR_ARRAY|VAR_LINK)) ? "" : ", scalar",
|
||||
(localPtr->flags & VAR_ARRAY) ? ", array" : "",
|
||||
(localPtr->flags & VAR_LINK) ? ", link" : "",
|
||||
(localPtr->flags & VAR_ARGUMENT) ? ", arg" : "",
|
||||
(localPtr->flags & VAR_TEMPORARY) ? ", temp" : "",
|
||||
(localPtr->flags & VAR_RESOLVED) ? ", resolved" : "");
|
||||
if (TclIsVarTemporary(localPtr)) {
|
||||
Tcl_AppendToObj(bufferObj, "\n", -1);
|
||||
} else {
|
||||
Tcl_AppendPrintfToObj(bufferObj, ", \"%s\"\n",
|
||||
localPtr->name);
|
||||
}
|
||||
localPtr = localPtr->nextPtr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the ExceptionRange array.
|
||||
*/
|
||||
|
||||
if (codePtr->numExceptRanges > 0) {
|
||||
Tcl_AppendPrintfToObj(bufferObj, " Exception ranges %d, depth %d:\n",
|
||||
codePtr->numExceptRanges, codePtr->maxExceptDepth);
|
||||
for (i = 0; i < codePtr->numExceptRanges; i++) {
|
||||
ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i];
|
||||
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
" %d: level %d, %s, pc %d-%d, ",
|
||||
i, rangePtr->nestingLevel,
|
||||
(rangePtr->type==LOOP_EXCEPTION_RANGE ? "loop" : "catch"),
|
||||
rangePtr->codeOffset,
|
||||
(rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
|
||||
switch (rangePtr->type) {
|
||||
case LOOP_EXCEPTION_RANGE:
|
||||
Tcl_AppendPrintfToObj(bufferObj, "continue %d, break %d\n",
|
||||
rangePtr->continueOffset, rangePtr->breakOffset);
|
||||
break;
|
||||
case CATCH_EXCEPTION_RANGE:
|
||||
Tcl_AppendPrintfToObj(bufferObj, "catch %d\n",
|
||||
rangePtr->catchOffset);
|
||||
break;
|
||||
default:
|
||||
Tcl_Panic("TclDisassembleByteCodeObj: bad ExceptionRange type %d",
|
||||
rangePtr->type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If there were no commands (e.g., an expression or an empty string was
|
||||
* compiled), just print all instructions and return.
|
||||
*/
|
||||
|
||||
if (numCmds == 0) {
|
||||
pc = codeStart;
|
||||
while (pc < codeLimit) {
|
||||
Tcl_AppendToObj(bufferObj, " ", -1);
|
||||
pc += FormatInstruction(codePtr, pc, bufferObj);
|
||||
}
|
||||
return bufferObj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print table showing the code offset, source offset, and source length
|
||||
* for each command. These are encoded as a sequence of bytes.
|
||||
*/
|
||||
|
||||
Tcl_AppendPrintfToObj(bufferObj, " Commands %d:", numCmds);
|
||||
codeDeltaNext = codePtr->codeDeltaStart;
|
||||
codeLengthNext = codePtr->codeLengthStart;
|
||||
srcDeltaNext = codePtr->srcDeltaStart;
|
||||
srcLengthNext = codePtr->srcLengthStart;
|
||||
codeOffset = srcOffset = 0;
|
||||
for (i = 0; i < numCmds; i++) {
|
||||
if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) {
|
||||
codeDeltaNext++;
|
||||
delta = TclGetInt4AtPtr(codeDeltaNext);
|
||||
codeDeltaNext += 4;
|
||||
} else {
|
||||
delta = TclGetInt1AtPtr(codeDeltaNext);
|
||||
codeDeltaNext++;
|
||||
}
|
||||
codeOffset += delta;
|
||||
|
||||
if ((unsigned) *codeLengthNext == (unsigned) 0xFF) {
|
||||
codeLengthNext++;
|
||||
codeLen = TclGetInt4AtPtr(codeLengthNext);
|
||||
codeLengthNext += 4;
|
||||
} else {
|
||||
codeLen = TclGetInt1AtPtr(codeLengthNext);
|
||||
codeLengthNext++;
|
||||
}
|
||||
|
||||
if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) {
|
||||
srcDeltaNext++;
|
||||
delta = TclGetInt4AtPtr(srcDeltaNext);
|
||||
srcDeltaNext += 4;
|
||||
} else {
|
||||
delta = TclGetInt1AtPtr(srcDeltaNext);
|
||||
srcDeltaNext++;
|
||||
}
|
||||
srcOffset += delta;
|
||||
|
||||
if ((unsigned) *srcLengthNext == (unsigned) 0xFF) {
|
||||
srcLengthNext++;
|
||||
srcLen = TclGetInt4AtPtr(srcLengthNext);
|
||||
srcLengthNext += 4;
|
||||
} else {
|
||||
srcLen = TclGetInt1AtPtr(srcLengthNext);
|
||||
srcLengthNext++;
|
||||
}
|
||||
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%s%4d: pc %d-%d, src %d-%d",
|
||||
((i % 2)? " " : "\n "),
|
||||
(i+1), codeOffset, (codeOffset + codeLen - 1),
|
||||
srcOffset, (srcOffset + srcLen - 1));
|
||||
}
|
||||
if (numCmds > 0) {
|
||||
Tcl_AppendToObj(bufferObj, "\n", -1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print each instruction. If the instruction corresponds to the start of
|
||||
* a command, print the command's source. Note that we don't need the code
|
||||
* length here.
|
||||
*/
|
||||
|
||||
codeDeltaNext = codePtr->codeDeltaStart;
|
||||
srcDeltaNext = codePtr->srcDeltaStart;
|
||||
srcLengthNext = codePtr->srcLengthStart;
|
||||
codeOffset = srcOffset = 0;
|
||||
pc = codeStart;
|
||||
for (i = 0; i < numCmds; i++) {
|
||||
if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) {
|
||||
codeDeltaNext++;
|
||||
delta = TclGetInt4AtPtr(codeDeltaNext);
|
||||
codeDeltaNext += 4;
|
||||
} else {
|
||||
delta = TclGetInt1AtPtr(codeDeltaNext);
|
||||
codeDeltaNext++;
|
||||
}
|
||||
codeOffset += delta;
|
||||
|
||||
if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) {
|
||||
srcDeltaNext++;
|
||||
delta = TclGetInt4AtPtr(srcDeltaNext);
|
||||
srcDeltaNext += 4;
|
||||
} else {
|
||||
delta = TclGetInt1AtPtr(srcDeltaNext);
|
||||
srcDeltaNext++;
|
||||
}
|
||||
srcOffset += delta;
|
||||
|
||||
if ((unsigned) *srcLengthNext == (unsigned) 0xFF) {
|
||||
srcLengthNext++;
|
||||
srcLen = TclGetInt4AtPtr(srcLengthNext);
|
||||
srcLengthNext += 4;
|
||||
} else {
|
||||
srcLen = TclGetInt1AtPtr(srcLengthNext);
|
||||
srcLengthNext++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print instructions before command i.
|
||||
*/
|
||||
|
||||
while ((pc-codeStart) < codeOffset) {
|
||||
Tcl_AppendToObj(bufferObj, " ", -1);
|
||||
pc += FormatInstruction(codePtr, pc, bufferObj);
|
||||
}
|
||||
|
||||
Tcl_AppendPrintfToObj(bufferObj, " Command %d: ", i+1);
|
||||
PrintSourceToObj(bufferObj, (codePtr->source + srcOffset),
|
||||
TclMin(srcLen, 55));
|
||||
Tcl_AppendToObj(bufferObj, "\n", -1);
|
||||
}
|
||||
if (pc < codeLimit) {
|
||||
/*
|
||||
* Print instructions after the last command.
|
||||
*/
|
||||
|
||||
while (pc < codeLimit) {
|
||||
Tcl_AppendToObj(bufferObj, " ", -1);
|
||||
pc += FormatInstruction(codePtr, pc, bufferObj);
|
||||
}
|
||||
}
|
||||
return bufferObj;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FormatInstruction --
|
||||
*
|
||||
* Appends a representation of a bytecode instruction to a Tcl_Obj.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
FormatInstruction(
|
||||
ByteCode *codePtr, /* Bytecode containing the instruction. */
|
||||
const unsigned char *pc, /* Points to first byte of instruction. */
|
||||
Tcl_Obj *bufferObj) /* Object to append instruction info to. */
|
||||
{
|
||||
Proc *procPtr = codePtr->procPtr;
|
||||
unsigned char opCode = *pc;
|
||||
register const InstructionDesc *instDesc = &tclInstructionTable[opCode];
|
||||
unsigned char *codeStart = codePtr->codeStart;
|
||||
unsigned pcOffset = pc - codeStart;
|
||||
int opnd = 0, i, j, numBytes = 1;
|
||||
int localCt = procPtr ? procPtr->numCompiledLocals : 0;
|
||||
CompiledLocal *localPtr = procPtr ? procPtr->firstLocalPtr : NULL;
|
||||
char suffixBuffer[128]; /* Additional info to print after main opcode
|
||||
* and immediates. */
|
||||
char *suffixSrc = NULL;
|
||||
Tcl_Obj *suffixObj = NULL;
|
||||
AuxData *auxPtr = NULL;
|
||||
|
||||
suffixBuffer[0] = '\0';
|
||||
Tcl_AppendPrintfToObj(bufferObj, "(%u) %s ", pcOffset, instDesc->name);
|
||||
for (i = 0; i < instDesc->numOperands; i++) {
|
||||
switch (instDesc->opTypes[i]) {
|
||||
case OPERAND_INT1:
|
||||
opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++;
|
||||
if (opCode == INST_JUMP1 || opCode == INST_JUMP_TRUE1
|
||||
|| opCode == INST_JUMP_FALSE1) {
|
||||
sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
|
||||
}
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
|
||||
break;
|
||||
case OPERAND_INT4:
|
||||
opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
|
||||
if (opCode == INST_JUMP4 || opCode == INST_JUMP_TRUE4
|
||||
|| opCode == INST_JUMP_FALSE4) {
|
||||
sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
|
||||
} else if (opCode == INST_START_CMD) {
|
||||
sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd);
|
||||
}
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
|
||||
break;
|
||||
case OPERAND_UINT1:
|
||||
opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
|
||||
if (opCode == INST_PUSH1) {
|
||||
suffixObj = codePtr->objArrayPtr[opnd];
|
||||
}
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
|
||||
break;
|
||||
case OPERAND_AUX4:
|
||||
case OPERAND_UINT4:
|
||||
opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
|
||||
if (opCode == INST_PUSH4) {
|
||||
suffixObj = codePtr->objArrayPtr[opnd];
|
||||
} else if (opCode == INST_START_CMD && opnd != 1) {
|
||||
sprintf(suffixBuffer+strlen(suffixBuffer),
|
||||
", %u cmds start here", opnd);
|
||||
}
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
|
||||
if (instDesc->opTypes[i] == OPERAND_AUX4) {
|
||||
auxPtr = &codePtr->auxDataArrayPtr[opnd];
|
||||
}
|
||||
break;
|
||||
case OPERAND_IDX4:
|
||||
opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
|
||||
if (opnd >= -1) {
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%d ", opnd);
|
||||
} else if (opnd == -2) {
|
||||
Tcl_AppendPrintfToObj(bufferObj, "end ");
|
||||
} else {
|
||||
Tcl_AppendPrintfToObj(bufferObj, "end-%d ", -2-opnd);
|
||||
}
|
||||
break;
|
||||
case OPERAND_LVT1:
|
||||
opnd = TclGetUInt1AtPtr(pc+numBytes);
|
||||
numBytes++;
|
||||
goto printLVTindex;
|
||||
case OPERAND_LVT4:
|
||||
opnd = TclGetUInt4AtPtr(pc+numBytes);
|
||||
numBytes += 4;
|
||||
printLVTindex:
|
||||
if (localPtr != NULL) {
|
||||
if (opnd >= localCt) {
|
||||
Tcl_Panic("FormatInstruction: bad local var index %u (%u locals)",
|
||||
(unsigned) opnd, localCt);
|
||||
}
|
||||
for (j = 0; j < opnd; j++) {
|
||||
localPtr = localPtr->nextPtr;
|
||||
}
|
||||
if (TclIsVarTemporary(localPtr)) {
|
||||
sprintf(suffixBuffer, "temp var %u", (unsigned) opnd);
|
||||
} else {
|
||||
sprintf(suffixBuffer, "var ");
|
||||
suffixSrc = localPtr->name;
|
||||
}
|
||||
}
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", (unsigned) opnd);
|
||||
break;
|
||||
case OPERAND_SCLS1:
|
||||
opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
|
||||
Tcl_AppendPrintfToObj(bufferObj, "%s ",
|
||||
tclStringClassTable[opnd].name);
|
||||
break;
|
||||
case OPERAND_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (suffixObj) {
|
||||
const char *bytes;
|
||||
int length;
|
||||
|
||||
Tcl_AppendToObj(bufferObj, "\t# ", -1);
|
||||
bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length);
|
||||
PrintSourceToObj(bufferObj, bytes, TclMin(length, 40));
|
||||
} else if (suffixBuffer[0]) {
|
||||
Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer);
|
||||
if (suffixSrc) {
|
||||
PrintSourceToObj(bufferObj, suffixSrc, 40);
|
||||
}
|
||||
}
|
||||
Tcl_AppendToObj(bufferObj, "\n", -1);
|
||||
if (auxPtr && auxPtr->type->printProc) {
|
||||
Tcl_AppendToObj(bufferObj, "\t\t[", -1);
|
||||
auxPtr->type->printProc(auxPtr->clientData, bufferObj, codePtr,
|
||||
pcOffset);
|
||||
Tcl_AppendToObj(bufferObj, "]\n", -1);
|
||||
}
|
||||
return numBytes;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclGetInnerContext --
|
||||
*
|
||||
* If possible, returns a list capturing the inner context. Otherwise
|
||||
* return NULL.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *
|
||||
TclGetInnerContext(
|
||||
Tcl_Interp *interp,
|
||||
const unsigned char *pc,
|
||||
Tcl_Obj **tosPtr)
|
||||
{
|
||||
int objc = 0, off = 0;
|
||||
Tcl_Obj *result;
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
|
||||
switch (*pc) {
|
||||
case INST_STR_LEN:
|
||||
case INST_LNOT:
|
||||
case INST_BITNOT:
|
||||
case INST_UMINUS:
|
||||
case INST_UPLUS:
|
||||
case INST_TRY_CVT_TO_NUMERIC:
|
||||
case INST_EXPAND_STKTOP:
|
||||
case INST_EXPR_STK:
|
||||
objc = 1;
|
||||
break;
|
||||
|
||||
case INST_LIST_IN:
|
||||
case INST_LIST_NOT_IN: /* Basic list containment operators. */
|
||||
case INST_STR_EQ:
|
||||
case INST_STR_NEQ: /* String (in)equality check */
|
||||
case INST_STR_CMP: /* String compare. */
|
||||
case INST_STR_INDEX:
|
||||
case INST_STR_MATCH:
|
||||
case INST_REGEXP:
|
||||
case INST_EQ:
|
||||
case INST_NEQ:
|
||||
case INST_LT:
|
||||
case INST_GT:
|
||||
case INST_LE:
|
||||
case INST_GE:
|
||||
case INST_MOD:
|
||||
case INST_LSHIFT:
|
||||
case INST_RSHIFT:
|
||||
case INST_BITOR:
|
||||
case INST_BITXOR:
|
||||
case INST_BITAND:
|
||||
case INST_EXPON:
|
||||
case INST_ADD:
|
||||
case INST_SUB:
|
||||
case INST_DIV:
|
||||
case INST_MULT:
|
||||
objc = 2;
|
||||
break;
|
||||
|
||||
case INST_RETURN_STK:
|
||||
/* early pop. TODO: dig out opt dict too :/ */
|
||||
objc = 1;
|
||||
break;
|
||||
|
||||
case INST_SYNTAX:
|
||||
case INST_RETURN_IMM:
|
||||
objc = 2;
|
||||
break;
|
||||
|
||||
case INST_INVOKE_STK4:
|
||||
objc = TclGetUInt4AtPtr(pc+1);
|
||||
break;
|
||||
|
||||
case INST_INVOKE_STK1:
|
||||
objc = TclGetUInt1AtPtr(pc+1);
|
||||
break;
|
||||
}
|
||||
|
||||
result = iPtr->innerContext;
|
||||
if (Tcl_IsShared(result)) {
|
||||
Tcl_DecrRefCount(result);
|
||||
iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL);
|
||||
Tcl_IncrRefCount(result);
|
||||
} else {
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Reset while keeping the list intrep as much as possible.
|
||||
*/
|
||||
|
||||
Tcl_ListObjLength(interp, result, &len);
|
||||
Tcl_ListObjReplace(interp, result, 0, len, 0, NULL);
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, result, TclNewInstNameObj(*pc));
|
||||
|
||||
for (; objc>0 ; objc--) {
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
objPtr = tosPtr[1 - objc + off];
|
||||
if (!objPtr) {
|
||||
Tcl_Panic("InnerContext: bad tos -- appending null object");
|
||||
}
|
||||
if ((objPtr->refCount<=0)
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
|| (objPtr->refCount==0x61616161)
|
||||
#endif
|
||||
) {
|
||||
Tcl_Panic("InnerContext: bad tos -- appending freed object %p",
|
||||
objPtr);
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, result, objPtr);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclNewInstNameObj --
|
||||
*
|
||||
* Creates a new InstName Tcl_Obj based on the given instruction
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *
|
||||
TclNewInstNameObj(
|
||||
unsigned char inst)
|
||||
{
|
||||
Tcl_Obj *objPtr = Tcl_NewObj();
|
||||
|
||||
objPtr->typePtr = &tclInstNameType;
|
||||
objPtr->internalRep.longValue = (long) inst;
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
return objPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* UpdateStringOfInstName --
|
||||
*
|
||||
* Update the string representation for an instruction name object.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
UpdateStringOfInstName(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
int inst = objPtr->internalRep.longValue;
|
||||
char *s, buf[20];
|
||||
int len;
|
||||
|
||||
if ((inst < 0) || (inst > LAST_INST_OPCODE)) {
|
||||
sprintf(buf, "inst_%d", inst);
|
||||
s = buf;
|
||||
} else {
|
||||
s = (char *) tclInstructionTable[objPtr->internalRep.longValue].name;
|
||||
}
|
||||
len = strlen(s);
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, s, len + 1);
|
||||
objPtr->length = len;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* PrintSourceToObj --
|
||||
*
|
||||
* Appends a quoted representation of a string to a Tcl_Obj.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
PrintSourceToObj(
|
||||
Tcl_Obj *appendObj, /* The object to print the source to. */
|
||||
const char *stringPtr, /* The string to print. */
|
||||
int maxChars) /* Maximum number of chars to print. */
|
||||
{
|
||||
register const char *p;
|
||||
register int i = 0;
|
||||
|
||||
if (stringPtr == NULL) {
|
||||
Tcl_AppendToObj(appendObj, "\"\"", -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Tcl_AppendToObj(appendObj, "\"", -1);
|
||||
p = stringPtr;
|
||||
for (; (*p != '\0') && (i < maxChars); p++, i++) {
|
||||
switch (*p) {
|
||||
case '"':
|
||||
Tcl_AppendToObj(appendObj, "\\\"", -1);
|
||||
continue;
|
||||
case '\f':
|
||||
Tcl_AppendToObj(appendObj, "\\f", -1);
|
||||
continue;
|
||||
case '\n':
|
||||
Tcl_AppendToObj(appendObj, "\\n", -1);
|
||||
continue;
|
||||
case '\r':
|
||||
Tcl_AppendToObj(appendObj, "\\r", -1);
|
||||
continue;
|
||||
case '\t':
|
||||
Tcl_AppendToObj(appendObj, "\\t", -1);
|
||||
continue;
|
||||
case '\v':
|
||||
Tcl_AppendToObj(appendObj, "\\v", -1);
|
||||
continue;
|
||||
default:
|
||||
Tcl_AppendPrintfToObj(appendObj, "%c", *p);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Tcl_AppendToObj(appendObj, "\"", -1);
|
||||
}
|
||||
|
||||
#ifdef TCL_COMPILE_STATS
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
+42
-21
@@ -48,6 +48,13 @@ MODULE_SCOPE int tclTraceCompile;
|
||||
|
||||
MODULE_SCOPE int tclTraceExec;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The type of lambda expressions. Note that every lambda will *always* have a
|
||||
* string representation.
|
||||
*/
|
||||
|
||||
MODULE_SCOPE const Tcl_ObjType tclLambdaType;
|
||||
|
||||
/*
|
||||
*------------------------------------------------------------------------
|
||||
@@ -238,6 +245,16 @@ typedef struct AuxDataType {
|
||||
AuxDataPrintProc *printProc;/* Callback function to invoke when printing
|
||||
* the aux data as part of debugging. NULL
|
||||
* means that the data can't be printed. */
|
||||
AuxDataPrintProc *disassembleProc;
|
||||
/* Callback function to invoke when doing a
|
||||
* disassembly of the aux data (like the
|
||||
* printProc, except that the output is
|
||||
* intended to be script-readable). The
|
||||
* appendObj argument should be filled in with
|
||||
* a descriptive dictionary; it will start out
|
||||
* with "name" mapped to the content of the
|
||||
* name field. NULL means that the printProc
|
||||
* should be used instead. */
|
||||
} AuxDataType;
|
||||
|
||||
/*
|
||||
@@ -799,8 +816,13 @@ typedef struct ByteCode {
|
||||
#define INST_TRY_CVT_TO_BOOLEAN 183
|
||||
#define INST_STR_CLASS 184
|
||||
|
||||
#define INST_LAPPEND_LIST 185
|
||||
#define INST_LAPPEND_LIST_ARRAY 186
|
||||
#define INST_LAPPEND_LIST_ARRAY_STK 187
|
||||
#define INST_LAPPEND_LIST_STK 188
|
||||
|
||||
/* The last opcode */
|
||||
#define LAST_INST_OPCODE 184
|
||||
#define LAST_INST_OPCODE 188
|
||||
|
||||
/*
|
||||
* Table describing the Tcl bytecode instructions: their name (for displaying
|
||||
@@ -827,6 +849,12 @@ typedef enum InstOperandType {
|
||||
* variable table. */
|
||||
OPERAND_AUX4, /* Four byte unsigned index into the aux data
|
||||
* table. */
|
||||
OPERAND_OFFSET1, /* One byte signed jump offset. */
|
||||
OPERAND_OFFSET4, /* Four byte signed jump offset. */
|
||||
OPERAND_LIT1, /* One byte unsigned index into table of
|
||||
* literals. */
|
||||
OPERAND_LIT4, /* Four byte unsigned index into table of
|
||||
* literals. */
|
||||
OPERAND_SCLS1 /* Index into tclStringClassTable. */
|
||||
} InstOperandType;
|
||||
|
||||
@@ -1123,6 +1151,10 @@ MODULE_SCOPE void TclFinalizeLoopExceptionRange(CompileEnv *envPtr,
|
||||
MODULE_SCOPE char * TclLiteralStats(LiteralTable *tablePtr);
|
||||
MODULE_SCOPE int TclLog2(int value);
|
||||
#endif
|
||||
MODULE_SCOPE int TclLocalScalar(const char *bytes, int numBytes,
|
||||
CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclLocalScalarFromToken(Tcl_Token *tokenPtr,
|
||||
CompileEnv *envPtr);
|
||||
MODULE_SCOPE void TclOptimizeBytecode(void *envPtr);
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
MODULE_SCOPE void TclPrintByteCodeObj(Tcl_Interp *interp,
|
||||
@@ -1160,12 +1192,15 @@ MODULE_SCOPE void TclVerifyLocalLiteralTable(CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclWordKnownAtCompileTime(Tcl_Token *tokenPtr,
|
||||
Tcl_Obj *valuePtr);
|
||||
MODULE_SCOPE void TclLogCommandInfo(Tcl_Interp *interp,
|
||||
const char *script,
|
||||
const char *command, int length,
|
||||
const unsigned char *pc, Tcl_Obj **tosPtr);
|
||||
const char *script, const char *command,
|
||||
int length, const unsigned char *pc,
|
||||
Tcl_Obj **tosPtr);
|
||||
MODULE_SCOPE Tcl_Obj *TclGetInnerContext(Tcl_Interp *interp,
|
||||
const unsigned char *pc, Tcl_Obj **tosPtr);
|
||||
const unsigned char *pc, Tcl_Obj **tosPtr);
|
||||
MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
|
||||
MODULE_SCOPE int TclPushProcCallFrame(ClientData clientData,
|
||||
register Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[], int isLambda);
|
||||
|
||||
|
||||
/*
|
||||
@@ -1382,18 +1417,6 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* If the expr compiler finished with TRY_CONVERT, macro to remove it when the
|
||||
* job is done by the following instruction.
|
||||
*/
|
||||
|
||||
#define TclClearNumConversion(envPtr) \
|
||||
do { \
|
||||
if (*(envPtr->codeNext - 1) == INST_TRY_CVT_TO_NUMERIC) { \
|
||||
envPtr->codeNext--; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Macros to update a (signed or unsigned) integer starting at a pointer. The
|
||||
* two variants depend on the number of bytes. The ANSI C "prototypes" for
|
||||
@@ -1659,11 +1682,9 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
|
||||
#define AnonymousLocal(envPtr) \
|
||||
(TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1, (envPtr)))
|
||||
#define LocalScalar(chars,len,envPtr) \
|
||||
(!TclIsLocalScalar((chars), (len)) ? -1 : \
|
||||
TclFindCompiledLocal((chars), (len), /*create*/ 1, (envPtr)))
|
||||
TclLocalScalar(chars, len, envPtr)
|
||||
#define LocalScalarFromToken(tokenPtr,envPtr) \
|
||||
((tokenPtr)->type != TCL_TOKEN_SIMPLE_WORD ? -1 : \
|
||||
LocalScalar((tokenPtr)[1].start, (tokenPtr)[1].size, (envPtr)))
|
||||
TclLocalScalarFromToken(tokenPtr, envPtr)
|
||||
|
||||
/*
|
||||
* Flags bits used by TclPushVarName.
|
||||
|
||||
+12
-12
@@ -63,7 +63,7 @@ EXTERN void Tcl_DbCkfree(char *ptr, const char *file, int line);
|
||||
/* 8 */
|
||||
EXTERN char * Tcl_DbCkrealloc(char *ptr, unsigned int size,
|
||||
const char *file, int line);
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
/* 9 */
|
||||
EXTERN void Tcl_CreateFileHandler(int fd, int mask,
|
||||
Tcl_FileProc *proc, ClientData clientData);
|
||||
@@ -73,7 +73,7 @@ EXTERN void Tcl_CreateFileHandler(int fd, int mask,
|
||||
EXTERN void Tcl_CreateFileHandler(int fd, int mask,
|
||||
Tcl_FileProc *proc, ClientData clientData);
|
||||
#endif /* MACOSX */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
/* 10 */
|
||||
EXTERN void Tcl_DeleteFileHandler(int fd);
|
||||
#endif /* UNIX */
|
||||
@@ -511,7 +511,7 @@ EXTERN Tcl_Interp * Tcl_GetMaster(Tcl_Interp *interp);
|
||||
EXTERN const char * Tcl_GetNameOfExecutable(void);
|
||||
/* 166 */
|
||||
EXTERN Tcl_Obj * Tcl_GetObjResult(Tcl_Interp *interp);
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
/* 167 */
|
||||
EXTERN int Tcl_GetOpenFile(Tcl_Interp *interp,
|
||||
const char *chanID, int forWriting,
|
||||
@@ -1835,19 +1835,19 @@ typedef struct TclStubs {
|
||||
char * (*tcl_DbCkalloc) (unsigned int size, const char *file, int line); /* 6 */
|
||||
void (*tcl_DbCkfree) (char *ptr, const char *file, int line); /* 7 */
|
||||
char * (*tcl_DbCkrealloc) (char *ptr, unsigned int size, const char *file, int line); /* 8 */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, ClientData clientData); /* 9 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) /* WIN */
|
||||
#if defined(_WIN32) /* WIN */
|
||||
void (*reserved9)(void);
|
||||
#endif /* WIN */
|
||||
#ifdef MAC_OSX_TCL /* MACOSX */
|
||||
void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, ClientData clientData); /* 9 */
|
||||
#endif /* MACOSX */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
void (*tcl_DeleteFileHandler) (int fd); /* 10 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) /* WIN */
|
||||
#if defined(_WIN32) /* WIN */
|
||||
void (*reserved10)(void);
|
||||
#endif /* WIN */
|
||||
#ifdef MAC_OSX_TCL /* MACOSX */
|
||||
@@ -2009,10 +2009,10 @@ typedef struct TclStubs {
|
||||
Tcl_Interp * (*tcl_GetMaster) (Tcl_Interp *interp); /* 164 */
|
||||
const char * (*tcl_GetNameOfExecutable) (void); /* 165 */
|
||||
Tcl_Obj * (*tcl_GetObjResult) (Tcl_Interp *interp); /* 166 */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
int (*tcl_GetOpenFile) (Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); /* 167 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) /* WIN */
|
||||
#if defined(_WIN32) /* WIN */
|
||||
void (*reserved167)(void);
|
||||
#endif /* WIN */
|
||||
#ifdef MAC_OSX_TCL /* MACOSX */
|
||||
@@ -2513,7 +2513,7 @@ extern const TclStubs *tclStubsPtr;
|
||||
(tclStubsPtr->tcl_DbCkfree) /* 7 */
|
||||
#define Tcl_DbCkrealloc \
|
||||
(tclStubsPtr->tcl_DbCkrealloc) /* 8 */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#define Tcl_CreateFileHandler \
|
||||
(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
|
||||
#endif /* UNIX */
|
||||
@@ -2521,7 +2521,7 @@ extern const TclStubs *tclStubsPtr;
|
||||
#define Tcl_CreateFileHandler \
|
||||
(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
|
||||
#endif /* MACOSX */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#define Tcl_DeleteFileHandler \
|
||||
(tclStubsPtr->tcl_DeleteFileHandler) /* 10 */
|
||||
#endif /* UNIX */
|
||||
@@ -2841,7 +2841,7 @@ extern const TclStubs *tclStubsPtr;
|
||||
(tclStubsPtr->tcl_GetNameOfExecutable) /* 165 */
|
||||
#define Tcl_GetObjResult \
|
||||
(tclStubsPtr->tcl_GetObjResult) /* 166 */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#define Tcl_GetOpenFile \
|
||||
(tclStubsPtr->tcl_GetOpenFile) /* 167 */
|
||||
#endif /* UNIX */
|
||||
|
||||
+133
-151
@@ -154,6 +154,13 @@ 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) (*((Dict **)&(dictObj)->internalRep.twoPtrValue.ptr1))
|
||||
|
||||
/*
|
||||
* The structure below defines the dictionary object type by means of
|
||||
* functions that can be invoked by generic object code.
|
||||
@@ -312,6 +319,7 @@ DeleteChainEntry(
|
||||
return 0;
|
||||
} else {
|
||||
Tcl_Obj *valuePtr = Tcl_GetHashValue(&cPtr->entry);
|
||||
|
||||
TclDecrRefCount(valuePtr);
|
||||
}
|
||||
|
||||
@@ -361,7 +369,7 @@ DupDictInternalRep(
|
||||
Tcl_Obj *srcPtr,
|
||||
Tcl_Obj *copyPtr)
|
||||
{
|
||||
Dict *oldDict = srcPtr->internalRep.twoPtrValue.ptr1;
|
||||
Dict *oldDict = DICT(srcPtr);
|
||||
Dict *newDict = ckalloc(sizeof(Dict));
|
||||
ChainEntry *cPtr;
|
||||
|
||||
@@ -396,7 +404,8 @@ DupDictInternalRep(
|
||||
* Store in the object.
|
||||
*/
|
||||
|
||||
copyPtr->internalRep.twoPtrValue.ptr1 = newDict;
|
||||
DICT(copyPtr) = newDict;
|
||||
copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
copyPtr->typePtr = &tclDictType;
|
||||
}
|
||||
|
||||
@@ -422,7 +431,7 @@ static void
|
||||
FreeDictInternalRep(
|
||||
Tcl_Obj *dictPtr)
|
||||
{
|
||||
Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
Dict *dict = DICT(dictPtr);
|
||||
|
||||
dict->refcount--;
|
||||
if (dict->refcount <= 0) {
|
||||
@@ -487,7 +496,7 @@ UpdateStringOfDict(
|
||||
{
|
||||
#define LOCAL_SIZE 20
|
||||
int localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
Dict *dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
Dict *dict = DICT(dictPtr);
|
||||
ChainEntry *cPtr;
|
||||
Tcl_Obj *keyPtr, *valuePtr;
|
||||
int i, length, bytesNeeded = 0;
|
||||
@@ -600,7 +609,7 @@ SetDictFromAny(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
Tcl_HashEntry *hPtr;
|
||||
int isNew, result;
|
||||
int isNew;
|
||||
Dict *dict = ckalloc(sizeof(Dict));
|
||||
|
||||
InitChainTable(dict);
|
||||
@@ -651,10 +660,9 @@ SetDictFromAny(
|
||||
const char *elemStart;
|
||||
int elemSize, literal;
|
||||
|
||||
result = TclFindElement(interp, nextElem, (limit - nextElem),
|
||||
&elemStart, &nextElem, &elemSize, &literal);
|
||||
if (result != TCL_OK) {
|
||||
goto errorExit;
|
||||
if (TclFindDictElement(interp, nextElem, (limit - nextElem),
|
||||
&elemStart, &nextElem, &elemSize, &literal) != TCL_OK) {
|
||||
goto errorInFindDictElement;
|
||||
}
|
||||
if (elemStart == limit) {
|
||||
break;
|
||||
@@ -673,11 +681,10 @@ SetDictFromAny(
|
||||
keyPtr->bytes);
|
||||
}
|
||||
|
||||
result = TclFindElement(interp, nextElem, (limit - nextElem),
|
||||
&elemStart, &nextElem, &elemSize, &literal);
|
||||
if (result != TCL_OK) {
|
||||
if (TclFindDictElement(interp, nextElem, (limit - nextElem),
|
||||
&elemStart, &nextElem, &elemSize, &literal) != TCL_OK) {
|
||||
TclDecrRefCount(keyPtr);
|
||||
goto errorExit;
|
||||
goto errorInFindDictElement;
|
||||
}
|
||||
|
||||
if (literal) {
|
||||
@@ -713,7 +720,8 @@ SetDictFromAny(
|
||||
dict->epoch = 0;
|
||||
dict->chain = NULL;
|
||||
dict->refcount = 1;
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = dict;
|
||||
DICT(objPtr) = dict;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
objPtr->typePtr = &tclDictType;
|
||||
return TCL_OK;
|
||||
|
||||
@@ -723,15 +731,10 @@ SetDictFromAny(
|
||||
"missing value to go with key", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL);
|
||||
}
|
||||
result = TCL_ERROR;
|
||||
|
||||
errorExit:
|
||||
if (interp != NULL) {
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL);
|
||||
}
|
||||
errorInFindDictElement:
|
||||
DeleteChainTable(dict);
|
||||
ckfree(dict);
|
||||
return result;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -777,12 +780,11 @@ TclTraceDictPath(
|
||||
Dict *dict, *newDict;
|
||||
int i;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
if (SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
if (flags & DICT_PATH_UPDATE) {
|
||||
dict->chain = NULL;
|
||||
}
|
||||
@@ -818,14 +820,13 @@ TclTraceDictPath(
|
||||
Tcl_SetHashValue(hPtr, tmpObj);
|
||||
} else {
|
||||
tmpObj = Tcl_GetHashValue(hPtr);
|
||||
if (tmpObj->typePtr != &tclDictType) {
|
||||
if (SetDictFromAny(interp, tmpObj) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
if (tmpObj->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, tmpObj) != TCL_OK) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
newDict = tmpObj->internalRep.twoPtrValue.ptr1;
|
||||
newDict = DICT(tmpObj);
|
||||
if (flags & DICT_PATH_UPDATE) {
|
||||
if (Tcl_IsShared(tmpObj)) {
|
||||
TclDecrRefCount(tmpObj);
|
||||
@@ -833,7 +834,7 @@ TclTraceDictPath(
|
||||
Tcl_IncrRefCount(tmpObj);
|
||||
Tcl_SetHashValue(hPtr, tmpObj);
|
||||
dict->epoch++;
|
||||
newDict = tmpObj->internalRep.twoPtrValue.ptr1;
|
||||
newDict = DICT(tmpObj);
|
||||
}
|
||||
|
||||
newDict->chain = dictPtr;
|
||||
@@ -868,7 +869,7 @@ static void
|
||||
InvalidateDictChain(
|
||||
Tcl_Obj *dictObj)
|
||||
{
|
||||
Dict *dict = dictObj->internalRep.twoPtrValue.ptr1;
|
||||
Dict *dict = DICT(dictObj);
|
||||
|
||||
do {
|
||||
TclInvalidateStringRep(dictObj);
|
||||
@@ -878,7 +879,7 @@ InvalidateDictChain(
|
||||
break;
|
||||
}
|
||||
dict->chain = NULL;
|
||||
dict = dictObj->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictObj);
|
||||
} while (dict != NULL);
|
||||
}
|
||||
|
||||
@@ -916,18 +917,15 @@ Tcl_DictObjPut(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_DictObjPut");
|
||||
}
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, dictPtr);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
hPtr = CreateChainEntry(dict, keyPtr, &isNew);
|
||||
Tcl_IncrRefCount(valuePtr);
|
||||
if (!isNew) {
|
||||
@@ -970,15 +968,13 @@ Tcl_DictObjGet(
|
||||
Dict *dict;
|
||||
Tcl_HashEntry *hPtr;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, dictPtr);
|
||||
if (result != TCL_OK) {
|
||||
*valuePtrPtr = NULL;
|
||||
return result;
|
||||
}
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
*valuePtrPtr = NULL;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
hPtr = Tcl_FindHashEntry(&dict->table, keyPtr);
|
||||
if (hPtr == NULL) {
|
||||
*valuePtrPtr = NULL;
|
||||
@@ -1019,18 +1015,16 @@ Tcl_DictObjRemove(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_DictObjRemove");
|
||||
}
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, dictPtr);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
if (DeleteChainEntry(dict, keyPtr)) {
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
dict->epoch++;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -1062,14 +1056,12 @@ Tcl_DictObjSize(
|
||||
{
|
||||
Dict *dict;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, dictPtr);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
*sizePtr = dict->table.numEntries;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1116,15 +1108,12 @@ Tcl_DictObjFirst(
|
||||
Dict *dict;
|
||||
ChainEntry *cPtr;
|
||||
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, dictPtr);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
cPtr = dict->entryChainHead;
|
||||
if (cPtr == NULL) {
|
||||
searchPtr->epoch = -1;
|
||||
@@ -1299,11 +1288,12 @@ Tcl_DictObjPutKeyList(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
hPtr = CreateChainEntry(dict, keyv[keyc-1], &isNew);
|
||||
Tcl_IncrRefCount(valuePtr);
|
||||
if (!isNew) {
|
||||
Tcl_Obj *oldValuePtr = Tcl_GetHashValue(hPtr);
|
||||
|
||||
TclDecrRefCount(oldValuePtr);
|
||||
}
|
||||
Tcl_SetHashValue(hPtr, valuePtr);
|
||||
@@ -1355,7 +1345,7 @@ Tcl_DictObjRemoveKeyList(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
DeleteChainEntry(dict, keyv[keyc-1]);
|
||||
InvalidateDictChain(dictPtr);
|
||||
return TCL_OK;
|
||||
@@ -1401,7 +1391,8 @@ Tcl_NewDictObj(void)
|
||||
dict->epoch = 0;
|
||||
dict->chain = NULL;
|
||||
dict->refcount = 1;
|
||||
dictPtr->internalRep.twoPtrValue.ptr1 = dict;
|
||||
DICT(dictPtr) = dict;
|
||||
dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
dictPtr->typePtr = &tclDictType;
|
||||
return dictPtr;
|
||||
#endif
|
||||
@@ -1450,7 +1441,8 @@ Tcl_DbNewDictObj(
|
||||
dict->epoch = 0;
|
||||
dict->chain = NULL;
|
||||
dict->refcount = 1;
|
||||
dictPtr->internalRep.twoPtrValue.ptr1 = dict;
|
||||
DICT(dictPtr) = dict;
|
||||
dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
|
||||
dictPtr->typePtr = &tclDictType;
|
||||
return dictPtr;
|
||||
#else /* !TCL_MEM_DEBUG */
|
||||
@@ -1504,7 +1496,7 @@ DictCreateCmd(
|
||||
/*
|
||||
* The next command is assumed to never fail...
|
||||
*/
|
||||
Tcl_DictObjPut(interp, dictObj, objv[i], objv[i+1]);
|
||||
Tcl_DictObjPut(NULL, dictObj, objv[i], objv[i+1]);
|
||||
}
|
||||
Tcl_SetObjResult(interp, dictObj);
|
||||
return TCL_OK;
|
||||
@@ -1629,8 +1621,7 @@ DictReplaceCmd(
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Tcl_Obj *dictPtr;
|
||||
int i, result;
|
||||
int allocatedDict = 0;
|
||||
int i;
|
||||
|
||||
if ((objc < 2) || (objc & 1)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key value ...?");
|
||||
@@ -1638,18 +1629,18 @@ DictReplaceCmd(
|
||||
}
|
||||
|
||||
dictPtr = objv[1];
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_IsShared(dictPtr)) {
|
||||
dictPtr = Tcl_DuplicateObj(dictPtr);
|
||||
allocatedDict = 1;
|
||||
}
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
for (i=2 ; i<objc ; i+=2) {
|
||||
result = Tcl_DictObjPut(interp, dictPtr, objv[i], objv[i+1]);
|
||||
if (result != TCL_OK) {
|
||||
if (allocatedDict) {
|
||||
TclDecrRefCount(dictPtr);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[i], objv[i+1]);
|
||||
}
|
||||
Tcl_SetObjResult(interp, dictPtr);
|
||||
return TCL_OK;
|
||||
@@ -1681,8 +1672,7 @@ DictRemoveCmd(
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Tcl_Obj *dictPtr;
|
||||
int i, result;
|
||||
int allocatedDict = 0;
|
||||
int i;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key ...?");
|
||||
@@ -1690,18 +1680,18 @@ DictRemoveCmd(
|
||||
}
|
||||
|
||||
dictPtr = objv[1];
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_IsShared(dictPtr)) {
|
||||
dictPtr = Tcl_DuplicateObj(dictPtr);
|
||||
allocatedDict = 1;
|
||||
}
|
||||
if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
for (i=2 ; i<objc ; i++) {
|
||||
result = Tcl_DictObjRemove(interp, dictPtr, objv[i]);
|
||||
if (result != TCL_OK) {
|
||||
if (allocatedDict) {
|
||||
TclDecrRefCount(dictPtr);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_DictObjRemove(NULL, dictPtr, objv[i]);
|
||||
}
|
||||
Tcl_SetObjResult(interp, dictPtr);
|
||||
return TCL_OK;
|
||||
@@ -1750,10 +1740,9 @@ DictMergeCmd(
|
||||
*/
|
||||
|
||||
targetObj = objv[1];
|
||||
if (targetObj->typePtr != &tclDictType) {
|
||||
if (SetDictFromAny(interp, targetObj) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (targetObj->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, targetObj) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (objc == 2) {
|
||||
@@ -1835,12 +1824,9 @@ DictKeysCmd(
|
||||
* need. [Bug 1705778, leak K04]
|
||||
*/
|
||||
|
||||
if (objv[1]->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, objv[1]);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
if (objv[1]->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, objv[1]) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (objc == 3) {
|
||||
@@ -2056,13 +2042,11 @@ DictInfoCmd(
|
||||
}
|
||||
|
||||
dictPtr = objv[1];
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, dictPtr);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
if (dictPtr->typePtr != &tclDictType
|
||||
&& SetDictFromAny(interp, dictPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
dict = dictPtr->internalRep.twoPtrValue.ptr1;
|
||||
dict = DICT(dictPtr);
|
||||
|
||||
statsStr = Tcl_HashStats(&dict->table);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1));
|
||||
@@ -2099,7 +2083,7 @@ DictIncrCmd(
|
||||
Tcl_Obj *dictPtr, *valuePtr = NULL;
|
||||
|
||||
if (objc < 3 || objc > 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "varName key ?increment?");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?increment?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2152,10 +2136,10 @@ DictIncrCmd(
|
||||
*/
|
||||
|
||||
mp_clear(&increment);
|
||||
Tcl_DictObjPut(interp, dictPtr, objv[2], objv[3]);
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], objv[3]);
|
||||
}
|
||||
} else {
|
||||
Tcl_DictObjPut(interp, dictPtr, objv[2], Tcl_NewIntObj(1));
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], Tcl_NewIntObj(1));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
@@ -2164,7 +2148,7 @@ DictIncrCmd(
|
||||
|
||||
if (Tcl_IsShared(valuePtr)) {
|
||||
valuePtr = Tcl_DuplicateObj(valuePtr);
|
||||
Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr);
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
|
||||
}
|
||||
if (objc == 4) {
|
||||
code = TclIncrObj(interp, valuePtr, objv[3]);
|
||||
@@ -2173,7 +2157,7 @@ DictIncrCmd(
|
||||
|
||||
Tcl_IncrRefCount(incrPtr);
|
||||
code = TclIncrObj(interp, valuePtr, incrPtr);
|
||||
Tcl_DecrRefCount(incrPtr);
|
||||
TclDecrRefCount(incrPtr);
|
||||
}
|
||||
}
|
||||
if (code == TCL_OK) {
|
||||
@@ -2186,7 +2170,7 @@ DictIncrCmd(
|
||||
Tcl_SetObjResult(interp, valuePtr);
|
||||
}
|
||||
} else if (dictPtr->refCount == 0) {
|
||||
Tcl_DecrRefCount(dictPtr);
|
||||
TclDecrRefCount(dictPtr);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
@@ -2220,7 +2204,7 @@ DictLappendCmd(
|
||||
int i, allocatedDict = 0, allocatedValue = 0;
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "varName key ?value ...?");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2264,7 +2248,7 @@ DictLappendCmd(
|
||||
}
|
||||
|
||||
if (allocatedValue) {
|
||||
Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr);
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
|
||||
} else if (dictPtr->bytes != NULL) {
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
}
|
||||
@@ -2307,7 +2291,7 @@ DictAppendCmd(
|
||||
int i, allocatedDict = 0;
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "varName key ?value ...?");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2329,17 +2313,15 @@ DictAppendCmd(
|
||||
|
||||
if (valuePtr == NULL) {
|
||||
TclNewObj(valuePtr);
|
||||
} else {
|
||||
if (Tcl_IsShared(valuePtr)) {
|
||||
valuePtr = Tcl_DuplicateObj(valuePtr);
|
||||
}
|
||||
} else if (Tcl_IsShared(valuePtr)) {
|
||||
valuePtr = Tcl_DuplicateObj(valuePtr);
|
||||
}
|
||||
|
||||
for (i=3 ; i<objc ; i++) {
|
||||
Tcl_AppendObjToObj(valuePtr, objv[i]);
|
||||
}
|
||||
|
||||
Tcl_DictObjPut(interp, dictPtr, objv[2], valuePtr);
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
|
||||
|
||||
resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr,
|
||||
TCL_LEAVE_ERR_MSG);
|
||||
@@ -2383,7 +2365,7 @@ DictForNRCmd(
|
||||
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"{keyVar valueVar} dictionary script");
|
||||
"{keyVarName valueVarName} dictionary script");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2397,6 +2379,7 @@ DictForNRCmd(
|
||||
if (varc != 2) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"must have exactly two variable names", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SYNTAX", "dict", "for", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
searchPtr = TclStackAlloc(interp, sizeof(Tcl_DictSearch));
|
||||
@@ -2430,12 +2413,14 @@ DictForNRCmd(
|
||||
*/
|
||||
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj, TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
TclDecrRefCount(valueObj);
|
||||
goto error;
|
||||
}
|
||||
TclDecrRefCount(valueObj);
|
||||
if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj, TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -2574,7 +2559,7 @@ DictMapNRCmd(
|
||||
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"{keyVar valueVar} dictionary script");
|
||||
"{keyVarName valueVarName} dictionary script");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2588,6 +2573,7 @@ DictMapNRCmd(
|
||||
if (varc != 2) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"must have exactly two variable names", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SYNTAX", "dict", "map", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
storagePtr = TclStackAlloc(interp, sizeof(DictMapStorage));
|
||||
@@ -2782,7 +2768,7 @@ DictSetCmd(
|
||||
int result, allocatedDict = 0;
|
||||
|
||||
if (objc < 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "varName key ?key ...? value");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?key ...? value");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2842,7 +2828,7 @@ DictUnsetCmd(
|
||||
int result, allocatedDict = 0;
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "varName key ?key ...?");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?key ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2949,12 +2935,12 @@ DictFilterCmd(
|
||||
Tcl_DictObjDone(&search);
|
||||
Tcl_DictObjGet(interp, objv[1], objv[3], &valueObj);
|
||||
if (valueObj != NULL) {
|
||||
Tcl_DictObjPut(interp, resultObj, objv[3], valueObj);
|
||||
Tcl_DictObjPut(NULL, resultObj, objv[3], valueObj);
|
||||
}
|
||||
} else {
|
||||
while (!done) {
|
||||
if (Tcl_StringMatch(TclGetString(keyObj), pattern)) {
|
||||
Tcl_DictObjPut(interp, resultObj, keyObj, valueObj);
|
||||
Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
|
||||
}
|
||||
Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
|
||||
}
|
||||
@@ -2972,7 +2958,7 @@ DictFilterCmd(
|
||||
for (i=3 ; i<objc ; i++) {
|
||||
pattern = TclGetString(objv[i]);
|
||||
if (Tcl_StringMatch(TclGetString(keyObj), pattern)) {
|
||||
Tcl_DictObjPut(interp, resultObj, keyObj, valueObj);
|
||||
Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
|
||||
break; /* stop inner loop */
|
||||
}
|
||||
}
|
||||
@@ -2998,7 +2984,7 @@ DictFilterCmd(
|
||||
for (i=3 ; i<objc ; i++) {
|
||||
pattern = TclGetString(objv[i]);
|
||||
if (Tcl_StringMatch(TclGetString(valueObj), pattern)) {
|
||||
Tcl_DictObjPut(interp, resultObj, keyObj, valueObj);
|
||||
Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
|
||||
break; /* stop inner loop */
|
||||
}
|
||||
}
|
||||
@@ -3010,7 +2996,7 @@ DictFilterCmd(
|
||||
case FILTER_SCRIPT:
|
||||
if (objc != 5) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"dictionary script {keyVar valueVar} filterScript");
|
||||
"dictionary script {keyVarName valueVarName} filterScript");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3026,6 +3012,7 @@ DictFilterCmd(
|
||||
if (varc != 2) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"must have exactly two variable names", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "SYNTAX", "dict", "filter", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
keyVarObj = varv[0];
|
||||
@@ -3064,19 +3051,15 @@ DictFilterCmd(
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't set key variable: \"%s\"",
|
||||
TclGetString(keyVarObj)));
|
||||
Tcl_AddErrorInfo(interp,
|
||||
"\n (\"dict filter\" filter script key variable)");
|
||||
result = TCL_ERROR;
|
||||
goto abnormalResult;
|
||||
}
|
||||
if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't set value variable: \"%s\"",
|
||||
TclGetString(valueVarObj)));
|
||||
Tcl_AddErrorInfo(interp,
|
||||
"\n (\"dict filter\" filter script value variable)");
|
||||
result = TCL_ERROR;
|
||||
goto abnormalResult;
|
||||
}
|
||||
@@ -3099,7 +3082,7 @@ DictFilterCmd(
|
||||
}
|
||||
TclDecrRefCount(boolObj);
|
||||
if (satisfied) {
|
||||
Tcl_DictObjPut(interp, resultObj, keyObj, valueObj);
|
||||
Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
|
||||
}
|
||||
break;
|
||||
case TCL_BREAK:
|
||||
@@ -3190,7 +3173,7 @@ DictUpdateCmd(
|
||||
|
||||
if (objc < 5 || !(objc & 1)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"varName key varName ?key varName ...? script");
|
||||
"dictVarName key varName ?key varName ...? script");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3287,18 +3270,17 @@ FinalizeDictUpdate(
|
||||
for (i=0 ; i<objc ; i+=2) {
|
||||
objPtr = Tcl_ObjGetVar2(interp, objv[i+1], NULL, 0);
|
||||
if (objPtr == NULL) {
|
||||
Tcl_DictObjRemove(interp, dictPtr, objv[i]);
|
||||
Tcl_DictObjRemove(NULL, dictPtr, objv[i]);
|
||||
} else if (objPtr == dictPtr) {
|
||||
/*
|
||||
* Someone is messing us around, trying to build a recursive
|
||||
* structure. [Bug 1786481]
|
||||
*/
|
||||
|
||||
Tcl_DictObjPut(interp, dictPtr, objv[i],
|
||||
Tcl_DuplicateObj(objPtr));
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[i], Tcl_DuplicateObj(objPtr));
|
||||
} else {
|
||||
/* Shouldn't fail */
|
||||
Tcl_DictObjPut(interp, dictPtr, objv[i], objPtr);
|
||||
Tcl_DictObjPut(NULL, dictPtr, objv[i], objPtr);
|
||||
}
|
||||
}
|
||||
TclDecrRefCount(argsObj);
|
||||
@@ -3347,7 +3329,7 @@ DictWithCmd(
|
||||
Tcl_Obj *dictPtr, *keysPtr, *pathPtr;
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVar ?key ...? script");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictVarName ?key ...? script");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+74
-24
@@ -180,8 +180,9 @@ TCL_DECLARE_MUTEX(encodingMutex)
|
||||
* the system encoding will be used to perform the conversion.
|
||||
*/
|
||||
|
||||
static Tcl_Encoding defaultEncoding;
|
||||
static Tcl_Encoding systemEncoding;
|
||||
static Tcl_Encoding defaultEncoding = NULL;
|
||||
static Tcl_Encoding systemEncoding = NULL;
|
||||
Tcl_Encoding tclIdentityEncoding = NULL;
|
||||
|
||||
/*
|
||||
* The following variable is used in the sparse matrix code for a
|
||||
@@ -567,7 +568,7 @@ TclInitEncodingSubsystem(void)
|
||||
type.freeProc = NULL;
|
||||
type.nullSize = 1;
|
||||
type.clientData = NULL;
|
||||
Tcl_CreateEncoding(&type);
|
||||
tclIdentityEncoding = Tcl_CreateEncoding(&type);
|
||||
|
||||
type.encodingName = "utf-8";
|
||||
type.toUtfProc = UtfExtToUtfIntProc;
|
||||
@@ -651,6 +652,10 @@ TclFinalizeEncodingSubsystem(void)
|
||||
Tcl_MutexLock(&encodingMutex);
|
||||
encodingsInitialized = 0;
|
||||
FreeEncoding(systemEncoding);
|
||||
systemEncoding = NULL;
|
||||
defaultEncoding = NULL;
|
||||
FreeEncoding(tclIdentityEncoding);
|
||||
tclIdentityEncoding = NULL;
|
||||
|
||||
hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
|
||||
while (hPtr != NULL) {
|
||||
@@ -1201,7 +1206,10 @@ Tcl_ExternalToUtf(
|
||||
* output buffer. */
|
||||
{
|
||||
const Encoding *encodingPtr;
|
||||
int result, srcRead, dstWrote, dstChars;
|
||||
int result, srcRead, dstWrote, dstChars = 0;
|
||||
int noTerminate = flags & TCL_ENCODING_NO_TERMINATE;
|
||||
int charLimited = (flags & TCL_ENCODING_CHAR_LIMIT) && dstCharsPtr;
|
||||
int maxChars = INT_MAX;
|
||||
Tcl_EncodingState state;
|
||||
|
||||
if (encoding == NULL) {
|
||||
@@ -1226,19 +1234,40 @@ Tcl_ExternalToUtf(
|
||||
}
|
||||
if (dstCharsPtr == NULL) {
|
||||
dstCharsPtr = &dstChars;
|
||||
flags &= ~TCL_ENCODING_CHAR_LIMIT;
|
||||
} else if (charLimited) {
|
||||
maxChars = *dstCharsPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there are any null characters in the middle of the buffer, they will
|
||||
* converted to the UTF-8 null character (\xC080). To get the actual \0 at
|
||||
* the end of the destination buffer, we need to append it manually.
|
||||
*/
|
||||
if (!noTerminate) {
|
||||
/*
|
||||
* If there are any null characters in the middle of the buffer,
|
||||
* they will converted to the UTF-8 null character (\xC080). To get
|
||||
* the actual \0 at the end of the destination buffer, we need to
|
||||
* append it manually. First make room for it...
|
||||
*/
|
||||
|
||||
dstLen--;
|
||||
result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen,
|
||||
flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
|
||||
dstCharsPtr);
|
||||
dst[*dstWrotePtr] = '\0';
|
||||
dstLen--;
|
||||
}
|
||||
do {
|
||||
int savedFlags = flags;
|
||||
Tcl_EncodingState savedState = *statePtr;
|
||||
|
||||
result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen,
|
||||
flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
|
||||
dstCharsPtr);
|
||||
if (*dstCharsPtr <= maxChars) {
|
||||
break;
|
||||
}
|
||||
dstLen = Tcl_UtfAtIndex(dst, maxChars) - 1 - dst + TCL_UTF_MAX;
|
||||
flags = savedFlags;
|
||||
*statePtr = savedState;
|
||||
} while (1);
|
||||
if (!noTerminate) {
|
||||
/* ...and then append it */
|
||||
|
||||
dst[*dstWrotePtr] = '\0';
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -2102,6 +2131,9 @@ BinaryProc(
|
||||
if (dstLen < 0) {
|
||||
dstLen = 0;
|
||||
}
|
||||
if ((flags & TCL_ENCODING_CHAR_LIMIT) && srcLen > *dstCharsPtr) {
|
||||
srcLen = *dstCharsPtr;
|
||||
}
|
||||
if (srcLen > dstLen) {
|
||||
srcLen = dstLen;
|
||||
result = TCL_CONVERT_NOSPACE;
|
||||
@@ -2262,7 +2294,7 @@ UtfToUtfProc(
|
||||
{
|
||||
const char *srcStart, *srcEnd, *srcClose;
|
||||
const char *dstStart, *dstEnd;
|
||||
int result, numChars;
|
||||
int result, numChars, charLimit = INT_MAX;
|
||||
Tcl_UniChar ch;
|
||||
|
||||
result = TCL_OK;
|
||||
@@ -2273,11 +2305,14 @@ UtfToUtfProc(
|
||||
if ((flags & TCL_ENCODING_END) == 0) {
|
||||
srcClose -= TCL_UTF_MAX;
|
||||
}
|
||||
if (flags & TCL_ENCODING_CHAR_LIMIT) {
|
||||
charLimit = *dstCharsPtr;
|
||||
}
|
||||
|
||||
dstStart = dst;
|
||||
dstEnd = dst + dstLen - TCL_UTF_MAX;
|
||||
|
||||
for (numChars = 0; src < srcEnd; numChars++) {
|
||||
for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
|
||||
if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
|
||||
/*
|
||||
* If there is more string to follow, this will ensure that the
|
||||
@@ -2373,9 +2408,12 @@ UnicodeToUtfProc(
|
||||
{
|
||||
const char *srcStart, *srcEnd;
|
||||
const char *dstEnd, *dstStart;
|
||||
int result, numChars;
|
||||
int result, numChars, charLimit = INT_MAX;
|
||||
Tcl_UniChar ch;
|
||||
|
||||
if (flags & TCL_ENCODING_CHAR_LIMIT) {
|
||||
charLimit = *dstCharsPtr;
|
||||
}
|
||||
result = TCL_OK;
|
||||
if ((srcLen % sizeof(Tcl_UniChar)) != 0) {
|
||||
result = TCL_CONVERT_MULTIBYTE;
|
||||
@@ -2389,7 +2427,7 @@ UnicodeToUtfProc(
|
||||
dstStart = dst;
|
||||
dstEnd = dst + dstLen - TCL_UTF_MAX;
|
||||
|
||||
for (numChars = 0; src < srcEnd; numChars++) {
|
||||
for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
|
||||
if (dst > dstEnd) {
|
||||
result = TCL_CONVERT_NOSPACE;
|
||||
break;
|
||||
@@ -2557,12 +2595,15 @@ TableToUtfProc(
|
||||
{
|
||||
const char *srcStart, *srcEnd;
|
||||
const char *dstEnd, *dstStart, *prefixBytes;
|
||||
int result, byte, numChars;
|
||||
int result, byte, numChars, charLimit = INT_MAX;
|
||||
Tcl_UniChar ch;
|
||||
const unsigned short *const *toUnicode;
|
||||
const unsigned short *pageZero;
|
||||
TableEncodingData *dataPtr = clientData;
|
||||
|
||||
if (flags & TCL_ENCODING_CHAR_LIMIT) {
|
||||
charLimit = *dstCharsPtr;
|
||||
}
|
||||
srcStart = src;
|
||||
srcEnd = src + srcLen;
|
||||
|
||||
@@ -2574,7 +2615,7 @@ TableToUtfProc(
|
||||
pageZero = toUnicode[0];
|
||||
|
||||
result = TCL_OK;
|
||||
for (numChars = 0; src < srcEnd; numChars++) {
|
||||
for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
|
||||
if (dst > dstEnd) {
|
||||
result = TCL_CONVERT_NOSPACE;
|
||||
break;
|
||||
@@ -2788,8 +2829,11 @@ Iso88591ToUtfProc(
|
||||
{
|
||||
const char *srcStart, *srcEnd;
|
||||
const char *dstEnd, *dstStart;
|
||||
int result, numChars;
|
||||
int result, numChars, charLimit = INT_MAX;
|
||||
|
||||
if (flags & TCL_ENCODING_CHAR_LIMIT) {
|
||||
charLimit = *dstCharsPtr;
|
||||
}
|
||||
srcStart = src;
|
||||
srcEnd = src + srcLen;
|
||||
|
||||
@@ -2797,7 +2841,7 @@ Iso88591ToUtfProc(
|
||||
dstEnd = dst + dstLen - TCL_UTF_MAX;
|
||||
|
||||
result = TCL_OK;
|
||||
for (numChars = 0; src < srcEnd; numChars++) {
|
||||
for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
|
||||
Tcl_UniChar ch;
|
||||
|
||||
if (dst > dstEnd) {
|
||||
@@ -2958,7 +3002,9 @@ TableFreeProc(
|
||||
*/
|
||||
|
||||
ckfree(dataPtr->toUnicode);
|
||||
dataPtr->toUnicode = NULL;
|
||||
ckfree(dataPtr->fromUnicode);
|
||||
dataPtr->fromUnicode = NULL;
|
||||
ckfree(dataPtr);
|
||||
}
|
||||
|
||||
@@ -3011,9 +3057,12 @@ EscapeToUtfProc(
|
||||
const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd;
|
||||
const unsigned short *const *tableToUnicode;
|
||||
const Encoding *encodingPtr;
|
||||
int state, result, numChars;
|
||||
int state, result, numChars, charLimit = INT_MAX;
|
||||
const char *dstStart, *dstEnd;
|
||||
|
||||
if (flags & TCL_ENCODING_CHAR_LIMIT) {
|
||||
charLimit = *dstCharsPtr;
|
||||
}
|
||||
result = TCL_OK;
|
||||
tablePrefixBytes = NULL; /* lint. */
|
||||
tableToUnicode = NULL; /* lint. */
|
||||
@@ -3031,7 +3080,7 @@ EscapeToUtfProc(
|
||||
state = 0;
|
||||
}
|
||||
|
||||
for (numChars = 0; src < srcEnd; ) {
|
||||
for (numChars = 0; src < srcEnd && numChars <= charLimit; ) {
|
||||
int byte, hi, lo, ch;
|
||||
|
||||
if (dst > dstEnd) {
|
||||
@@ -3431,6 +3480,7 @@ EscapeFreeProc(
|
||||
subTablePtr = dataPtr->subTables;
|
||||
for (i = 0; i < dataPtr->numSubTables; i++) {
|
||||
FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
|
||||
subTablePtr->encodingPtr = NULL;
|
||||
subTablePtr++;
|
||||
}
|
||||
}
|
||||
|
||||
+52
-8
@@ -2749,15 +2749,9 @@ TclCompileEnsemble(
|
||||
int ourResult = TCL_ERROR;
|
||||
unsigned numBytes;
|
||||
const char *word;
|
||||
DefineLineInformation;
|
||||
|
||||
Tcl_IncrRefCount(replaced);
|
||||
|
||||
/*
|
||||
* This is where we return to if we are parsing multiple nested compiled
|
||||
* ensembles. [info object] is such a beast.
|
||||
*/
|
||||
|
||||
checkNextWord:
|
||||
if (parsePtr->numWords < depth + 1) {
|
||||
goto failed;
|
||||
}
|
||||
@@ -2769,6 +2763,12 @@ TclCompileEnsemble(
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is where we return to if we are parsing multiple nested compiled
|
||||
* ensembles. [info object] is such a beast.
|
||||
*/
|
||||
|
||||
checkNextWord:
|
||||
word = tokenPtr[1].start;
|
||||
numBytes = tokenPtr[1].size;
|
||||
|
||||
@@ -2979,6 +2979,17 @@ TclCompileEnsemble(
|
||||
|
||||
if (cmdPtr->compileProc == TclCompileEnsemble) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (parsePtr->numWords < depth + 1
|
||||
|| tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
|
||||
/*
|
||||
* Too hard because the user has done something unpleasant like
|
||||
* omitting the sub-ensemble's command name or used a non-constant
|
||||
* name for a sub-ensemble's command name; we respond by bailing
|
||||
* out completely (this is a rare case). [Bug 6d2f249a01]
|
||||
*/
|
||||
|
||||
goto cleanup;
|
||||
}
|
||||
ensemble = (Tcl_Command) cmdPtr;
|
||||
goto checkNextWord;
|
||||
}
|
||||
@@ -2997,6 +3008,23 @@ TclCompileEnsemble(
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/*
|
||||
* Throw out any line information generated by the failed compile attempt.
|
||||
*/
|
||||
|
||||
while (mapPtr->nuloc - 1 > eclIndex) {
|
||||
mapPtr->nuloc--;
|
||||
ckfree(mapPtr->loc[mapPtr->nuloc].line);
|
||||
mapPtr->loc[mapPtr->nuloc].line = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset the index of next command. Toss out any from failed nested
|
||||
* partial compiles.
|
||||
*/
|
||||
|
||||
envPtr->numCommands = mapPtr->nuloc;
|
||||
|
||||
/*
|
||||
* Failed to do a full compile for some reason. Try to do a direct invoke
|
||||
* instead of going through the ensemble lookup process again.
|
||||
@@ -3009,8 +3037,24 @@ TclCompileEnsemble(
|
||||
cmdPtr = oldCmdPtr;
|
||||
depth--;
|
||||
}
|
||||
(void) Tcl_ListObjReplace(NULL, replaced, depth, 2, 0, NULL);
|
||||
}
|
||||
/*
|
||||
* The length of the "replaced" list must be depth-1. Trim back
|
||||
* any extra elements that might have been appended by failing
|
||||
* pathways above.
|
||||
*/
|
||||
(void) Tcl_ListObjReplace(NULL, replaced, depth-1, INT_MAX, 0, NULL);
|
||||
|
||||
/*
|
||||
* TODO: Reconsider whether we ought to call CompileToInvokedCommand()
|
||||
* when depth==1. In that case we are choosing to emit the
|
||||
* INST_INVOKE_REPLACE bytecode when there is in fact no replacing
|
||||
* to be done. It would be equally functional and presumably more
|
||||
* performant to fall through to cleanup below, return TCL_ERROR,
|
||||
* and let the compiler harness emit the INST_INVOKE_STK
|
||||
* implementation for us.
|
||||
*/
|
||||
|
||||
CompileToInvokedCommand(interp, parsePtr, replaced, cmdPtr, envPtr);
|
||||
ourResult = TCL_OK;
|
||||
}
|
||||
|
||||
+2
-2
@@ -444,7 +444,7 @@ TclUnsetEnv(
|
||||
* that no = should be included, and Windows requires it.
|
||||
*/
|
||||
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__)
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
string = ckalloc(length + 2);
|
||||
memcpy(string, name, (size_t) length);
|
||||
string[length] = '=';
|
||||
@@ -453,7 +453,7 @@ TclUnsetEnv(
|
||||
string = ckalloc(length + 1);
|
||||
memcpy(string, name, (size_t) length);
|
||||
string[length] = '\0';
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
Tcl_UtfToExternalDString(NULL, string, -1, &envString);
|
||||
string = ckrealloc(string, Tcl_DStringLength(&envString) + 1);
|
||||
|
||||
+11
-4
@@ -119,6 +119,7 @@ static char * VwaitVarProc(ClientData clientData,
|
||||
Tcl_Interp *interp, const char *name1,
|
||||
const char *name2, int flags);
|
||||
static void InvokeExitHandlers(void);
|
||||
static void FinalizeThread(int quick);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -983,7 +984,7 @@ Tcl_Exit(
|
||||
* Tcl_Channels that may have data enqueued.
|
||||
*/
|
||||
|
||||
Tcl_FinalizeThread();
|
||||
FinalizeThread(/* quick */ 1);
|
||||
}
|
||||
TclpExit(status);
|
||||
Tcl_Panic("OS exit failed!");
|
||||
@@ -1183,7 +1184,7 @@ Tcl_Finalize(void)
|
||||
* This fixes the Tcl Bug #990552.
|
||||
*/
|
||||
|
||||
TclFinalizeThreadData();
|
||||
TclFinalizeThreadData(/* quick */ 0);
|
||||
|
||||
/*
|
||||
* Now we can free constants for conversions to/from double.
|
||||
@@ -1268,6 +1269,13 @@ Tcl_Finalize(void)
|
||||
|
||||
void
|
||||
Tcl_FinalizeThread(void)
|
||||
{
|
||||
FinalizeThread(/* quick */ 0);
|
||||
}
|
||||
|
||||
void
|
||||
FinalizeThread(
|
||||
int quick)
|
||||
{
|
||||
ExitHandler *exitPtr;
|
||||
ThreadSpecificData *tsdPtr;
|
||||
@@ -1309,8 +1317,7 @@ Tcl_FinalizeThread(void)
|
||||
*
|
||||
* Fix [Bug #571002]
|
||||
*/
|
||||
|
||||
TclFinalizeThreadData();
|
||||
TclFinalizeThreadData(quick);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+254
-43
@@ -81,9 +81,7 @@ int tclTraceExec = 0;
|
||||
|
||||
static const char *const operatorStrings[] = {
|
||||
"||", "&&", "|", "^", "&", "==", "!=", "<", ">", "<=", ">=", "<<", ">>",
|
||||
"+", "-", "*", "/", "%", "+", "-", "~", "!",
|
||||
"BUILTIN FUNCTION", "FUNCTION",
|
||||
"", "", "", "", "", "", "", "", "eq", "ne"
|
||||
"+", "-", "*", "/", "%", "+", "-", "~", "!"
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -555,30 +553,6 @@ VarHashCreateVar(
|
||||
? (*(boolPtr) = ((objPtr)->internalRep.longValue!=0), TCL_OK) \
|
||||
: Tcl_GetBooleanFromObj((interp), (objPtr), (boolPtr)))
|
||||
|
||||
/*
|
||||
* Macro used in this file to save a function call for common uses of
|
||||
* Tcl_GetWideIntFromObj(). The ANSI C "prototype" is:
|
||||
*
|
||||
* MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
* Tcl_WideInt *wideIntPtr);
|
||||
*/
|
||||
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(wideIntPtr) = (Tcl_WideInt) \
|
||||
((objPtr)->internalRep.longValue), TCL_OK) : \
|
||||
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
|
||||
#else /* !TCL_WIDE_INT_IS_LONG */
|
||||
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
|
||||
(((objPtr)->typePtr == &tclWideIntType) \
|
||||
? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \
|
||||
((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(wideIntPtr) = (Tcl_WideInt) \
|
||||
((objPtr)->internalRep.longValue), TCL_OK) : \
|
||||
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
/*
|
||||
* Macro used to make the check for type overflow more mnemonic. This works by
|
||||
* comparing sign bits; the rest of the word is irrelevant. The ANSI C
|
||||
@@ -2228,10 +2202,6 @@ TEBCresume(
|
||||
} else {
|
||||
/* resume from invocation */
|
||||
CACHE_STACK_INFO();
|
||||
if (iPtr->execEnvPtr->rewind) {
|
||||
result = TCL_ERROR;
|
||||
goto abnormalReturn;
|
||||
}
|
||||
|
||||
NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr);
|
||||
if (bcFramePtr->cmdObj) {
|
||||
@@ -2243,6 +2213,10 @@ TEBCresume(
|
||||
if (iPtr->flags & INTERP_DEBUG_FRAME) {
|
||||
TclArgumentBCRelease(interp, bcFramePtr);
|
||||
}
|
||||
if (iPtr->execEnvPtr->rewind) {
|
||||
result = TCL_ERROR;
|
||||
goto abnormalReturn;
|
||||
}
|
||||
if (codePtr->flags & TCL_BYTECODE_RECOMPILE) {
|
||||
iPtr->flags |= ERR_ALREADY_LOGGED;
|
||||
codePtr->flags &= ~TCL_BYTECODE_RECOMPILE;
|
||||
@@ -3371,7 +3345,7 @@ TEBCresume(
|
||||
*/
|
||||
|
||||
{
|
||||
int storeFlags;
|
||||
int storeFlags, len;
|
||||
|
||||
case INST_STORE_ARRAY4:
|
||||
opnd = TclGetUInt4AtPtr(pc+1);
|
||||
@@ -3611,6 +3585,171 @@ TEBCresume(
|
||||
#endif
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(pcAdjustment, cleanup, 1);
|
||||
|
||||
case INST_LAPPEND_LIST:
|
||||
opnd = TclGetUInt4AtPtr(pc+1);
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
varPtr = LOCAL(opnd);
|
||||
cleanup = 1;
|
||||
pcAdjustment = 5;
|
||||
while (TclIsVarLink(varPtr)) {
|
||||
varPtr = varPtr->value.linkPtr;
|
||||
}
|
||||
TRACE(("%u <- \"%.30s\" => ", opnd, O2S(valuePtr)));
|
||||
if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
|
||||
!= TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
if (TclIsVarDirectReadable(varPtr)
|
||||
&& TclIsVarDirectWritable(varPtr)) {
|
||||
goto lappendListDirect;
|
||||
}
|
||||
arrayPtr = NULL;
|
||||
part1Ptr = part2Ptr = NULL;
|
||||
goto lappendListPtr;
|
||||
|
||||
case INST_LAPPEND_LIST_ARRAY:
|
||||
opnd = TclGetUInt4AtPtr(pc+1);
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
part1Ptr = NULL;
|
||||
part2Ptr = OBJ_UNDER_TOS;
|
||||
arrayPtr = LOCAL(opnd);
|
||||
cleanup = 2;
|
||||
pcAdjustment = 5;
|
||||
while (TclIsVarLink(arrayPtr)) {
|
||||
arrayPtr = arrayPtr->value.linkPtr;
|
||||
}
|
||||
TRACE(("%u \"%.30s\" \"%.30s\" => ",
|
||||
opnd, O2S(part2Ptr), O2S(valuePtr)));
|
||||
if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
|
||||
!= TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)
|
||||
&& !WriteTraced(arrayPtr)) {
|
||||
varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
|
||||
if (varPtr && TclIsVarDirectReadable(varPtr)
|
||||
&& TclIsVarDirectWritable(varPtr)) {
|
||||
goto lappendListDirect;
|
||||
}
|
||||
}
|
||||
varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
|
||||
TCL_LEAVE_ERR_MSG, "set", 1, 1, arrayPtr, opnd);
|
||||
if (varPtr == NULL) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
goto lappendListPtr;
|
||||
|
||||
case INST_LAPPEND_LIST_ARRAY_STK:
|
||||
pcAdjustment = 1;
|
||||
cleanup = 3;
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
part2Ptr = OBJ_UNDER_TOS; /* element name */
|
||||
part1Ptr = OBJ_AT_DEPTH(2); /* array name */
|
||||
TRACE(("\"%.30s(%.30s)\" \"%.30s\" => ",
|
||||
O2S(part1Ptr), O2S(part2Ptr), O2S(valuePtr)));
|
||||
goto lappendList;
|
||||
|
||||
case INST_LAPPEND_LIST_STK:
|
||||
pcAdjustment = 1;
|
||||
cleanup = 2;
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
part2Ptr = NULL;
|
||||
part1Ptr = OBJ_UNDER_TOS; /* variable name */
|
||||
TRACE(("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(valuePtr)));
|
||||
goto lappendList;
|
||||
|
||||
lappendListDirect:
|
||||
objResultPtr = varPtr->value.objPtr;
|
||||
if (TclListObjLength(interp, objResultPtr, &len) != TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
if (Tcl_IsShared(objResultPtr)) {
|
||||
Tcl_Obj *newValue = Tcl_DuplicateObj(objResultPtr);
|
||||
|
||||
TclDecrRefCount(objResultPtr);
|
||||
varPtr->value.objPtr = objResultPtr = newValue;
|
||||
Tcl_IncrRefCount(newValue);
|
||||
}
|
||||
if (Tcl_ListObjReplace(interp, objResultPtr, len, 0, objc, objv)
|
||||
!= TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(pcAdjustment, cleanup, 1);
|
||||
|
||||
lappendList:
|
||||
opnd = -1;
|
||||
if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
|
||||
!= TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
DECACHE_STACK_INFO();
|
||||
varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
|
||||
TCL_LEAVE_ERR_MSG, "set", 1, 1, &arrayPtr);
|
||||
CACHE_STACK_INFO();
|
||||
if (!varPtr) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
lappendListPtr:
|
||||
if (TclIsVarInHash(varPtr)) {
|
||||
VarHashRefCount(varPtr)++;
|
||||
}
|
||||
if (arrayPtr && TclIsVarInHash(arrayPtr)) {
|
||||
VarHashRefCount(arrayPtr)++;
|
||||
}
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrGetVar(interp, varPtr, arrayPtr,
|
||||
part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (TclIsVarInHash(varPtr)) {
|
||||
VarHashRefCount(varPtr)--;
|
||||
}
|
||||
if (arrayPtr && TclIsVarInHash(arrayPtr)) {
|
||||
VarHashRefCount(arrayPtr)--;
|
||||
}
|
||||
|
||||
{
|
||||
int createdNewObj = 0;
|
||||
|
||||
if (!objResultPtr) {
|
||||
objResultPtr = valuePtr;
|
||||
} else if (TclListObjLength(interp, objResultPtr, &len)!=TCL_OK) {
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
} else {
|
||||
if (Tcl_IsShared(objResultPtr)) {
|
||||
objResultPtr = Tcl_DuplicateObj(objResultPtr);
|
||||
createdNewObj = 1;
|
||||
}
|
||||
if (Tcl_ListObjReplace(interp, objResultPtr, len,0, objc,objv)
|
||||
!= TCL_OK) {
|
||||
goto errorInLappendListPtr;
|
||||
}
|
||||
}
|
||||
DECACHE_STACK_INFO();
|
||||
objResultPtr = TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr,
|
||||
part2Ptr, objResultPtr, TCL_LEAVE_ERR_MSG, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (!objResultPtr) {
|
||||
errorInLappendListPtr:
|
||||
if (createdNewObj) {
|
||||
TclDecrRefCount(objResultPtr);
|
||||
}
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
}
|
||||
}
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(pcAdjustment, cleanup, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -4938,7 +5077,7 @@ TEBCresume(
|
||||
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
opnd = TclGetInt4AtPtr(pc+1);
|
||||
TRACE(("\%.30s\" %d => ", O2S(valuePtr), opnd));
|
||||
TRACE(("\"%.30s\" %d => ", O2S(valuePtr), opnd));
|
||||
|
||||
/*
|
||||
* Get the contents of the list, making sure that it really is a list
|
||||
@@ -5271,8 +5410,8 @@ TEBCresume(
|
||||
s1 = (char *) Tcl_GetByteArrayFromObj(valuePtr, &s1len);
|
||||
s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
|
||||
memCmpFn = memcmp;
|
||||
} else if (((valuePtr->typePtr == &tclStringType)
|
||||
&& (value2Ptr->typePtr == &tclStringType))) {
|
||||
} else if ((valuePtr->typePtr == &tclStringType)
|
||||
&& (value2Ptr->typePtr == &tclStringType)) {
|
||||
/*
|
||||
* Do a unicode-specific comparison if both of the args are of
|
||||
* String type. If the char length == byte length, we can do a
|
||||
@@ -5283,7 +5422,9 @@ TEBCresume(
|
||||
s1len = Tcl_GetCharLength(valuePtr);
|
||||
s2len = Tcl_GetCharLength(value2Ptr);
|
||||
if ((s1len == valuePtr->length)
|
||||
&& (s2len == value2Ptr->length)) {
|
||||
&& (valuePtr->bytes != NULL)
|
||||
&& (s2len == value2Ptr->length)
|
||||
&& (value2Ptr->bytes != NULL)) {
|
||||
s1 = valuePtr->bytes;
|
||||
s2 = value2Ptr->bytes;
|
||||
memCmpFn = memcmp;
|
||||
@@ -5392,6 +5533,7 @@ TEBCresume(
|
||||
} else {
|
||||
length = Tcl_UtfToUpper(TclGetString(valuePtr));
|
||||
Tcl_SetObjLength(valuePtr, length);
|
||||
TclFreeIntRep(valuePtr);
|
||||
TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
}
|
||||
@@ -5408,6 +5550,7 @@ TEBCresume(
|
||||
} else {
|
||||
length = Tcl_UtfToLower(TclGetString(valuePtr));
|
||||
Tcl_SetObjLength(valuePtr, length);
|
||||
TclFreeIntRep(valuePtr);
|
||||
TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
}
|
||||
@@ -5424,6 +5567,7 @@ TEBCresume(
|
||||
} else {
|
||||
length = Tcl_UtfToTitle(TclGetString(valuePtr));
|
||||
Tcl_SetObjLength(valuePtr, length);
|
||||
TclFreeIntRep(valuePtr);
|
||||
TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
}
|
||||
@@ -5622,6 +5766,7 @@ TEBCresume(
|
||||
((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0;
|
||||
}
|
||||
Tcl_InvalidateStringRep(objResultPtr);
|
||||
TclDecrRefCount(value3Ptr);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
} else {
|
||||
@@ -5648,6 +5793,7 @@ TEBCresume(
|
||||
((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0;
|
||||
}
|
||||
Tcl_InvalidateStringRep(valuePtr);
|
||||
TclDecrRefCount(value3Ptr);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
}
|
||||
@@ -5699,11 +5845,21 @@ TEBCresume(
|
||||
length - toIdx);
|
||||
}
|
||||
} else {
|
||||
objResultPtr = value3Ptr;
|
||||
/*
|
||||
* Be careful with splicing the stack in this case; we have a
|
||||
* refCount:1 object in value3Ptr and we want to append to it and
|
||||
* make it be the refCount:1 object at the top of the stack
|
||||
* afterwards. [Bug 82e7f67325]
|
||||
*/
|
||||
|
||||
if (toIdx < length) {
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
|
||||
Tcl_AppendUnicodeToObj(value3Ptr, ustring1 + toIdx + 1,
|
||||
length - toIdx);
|
||||
}
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr)));
|
||||
TclDecrRefCount(valuePtr);
|
||||
OBJ_AT_TOS = value3Ptr; /* Tricky! */
|
||||
NEXT_INST_F(1, 0, 0);
|
||||
}
|
||||
TclDecrRefCount(value3Ptr);
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
|
||||
@@ -5905,14 +6061,34 @@ TEBCresume(
|
||||
trim2 = 0;
|
||||
}
|
||||
createTrimmedString:
|
||||
/*
|
||||
* Careful here; trim set often contains non-ASCII characters so we
|
||||
* take care when printing. [Bug 971cb4f1db]
|
||||
*/
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (traceInstructions) {
|
||||
TRACE(("\"%.30s\" ", O2S(valuePtr)));
|
||||
TclPrintObject(stdout, value2Ptr, 30);
|
||||
printf(" => ");
|
||||
}
|
||||
#endif
|
||||
if (trim1 == 0 && trim2 == 0) {
|
||||
TRACE_WITH_OBJ(("\"%.30s\" \"%.30s\" => ",
|
||||
O2S(valuePtr), O2S(value2Ptr)), valuePtr);
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (traceInstructions) {
|
||||
TclPrintObject(stdout, valuePtr, 30);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
NEXT_INST_F(1, 1, 0);
|
||||
} else {
|
||||
objResultPtr = Tcl_NewStringObj(string1+trim1, length-trim1-trim2);
|
||||
TRACE_WITH_OBJ(("\"%.30s\" \"%.30s\" => ",
|
||||
O2S(valuePtr), O2S(value2Ptr)), objResultPtr);
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (traceInstructions) {
|
||||
TclPrintObject(stdout, objResultPtr, 30);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
NEXT_INST_F(1, 2, 1);
|
||||
}
|
||||
}
|
||||
@@ -5966,6 +6142,31 @@ TEBCresume(
|
||||
case INST_NUM_TYPE:
|
||||
if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) {
|
||||
type1 = 0;
|
||||
} else if (type1 == TCL_NUMBER_LONG) {
|
||||
/* value is between LONG_MIN and LONG_MAX */
|
||||
/* [string is integer] is -UINT_MAX to UINT_MAX range */
|
||||
int i;
|
||||
|
||||
if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) != TCL_OK) {
|
||||
type1 = TCL_NUMBER_WIDE;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else if (type1 == TCL_NUMBER_WIDE) {
|
||||
/* value is between WIDE_MIN and WIDE_MAX */
|
||||
/* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
|
||||
int i;
|
||||
if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) {
|
||||
type1 = TCL_NUMBER_LONG;
|
||||
}
|
||||
#endif
|
||||
} else if (type1 == TCL_NUMBER_BIG) {
|
||||
/* value is an integer outside the WIDE_MIN to WIDE_MAX range */
|
||||
/* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
|
||||
Tcl_WideInt w;
|
||||
|
||||
if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) {
|
||||
type1 = TCL_NUMBER_WIDE;
|
||||
}
|
||||
}
|
||||
TclNewIntObj(objResultPtr, type1);
|
||||
TRACE(("\"%.20s\" => %d\n", O2S(OBJ_AT_TOS), type1));
|
||||
@@ -7440,6 +7641,14 @@ TEBCresume(
|
||||
searchPtr = ckalloc(sizeof(Tcl_DictSearch));
|
||||
if (Tcl_DictObjFirst(interp, dictPtr, searchPtr, &keyPtr,
|
||||
&valuePtr, &done) != TCL_OK) {
|
||||
|
||||
/*
|
||||
* dictPtr is no longer on the stack, and we're not
|
||||
* moving it into the intrep of an iterator. We need
|
||||
* to drop the refcount [Tcl Bug 9b352768e6].
|
||||
*/
|
||||
|
||||
Tcl_DecrRefCount(dictPtr);
|
||||
ckfree(searchPtr);
|
||||
TRACE_ERROR(interp);
|
||||
goto gotError;
|
||||
@@ -9617,10 +9826,12 @@ IllegalExprOperandType(
|
||||
ClientData ptr;
|
||||
int type;
|
||||
const unsigned char opcode = *pc;
|
||||
const char *description, *operator = operatorStrings[opcode - INST_LOR];
|
||||
const char *description, *operator = "unknown";
|
||||
|
||||
if (opcode == INST_EXPON) {
|
||||
operator = "**";
|
||||
} else if (opcode <= INST_LNOT) {
|
||||
operator = operatorStrings[opcode - INST_LOR];
|
||||
}
|
||||
|
||||
if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) {
|
||||
|
||||
+2
-2
@@ -517,7 +517,7 @@ CopyRenameOneFile(
|
||||
* 16 bits and we get collisions. See bug #2015723.
|
||||
*/
|
||||
|
||||
#if !defined(WIN32) && !defined(__CYGWIN__)
|
||||
#if !defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if ((sourceStatBuf.st_ino != 0) && (targetStatBuf.st_ino != 0)) {
|
||||
if ((sourceStatBuf.st_ino == targetStatBuf.st_ino) &&
|
||||
(sourceStatBuf.st_dev == targetStatBuf.st_dev)) {
|
||||
@@ -1196,7 +1196,7 @@ TclFileLinkCmd(
|
||||
static const char *const linkTypes[] = {
|
||||
"-symbolic", "-hard", NULL
|
||||
};
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], linkTypes, "switch", 0,
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], linkTypes, "option", 0,
|
||||
&linkAction) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -235,9 +235,9 @@ ExtractWinRoot(
|
||||
if ((path[0] == 'c' || path[0] == 'C')
|
||||
&& (path[1] == 'o' || path[1] == 'O')) {
|
||||
if ((path[2] == 'm' || path[2] == 'M')
|
||||
&& path[3] >= '1' && path[3] <= '4') {
|
||||
&& path[3] >= '1' && path[3] <= '9') {
|
||||
/*
|
||||
* May have match for 'com[1-4]:?', which is a serial port.
|
||||
* May have match for 'com[1-9]:?', which is a serial port.
|
||||
*/
|
||||
|
||||
if (path[4] == '\0') {
|
||||
@@ -257,9 +257,9 @@ ExtractWinRoot(
|
||||
} else if ((path[0] == 'l' || path[0] == 'L')
|
||||
&& (path[1] == 'p' || path[1] == 'P')
|
||||
&& (path[2] == 't' || path[2] == 'T')) {
|
||||
if (path[3] >= '1' && path[3] <= '3') {
|
||||
if (path[3] >= '1' && path[3] <= '9') {
|
||||
/*
|
||||
* May have match for 'lpt[1-3]:?'
|
||||
* May have match for 'lpt[1-9]:?'
|
||||
*/
|
||||
|
||||
if (path[4] == '\0') {
|
||||
|
||||
+1702
-2052
File diff suppressed because it is too large
Load Diff
+3
-31
@@ -36,6 +36,7 @@
|
||||
*/
|
||||
|
||||
typedef struct ChannelBuffer {
|
||||
int refCount; /* Current uses count */
|
||||
int nextAdded; /* The next position into which a character
|
||||
* will be put in the buffer. */
|
||||
int nextRemoved; /* Position of next byte to be removed from
|
||||
@@ -111,6 +112,8 @@ typedef struct Channel {
|
||||
|
||||
ChannelBuffer *inQueueHead; /* Points at first buffer in input queue. */
|
||||
ChannelBuffer *inQueueTail; /* Points at last buffer in input queue. */
|
||||
|
||||
int refCount;
|
||||
} Channel;
|
||||
|
||||
/*
|
||||
@@ -226,11 +229,6 @@ typedef struct ChannelState {
|
||||
* flushed after every newline. */
|
||||
#define CHANNEL_UNBUFFERED (1<<5) /* Output to the channel must always
|
||||
* be flushed immediately. */
|
||||
#define BUFFER_READY (1<<6) /* Current output buffer (the
|
||||
* curOutPtr field in the channel
|
||||
* structure) should be output as soon
|
||||
* as possible even though it may not
|
||||
* be full. */
|
||||
#define BG_FLUSH_SCHEDULED (1<<7) /* A background flush of the queued
|
||||
* output buffers has been
|
||||
* scheduled. */
|
||||
@@ -252,9 +250,6 @@ typedef struct ChannelState {
|
||||
#define INPUT_SAW_CR (1<<12) /* Channel is in CRLF eol input
|
||||
* translation mode and the last byte
|
||||
* seen was a "\r". */
|
||||
#define INPUT_NEED_NL (1<<15) /* Saw a '\r' at end of last buffer,
|
||||
* and there should be a '\n' at
|
||||
* beginning of next buffer. */
|
||||
#define CHANNEL_DEAD (1<<13) /* The channel has been closed by the
|
||||
* exit handler (on exit) but not
|
||||
* deallocated. When any IO operation
|
||||
@@ -274,29 +269,6 @@ typedef struct ChannelState {
|
||||
* changes. */
|
||||
#define CHANNEL_RAW_MODE (1<<16) /* When set, notes that the Raw API is
|
||||
* being used. */
|
||||
#ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
|
||||
#define CHANNEL_TIMER_FEV (1<<17) /* When set the event we are notified
|
||||
* by is a fileevent generated by a
|
||||
* timer. We don't know if the driver
|
||||
* has more data and should not try to
|
||||
* read from it. If the system needs
|
||||
* more than is in the buffers out
|
||||
* read routines will simulate a short
|
||||
* read (0 characters read) */
|
||||
#define CHANNEL_HAS_MORE_DATA (1<<18) /* Set by NotifyChannel for a channel
|
||||
* if and only if the channel is
|
||||
* configured non-blocking, the driver
|
||||
* for said channel has no
|
||||
* blockmodeproc, and data has arrived
|
||||
* for reading at the OS level). A
|
||||
* GetInput will pass reading from the
|
||||
* driver if the channel is
|
||||
* non-blocking, without blockmode
|
||||
* proc and the flag has not been set.
|
||||
* A read will be performed if the
|
||||
* flag is set. This will reset the
|
||||
* flag as well. */
|
||||
#endif /* TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING */
|
||||
|
||||
#define CHANNEL_INCLOSE (1<<19) /* Channel is currently being closed.
|
||||
* Its structures are still live and
|
||||
|
||||
+30
-7
@@ -181,6 +181,7 @@ Tcl_PutsObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclChannelPreserve(chan);
|
||||
result = Tcl_WriteObj(chan, string);
|
||||
if (result < 0) {
|
||||
goto error;
|
||||
@@ -191,6 +192,7 @@ Tcl_PutsObjCmd(
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
TclChannelRelease(chan);
|
||||
return TCL_OK;
|
||||
|
||||
/*
|
||||
@@ -205,6 +207,7 @@ Tcl_PutsObjCmd(
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
TclChannelRelease(chan);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -252,6 +255,7 @@ Tcl_FlushObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclChannelPreserve(chan);
|
||||
if (Tcl_Flush(chan) != TCL_OK) {
|
||||
/*
|
||||
* TIP #219.
|
||||
@@ -265,8 +269,10 @@ Tcl_FlushObjCmd(
|
||||
"error flushing \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
TclChannelRelease(chan);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclChannelRelease(chan);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -299,6 +305,7 @@ Tcl_GetsObjCmd(
|
||||
int lineLen; /* Length of line just read. */
|
||||
int mode; /* Mode in which channel is opened. */
|
||||
Tcl_Obj *linePtr, *chanObjPtr;
|
||||
int code = TCL_OK;
|
||||
|
||||
if ((objc != 2) && (objc != 3)) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?");
|
||||
@@ -315,6 +322,7 @@ Tcl_GetsObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclChannelPreserve(chan);
|
||||
linePtr = Tcl_NewObj();
|
||||
lineLen = Tcl_GetsObj(chan, linePtr);
|
||||
if (lineLen < 0) {
|
||||
@@ -333,20 +341,24 @@ Tcl_GetsObjCmd(
|
||||
"error reading \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
lineLen = -1;
|
||||
}
|
||||
if (objc == 3) {
|
||||
if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
return TCL_ERROR;
|
||||
code = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(lineLen));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, linePtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
done:
|
||||
TclChannelRelease(chan);
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -453,6 +465,7 @@ Tcl_ReadObjCmd(
|
||||
|
||||
resultPtr = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(resultPtr);
|
||||
TclChannelPreserve(chan);
|
||||
charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 0);
|
||||
if (charactersRead < 0) {
|
||||
/*
|
||||
@@ -467,6 +480,7 @@ Tcl_ReadObjCmd(
|
||||
"error reading \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
TclChannelRelease(chan);
|
||||
Tcl_DecrRefCount(resultPtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -485,6 +499,7 @@ Tcl_ReadObjCmd(
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
TclChannelRelease(chan);
|
||||
Tcl_DecrRefCount(resultPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -544,6 +559,7 @@ Tcl_SeekObjCmd(
|
||||
mode = modeArray[optionIndex];
|
||||
}
|
||||
|
||||
TclChannelPreserve(chan);
|
||||
result = Tcl_Seek(chan, offset, mode);
|
||||
if (result == Tcl_LongAsWide(-1)) {
|
||||
/*
|
||||
@@ -558,8 +574,10 @@ Tcl_SeekObjCmd(
|
||||
"error during seek on \"%s\": %s",
|
||||
TclGetString(objv[1]), Tcl_PosixError(interp)));
|
||||
}
|
||||
TclChannelRelease(chan);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclChannelRelease(chan);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -590,6 +608,7 @@ Tcl_TellObjCmd(
|
||||
{
|
||||
Tcl_Channel chan; /* The channel to tell on. */
|
||||
Tcl_WideInt newLoc;
|
||||
int code;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "channelId");
|
||||
@@ -605,6 +624,7 @@ Tcl_TellObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclChannelPreserve(chan);
|
||||
newLoc = Tcl_Tell(chan);
|
||||
|
||||
/*
|
||||
@@ -613,7 +633,10 @@ Tcl_TellObjCmd(
|
||||
* them into the regular interpreter result.
|
||||
*/
|
||||
|
||||
if (TclChanCaughtErrorBypass(interp, chan)) {
|
||||
|
||||
code = TclChanCaughtErrorBypass(interp, chan);
|
||||
TclChannelRelease(chan);
|
||||
if (code) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -896,7 +919,7 @@ Tcl_ExecObjCmd(
|
||||
if (string[0] != '-') {
|
||||
break;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[skip], options, "switch",
|
||||
if (Tcl_GetIndexFromObj(interp, objv[skip], options, "option",
|
||||
TCL_EXACT, &index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -910,7 +933,7 @@ Tcl_ExecObjCmd(
|
||||
}
|
||||
}
|
||||
if (objc <= skip) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?-switch ...? arg ?arg ...?");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?-option ...? arg ?arg ...?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1673,7 +1696,7 @@ Tcl_FcopyObjCmd(
|
||||
toRead = -1;
|
||||
cmdPtr = NULL;
|
||||
for (i = 3; i < objc; i += 2) {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], switches, "switch", 0,
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0,
|
||||
&index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+125
-80
@@ -187,6 +187,7 @@ struct TransformChannelData {
|
||||
Tcl_Channel self; /* Our own Channel handle. */
|
||||
int readIsFlushed; /* Flag to note whether in.flushProc was
|
||||
* called or not. */
|
||||
int eofPending; /* Flag: EOF seen down, not raised up */
|
||||
int flags; /* Currently CHANNEL_ASYNC or zero. */
|
||||
int watchMask; /* Current watch/event/interest mask. */
|
||||
int mode; /* Mode of parent channel, OR'ed combination
|
||||
@@ -210,7 +211,27 @@ struct TransformChannelData {
|
||||
* a transformation of incoming data. Also
|
||||
* serves as buffer of all data not yet
|
||||
* consumed by the reader. */
|
||||
int refCount;
|
||||
};
|
||||
|
||||
static void
|
||||
PreserveData(
|
||||
TransformChannelData *dataPtr)
|
||||
{
|
||||
dataPtr->refCount++;
|
||||
}
|
||||
|
||||
static void
|
||||
ReleaseData(
|
||||
TransformChannelData *dataPtr)
|
||||
{
|
||||
if (--dataPtr->refCount) {
|
||||
return;
|
||||
}
|
||||
ResultClear(&dataPtr->result);
|
||||
Tcl_DecrRefCount(dataPtr->command);
|
||||
ckfree(dataPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -240,6 +261,7 @@ TclChannelTransform(
|
||||
Channel *chanPtr; /* The actual channel. */
|
||||
ChannelState *statePtr; /* State info for channel. */
|
||||
int mode; /* Read/write mode of the channel. */
|
||||
int objc;
|
||||
TransformChannelData *dataPtr;
|
||||
Tcl_DString ds;
|
||||
|
||||
@@ -247,6 +269,12 @@ TclChannelTransform(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (TCL_OK != Tcl_ListObjLength(interp, cmdObjPtr, &objc)) {
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewStringObj("-command value is not a list", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
chanPtr = (Channel *) chan;
|
||||
statePtr = chanPtr->state;
|
||||
chanPtr = statePtr->topChanPtr;
|
||||
@@ -261,16 +289,17 @@ TclChannelTransform(
|
||||
|
||||
dataPtr = ckalloc(sizeof(TransformChannelData));
|
||||
|
||||
dataPtr->refCount = 1;
|
||||
Tcl_DStringInit(&ds);
|
||||
Tcl_GetChannelOption(interp, chan, "-blocking", &ds);
|
||||
dataPtr->readIsFlushed = 0;
|
||||
dataPtr->eofPending = 0;
|
||||
dataPtr->flags = 0;
|
||||
if (ds.string[0] == '0') {
|
||||
dataPtr->flags |= CHANNEL_ASYNC;
|
||||
}
|
||||
Tcl_DStringFree(&ds);
|
||||
|
||||
dataPtr->self = chan;
|
||||
dataPtr->watchMask = 0;
|
||||
dataPtr->mode = mode;
|
||||
dataPtr->timer = NULL;
|
||||
@@ -286,19 +315,20 @@ TclChannelTransform(
|
||||
if (dataPtr->self == NULL) {
|
||||
Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp),
|
||||
"\nfailed to stack channel \"%s\"", Tcl_GetChannelName(chan));
|
||||
Tcl_DecrRefCount(dataPtr->command);
|
||||
ResultClear(&dataPtr->result);
|
||||
ckfree(dataPtr);
|
||||
ReleaseData(dataPtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_Preserve(dataPtr->self);
|
||||
|
||||
/*
|
||||
* At last initialize the transformation at the script level.
|
||||
*/
|
||||
|
||||
PreserveData(dataPtr);
|
||||
if ((dataPtr->mode & TCL_WRITABLE) && ExecuteCallback(dataPtr, NULL,
|
||||
A_CREATE_WRITE, NULL, 0, TRANSMIT_DONT, P_NO_PRESERVE) != TCL_OK){
|
||||
Tcl_UnstackChannel(interp, chan);
|
||||
ReleaseData(dataPtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -307,9 +337,11 @@ TclChannelTransform(
|
||||
ExecuteCallback(dataPtr, NULL, A_DELETE_WRITE, NULL, 0, TRANSMIT_DONT,
|
||||
P_NO_PRESERVE);
|
||||
Tcl_UnstackChannel(interp, chan);
|
||||
ReleaseData(dataPtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
ReleaseData(dataPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -350,7 +382,10 @@ ExecuteCallback(
|
||||
unsigned char *resBuf;
|
||||
Tcl_InterpState state = NULL;
|
||||
int res = TCL_OK;
|
||||
Tcl_Obj *command = Tcl_DuplicateObj(dataPtr->command);
|
||||
Tcl_Obj *command = TclListObjCopy(NULL, dataPtr->command);
|
||||
Tcl_Interp *eval = dataPtr->interp;
|
||||
|
||||
Tcl_Preserve(eval);
|
||||
|
||||
/*
|
||||
* Step 1, create the complete command to execute. Do this by appending
|
||||
@@ -361,26 +396,18 @@ ExecuteCallback(
|
||||
*/
|
||||
|
||||
if (preserve == P_PRESERVE) {
|
||||
state = Tcl_SaveInterpState(dataPtr->interp, res);
|
||||
state = Tcl_SaveInterpState(eval, res);
|
||||
}
|
||||
|
||||
Tcl_IncrRefCount(command);
|
||||
res = Tcl_ListObjAppendElement(dataPtr->interp, command,
|
||||
Tcl_NewStringObj((char *) op, -1));
|
||||
if (res != TCL_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, command, Tcl_NewStringObj((char *) op, -1));
|
||||
|
||||
/*
|
||||
* Use a byte-array to prevent the misinterpretation of binary data coming
|
||||
* through as UTF while at the tcl level.
|
||||
*/
|
||||
|
||||
res = Tcl_ListObjAppendElement(dataPtr->interp, command,
|
||||
Tcl_NewByteArrayObj(buf, bufLen));
|
||||
if (res != TCL_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, command, Tcl_NewByteArrayObj(buf, bufLen));
|
||||
|
||||
/*
|
||||
* Step 2, execute the command at the global level of the interpreter used
|
||||
@@ -390,13 +417,14 @@ ExecuteCallback(
|
||||
* current interpreter. Don't copy if in preservation mode.
|
||||
*/
|
||||
|
||||
res = Tcl_EvalObjEx(dataPtr->interp, command, TCL_EVAL_GLOBAL);
|
||||
res = Tcl_EvalObjEx(eval, command, TCL_EVAL_GLOBAL);
|
||||
Tcl_DecrRefCount(command);
|
||||
command = NULL;
|
||||
|
||||
if ((res != TCL_OK) && (interp != NULL) && (dataPtr->interp != interp)
|
||||
if ((res != TCL_OK) && (interp != NULL) && (eval != interp)
|
||||
&& (preserve == P_NO_PRESERVE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_GetObjResult(dataPtr->interp));
|
||||
Tcl_SetObjResult(interp, Tcl_GetObjResult(eval));
|
||||
Tcl_Release(eval);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -411,20 +439,26 @@ ExecuteCallback(
|
||||
break;
|
||||
|
||||
case TRANSMIT_DOWN:
|
||||
resObj = Tcl_GetObjResult(dataPtr->interp);
|
||||
if (dataPtr->self == NULL) {
|
||||
break;
|
||||
}
|
||||
resObj = Tcl_GetObjResult(eval);
|
||||
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
|
||||
Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf,
|
||||
resLen);
|
||||
break;
|
||||
|
||||
case TRANSMIT_SELF:
|
||||
resObj = Tcl_GetObjResult(dataPtr->interp);
|
||||
if (dataPtr->self == NULL) {
|
||||
break;
|
||||
}
|
||||
resObj = Tcl_GetObjResult(eval);
|
||||
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
|
||||
Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen);
|
||||
break;
|
||||
|
||||
case TRANSMIT_IBUF:
|
||||
resObj = Tcl_GetObjResult(dataPtr->interp);
|
||||
resObj = Tcl_GetObjResult(eval);
|
||||
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
|
||||
ResultAdd(&dataPtr->result, resBuf, resLen);
|
||||
break;
|
||||
@@ -434,24 +468,16 @@ ExecuteCallback(
|
||||
* Interpret result as integer number.
|
||||
*/
|
||||
|
||||
resObj = Tcl_GetObjResult(dataPtr->interp);
|
||||
TclGetIntFromObj(dataPtr->interp, resObj, &dataPtr->maxRead);
|
||||
resObj = Tcl_GetObjResult(eval);
|
||||
TclGetIntFromObj(eval, resObj, &dataPtr->maxRead);
|
||||
break;
|
||||
}
|
||||
|
||||
Tcl_ResetResult(dataPtr->interp);
|
||||
Tcl_ResetResult(eval);
|
||||
if (preserve == P_PRESERVE) {
|
||||
(void) Tcl_RestoreInterpState(dataPtr->interp, state);
|
||||
}
|
||||
return res;
|
||||
|
||||
cleanup:
|
||||
if (preserve == P_PRESERVE) {
|
||||
(void) Tcl_RestoreInterpState(dataPtr->interp, state);
|
||||
}
|
||||
if (command != NULL) {
|
||||
Tcl_DecrRefCount(command);
|
||||
(void) Tcl_RestoreInterpState(eval, state);
|
||||
}
|
||||
Tcl_Release(eval);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -535,6 +561,7 @@ TransformCloseProc(
|
||||
* system rely on (f.e. signaling the close to interested parties).
|
||||
*/
|
||||
|
||||
PreserveData(dataPtr);
|
||||
if (dataPtr->mode & TCL_WRITABLE) {
|
||||
ExecuteCallback(dataPtr, interp, A_FLUSH_WRITE, NULL, 0,
|
||||
TRANSMIT_DOWN, P_PRESERVE);
|
||||
@@ -554,14 +581,15 @@ TransformCloseProc(
|
||||
ExecuteCallback(dataPtr, interp, A_DELETE_READ, NULL, 0,
|
||||
TRANSMIT_DONT, P_PRESERVE);
|
||||
}
|
||||
ReleaseData(dataPtr);
|
||||
|
||||
/*
|
||||
* General cleanup.
|
||||
*/
|
||||
|
||||
ResultClear(&dataPtr->result);
|
||||
Tcl_DecrRefCount(dataPtr->command);
|
||||
ckfree(dataPtr);
|
||||
Tcl_Release(dataPtr->self);
|
||||
dataPtr->self = NULL;
|
||||
ReleaseData(dataPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -596,9 +624,9 @@ TransformInputProc(
|
||||
* Should assert(dataPtr->mode & TCL_READABLE);
|
||||
*/
|
||||
|
||||
if (toRead == 0) {
|
||||
if (toRead == 0 || dataPtr->self == NULL) {
|
||||
/*
|
||||
* Catch a no-op.
|
||||
* Catch a no-op. TODO: Is this a panic()?
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
@@ -606,6 +634,7 @@ TransformInputProc(
|
||||
gotBytes = 0;
|
||||
downChan = Tcl_GetStackedChannel(dataPtr->self);
|
||||
|
||||
PreserveData(dataPtr);
|
||||
while (toRead > 0) {
|
||||
/*
|
||||
* Loop until the request is satisfied (or no data is available from
|
||||
@@ -623,7 +652,7 @@ TransformInputProc(
|
||||
* break out of the loop and return to the caller.
|
||||
*/
|
||||
|
||||
return gotBytes;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -647,7 +676,18 @@ TransformInputProc(
|
||||
}
|
||||
} /* else: 'maxRead < 0' == Accept the current value of toRead. */
|
||||
if (toRead <= 0) {
|
||||
return gotBytes;
|
||||
break;
|
||||
}
|
||||
if (dataPtr->eofPending) {
|
||||
/*
|
||||
* Already saw EOF from downChan; don't ask again.
|
||||
* NOTE: Could move this up to avoid the last maxRead
|
||||
* execution. Believe this would still be correct behavior,
|
||||
* but the test suite tests the whole command callback
|
||||
* sequence, so leave it unchanged for now.
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -656,46 +696,35 @@ TransformInputProc(
|
||||
|
||||
read = Tcl_ReadRaw(downChan, buf, toRead);
|
||||
if (read < 0) {
|
||||
/*
|
||||
* Report errors to caller. EAGAIN is a special situation. If we
|
||||
* had some data before we report that instead of the request to
|
||||
* re-try.
|
||||
*/
|
||||
int error = Tcl_GetErrno();
|
||||
|
||||
if ((error == EAGAIN) && (gotBytes > 0)) {
|
||||
return gotBytes;
|
||||
}
|
||||
|
||||
*errorCodePtr = error;
|
||||
return -1;
|
||||
} else if (read == 0) {
|
||||
/*
|
||||
* Check wether we hit on EOF in the underlying channel or not. If
|
||||
* not differentiate between blocking and non-blocking modes. In
|
||||
* non-blocking mode we ran temporarily out of data. Signal this
|
||||
* to the caller via EWOULDBLOCK and error return (-1). In the
|
||||
* other cases we simply return what we got and let the caller
|
||||
* wait for more. On the other hand, if we got an EOF we have to
|
||||
* convert and flush all waiting partial data.
|
||||
*/
|
||||
|
||||
if (!Tcl_Eof(downChan)) {
|
||||
if ((gotBytes == 0) && (dataPtr->flags & CHANNEL_ASYNC)) {
|
||||
*errorCodePtr = EWOULDBLOCK;
|
||||
return -1;
|
||||
}
|
||||
return gotBytes;
|
||||
}
|
||||
|
||||
if (dataPtr->readIsFlushed) {
|
||||
if (Tcl_InputBlocked(downChan) && (gotBytes > 0)) {
|
||||
/*
|
||||
* Already flushed, nothing to do anymore.
|
||||
* Zero bytes available from downChan because blocked.
|
||||
* But nonzero bytes already copied, so total is a
|
||||
* valid blocked short read. Return to caller.
|
||||
*/
|
||||
|
||||
return gotBytes;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Either downChan is not blocked (there's a real error).
|
||||
* or it is and there are no bytes copied yet. In either
|
||||
* case we want to pass the "error" along to the caller,
|
||||
* either to report an error, or to signal to the caller
|
||||
* that zero bytes are available because blocked.
|
||||
*/
|
||||
|
||||
*errorCodePtr = Tcl_GetErrno();
|
||||
gotBytes = -1;
|
||||
break;
|
||||
} else if (read == 0) {
|
||||
|
||||
/*
|
||||
* Zero returned from Tcl_ReadRaw() always indicates EOF
|
||||
* on the down channel.
|
||||
*/
|
||||
|
||||
dataPtr->eofPending = 1;
|
||||
dataPtr->readIsFlushed = 1;
|
||||
ExecuteCallback(dataPtr, NULL, A_FLUSH_READ, NULL, 0,
|
||||
TRANSMIT_IBUF, P_PRESERVE);
|
||||
@@ -705,7 +734,7 @@ TransformInputProc(
|
||||
* We had nothing to flush.
|
||||
*/
|
||||
|
||||
return gotBytes;
|
||||
break;
|
||||
}
|
||||
|
||||
continue; /* at: while (toRead > 0) */
|
||||
@@ -719,10 +748,15 @@ TransformInputProc(
|
||||
if (ExecuteCallback(dataPtr, NULL, A_READ, UCHARP(buf), read,
|
||||
TRANSMIT_IBUF, P_PRESERVE) != TCL_OK) {
|
||||
*errorCodePtr = EINVAL;
|
||||
return -1;
|
||||
gotBytes = -1;
|
||||
break;
|
||||
}
|
||||
} /* while toRead > 0 */
|
||||
|
||||
if (gotBytes == 0) {
|
||||
dataPtr->eofPending = 0;
|
||||
}
|
||||
ReleaseData(dataPtr);
|
||||
return gotBytes;
|
||||
}
|
||||
|
||||
@@ -763,11 +797,13 @@ TransformOutputProc(
|
||||
return 0;
|
||||
}
|
||||
|
||||
PreserveData(dataPtr);
|
||||
if (ExecuteCallback(dataPtr, NULL, A_WRITE, UCHARP(buf), toWrite,
|
||||
TRANSMIT_DOWN, P_NO_PRESERVE) != TCL_OK) {
|
||||
*errorCodePtr = EINVAL;
|
||||
return -1;
|
||||
toWrite = -1;
|
||||
}
|
||||
ReleaseData(dataPtr);
|
||||
|
||||
return toWrite;
|
||||
}
|
||||
@@ -820,6 +856,7 @@ TransformSeekProc(
|
||||
* request down, unchanged.
|
||||
*/
|
||||
|
||||
PreserveData(dataPtr);
|
||||
if (dataPtr->mode & TCL_WRITABLE) {
|
||||
ExecuteCallback(dataPtr, NULL, A_FLUSH_WRITE, NULL, 0, TRANSMIT_DOWN,
|
||||
P_NO_PRESERVE);
|
||||
@@ -830,7 +867,9 @@ TransformSeekProc(
|
||||
P_NO_PRESERVE);
|
||||
ResultClear(&dataPtr->result);
|
||||
dataPtr->readIsFlushed = 0;
|
||||
dataPtr->eofPending = 0;
|
||||
}
|
||||
ReleaseData(dataPtr);
|
||||
|
||||
return parentSeekProc(Tcl_GetChannelInstanceData(parent), offset, mode,
|
||||
errorCodePtr);
|
||||
@@ -891,6 +930,7 @@ TransformWideSeekProc(
|
||||
* request down, unchanged.
|
||||
*/
|
||||
|
||||
PreserveData(dataPtr);
|
||||
if (dataPtr->mode & TCL_WRITABLE) {
|
||||
ExecuteCallback(dataPtr, NULL, A_FLUSH_WRITE, NULL, 0, TRANSMIT_DOWN,
|
||||
P_NO_PRESERVE);
|
||||
@@ -901,7 +941,9 @@ TransformWideSeekProc(
|
||||
P_NO_PRESERVE);
|
||||
ResultClear(&dataPtr->result);
|
||||
dataPtr->readIsFlushed = 0;
|
||||
dataPtr->eofPending = 0;
|
||||
}
|
||||
ReleaseData(dataPtr);
|
||||
|
||||
/*
|
||||
* If we have a wide seek capability, we should stick with that.
|
||||
@@ -1056,6 +1098,9 @@ TransformWatchProc(
|
||||
* unchanged.
|
||||
*/
|
||||
|
||||
if (dataPtr->self == NULL) {
|
||||
return;
|
||||
}
|
||||
downChan = Tcl_GetStackedChannel(dataPtr->self);
|
||||
|
||||
Tcl_GetChannelType(downChan)->watchProc(
|
||||
|
||||
+136
-227
@@ -99,31 +99,9 @@ typedef struct {
|
||||
Tcl_ThreadId thread; /* Thread the 'interp' belongs to. == Handler thread */
|
||||
Tcl_ThreadId owner; /* Thread owning the structure. == Channel thread */
|
||||
#endif
|
||||
|
||||
/* See [==] as well.
|
||||
* Storage for the command prefix and the additional words required for
|
||||
* the invocation of methods in the command handler.
|
||||
*
|
||||
* argv [0] ... [.] | [argc-2] [argc-1] | [argc] [argc+2]
|
||||
* cmd ... pfx | method chan | detail1 detail2
|
||||
* ~~~~ CT ~~~ ~~ CT ~~
|
||||
*
|
||||
* CT = Belongs to the 'Command handler Thread'.
|
||||
*/
|
||||
|
||||
int argc; /* Number of preallocated words - 2 */
|
||||
Tcl_Obj **argv; /* Preallocated array for calling the handler.
|
||||
* args[0] is placeholder for cmd word.
|
||||
* Followed by the arguments in the prefix,
|
||||
* plus 4 placeholders for method, channel,
|
||||
* and at most two varying (method specific)
|
||||
* words. */
|
||||
int methods; /* Bitmask of supported methods */
|
||||
|
||||
/*
|
||||
* NOTE (9): Should we have predefined shared literals for the method
|
||||
* names?
|
||||
*/
|
||||
Tcl_Obj *cmd; /* Callback command prefix */
|
||||
Tcl_Obj *methods; /* Methods to append to command prefix */
|
||||
Tcl_Obj *name; /* Name of the channel as created */
|
||||
|
||||
int mode; /* Mask of R/W mode */
|
||||
int interest; /* Mask of events the channel is interested
|
||||
@@ -450,15 +428,15 @@ static ReflectedChannel * NewReflectedChannel(Tcl_Interp *interp,
|
||||
Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj);
|
||||
static Tcl_Obj * NextHandle(void);
|
||||
static void FreeReflectedChannel(ReflectedChannel *rcPtr);
|
||||
static void FreeReflectedChannelArgs(ReflectedChannel *rcPtr);
|
||||
static int InvokeTclMethod(ReflectedChannel *rcPtr,
|
||||
const char *method, Tcl_Obj *argOneObj,
|
||||
MethodName method, Tcl_Obj *argOneObj,
|
||||
Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr);
|
||||
|
||||
static ReflectedChannelMap * GetReflectedChannelMap(Tcl_Interp *interp);
|
||||
static void DeleteReflectedChannelMap(ClientData clientData,
|
||||
Tcl_Interp *interp);
|
||||
static int ErrnoReturn(ReflectedChannel *rcPtr, Tcl_Obj *resObj);
|
||||
static void MarkDead(ReflectedChannel *rcPtr);
|
||||
|
||||
/*
|
||||
* Global constant strings (messages). ==================
|
||||
@@ -467,16 +445,14 @@ static int ErrnoReturn(ReflectedChannel *rcPtr, Tcl_Obj *resObj);
|
||||
* list-quoting to keep the words of the message together. See also [x].
|
||||
*/
|
||||
|
||||
static const char *msg_read_unsup = "{read not supported by Tcl driver}";
|
||||
static const char *msg_read_toomuch = "{read delivered more than requested}";
|
||||
static const char *msg_write_unsup = "{write not supported by Tcl driver}";
|
||||
static const char *msg_write_toomuch = "{write wrote more than requested}";
|
||||
static const char *msg_write_nothing = "{write wrote nothing}";
|
||||
static const char *msg_seek_beforestart = "{Tried to seek before origin}";
|
||||
#ifdef TCL_THREADS
|
||||
static const char *msg_send_originlost = "{Channel thread lost}";
|
||||
static const char *msg_send_dstlost = "{Owner lost}";
|
||||
#endif /* TCL_THREADS */
|
||||
static const char *msg_send_dstlost = "{Owner lost}";
|
||||
static const char *msg_dstlost = "-code 1 -level 0 -errorcode NONE -errorinfo {} -errorline 1 {Owner lost}";
|
||||
|
||||
/*
|
||||
@@ -583,10 +559,6 @@ TclChanCreateObjCmd(
|
||||
|
||||
rcId = NextHandle();
|
||||
rcPtr = NewReflectedChannel(interp, cmdObj, mode, rcId);
|
||||
chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr,
|
||||
mode);
|
||||
rcPtr->chan = chan;
|
||||
chanPtr = (Channel *) chan;
|
||||
|
||||
/*
|
||||
* Invoke 'initialize' and validate that the handler is present and ok.
|
||||
@@ -600,7 +572,7 @@ TclChanCreateObjCmd(
|
||||
|
||||
modeObj = DecodeEventMask(mode);
|
||||
/* assert modeObj.refCount == 1 */
|
||||
result = InvokeTclMethod(rcPtr, "initialize", modeObj, NULL, &resObj);
|
||||
result = InvokeTclMethod(rcPtr, METH_INIT, modeObj, NULL, &resObj);
|
||||
Tcl_DecrRefCount(modeObj);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
@@ -683,7 +655,11 @@ TclChanCreateObjCmd(
|
||||
* Everything is fine now.
|
||||
*/
|
||||
|
||||
rcPtr->methods = methods;
|
||||
chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr,
|
||||
mode);
|
||||
rcPtr->chan = chan;
|
||||
TclChannelPreserve(chan);
|
||||
chanPtr = (Channel *) chan;
|
||||
|
||||
if ((methods & NULLABLE_METHODS) != NULLABLE_METHODS) {
|
||||
/*
|
||||
@@ -744,12 +720,10 @@ TclChanCreateObjCmd(
|
||||
return TCL_OK;
|
||||
|
||||
error:
|
||||
/*
|
||||
* Signal to ReflectClose to not call 'finalize'.
|
||||
*/
|
||||
|
||||
rcPtr->methods = 0;
|
||||
Tcl_Close(interp, chan);
|
||||
Tcl_DecrRefCount(rcPtr->name);
|
||||
Tcl_DecrRefCount(rcPtr->methods);
|
||||
Tcl_DecrRefCount(rcPtr->cmd);
|
||||
ckfree((char*) rcPtr);
|
||||
return TCL_ERROR;
|
||||
|
||||
#undef MODE
|
||||
@@ -1138,6 +1112,7 @@ ReflectClose(
|
||||
ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
|
||||
* this interp */
|
||||
Tcl_HashEntry *hPtr; /* Entry in the above map */
|
||||
const Tcl_ChannelType *tctPtr;
|
||||
|
||||
if (TclInThreadExit()) {
|
||||
/*
|
||||
@@ -1175,18 +1150,11 @@ ReflectClose(
|
||||
}
|
||||
#endif
|
||||
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/*
|
||||
* -- No -- ASSERT rcPtr->methods & FLAG(METH_FINAL)
|
||||
*
|
||||
* A cleaned method mask here implies that the channel creation was
|
||||
* aborted, and "finalize" must not be called.
|
||||
*/
|
||||
|
||||
if (rcPtr->methods == 0) {
|
||||
tctPtr = ((Channel *)rcPtr->chan)->typePtr;
|
||||
if (tctPtr && tctPtr != &tclRChannelType) {
|
||||
ckfree((char *)tctPtr);
|
||||
((Channel *)rcPtr->chan)->typePtr = NULL;
|
||||
}
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
return EOK;
|
||||
}
|
||||
@@ -1208,14 +1176,12 @@ ReflectClose(
|
||||
|
||||
Tcl_DeleteEvents(ReflectEventDelete, rcPtr);
|
||||
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
PassReceivedErrorInterp(interp, &p);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
result = InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj);
|
||||
result = InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj);
|
||||
if ((result != TCL_OK) && (interp != NULL)) {
|
||||
Tcl_SetChannelErrorInterp(interp, resObj);
|
||||
}
|
||||
@@ -1251,12 +1217,14 @@ ReflectClose(
|
||||
if (hPtr) {
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
#ifdef TCL_THREADS
|
||||
}
|
||||
#endif
|
||||
tctPtr = ((Channel *)rcPtr->chan)->typePtr;
|
||||
if (tctPtr && tctPtr != &tclRChannelType) {
|
||||
ckfree((char *)tctPtr);
|
||||
((Channel *)rcPtr->chan)->typePtr = NULL;
|
||||
}
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
return (result == TCL_OK) ? EOK : EINVAL;
|
||||
}
|
||||
|
||||
@@ -1289,18 +1257,6 @@ ReflectInput(
|
||||
unsigned char *bytev; /* Array of returned bytes */
|
||||
Tcl_Obj *resObj; /* Result data for 'read' */
|
||||
|
||||
/*
|
||||
* The following check can be done before thread redirection, because we
|
||||
* are reading from an item which is readonly, i.e. will never change
|
||||
* during the lifetime of the channel.
|
||||
*/
|
||||
|
||||
if (!(rcPtr->methods & FLAG(METH_READ))) {
|
||||
SetChannelErrorStr(rcPtr->chan, msg_read_unsup);
|
||||
*errorCodePtr = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Are we in the correct thread?
|
||||
*/
|
||||
@@ -1339,7 +1295,7 @@ ReflectInput(
|
||||
toReadObj = Tcl_NewIntObj(toRead);
|
||||
Tcl_IncrRefCount(toReadObj);
|
||||
|
||||
if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj)!=TCL_OK) {
|
||||
if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK) {
|
||||
int code = ErrnoReturn(rcPtr, resObj);
|
||||
|
||||
if (code < 0) {
|
||||
@@ -1404,18 +1360,6 @@ ReflectOutput(
|
||||
Tcl_Obj *resObj; /* Result data for 'write' */
|
||||
int written;
|
||||
|
||||
/*
|
||||
* The following check can be done before thread redirection, because we
|
||||
* are reading from an item which is readonly, i.e. will never change
|
||||
* during the lifetime of the channel.
|
||||
*/
|
||||
|
||||
if (!(rcPtr->methods & FLAG(METH_WRITE))) {
|
||||
SetChannelErrorStr(rcPtr->chan, msg_write_unsup);
|
||||
*errorCodePtr = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Are we in the correct thread?
|
||||
*/
|
||||
@@ -1450,11 +1394,12 @@ ReflectOutput(
|
||||
/* ASSERT: rcPtr->mode & TCL_WRITABLE */
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
Tcl_Preserve(rcPtr->interp);
|
||||
|
||||
bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite);
|
||||
Tcl_IncrRefCount(bufObj);
|
||||
|
||||
if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
|
||||
if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) {
|
||||
int code = ErrnoReturn(rcPtr, resObj);
|
||||
|
||||
if (code < 0) {
|
||||
@@ -1466,6 +1411,14 @@ ReflectOutput(
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
if (Tcl_InterpDeleted(rcPtr->interp)) {
|
||||
/*
|
||||
* The interp was destroyed during InvokeTclMethod().
|
||||
*/
|
||||
|
||||
SetChannelErrorStr(rcPtr->chan, msg_send_dstlost);
|
||||
goto invalid;
|
||||
}
|
||||
if (Tcl_GetIntFromObj(rcPtr->interp, resObj, &written) != TCL_OK) {
|
||||
Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp));
|
||||
goto invalid;
|
||||
@@ -1495,6 +1448,7 @@ ReflectOutput(
|
||||
stop:
|
||||
Tcl_DecrRefCount(bufObj);
|
||||
Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
|
||||
Tcl_Release(rcPtr->interp);
|
||||
Tcl_Release(rcPtr);
|
||||
return written;
|
||||
invalid:
|
||||
@@ -1568,7 +1522,7 @@ ReflectSeekWide(
|
||||
Tcl_IncrRefCount(offObj);
|
||||
Tcl_IncrRefCount(baseObj);
|
||||
|
||||
if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj) != TCL_OK) {
|
||||
if (InvokeTclMethod(rcPtr, METH_SEEK, offObj, baseObj, &resObj)!=TCL_OK) {
|
||||
Tcl_SetChannelError(rcPtr->chan, resObj);
|
||||
goto invalid;
|
||||
}
|
||||
@@ -1639,8 +1593,6 @@ ReflectWatch(
|
||||
ReflectedChannel *rcPtr = clientData;
|
||||
Tcl_Obj *maskObj;
|
||||
|
||||
/* ASSERT rcPtr->methods & FLAG(METH_WATCH) */
|
||||
|
||||
/*
|
||||
* We restrict the interest to what the channel can support. IOW there
|
||||
* will never be write events for a channel which is not writable.
|
||||
@@ -1683,7 +1635,7 @@ ReflectWatch(
|
||||
|
||||
maskObj = DecodeEventMask(mask);
|
||||
/* assert maskObj.refCount == 1 */
|
||||
(void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL);
|
||||
(void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
|
||||
Tcl_DecrRefCount(maskObj);
|
||||
|
||||
Tcl_Release(rcPtr);
|
||||
@@ -1742,7 +1694,7 @@ ReflectBlock(
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
|
||||
if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL, &resObj)!=TCL_OK) {
|
||||
if (InvokeTclMethod(rcPtr,METH_BLOCKING,blockObj,NULL,&resObj)!=TCL_OK) {
|
||||
Tcl_SetChannelError(rcPtr->chan, resObj);
|
||||
errorNum = EINVAL;
|
||||
} else {
|
||||
@@ -1854,7 +1806,7 @@ ReflectSetOption(
|
||||
Tcl_IncrRefCount(optionObj);
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
|
||||
result = InvokeTclMethod(rcPtr, "configure",optionObj,valueObj, &resObj);
|
||||
result = InvokeTclMethod(rcPtr, METH_CONFIGURE,optionObj,valueObj, &resObj);
|
||||
if (result != TCL_OK) {
|
||||
UnmarshallErrorResult(interp, resObj);
|
||||
}
|
||||
@@ -1899,7 +1851,7 @@ ReflectGetOption(
|
||||
Tcl_Obj *resObj; /* Result data for 'configure' */
|
||||
int listc, result = TCL_OK;
|
||||
Tcl_Obj **listv;
|
||||
const char *method;
|
||||
MethodName method;
|
||||
|
||||
/*
|
||||
* Are we in the correct thread?
|
||||
@@ -1938,14 +1890,14 @@ ReflectGetOption(
|
||||
* Retrieve all options.
|
||||
*/
|
||||
|
||||
method = "cgetall";
|
||||
method = METH_CGETALL;
|
||||
optionObj = NULL;
|
||||
} else {
|
||||
/*
|
||||
* Retrieve the value of one option.
|
||||
*/
|
||||
|
||||
method = "cget";
|
||||
method = METH_CGET;
|
||||
optionObj = Tcl_NewStringObj(optionName, -1);
|
||||
Tcl_IncrRefCount(optionObj);
|
||||
}
|
||||
@@ -2159,16 +2111,13 @@ NewReflectedChannel(
|
||||
Tcl_Obj *handleObj)
|
||||
{
|
||||
ReflectedChannel *rcPtr;
|
||||
int i, listc;
|
||||
Tcl_Obj **listv;
|
||||
MethodName mn = METH_BLOCKING;
|
||||
|
||||
rcPtr = ckalloc(sizeof(ReflectedChannel));
|
||||
|
||||
/* rcPtr->chan: Assigned by caller. Dummy data here. */
|
||||
/* rcPtr->methods: Assigned by caller. Dummy data here. */
|
||||
|
||||
rcPtr->chan = NULL;
|
||||
rcPtr->methods = 0;
|
||||
rcPtr->interp = interp;
|
||||
rcPtr->dead = 0;
|
||||
#ifdef TCL_THREADS
|
||||
@@ -2177,54 +2126,17 @@ NewReflectedChannel(
|
||||
rcPtr->mode = mode;
|
||||
rcPtr->interest = 0; /* Initially no interest registered */
|
||||
|
||||
/*
|
||||
* Method placeholder.
|
||||
*/
|
||||
|
||||
/* ASSERT: cmdpfxObj is a Tcl List */
|
||||
|
||||
Tcl_ListObjGetElements(interp, cmdpfxObj, &listc, &listv);
|
||||
|
||||
/*
|
||||
* See [==] as well.
|
||||
* Storage for the command prefix and the additional words required for
|
||||
* the invocation of methods in the command handler.
|
||||
*
|
||||
* listv [0] [listc-1] | [listc] [listc+1] |
|
||||
* argv [0] ... [.] | [argc-2] [argc-1] | [argc] [argc+2]
|
||||
* cmd ... pfx | method chan | detail1 detail2
|
||||
*/
|
||||
|
||||
rcPtr->argc = listc + 2;
|
||||
rcPtr->argv = ckalloc(sizeof(Tcl_Obj *) * (listc+4));
|
||||
|
||||
/*
|
||||
* Duplicate object references.
|
||||
*/
|
||||
|
||||
for (i=0; i<listc ; i++) {
|
||||
Tcl_Obj *word = rcPtr->argv[i] = listv[i];
|
||||
|
||||
Tcl_IncrRefCount(word);
|
||||
rcPtr->cmd = TclListObjCopy(NULL, cmdpfxObj);
|
||||
Tcl_IncrRefCount(rcPtr->cmd);
|
||||
rcPtr->methods = Tcl_NewListObj(METH_WRITE + 1, NULL);
|
||||
while (mn <= METH_WRITE) {
|
||||
Tcl_ListObjAppendElement(NULL, rcPtr->methods,
|
||||
Tcl_NewStringObj(methodNames[mn++], -1));
|
||||
}
|
||||
|
||||
i++; /* Skip placeholder for method */
|
||||
|
||||
/*
|
||||
* [Bug 1667990]: See [x] in FreeReflectedChannel for release
|
||||
*/
|
||||
|
||||
rcPtr->argv[i] = handleObj;
|
||||
Tcl_IncrRefCount(handleObj);
|
||||
|
||||
/*
|
||||
* The next two objects are kept empty, varying arguments.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Initialization complete.
|
||||
*/
|
||||
|
||||
Tcl_IncrRefCount(rcPtr->methods);
|
||||
rcPtr->name = handleObj;
|
||||
Tcl_IncrRefCount(rcPtr->name);
|
||||
return rcPtr;
|
||||
}
|
||||
|
||||
@@ -2271,45 +2183,21 @@ NextHandle(void)
|
||||
}
|
||||
|
||||
static void
|
||||
FreeReflectedChannelArgs(
|
||||
ReflectedChannel *rcPtr)
|
||||
{
|
||||
int i, n = rcPtr->argc - 2;
|
||||
|
||||
if (n < 0) {
|
||||
return;
|
||||
}
|
||||
for (i=0; i<n; i++) {
|
||||
Tcl_DecrRefCount(rcPtr->argv[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* [Bug 1667990]: See [x] in NewReflectedChannel for lock. n+1 = argc-1.
|
||||
*/
|
||||
|
||||
Tcl_DecrRefCount(rcPtr->argv[n+1]);
|
||||
|
||||
rcPtr->argc = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
FreeReflectedChannel(
|
||||
ReflectedChannel *rcPtr)
|
||||
{
|
||||
Channel *chanPtr = (Channel *) rcPtr->chan;
|
||||
|
||||
if (chanPtr->typePtr != &tclRChannelType) {
|
||||
/*
|
||||
* Delete a cloned ChannelType structure.
|
||||
*/
|
||||
|
||||
ckfree(chanPtr->typePtr);
|
||||
chanPtr->typePtr = NULL;
|
||||
TclChannelRelease((Tcl_Channel)chanPtr);
|
||||
if (rcPtr->name) {
|
||||
Tcl_DecrRefCount(rcPtr->name);
|
||||
}
|
||||
if (rcPtr->methods) {
|
||||
Tcl_DecrRefCount(rcPtr->methods);
|
||||
}
|
||||
if (rcPtr->cmd) {
|
||||
Tcl_DecrRefCount(rcPtr->cmd);
|
||||
}
|
||||
|
||||
FreeReflectedChannelArgs(rcPtr);
|
||||
|
||||
ckfree(rcPtr->argv);
|
||||
ckfree(rcPtr);
|
||||
}
|
||||
|
||||
@@ -2340,16 +2228,16 @@ FreeReflectedChannel(
|
||||
static int
|
||||
InvokeTclMethod(
|
||||
ReflectedChannel *rcPtr,
|
||||
const char *method,
|
||||
MethodName method,
|
||||
Tcl_Obj *argOneObj, /* NULL'able */
|
||||
Tcl_Obj *argTwoObj, /* NULL'able */
|
||||
Tcl_Obj **resultObjPtr) /* NULL'able */
|
||||
{
|
||||
int cmdc; /* #words in constructed command */
|
||||
Tcl_Obj *methObj = NULL; /* Method name in object form */
|
||||
Tcl_InterpState sr; /* State of handler interp */
|
||||
int result; /* Result code of method invokation */
|
||||
Tcl_Obj *resObj = NULL; /* Result of method invokation. */
|
||||
Tcl_Obj *cmd;
|
||||
|
||||
if (rcPtr->dead) {
|
||||
/*
|
||||
@@ -2372,19 +2260,15 @@ InvokeTclMethod(
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE (5): Decide impl. issue: Cache objects with method names? Needs
|
||||
* TSD data as reflections can be created in many different threads.
|
||||
* NO: Caching of command resolutions means storage per channel.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Insert method into the pre-allocated area, after the command prefix,
|
||||
* Insert method into the callback command, after the command prefix,
|
||||
* before the channel id.
|
||||
*/
|
||||
|
||||
methObj = Tcl_NewStringObj(method, -1);
|
||||
Tcl_IncrRefCount(methObj);
|
||||
rcPtr->argv[rcPtr->argc - 2] = methObj;
|
||||
cmd = TclListObjCopy(NULL, rcPtr->cmd);
|
||||
|
||||
Tcl_ListObjIndex(NULL, rcPtr->methods, method, &methObj);
|
||||
Tcl_ListObjAppendElement(NULL, cmd, methObj);
|
||||
Tcl_ListObjAppendElement(NULL, cmd, rcPtr->name);
|
||||
|
||||
/*
|
||||
* Append the additional argument containing method specific details
|
||||
@@ -2394,13 +2278,10 @@ InvokeTclMethod(
|
||||
* The objects will survive the Tcl_EvalObjv without change.
|
||||
*/
|
||||
|
||||
cmdc = rcPtr->argc;
|
||||
if (argOneObj) {
|
||||
rcPtr->argv[cmdc] = argOneObj;
|
||||
cmdc++;
|
||||
Tcl_ListObjAppendElement(NULL, cmd, argOneObj);
|
||||
if (argTwoObj) {
|
||||
rcPtr->argv[cmdc] = argTwoObj;
|
||||
cmdc++;
|
||||
Tcl_ListObjAppendElement(NULL, cmd, argTwoObj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2409,9 +2290,10 @@ InvokeTclMethod(
|
||||
* existing state intact.
|
||||
*/
|
||||
|
||||
Tcl_IncrRefCount(cmd);
|
||||
sr = Tcl_SaveInterpState(rcPtr->interp, 0 /* Dummy */);
|
||||
Tcl_Preserve(rcPtr->interp);
|
||||
result = Tcl_EvalObjv(rcPtr->interp, cmdc, rcPtr->argv, TCL_EVAL_GLOBAL);
|
||||
result = Tcl_EvalObjEx(rcPtr->interp, cmd, TCL_EVAL_GLOBAL);
|
||||
|
||||
/*
|
||||
* We do not try to extract the result information if the caller has no
|
||||
@@ -2437,7 +2319,6 @@ InvokeTclMethod(
|
||||
*/
|
||||
|
||||
if (result != TCL_ERROR) {
|
||||
Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rcPtr->argv);
|
||||
int cmdLen;
|
||||
const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen);
|
||||
|
||||
@@ -2451,24 +2332,16 @@ InvokeTclMethod(
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
Tcl_AppendObjToErrorInfo(rcPtr->interp, Tcl_ObjPrintf(
|
||||
"\n (chan handler subcommand \"%s\")", method));
|
||||
"\n (chan handler subcommand \"%s\")",
|
||||
methodNames[method]));
|
||||
resObj = MarshallError(rcPtr->interp);
|
||||
}
|
||||
Tcl_IncrRefCount(resObj);
|
||||
}
|
||||
Tcl_DecrRefCount(cmd);
|
||||
Tcl_RestoreInterpState(rcPtr->interp, sr);
|
||||
Tcl_Release(rcPtr->interp);
|
||||
|
||||
/*
|
||||
* Cleanup of the dynamic parts of the command.
|
||||
*
|
||||
* The detail objects survived the Tcl_EvalObjv without change because of
|
||||
* the contract. Therefore there is no need to decrement the refcounts. Only
|
||||
* the internal method object has to be disposed of.
|
||||
*/
|
||||
|
||||
Tcl_DecrRefCount(methObj);
|
||||
|
||||
/*
|
||||
* The resObj has a ref count of 1 at this location. This means that the
|
||||
* caller of InvokeTclMethod has to dispose of it (but only if it was
|
||||
@@ -2589,6 +2462,28 @@ GetReflectedChannelMap(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
MarkDead(
|
||||
ReflectedChannel *rcPtr)
|
||||
{
|
||||
if (rcPtr->dead) {
|
||||
return;
|
||||
}
|
||||
if (rcPtr->name) {
|
||||
Tcl_DecrRefCount(rcPtr->name);
|
||||
rcPtr->name = NULL;
|
||||
}
|
||||
if (rcPtr->methods) {
|
||||
Tcl_DecrRefCount(rcPtr->methods);
|
||||
rcPtr->methods = NULL;
|
||||
}
|
||||
if (rcPtr->cmd) {
|
||||
Tcl_DecrRefCount(rcPtr->cmd);
|
||||
rcPtr->cmd = NULL;
|
||||
}
|
||||
rcPtr->dead = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
DeleteReflectedChannelMap(
|
||||
ClientData clientData, /* The per-interpreter data structure. */
|
||||
@@ -2624,7 +2519,7 @@ DeleteReflectedChannelMap(
|
||||
chan = Tcl_GetHashValue(hPtr);
|
||||
rcPtr = Tcl_GetChannelInstanceData(chan);
|
||||
|
||||
rcPtr->dead = 1;
|
||||
MarkDead(rcPtr);
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
}
|
||||
Tcl_DeleteHashTable(&rcmPtr->map);
|
||||
@@ -2657,6 +2552,11 @@ DeleteReflectedChannelMap(
|
||||
/*
|
||||
* The receiver for the event exited, before processing the event. We
|
||||
* detach the result now, wake the originator up and signal failure.
|
||||
*
|
||||
* Attention: Results may have been detached already, by either the
|
||||
* receiver, or this thread, as part of other parts in the thread
|
||||
* teardown. Such results are ignored. See ticket [b47b176adf] for the
|
||||
* identical race condition in Tcl 8.6 IORTrans.
|
||||
*/
|
||||
|
||||
evPtr = resultPtr->evPtr;
|
||||
@@ -2666,6 +2566,9 @@ DeleteReflectedChannelMap(
|
||||
continue;
|
||||
}
|
||||
paramPtr = evPtr->param;
|
||||
if (!evPtr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
evPtr->resultPtr = NULL;
|
||||
resultPtr->evPtr = NULL;
|
||||
@@ -2699,8 +2602,7 @@ DeleteReflectedChannelMap(
|
||||
continue;
|
||||
}
|
||||
|
||||
rcPtr->dead = 1;
|
||||
FreeReflectedChannelArgs(rcPtr);
|
||||
MarkDead(rcPtr);
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
}
|
||||
#endif
|
||||
@@ -2797,6 +2699,11 @@ DeleteThreadReflectedChannelMap(
|
||||
/*
|
||||
* The receiver for the event exited, before processing the event. We
|
||||
* detach the result now, wake the originator up and signal failure.
|
||||
*
|
||||
* Attention: Results may have been detached already, by either the
|
||||
* receiver, or this thread, as part of other parts in the thread
|
||||
* teardown. Such results are ignored. See ticket [b47b176adf] for the
|
||||
* identical race condition in Tcl 8.6 IORTrans.
|
||||
*/
|
||||
|
||||
evPtr = resultPtr->evPtr;
|
||||
@@ -2806,6 +2713,9 @@ DeleteThreadReflectedChannelMap(
|
||||
continue;
|
||||
}
|
||||
paramPtr = evPtr->param;
|
||||
if (!evPtr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
evPtr->resultPtr = NULL;
|
||||
resultPtr->evPtr = NULL;
|
||||
@@ -2839,8 +2749,7 @@ DeleteThreadReflectedChannelMap(
|
||||
Tcl_Channel chan = Tcl_GetHashValue(hPtr);
|
||||
ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan);
|
||||
|
||||
rcPtr->dead = 1;
|
||||
FreeReflectedChannelArgs(rcPtr);
|
||||
MarkDead(rcPtr);
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
}
|
||||
ckfree(rcmPtr);
|
||||
@@ -3018,17 +2927,17 @@ ForwardProc(
|
||||
* call upon for the driver.
|
||||
*/
|
||||
|
||||
case ForwardedClose:
|
||||
case ForwardedClose: {
|
||||
/*
|
||||
* No parameters/results.
|
||||
*/
|
||||
|
||||
if (InvokeTclMethod(rcPtr, "finalize", NULL, NULL, &resObj)!=TCL_OK) {
|
||||
if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) {
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
}
|
||||
|
||||
/*
|
||||
* Freeing is done here, in the origin thread, because the argv[]
|
||||
* Freeing is done here, in the origin thread, callback command
|
||||
* objects belong to this thread. Deallocating them in a different
|
||||
* thread is not allowed
|
||||
*
|
||||
@@ -3046,16 +2955,16 @@ ForwardProc(
|
||||
hPtr = Tcl_FindHashEntry(&rcmPtr->map,
|
||||
Tcl_GetChannelName(rcPtr->chan));
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
|
||||
FreeReflectedChannelArgs(rcPtr);
|
||||
MarkDead(rcPtr);
|
||||
break;
|
||||
}
|
||||
|
||||
case ForwardedInput: {
|
||||
Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead);
|
||||
Tcl_IncrRefCount(toReadObj);
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "read", toReadObj, NULL, &resObj)!=TCL_OK){
|
||||
if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK){
|
||||
int code = ErrnoReturn(rcPtr, resObj);
|
||||
|
||||
if (code < 0) {
|
||||
@@ -3095,7 +3004,7 @@ ForwardProc(
|
||||
Tcl_IncrRefCount(bufObj);
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
|
||||
if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) {
|
||||
int code = ErrnoReturn(rcPtr, resObj);
|
||||
|
||||
if (code < 0) {
|
||||
@@ -3138,7 +3047,7 @@ ForwardProc(
|
||||
Tcl_IncrRefCount(baseObj);
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj)!=TCL_OK){
|
||||
if (InvokeTclMethod(rcPtr, METH_SEEK, offObj, baseObj, &resObj)!=TCL_OK){
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
paramPtr->seek.offset = -1;
|
||||
} else {
|
||||
@@ -3174,7 +3083,7 @@ ForwardProc(
|
||||
/* assert maskObj.refCount == 1 */
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
(void) InvokeTclMethod(rcPtr, "watch", maskObj, NULL, NULL);
|
||||
(void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
|
||||
Tcl_DecrRefCount(maskObj);
|
||||
Tcl_Release(rcPtr);
|
||||
break;
|
||||
@@ -3185,7 +3094,7 @@ ForwardProc(
|
||||
|
||||
Tcl_IncrRefCount(blockObj);
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL,
|
||||
if (InvokeTclMethod(rcPtr, METH_BLOCKING, blockObj, NULL,
|
||||
&resObj) != TCL_OK) {
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
}
|
||||
@@ -3201,7 +3110,7 @@ ForwardProc(
|
||||
Tcl_IncrRefCount(optionObj);
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "configure", optionObj, valueObj,
|
||||
if (InvokeTclMethod(rcPtr, METH_CONFIGURE, optionObj, valueObj,
|
||||
&resObj) != TCL_OK) {
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
}
|
||||
@@ -3220,7 +3129,7 @@ ForwardProc(
|
||||
|
||||
Tcl_IncrRefCount(optionObj);
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "cget", optionObj, NULL, &resObj)!=TCL_OK){
|
||||
if (InvokeTclMethod(rcPtr, METH_CGET, optionObj, NULL, &resObj)!=TCL_OK){
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
} else {
|
||||
TclDStringAppendObj(paramPtr->getOpt.value, resObj);
|
||||
@@ -3236,7 +3145,7 @@ ForwardProc(
|
||||
*/
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "cgetall", NULL, NULL, &resObj) != TCL_OK){
|
||||
if (InvokeTclMethod(rcPtr, METH_CGETALL, NULL, NULL, &resObj) != TCL_OK){
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
} else {
|
||||
/*
|
||||
|
||||
+63
-56
@@ -161,6 +161,7 @@ typedef struct {
|
||||
int mode; /* Mask of R/W mode */
|
||||
int nonblocking; /* Flag: Channel is blocking or not. */
|
||||
int readIsDrained; /* Flag: Read buffers are flushed. */
|
||||
int eofPending; /* Flag: EOF seen down, but not raised up */
|
||||
int dead; /* Boolean signal that some operations
|
||||
* should no longer be attempted. */
|
||||
ResultBuffer result;
|
||||
@@ -457,8 +458,7 @@ static void TimerKill(ReflectedTransform *rtPtr);
|
||||
static void TimerSetup(ReflectedTransform *rtPtr);
|
||||
static void TimerRun(ClientData clientData);
|
||||
static int TransformRead(ReflectedTransform *rtPtr,
|
||||
int *errorCodePtr, unsigned char *buf,
|
||||
int toRead);
|
||||
int *errorCodePtr, Tcl_Obj *bufObj);
|
||||
static int TransformWrite(ReflectedTransform *rtPtr,
|
||||
int *errorCodePtr, unsigned char *buf,
|
||||
int toWrite);
|
||||
@@ -1063,6 +1063,7 @@ ReflectInput(
|
||||
{
|
||||
ReflectedTransform *rtPtr = clientData;
|
||||
int gotBytes, copied, readBytes;
|
||||
Tcl_Obj *bufObj;
|
||||
|
||||
/*
|
||||
* The following check can be done before thread redirection, because we
|
||||
@@ -1078,7 +1079,14 @@ ReflectInput(
|
||||
|
||||
Tcl_Preserve(rtPtr);
|
||||
|
||||
/* TODO: Consider a more appropriate buffer size. */
|
||||
bufObj = Tcl_NewByteArrayObj(NULL, toRead);
|
||||
Tcl_IncrRefCount(bufObj);
|
||||
gotBytes = 0;
|
||||
if (rtPtr->eofPending) {
|
||||
goto stop;
|
||||
}
|
||||
rtPtr->readIsDrained = 0;
|
||||
while (toRead > 0) {
|
||||
/*
|
||||
* Loop until the request is satisfied (or no data available from
|
||||
@@ -1094,6 +1102,11 @@ ReflectInput(
|
||||
goto stop;
|
||||
}
|
||||
|
||||
if (rtPtr->eofPending) {
|
||||
goto stop;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The buffer is exhausted, but the caller wants even more. We now
|
||||
* have to go to the underlying channel, get more bytes and then
|
||||
@@ -1129,56 +1142,42 @@ ReflectInput(
|
||||
goto stop;
|
||||
}
|
||||
|
||||
readBytes = Tcl_ReadRaw(rtPtr->parent, buf, toRead);
|
||||
if (readBytes < 0) {
|
||||
/*
|
||||
* Report errors to caller. The state of the seek system is
|
||||
* unchanged!
|
||||
*/
|
||||
|
||||
if ((Tcl_GetErrno() == EAGAIN) && (gotBytes > 0)) {
|
||||
readBytes = Tcl_ReadRaw(rtPtr->parent,
|
||||
(char *) Tcl_SetByteArrayLength(bufObj, toRead), toRead);
|
||||
if (readBytes < 0) {
|
||||
if (Tcl_InputBlocked(rtPtr->parent) && (gotBytes > 0)) {
|
||||
|
||||
/*
|
||||
* EAGAIN is a special situation. If we had some data before
|
||||
* we report that instead of the request to re-try.
|
||||
* Down channel is blocked and offers zero additional bytes.
|
||||
* The nonzero gotBytes already returned makes the total
|
||||
* operation a valid short read. Return to caller.
|
||||
*/
|
||||
|
||||
goto stop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Either the down channel is not blocked (a real error)
|
||||
* or it is and there are gotBytes==0 byte copied so far.
|
||||
* In either case, pass up the error, so we either report
|
||||
* any real error, or do not mistakenly signal EOF by
|
||||
* returning 0 to the caller.
|
||||
*/
|
||||
|
||||
*errorCodePtr = Tcl_GetErrno();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (readBytes == 0) {
|
||||
|
||||
/*
|
||||
* Check wether we hit on EOF in 'parent' or not. If not
|
||||
* differentiate between blocking and non-blocking modes. In
|
||||
* non-blocking mode we ran temporarily out of data. Signal this
|
||||
* to the caller via EWOULDBLOCK and error return (-1). In the
|
||||
* other cases we simply return what we got and let the caller
|
||||
* wait for more. On the other hand, if we got an EOF we have to
|
||||
* convert and flush all waiting partial data.
|
||||
* Zero returned from Tcl_ReadRaw() always indicates EOF
|
||||
* on the down channel.
|
||||
*/
|
||||
|
||||
if (!Tcl_Eof(rtPtr->parent)) {
|
||||
/*
|
||||
* The state of the seek system is unchanged!
|
||||
*/
|
||||
|
||||
if ((gotBytes == 0) && rtPtr->nonblocking) {
|
||||
*errorCodePtr = EWOULDBLOCK;
|
||||
goto error;
|
||||
}
|
||||
goto stop;
|
||||
} else {
|
||||
/*
|
||||
* Eof in parent.
|
||||
*/
|
||||
|
||||
if (rtPtr->readIsDrained) {
|
||||
goto stop;
|
||||
}
|
||||
|
||||
rtPtr->eofPending = 1;
|
||||
|
||||
/*
|
||||
* Now this is a bit different. The partial data waiting is
|
||||
* converted and returned.
|
||||
@@ -1198,13 +1197,7 @@ ReflectInput(
|
||||
goto stop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset eof, force caller to drain result buffer.
|
||||
*/
|
||||
|
||||
((Channel *) rtPtr->parent)->state->flags &= ~CHANNEL_EOF;
|
||||
continue; /* at: while (toRead > 0) */
|
||||
}
|
||||
} /* readBytes == 0 */
|
||||
|
||||
/*
|
||||
@@ -1213,12 +1206,23 @@ ReflectInput(
|
||||
* iteration will put it into the result.
|
||||
*/
|
||||
|
||||
if (!TransformRead(rtPtr, errorCodePtr, UCHARP(buf), readBytes)) {
|
||||
Tcl_SetByteArrayLength(bufObj, readBytes);
|
||||
if (!TransformRead(rtPtr, errorCodePtr, bufObj)) {
|
||||
goto error;
|
||||
}
|
||||
if (Tcl_IsShared(bufObj)) {
|
||||
Tcl_DecrRefCount(bufObj);
|
||||
bufObj = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(bufObj);
|
||||
}
|
||||
Tcl_SetByteArrayLength(bufObj, 0);
|
||||
} /* while toRead > 0 */
|
||||
|
||||
stop:
|
||||
if (gotBytes == 0) {
|
||||
rtPtr->eofPending = 0;
|
||||
}
|
||||
Tcl_DecrRefCount(bufObj);
|
||||
Tcl_Release(rtPtr);
|
||||
return gotBytes;
|
||||
|
||||
@@ -1773,6 +1777,7 @@ NewReflectedTransform(
|
||||
rtPtr->timer = NULL;
|
||||
rtPtr->mode = 0;
|
||||
rtPtr->readIsDrained = 0;
|
||||
rtPtr->eofPending = 0;
|
||||
rtPtr->nonblocking =
|
||||
(((Channel *) parentChan)->state->flags & CHANNEL_NONBLOCKING);
|
||||
rtPtr->dead = 0;
|
||||
@@ -2010,6 +2015,7 @@ InvokeTclMethod(
|
||||
|
||||
sr = Tcl_SaveInterpState(rtPtr->interp, 0 /* Dummy */);
|
||||
Tcl_Preserve(rtPtr);
|
||||
Tcl_Preserve(rtPtr->interp);
|
||||
result = Tcl_EvalObjv(rtPtr->interp, cmdc, rtPtr->argv, TCL_EVAL_GLOBAL);
|
||||
|
||||
/*
|
||||
@@ -2054,6 +2060,7 @@ InvokeTclMethod(
|
||||
Tcl_IncrRefCount(resObj);
|
||||
}
|
||||
Tcl_RestoreInterpState(rtPtr->interp, sr);
|
||||
Tcl_Release(rtPtr->interp);
|
||||
Tcl_Release(rtPtr);
|
||||
|
||||
/*
|
||||
@@ -2230,6 +2237,9 @@ DeleteReflectedTransformMap(
|
||||
*/
|
||||
|
||||
evPtr = resultPtr->evPtr;
|
||||
if (evPtr == NULL) {
|
||||
continue;
|
||||
}
|
||||
paramPtr = evPtr->param;
|
||||
|
||||
evPtr->resultPtr = NULL;
|
||||
@@ -2355,6 +2365,9 @@ DeleteThreadReflectedTransformMap(
|
||||
*/
|
||||
|
||||
evPtr = resultPtr->evPtr;
|
||||
if (evPtr == NULL) {
|
||||
continue;
|
||||
}
|
||||
paramPtr = evPtr->param;
|
||||
|
||||
evPtr->resultPtr = NULL;
|
||||
@@ -3065,10 +3078,8 @@ static int
|
||||
TransformRead(
|
||||
ReflectedTransform *rtPtr,
|
||||
int *errorCodePtr,
|
||||
unsigned char *buf,
|
||||
int toRead)
|
||||
Tcl_Obj *bufObj)
|
||||
{
|
||||
Tcl_Obj *bufObj;
|
||||
Tcl_Obj *resObj;
|
||||
int bytec; /* Number of returned bytes */
|
||||
unsigned char *bytev; /* Array of returned bytes */
|
||||
@@ -3081,8 +3092,8 @@ TransformRead(
|
||||
if (rtPtr->thread != Tcl_GetCurrentThread()) {
|
||||
ForwardParam p;
|
||||
|
||||
p.transform.buf = (char *) buf;
|
||||
p.transform.size = toRead;
|
||||
p.transform.buf = (char *) Tcl_GetByteArrayFromObj(bufObj,
|
||||
&(p.transform.size));
|
||||
|
||||
ForwardOpToOwnerThread(rtPtr, ForwardedInput, &p);
|
||||
|
||||
@@ -3102,12 +3113,8 @@ TransformRead(
|
||||
/* ASSERT: rtPtr->method & FLAG(METH_READ) */
|
||||
/* ASSERT: rtPtr->mode & TCL_READABLE */
|
||||
|
||||
bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toRead);
|
||||
Tcl_IncrRefCount(bufObj);
|
||||
|
||||
if (InvokeTclMethod(rtPtr, "read", bufObj, NULL, &resObj) != TCL_OK) {
|
||||
Tcl_SetChannelError(rtPtr->chan, resObj);
|
||||
Tcl_DecrRefCount(bufObj);
|
||||
Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
|
||||
*errorCodePtr = EINVAL;
|
||||
return 0;
|
||||
@@ -3116,7 +3123,6 @@ TransformRead(
|
||||
bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
|
||||
ResultAdd(&rtPtr->result, bytev, bytec);
|
||||
|
||||
Tcl_DecrRefCount(bufObj);
|
||||
Tcl_DecrRefCount(resObj); /* Remove reference held from invoke */
|
||||
return 1;
|
||||
}
|
||||
@@ -3184,7 +3190,7 @@ TransformWrite(
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
*errorCodePtr = EINVAL;
|
||||
*errorCodePtr = Tcl_GetErrno();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3294,7 +3300,7 @@ TransformFlush(
|
||||
}
|
||||
|
||||
if (res < 0) {
|
||||
*errorCodePtr = EINVAL;
|
||||
*errorCodePtr = Tcl_GetErrno();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3324,6 +3330,7 @@ TransformClear(
|
||||
(void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL);
|
||||
|
||||
rtPtr->readIsDrained = 0;
|
||||
rtPtr->eofPending = 0;
|
||||
ResultClear(&rtPtr->result);
|
||||
}
|
||||
|
||||
|
||||
+20
-3
@@ -12,9 +12,26 @@
|
||||
#include "tclInt.h"
|
||||
|
||||
#if defined(_WIN32) && defined(UNICODE)
|
||||
/* On Windows, we always need the ASCII version. */
|
||||
# undef gai_strerror
|
||||
# define gai_strerror gai_strerrorA
|
||||
/* On Windows, we need to do proper Unicode->UTF-8 conversion. */
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
int initialized;
|
||||
Tcl_DString errorMsg; /* UTF-8 encoded error-message */
|
||||
} ThreadSpecificData;
|
||||
static Tcl_ThreadDataKey dataKey;
|
||||
|
||||
#undef gai_strerror
|
||||
static const char *gai_strerror(int code) {
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
if (tsdPtr->initialized) {
|
||||
Tcl_DStringFree(&tsdPtr->errorMsg);
|
||||
} else {
|
||||
tsdPtr->initialized = 1;
|
||||
}
|
||||
Tcl_WinTCharToUtf(gai_strerrorW(code), -1, &tsdPtr->errorMsg);
|
||||
return Tcl_DStringValue(&tsdPtr->errorMsg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
+89
-5
@@ -19,11 +19,17 @@
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
# include "tclWinInt.h"
|
||||
#endif
|
||||
#include "tclFileSystem.h"
|
||||
|
||||
#ifdef TCL_TEMPLOAD_NO_UNLINK
|
||||
#ifndef NO_FSTATFS
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* struct FilesystemRecord --
|
||||
*
|
||||
@@ -792,7 +798,7 @@ TclFinalizeFilesystem(void)
|
||||
* filesystem is likely to fail.
|
||||
*/
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
TclWinEncodingsCleanup();
|
||||
#endif
|
||||
}
|
||||
@@ -819,7 +825,7 @@ TclResetFilesystem(void)
|
||||
filesystemList = &nativeFilesystemRecord;
|
||||
theFilesystemEpoch++;
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Cleans up the win32 API filesystem proc lookup table. This must happen
|
||||
* very late in finalization so that deleting of copied dlls can occur.
|
||||
@@ -3110,6 +3116,82 @@ Tcl_FSLoadFile(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* Workaround for issue with modern HPUX which do allow the unlink (no ETXTBSY
|
||||
* error) yet somehow trash some internal data structures which prevents the
|
||||
* second and further shared libraries from getting properly loaded. Only the
|
||||
* first is ok. We try to get around the issue by not unlinking,
|
||||
* i.e. emulating the behaviour of the older HPUX which denied removal.
|
||||
*
|
||||
* Doing the unlink is also an issue within docker containers, whose AUFS
|
||||
* bungles this as well, see
|
||||
* https://github.com/dotcloud/docker/issues/1911
|
||||
*
|
||||
* For these situations the change below makes the execution of the unlink
|
||||
* semi-controllable at runtime.
|
||||
*
|
||||
* An AUFS filesystem (if it can be detected) will force avoidance of
|
||||
* unlink. The env variable TCL_TEMPLOAD_NO_UNLINK allows detection of a
|
||||
* users general request (unlink and not.
|
||||
*
|
||||
* By default the unlink is done (if not in AUFS). However if the variable is
|
||||
* present and set to true (any integer > 0) then the unlink is skipped.
|
||||
*/
|
||||
|
||||
int
|
||||
TclSkipUnlink (Tcl_Obj* shlibFile)
|
||||
{
|
||||
/* Order of testing:
|
||||
* 1. On hpux we generally want to skip unlink in general
|
||||
*
|
||||
* Outside of hpux then:
|
||||
* 2. For a general user request (TCL_TEMPLOAD_NO_UNLINK present, non-empty, => int)
|
||||
* 3. For general AUFS environment (statfs, if available).
|
||||
*
|
||||
* Ad 2: This variable can disable/override the AUFS detection, i.e. for
|
||||
* testing if a newer AUFS does not have the bug any more.
|
||||
*
|
||||
* Ad 3: This is conditionally compiled in. Condition currently must be set manually.
|
||||
* This part needs proper tests in the configure(.in).
|
||||
*/
|
||||
|
||||
#ifdef hpux
|
||||
return 1;
|
||||
#else
|
||||
char* skipstr;
|
||||
|
||||
skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK");
|
||||
if (skipstr && (skipstr[0] != '\0')) {
|
||||
return atoi(skipstr);
|
||||
}
|
||||
|
||||
#ifdef TCL_TEMPLOAD_NO_UNLINK
|
||||
#ifndef NO_FSTATFS
|
||||
{
|
||||
struct statfs fs;
|
||||
/* Have fstatfs. May not have the AUFS super magic ... Indeed our build
|
||||
* box is too old to have it directly in the headers. Define taken from
|
||||
* http://mooon.googlecode.com/svn/trunk/linux_include/linux/aufs_type.h
|
||||
* http://aufs.sourceforge.net/
|
||||
* Better reference will be gladly taken.
|
||||
*/
|
||||
#ifndef AUFS_SUPER_MAGIC
|
||||
#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
|
||||
#endif /* AUFS_SUPER_MAGIC */
|
||||
if ((statfs(Tcl_GetString (shlibFile), &fs) == 0) &&
|
||||
(fs.f_type == AUFS_SUPER_MAGIC)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
#endif /* ... NO_FSTATFS */
|
||||
#endif /* ... TCL_TEMPLOAD_NO_UNLINK */
|
||||
|
||||
/* Fallback: !hpux, no EV override, no AUFS (detection, nor detected):
|
||||
* Don't skip */
|
||||
return 0;
|
||||
#endif /* hpux */
|
||||
}
|
||||
|
||||
int
|
||||
Tcl_LoadFile(
|
||||
Tcl_Interp *interp, /* Used for error reporting. */
|
||||
@@ -3255,7 +3337,7 @@ Tcl_LoadFile(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
#ifndef __WIN32__
|
||||
#ifndef _WIN32
|
||||
/*
|
||||
* Do we need to set appropriate permissions on the file? This may be
|
||||
* required on some systems. On Unix we could loop over the file
|
||||
@@ -3300,7 +3382,9 @@ Tcl_LoadFile(
|
||||
* avoids any worries about leaving the copy laying around on exit.
|
||||
*/
|
||||
|
||||
if (Tcl_FSDeleteFile(copyToPtr) == TCL_OK) {
|
||||
if (
|
||||
!TclSkipUnlink (copyToPtr) &&
|
||||
(Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) {
|
||||
Tcl_DecrRefCount(copyToPtr);
|
||||
|
||||
/*
|
||||
|
||||
+44
-4
@@ -1686,6 +1686,7 @@ typedef struct Command {
|
||||
#define CMD_TRACE_ACTIVE 0x2
|
||||
#define CMD_HAS_EXEC_TRACES 0x4
|
||||
#define CMD_COMPILES_EXPANDED 0x8
|
||||
#define CMD_REDEF_IN_PROGRESS 0x10
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -1740,7 +1741,7 @@ enum PkgPreferOptions {
|
||||
* definition there.
|
||||
* Some macros require knowledge of some fields in the struct in order to
|
||||
* avoid hitting the TSD unnecessarily. In order to facilitate this, a pointer
|
||||
* to the relevant fields is kept in the objCache field in struct Interp.
|
||||
* to the relevant fields is kept in the allocCache field in struct Interp.
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -2451,6 +2452,30 @@ typedef struct List {
|
||||
TclGetIntForIndex(interp, objPtr, ignore, idxPtr)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro used to save a function call for common uses of
|
||||
* Tcl_GetWideIntFromObj(). The ANSI C "prototype" is:
|
||||
*
|
||||
* MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
* Tcl_WideInt *wideIntPtr);
|
||||
*/
|
||||
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(wideIntPtr) = (Tcl_WideInt) \
|
||||
((objPtr)->internalRep.longValue), TCL_OK) : \
|
||||
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
|
||||
#else /* !TCL_WIDE_INT_IS_LONG */
|
||||
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
|
||||
(((objPtr)->typePtr == &tclWideIntType) \
|
||||
? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \
|
||||
((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(wideIntPtr) = (Tcl_WideInt) \
|
||||
((objPtr)->internalRep.longValue), TCL_OK) : \
|
||||
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
/*
|
||||
* Flag values for TclTraceDictPath().
|
||||
*
|
||||
@@ -2639,6 +2664,8 @@ MODULE_SCOPE char *tclMemDumpFileName;
|
||||
MODULE_SCOPE TclPlatformType tclPlatform;
|
||||
MODULE_SCOPE Tcl_NotifierProcs tclNotifierHooks;
|
||||
|
||||
MODULE_SCOPE Tcl_Encoding tclIdentityEncoding;
|
||||
|
||||
/*
|
||||
* TIP #233 (Virtualized Time)
|
||||
* Data for the time hooks, if any.
|
||||
@@ -2837,6 +2864,8 @@ MODULE_SCOPE int TclByteArrayMatch(const unsigned char *string,
|
||||
int strLen, const unsigned char *pattern,
|
||||
int ptnLen, int flags);
|
||||
MODULE_SCOPE double TclCeil(const mp_int *a);
|
||||
MODULE_SCOPE void TclChannelPreserve(Tcl_Channel chan);
|
||||
MODULE_SCOPE void TclChannelRelease(Tcl_Channel chan);
|
||||
MODULE_SCOPE int TclCheckBadOctal(Tcl_Interp *interp,
|
||||
const char *value);
|
||||
MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp,
|
||||
@@ -2854,6 +2883,10 @@ MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr,
|
||||
MODULE_SCOPE int TclConvertElement(const char *src, int length,
|
||||
char *dst, int flags);
|
||||
MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr);
|
||||
MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp,
|
||||
const char *dict, int dictLength,
|
||||
const char **elementPtr, const char **nextPtr,
|
||||
int *sizePtr, int *literalPtr);
|
||||
/* TIP #280 - Modified token based evulation, with line information. */
|
||||
MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script,
|
||||
int numBytes, int flags, int line,
|
||||
@@ -2893,7 +2926,8 @@ MODULE_SCOPE void TclFinalizeObjects(void);
|
||||
MODULE_SCOPE void TclFinalizePreserve(void);
|
||||
MODULE_SCOPE void TclFinalizeSynchronization(void);
|
||||
MODULE_SCOPE void TclFinalizeThreadAlloc(void);
|
||||
MODULE_SCOPE void TclFinalizeThreadData(void);
|
||||
MODULE_SCOPE void TclFinalizeThreadAllocThread(void);
|
||||
MODULE_SCOPE void TclFinalizeThreadData(int quick);
|
||||
MODULE_SCOPE void TclFinalizeThreadObjects(void);
|
||||
MODULE_SCOPE double TclFloor(const mp_int *a);
|
||||
MODULE_SCOPE void TclFormatNaN(double value, char *buffer);
|
||||
@@ -2918,6 +2952,8 @@ MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp,
|
||||
MODULE_SCOPE Tcl_Obj * TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr);
|
||||
MODULE_SCOPE Tcl_Obj * TclGetSourceFromFrame(CmdFrame *cfPtr, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
MODULE_SCOPE char * TclGetStringStorage(Tcl_Obj *objPtr,
|
||||
unsigned int *sizePtr);
|
||||
MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern,
|
||||
Tcl_Obj *unquotedPrefix, int globFlags,
|
||||
Tcl_GlobTypeData *types);
|
||||
@@ -2949,8 +2985,8 @@ MODULE_SCOPE void TclInitNotifier(void);
|
||||
MODULE_SCOPE void TclInitObjSubsystem(void);
|
||||
MODULE_SCOPE void TclInitSubsystems(void);
|
||||
MODULE_SCOPE int TclInterpReady(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclIsLocalScalar(const char *src, int len);
|
||||
MODULE_SCOPE int TclIsSpaceProc(char byte);
|
||||
MODULE_SCOPE int TclIsBareword(char byte);
|
||||
MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]);
|
||||
MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result);
|
||||
MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp);
|
||||
@@ -3059,7 +3095,8 @@ MODULE_SCOPE void TclRememberJoinableThread(Tcl_ThreadId id);
|
||||
MODULE_SCOPE void TclRememberMutex(Tcl_Mutex *mutex);
|
||||
MODULE_SCOPE void TclRemoveScriptLimitCallbacks(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int TclReToGlob(Tcl_Interp *interp, const char *reStr,
|
||||
int reStrLen, Tcl_DString *dsPtr, int *flagsPtr);
|
||||
int reStrLen, Tcl_DString *dsPtr, int *flagsPtr,
|
||||
int *quantifiersFoundPtr);
|
||||
MODULE_SCOPE int TclScanElement(const char *string, int length,
|
||||
int *flagPtr);
|
||||
MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp,
|
||||
@@ -3610,6 +3647,9 @@ MODULE_SCOPE int TclCompileReturnCmd(Tcl_Interp *interp,
|
||||
MODULE_SCOPE int TclCompileSetCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileStringCatCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
MODULE_SCOPE int TclCompileStringCmpCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#ifndef _TCLINTPLATDECLS
|
||||
#define _TCLINTPLATDECLS
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
# define Tcl_DirEntry void
|
||||
# define DIR void
|
||||
#endif
|
||||
@@ -45,7 +45,7 @@ extern "C" {
|
||||
* Exported function declarations:
|
||||
*/
|
||||
|
||||
#if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
/* 0 */
|
||||
EXTERN void TclGetAndDetachPids(Tcl_Interp *interp,
|
||||
Tcl_Channel chan);
|
||||
@@ -104,7 +104,7 @@ EXTERN int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
|
||||
Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
|
||||
Tcl_Obj *resultingNameObj);
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
/* 0 */
|
||||
EXTERN void TclWinConvertError(DWORD errCode);
|
||||
/* 1 */
|
||||
@@ -258,7 +258,7 @@ typedef struct TclIntPlatStubs {
|
||||
int magic;
|
||||
void *hooks;
|
||||
|
||||
#if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */
|
||||
int (*tclpCloseFile) (TclFile file); /* 1 */
|
||||
Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */
|
||||
@@ -291,7 +291,7 @@ typedef struct TclIntPlatStubs {
|
||||
int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
|
||||
int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
void (*tclWinConvertError) (DWORD errCode); /* 0 */
|
||||
void (*tclWinConvertWSAError) (DWORD errCode); /* 1 */
|
||||
struct servent * (*tclWinGetServByName) (const char *nm, const char *proto); /* 2 */
|
||||
@@ -371,7 +371,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
|
||||
* Inline function declarations:
|
||||
*/
|
||||
|
||||
#if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#define TclGetAndDetachPids \
|
||||
(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 0 */
|
||||
#define TclpCloseFile \
|
||||
@@ -420,7 +420,7 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
|
||||
#define TclUnixOpenTemporaryFile \
|
||||
(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
#define TclWinConvertError \
|
||||
(tclIntPlatStubsPtr->tclWinConvertError) /* 0 */
|
||||
#define TclWinConvertWSAError \
|
||||
@@ -550,9 +550,15 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
|
||||
#undef TclpInetNtoa
|
||||
#define TclpInetNtoa inet_ntoa
|
||||
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__)
|
||||
#if defined(_WIN32)
|
||||
# undef TclWinNToHS
|
||||
# undef TclWinGetServByName
|
||||
# undef TclWinGetSockOpt
|
||||
# undef TclWinSetSockOpt
|
||||
# define TclWinNToHS ntohs
|
||||
# define TclWinGetServByName getservbyname
|
||||
# define TclWinGetSockOpt getsockopt
|
||||
# define TclWinSetSockOpt setsockopt
|
||||
#else
|
||||
# undef TclpGetPid
|
||||
# define TclpGetPid(pid) ((unsigned long) (pid))
|
||||
|
||||
+2
-2
@@ -830,7 +830,7 @@ Tcl_UnloadObjCmd(
|
||||
* Unload the shared library from the application memory...
|
||||
*/
|
||||
|
||||
#if defined(TCL_UNLOAD_DLLS) || defined(__WIN32__)
|
||||
#if defined(TCL_UNLOAD_DLLS) || defined(_WIN32)
|
||||
/*
|
||||
* Some Unix dlls are poorly behaved - registering things like atexit
|
||||
* calls that can't be unregistered. If you unload such dlls, you get
|
||||
@@ -1151,7 +1151,7 @@ TclFinalizeLoad(void)
|
||||
pkgPtr = firstPackagePtr;
|
||||
firstPackagePtr = pkgPtr->nextPtr;
|
||||
|
||||
#if defined(TCL_UNLOAD_DLLS) || defined(__WIN32__)
|
||||
#if defined(TCL_UNLOAD_DLLS) || defined(_WIN32)
|
||||
/*
|
||||
* Some Unix dlls are poorly behaved - registering things like atexit
|
||||
* calls that can't be unregistered. If you unload such dlls, you get
|
||||
|
||||
@@ -104,7 +104,9 @@ TclpLoadMemory(
|
||||
int size, /* Dummy: unused by this implementation */
|
||||
int codeSize, /* Dummy: unused by this implementation */
|
||||
Tcl_LoadHandle *loadHandle, /* Dummy: unused by this implementation */
|
||||
Tcl_FSUnloadFileProc **unloadProcPtr)
|
||||
Tcl_FSUnloadFileProc **unloadProcPtr,
|
||||
/* Dummy: unused by this implementation */
|
||||
int flags)
|
||||
/* Dummy: unused by this implementation */
|
||||
{
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("dynamic loading from memory "
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@
|
||||
* we have to translate that to strcmp here.
|
||||
*/
|
||||
|
||||
#ifndef __WIN32__
|
||||
#ifndef _WIN32
|
||||
# define TCHAR char
|
||||
# define TEXT(arg) arg
|
||||
# define _tcscmp strcmp
|
||||
|
||||
@@ -394,6 +394,7 @@ InitFoundation(
|
||||
fPtr->classCls->flags |= ROOT_CLASS;
|
||||
TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
|
||||
TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls);
|
||||
TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls);
|
||||
AddRef(fPtr->objectCls->thisPtr);
|
||||
AddRef(fPtr->objectCls);
|
||||
|
||||
@@ -1008,6 +1009,12 @@ ReleaseClassContents(
|
||||
}
|
||||
if (!Deleted(instancePtr)) {
|
||||
Tcl_DeleteCommandFromToken(interp, instancePtr->command);
|
||||
/*
|
||||
* Tcl_DeleteCommandFromToken() may have done to whole
|
||||
* job for us. Roll back and check again.
|
||||
*/
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
DelRef(instancePtr);
|
||||
}
|
||||
@@ -1280,6 +1287,9 @@ TclOORemoveFromInstances(
|
||||
|
||||
removeInstance:
|
||||
if (Deleted(clsPtr->thisPtr)) {
|
||||
if (!IsRootClass(clsPtr)) {
|
||||
DelRef(clsPtr->instances.list[i]);
|
||||
}
|
||||
clsPtr->instances.list[i] = NULL;
|
||||
} else {
|
||||
clsPtr->instances.num--;
|
||||
|
||||
@@ -18,6 +18,7 @@ library tclOO
|
||||
|
||||
interface tclOO
|
||||
hooks tclOOInt
|
||||
scspec TCLAPI
|
||||
|
||||
declare 0 {
|
||||
Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp,
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@
|
||||
* win/tclooConfig.sh
|
||||
*/
|
||||
|
||||
#define TCLOO_VERSION "1.0.1"
|
||||
#define TCLOO_VERSION "1.0.3"
|
||||
#define TCLOO_PATCHLEVEL TCLOO_VERSION
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
+72
-27
@@ -38,6 +38,12 @@ struct ChainBuilder {
|
||||
#define DEFINITE_PUBLIC 0x200000
|
||||
#define KNOWN_STATE (DEFINITE_PROTECTED | DEFINITE_PUBLIC)
|
||||
#define SPECIAL (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN)
|
||||
#define BUILDING_MIXINS 0x400000
|
||||
#define TRAVERSED_MIXIN 0x800000
|
||||
#define OBJECT_MIXIN 0x1000000
|
||||
#define MIXIN_CONSISTENT(flags) \
|
||||
(((flags) & OBJECT_MIXIN) || \
|
||||
!((flags) & BUILDING_MIXINS) == !((flags) & TRAVERSED_MIXIN))
|
||||
|
||||
/*
|
||||
* Function declarations for things defined in this file.
|
||||
@@ -45,13 +51,13 @@ struct ChainBuilder {
|
||||
|
||||
static void AddClassFiltersToCallContext(Object *const oPtr,
|
||||
Class *clsPtr, struct ChainBuilder *const cbPtr,
|
||||
Tcl_HashTable *const doneFilters);
|
||||
Tcl_HashTable *const doneFilters, int flags);
|
||||
static void AddClassMethodNames(Class *clsPtr, const int flags,
|
||||
Tcl_HashTable *const namesPtr);
|
||||
static inline void AddMethodToCallChain(Method *const mPtr,
|
||||
struct ChainBuilder *const cbPtr,
|
||||
Tcl_HashTable *const doneFilters,
|
||||
Class *const filterDecl);
|
||||
Class *const filterDecl, int flags);
|
||||
static inline void AddSimpleChainToCallContext(Object *const oPtr,
|
||||
Tcl_Obj *const methodNameObj,
|
||||
struct ChainBuilder *const cbPtr,
|
||||
@@ -150,7 +156,7 @@ void
|
||||
TclOODeleteChain(
|
||||
CallChain *callPtr)
|
||||
{
|
||||
if (--callPtr->refCount >= 1) {
|
||||
if (callPtr == NULL || --callPtr->refCount >= 1) {
|
||||
return;
|
||||
}
|
||||
if (callPtr->chain != callPtr->staticChain) {
|
||||
@@ -434,7 +440,7 @@ TclOOGetSortedMethodList(
|
||||
|
||||
AddClassMethodNames(oPtr->selfCls, flags, &names);
|
||||
FOREACH(mixinPtr, oPtr->mixins) {
|
||||
AddClassMethodNames(mixinPtr, flags, &names);
|
||||
AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, &names);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -598,7 +604,7 @@ AddClassMethodNames(
|
||||
|
||||
/* TODO: Beware of infinite loops! */
|
||||
FOREACH(mixinPtr, clsPtr->mixins) {
|
||||
AddClassMethodNames(mixinPtr, flags, namesPtr);
|
||||
AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, namesPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -695,13 +701,13 @@ AddSimpleChainToCallContext(
|
||||
|
||||
FOREACH(mixinPtr, oPtr->mixins) {
|
||||
AddSimpleClassChainToCallContext(mixinPtr, methodNameObj, cbPtr,
|
||||
doneFilters, flags, filterDecl);
|
||||
doneFilters, flags|TRAVERSED_MIXIN, filterDecl);
|
||||
}
|
||||
if (oPtr->methodsPtr) {
|
||||
hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char*) methodNameObj);
|
||||
if (hPtr != NULL) {
|
||||
AddMethodToCallChain(Tcl_GetHashValue(hPtr), cbPtr,
|
||||
doneFilters, filterDecl);
|
||||
doneFilters, filterDecl, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -732,9 +738,15 @@ AddMethodToCallChain(
|
||||
* processed. If NULL, not processing filters.
|
||||
* Note that this function does not update
|
||||
* this hashtable. */
|
||||
Class *const filterDecl) /* The class that declared the filter. If
|
||||
Class *const filterDecl, /* The class that declared the filter. If
|
||||
* NULL, either the filter was declared by the
|
||||
* object or this isn't a filter. */
|
||||
int flags) /* Used to check if we're mixin-consistent
|
||||
* only. Mixin-consistent means that either
|
||||
* we're looking to add things from a mixin
|
||||
* and we have passed a mixin, or we're not
|
||||
* looking to add things from a mixin and have
|
||||
* not passed a mixin. */
|
||||
{
|
||||
register CallChain *callPtr = cbPtr->callChainPtr;
|
||||
int i;
|
||||
@@ -743,9 +755,11 @@ AddMethodToCallChain(
|
||||
* Return if this is just an entry used to record whether this is a public
|
||||
* method. If so, there's nothing real to call and so nothing to add to
|
||||
* the call chain.
|
||||
*
|
||||
* This is also where we enforce mixin-consistency.
|
||||
*/
|
||||
|
||||
if (mPtr == NULL || mPtr->typePtr == NULL) {
|
||||
if (mPtr == NULL || mPtr->typePtr == NULL || !MIXIN_CONSISTENT(flags)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1000,6 +1014,8 @@ TclOOGetCallContext(
|
||||
*/
|
||||
|
||||
if (flags & FORCE_UNKNOWN) {
|
||||
AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
|
||||
&cb, NULL, BUILDING_MIXINS, NULL);
|
||||
AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
|
||||
&cb, NULL, 0, NULL);
|
||||
callPtr->flags |= OO_UNKNOWN_METHOD;
|
||||
@@ -1024,21 +1040,32 @@ TclOOGetCallContext(
|
||||
doFilters = 1;
|
||||
Tcl_InitObjHashTable(&doneFilters);
|
||||
FOREACH(mixinPtr, oPtr->mixins) {
|
||||
AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters);
|
||||
AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters,
|
||||
TRAVERSED_MIXIN|BUILDING_MIXINS|OBJECT_MIXIN);
|
||||
AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters,
|
||||
OBJECT_MIXIN);
|
||||
}
|
||||
FOREACH(filterObj, oPtr->filters) {
|
||||
AddSimpleChainToCallContext(oPtr, filterObj, &cb, &doneFilters,
|
||||
BUILDING_MIXINS, NULL);
|
||||
AddSimpleChainToCallContext(oPtr, filterObj, &cb, &doneFilters, 0,
|
||||
NULL);
|
||||
}
|
||||
AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters);
|
||||
AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters,
|
||||
BUILDING_MIXINS);
|
||||
AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters,
|
||||
0);
|
||||
Tcl_DeleteHashTable(&doneFilters);
|
||||
}
|
||||
count = cb.filterLength = callPtr->numChain;
|
||||
|
||||
/*
|
||||
* Add the actual method implementations.
|
||||
* Add the actual method implementations. We have to do this twice to
|
||||
* handle class mixins right.
|
||||
*/
|
||||
|
||||
AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL,
|
||||
flags|BUILDING_MIXINS, NULL);
|
||||
AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL, flags, NULL);
|
||||
|
||||
/*
|
||||
@@ -1057,6 +1084,8 @@ TclOOGetCallContext(
|
||||
TclOODeleteChain(callPtr);
|
||||
return NULL;
|
||||
}
|
||||
AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
|
||||
&cb, NULL, BUILDING_MIXINS, NULL);
|
||||
AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
|
||||
&cb, NULL, 0, NULL);
|
||||
callPtr->flags |= OO_UNKNOWN_METHOD;
|
||||
@@ -1201,7 +1230,9 @@ TclOOGetStereotypeCallChain(
|
||||
*/
|
||||
|
||||
Tcl_InitObjHashTable(&doneFilters);
|
||||
AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters);
|
||||
AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters,
|
||||
BUILDING_MIXINS);
|
||||
AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters, 0);
|
||||
Tcl_DeleteHashTable(&doneFilters);
|
||||
count = cb.filterLength = callPtr->numChain;
|
||||
|
||||
@@ -1209,6 +1240,8 @@ TclOOGetStereotypeCallChain(
|
||||
* Add the actual method implementations.
|
||||
*/
|
||||
|
||||
AddSimpleChainToCallContext(&obj, methodNameObj, &cb, NULL,
|
||||
flags|BUILDING_MIXINS, NULL);
|
||||
AddSimpleChainToCallContext(&obj, methodNameObj, &cb, NULL, flags, NULL);
|
||||
|
||||
/*
|
||||
@@ -1218,6 +1251,8 @@ TclOOGetStereotypeCallChain(
|
||||
*/
|
||||
|
||||
if (count == callPtr->numChain) {
|
||||
AddSimpleChainToCallContext(&obj, fPtr->unknownMethodNameObj, &cb,
|
||||
NULL, BUILDING_MIXINS, NULL);
|
||||
AddSimpleChainToCallContext(&obj, fPtr->unknownMethodNameObj, &cb,
|
||||
NULL, 0, NULL);
|
||||
callPtr->flags |= OO_UNKNOWN_METHOD;
|
||||
@@ -1259,12 +1294,15 @@ AddClassFiltersToCallContext(
|
||||
Class *clsPtr, /* Class to get the filters from. */
|
||||
struct ChainBuilder *const cbPtr,
|
||||
/* Context to fill with call chain entries. */
|
||||
Tcl_HashTable *const doneFilters)
|
||||
Tcl_HashTable *const doneFilters,
|
||||
/* Where to record what filters have been
|
||||
* processed. Keys are objects, values are
|
||||
* ignored. */
|
||||
int flags) /* Whether we've gone along a mixin link
|
||||
* yet. */
|
||||
{
|
||||
int i;
|
||||
int i, clearedFlags =
|
||||
flags & ~(TRAVERSED_MIXIN|OBJECT_MIXIN|BUILDING_MIXINS);
|
||||
Class *superPtr, *mixinPtr;
|
||||
Tcl_Obj *filterObj;
|
||||
|
||||
@@ -1279,7 +1317,8 @@ AddClassFiltersToCallContext(
|
||||
*/
|
||||
|
||||
FOREACH(mixinPtr, clsPtr->mixins) {
|
||||
AddClassFiltersToCallContext(oPtr, mixinPtr, cbPtr, doneFilters);
|
||||
AddClassFiltersToCallContext(oPtr, mixinPtr, cbPtr, doneFilters,
|
||||
flags|TRAVERSED_MIXIN);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1288,13 +1327,18 @@ AddClassFiltersToCallContext(
|
||||
* override how filters work to extend their behaviour.
|
||||
*/
|
||||
|
||||
FOREACH(filterObj, clsPtr->filters) {
|
||||
int isNew;
|
||||
if (MIXIN_CONSISTENT(flags)) {
|
||||
FOREACH(filterObj, clsPtr->filters) {
|
||||
int isNew;
|
||||
|
||||
(void) Tcl_CreateHashEntry(doneFilters, (char *) filterObj, &isNew);
|
||||
if (isNew) {
|
||||
AddSimpleChainToCallContext(oPtr, filterObj, cbPtr, doneFilters,
|
||||
0, clsPtr);
|
||||
(void) Tcl_CreateHashEntry(doneFilters, (char *) filterObj,
|
||||
&isNew);
|
||||
if (isNew) {
|
||||
AddSimpleChainToCallContext(oPtr, filterObj, cbPtr,
|
||||
doneFilters, clearedFlags|BUILDING_MIXINS, clsPtr);
|
||||
AddSimpleChainToCallContext(oPtr, filterObj, cbPtr,
|
||||
doneFilters, clearedFlags, clsPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1308,7 +1352,8 @@ AddClassFiltersToCallContext(
|
||||
goto tailRecurse;
|
||||
default:
|
||||
FOREACH(superPtr, clsPtr->superclasses) {
|
||||
AddClassFiltersToCallContext(oPtr, superPtr, cbPtr, doneFilters);
|
||||
AddClassFiltersToCallContext(oPtr, superPtr, cbPtr, doneFilters,
|
||||
flags);
|
||||
}
|
||||
case 0:
|
||||
return;
|
||||
@@ -1355,16 +1400,16 @@ AddSimpleClassChainToCallContext(
|
||||
tailRecurse:
|
||||
FOREACH(superPtr, classPtr->mixins) {
|
||||
AddSimpleClassChainToCallContext(superPtr, methodNameObj, cbPtr,
|
||||
doneFilters, flags, filterDecl);
|
||||
doneFilters, flags|TRAVERSED_MIXIN, filterDecl);
|
||||
}
|
||||
|
||||
if (flags & CONSTRUCTOR) {
|
||||
AddMethodToCallChain(classPtr->constructorPtr, cbPtr, doneFilters,
|
||||
filterDecl);
|
||||
filterDecl, flags);
|
||||
|
||||
} else if (flags & DESTRUCTOR) {
|
||||
AddMethodToCallChain(classPtr->destructorPtr, cbPtr, doneFilters,
|
||||
filterDecl);
|
||||
filterDecl, flags);
|
||||
} else {
|
||||
Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&classPtr->classMethods,
|
||||
(char *) methodNameObj);
|
||||
@@ -1383,7 +1428,7 @@ AddSimpleClassChainToCallContext(
|
||||
flags |= DEFINITE_PROTECTED;
|
||||
}
|
||||
}
|
||||
AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl);
|
||||
AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl, flags);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+38
-40
@@ -5,19 +5,19 @@
|
||||
#ifndef _TCLOODECLS
|
||||
#define _TCLOODECLS
|
||||
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#ifdef BUILD_tcl
|
||||
# define TCL_STORAGE_CLASS DLLEXPORT
|
||||
#else
|
||||
# ifdef USE_TCL_STUBS
|
||||
# undef USE_TCLOO_STUBS
|
||||
# define USE_TCLOO_STUBS
|
||||
# define TCL_STORAGE_CLASS
|
||||
#ifndef TCLAPI
|
||||
# ifdef BUILD_tcl
|
||||
# define TCLAPI extern DLLEXPORT
|
||||
# else
|
||||
# define TCL_STORAGE_CLASS DLLIMPORT
|
||||
# define TCLAPI extern DLLIMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef USE_TCL_STUBS
|
||||
# undef USE_TCLOO_STUBS
|
||||
# define USE_TCLOO_STUBS
|
||||
#endif
|
||||
|
||||
/* !BEGIN!: Do not edit below this line. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -29,92 +29,92 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/* 0 */
|
||||
EXTERN Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp,
|
||||
Tcl_Object sourceObject,
|
||||
const char *targetName,
|
||||
const char *targetNamespaceName);
|
||||
/* 1 */
|
||||
EXTERN Tcl_Object Tcl_GetClassAsObject(Tcl_Class clazz);
|
||||
TCLAPI Tcl_Object Tcl_GetClassAsObject(Tcl_Class clazz);
|
||||
/* 2 */
|
||||
EXTERN Tcl_Class Tcl_GetObjectAsClass(Tcl_Object object);
|
||||
TCLAPI Tcl_Class Tcl_GetObjectAsClass(Tcl_Object object);
|
||||
/* 3 */
|
||||
EXTERN Tcl_Command Tcl_GetObjectCommand(Tcl_Object object);
|
||||
TCLAPI Tcl_Command Tcl_GetObjectCommand(Tcl_Object object);
|
||||
/* 4 */
|
||||
EXTERN Tcl_Object Tcl_GetObjectFromObj(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Object Tcl_GetObjectFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
/* 5 */
|
||||
EXTERN Tcl_Namespace * Tcl_GetObjectNamespace(Tcl_Object object);
|
||||
TCLAPI Tcl_Namespace * Tcl_GetObjectNamespace(Tcl_Object object);
|
||||
/* 6 */
|
||||
EXTERN Tcl_Class Tcl_MethodDeclarerClass(Tcl_Method method);
|
||||
TCLAPI Tcl_Class Tcl_MethodDeclarerClass(Tcl_Method method);
|
||||
/* 7 */
|
||||
EXTERN Tcl_Object Tcl_MethodDeclarerObject(Tcl_Method method);
|
||||
TCLAPI Tcl_Object Tcl_MethodDeclarerObject(Tcl_Method method);
|
||||
/* 8 */
|
||||
EXTERN int Tcl_MethodIsPublic(Tcl_Method method);
|
||||
TCLAPI int Tcl_MethodIsPublic(Tcl_Method method);
|
||||
/* 9 */
|
||||
EXTERN int Tcl_MethodIsType(Tcl_Method method,
|
||||
TCLAPI int Tcl_MethodIsType(Tcl_Method method,
|
||||
const Tcl_MethodType *typePtr,
|
||||
ClientData *clientDataPtr);
|
||||
/* 10 */
|
||||
EXTERN Tcl_Obj * Tcl_MethodName(Tcl_Method method);
|
||||
TCLAPI Tcl_Obj * Tcl_MethodName(Tcl_Method method);
|
||||
/* 11 */
|
||||
EXTERN Tcl_Method Tcl_NewInstanceMethod(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Method Tcl_NewInstanceMethod(Tcl_Interp *interp,
|
||||
Tcl_Object object, Tcl_Obj *nameObj,
|
||||
int isPublic, const Tcl_MethodType *typePtr,
|
||||
ClientData clientData);
|
||||
/* 12 */
|
||||
EXTERN Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls,
|
||||
TCLAPI Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls,
|
||||
Tcl_Obj *nameObj, int isPublic,
|
||||
const Tcl_MethodType *typePtr,
|
||||
ClientData clientData);
|
||||
/* 13 */
|
||||
EXTERN Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp,
|
||||
Tcl_Class cls, const char *nameStr,
|
||||
const char *nsNameStr, int objc,
|
||||
Tcl_Obj *const *objv, int skip);
|
||||
/* 14 */
|
||||
EXTERN int Tcl_ObjectDeleted(Tcl_Object object);
|
||||
TCLAPI int Tcl_ObjectDeleted(Tcl_Object object);
|
||||
/* 15 */
|
||||
EXTERN int Tcl_ObjectContextIsFiltering(
|
||||
TCLAPI int Tcl_ObjectContextIsFiltering(
|
||||
Tcl_ObjectContext context);
|
||||
/* 16 */
|
||||
EXTERN Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context);
|
||||
TCLAPI Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context);
|
||||
/* 17 */
|
||||
EXTERN Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context);
|
||||
TCLAPI Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context);
|
||||
/* 18 */
|
||||
EXTERN int Tcl_ObjectContextSkippedArgs(
|
||||
TCLAPI int Tcl_ObjectContextSkippedArgs(
|
||||
Tcl_ObjectContext context);
|
||||
/* 19 */
|
||||
EXTERN ClientData Tcl_ClassGetMetadata(Tcl_Class clazz,
|
||||
TCLAPI ClientData Tcl_ClassGetMetadata(Tcl_Class clazz,
|
||||
const Tcl_ObjectMetadataType *typePtr);
|
||||
/* 20 */
|
||||
EXTERN void Tcl_ClassSetMetadata(Tcl_Class clazz,
|
||||
TCLAPI void Tcl_ClassSetMetadata(Tcl_Class clazz,
|
||||
const Tcl_ObjectMetadataType *typePtr,
|
||||
ClientData metadata);
|
||||
/* 21 */
|
||||
EXTERN ClientData Tcl_ObjectGetMetadata(Tcl_Object object,
|
||||
TCLAPI ClientData Tcl_ObjectGetMetadata(Tcl_Object object,
|
||||
const Tcl_ObjectMetadataType *typePtr);
|
||||
/* 22 */
|
||||
EXTERN void Tcl_ObjectSetMetadata(Tcl_Object object,
|
||||
TCLAPI void Tcl_ObjectSetMetadata(Tcl_Object object,
|
||||
const Tcl_ObjectMetadataType *typePtr,
|
||||
ClientData metadata);
|
||||
/* 23 */
|
||||
EXTERN int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp,
|
||||
TCLAPI int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp,
|
||||
Tcl_ObjectContext context, int objc,
|
||||
Tcl_Obj *const *objv, int skip);
|
||||
/* 24 */
|
||||
EXTERN Tcl_ObjectMapMethodNameProc * Tcl_ObjectGetMethodNameMapper(
|
||||
TCLAPI Tcl_ObjectMapMethodNameProc * Tcl_ObjectGetMethodNameMapper(
|
||||
Tcl_Object object);
|
||||
/* 25 */
|
||||
EXTERN void Tcl_ObjectSetMethodNameMapper(Tcl_Object object,
|
||||
TCLAPI void Tcl_ObjectSetMethodNameMapper(Tcl_Object object,
|
||||
Tcl_ObjectMapMethodNameProc *mapMethodNameProc);
|
||||
/* 26 */
|
||||
EXTERN void Tcl_ClassSetConstructor(Tcl_Interp *interp,
|
||||
TCLAPI void Tcl_ClassSetConstructor(Tcl_Interp *interp,
|
||||
Tcl_Class clazz, Tcl_Method method);
|
||||
/* 27 */
|
||||
EXTERN void Tcl_ClassSetDestructor(Tcl_Interp *interp,
|
||||
TCLAPI void Tcl_ClassSetDestructor(Tcl_Interp *interp,
|
||||
Tcl_Class clazz, Tcl_Method method);
|
||||
/* 28 */
|
||||
EXTERN Tcl_Obj * Tcl_GetObjectName(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Obj * Tcl_GetObjectName(Tcl_Interp *interp,
|
||||
Tcl_Object object);
|
||||
|
||||
typedef struct {
|
||||
@@ -231,6 +231,4 @@ extern const TclOOStubs *tclOOStubsPtr;
|
||||
|
||||
/* !END!: Do not edit above this line. */
|
||||
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#define TCL_STORAGE_CLASS DLLIMPORT
|
||||
#endif /* _TCLOODECLS */
|
||||
|
||||
+16
-29
@@ -5,17 +5,6 @@
|
||||
#ifndef _TCLOOINTDECLS
|
||||
#define _TCLOOINTDECLS
|
||||
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#ifdef BUILD_tcl
|
||||
# define TCL_STORAGE_CLASS DLLEXPORT
|
||||
#else
|
||||
# ifdef USE_TCL_STUBS
|
||||
# define TCL_STORAGE_CLASS
|
||||
# else
|
||||
# define TCL_STORAGE_CLASS DLLIMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* !BEGIN!: Do not edit below this line. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -27,46 +16,46 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/* 0 */
|
||||
EXTERN Tcl_Object TclOOGetDefineCmdContext(Tcl_Interp *interp);
|
||||
TCLAPI Tcl_Object TclOOGetDefineCmdContext(Tcl_Interp *interp);
|
||||
/* 1 */
|
||||
EXTERN Tcl_Method TclOOMakeProcInstanceMethod(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Method TclOOMakeProcInstanceMethod(Tcl_Interp *interp,
|
||||
Object *oPtr, int flags, Tcl_Obj *nameObj,
|
||||
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
|
||||
const Tcl_MethodType *typePtr,
|
||||
ClientData clientData, Proc **procPtrPtr);
|
||||
/* 2 */
|
||||
EXTERN Tcl_Method TclOOMakeProcMethod(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Method TclOOMakeProcMethod(Tcl_Interp *interp,
|
||||
Class *clsPtr, int flags, Tcl_Obj *nameObj,
|
||||
const char *namePtr, Tcl_Obj *argsObj,
|
||||
Tcl_Obj *bodyObj,
|
||||
const Tcl_MethodType *typePtr,
|
||||
ClientData clientData, Proc **procPtrPtr);
|
||||
/* 3 */
|
||||
EXTERN Method * TclOONewProcInstanceMethod(Tcl_Interp *interp,
|
||||
TCLAPI Method * TclOONewProcInstanceMethod(Tcl_Interp *interp,
|
||||
Object *oPtr, int flags, Tcl_Obj *nameObj,
|
||||
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
|
||||
ProcedureMethod **pmPtrPtr);
|
||||
/* 4 */
|
||||
EXTERN Method * TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr,
|
||||
TCLAPI Method * TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr,
|
||||
int flags, Tcl_Obj *nameObj,
|
||||
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
|
||||
ProcedureMethod **pmPtrPtr);
|
||||
/* 5 */
|
||||
EXTERN int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp,
|
||||
TCLAPI int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv,
|
||||
int publicOnly, Class *startCls);
|
||||
/* 6 */
|
||||
EXTERN int TclOOIsReachable(Class *targetPtr, Class *startPtr);
|
||||
TCLAPI int TclOOIsReachable(Class *targetPtr, Class *startPtr);
|
||||
/* 7 */
|
||||
EXTERN Method * TclOONewForwardMethod(Tcl_Interp *interp,
|
||||
TCLAPI Method * TclOONewForwardMethod(Tcl_Interp *interp,
|
||||
Class *clsPtr, int isPublic,
|
||||
Tcl_Obj *nameObj, Tcl_Obj *prefixObj);
|
||||
/* 8 */
|
||||
EXTERN Method * TclOONewForwardInstanceMethod(Tcl_Interp *interp,
|
||||
TCLAPI Method * TclOONewForwardInstanceMethod(Tcl_Interp *interp,
|
||||
Object *oPtr, int isPublic, Tcl_Obj *nameObj,
|
||||
Tcl_Obj *prefixObj);
|
||||
/* 9 */
|
||||
EXTERN Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
|
||||
Tcl_Object oPtr,
|
||||
TclOO_PreCallProc *preCallPtr,
|
||||
TclOO_PostCallProc *postCallPtr,
|
||||
@@ -75,7 +64,7 @@ EXTERN Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
|
||||
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
|
||||
int flags, void **internalTokenPtr);
|
||||
/* 10 */
|
||||
EXTERN Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp,
|
||||
TCLAPI Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp,
|
||||
Tcl_Class clsPtr,
|
||||
TclOO_PreCallProc *preCallPtr,
|
||||
TclOO_PostCallProc *postCallPtr,
|
||||
@@ -84,22 +73,22 @@ EXTERN Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp,
|
||||
Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
|
||||
int flags, void **internalTokenPtr);
|
||||
/* 11 */
|
||||
EXTERN int TclOOInvokeObject(Tcl_Interp *interp,
|
||||
TCLAPI int TclOOInvokeObject(Tcl_Interp *interp,
|
||||
Tcl_Object object, Tcl_Class startCls,
|
||||
int publicPrivate, int objc,
|
||||
Tcl_Obj *const *objv);
|
||||
/* 12 */
|
||||
EXTERN void TclOOObjectSetFilters(Object *oPtr, int numFilters,
|
||||
TCLAPI void TclOOObjectSetFilters(Object *oPtr, int numFilters,
|
||||
Tcl_Obj *const *filters);
|
||||
/* 13 */
|
||||
EXTERN void TclOOClassSetFilters(Tcl_Interp *interp,
|
||||
TCLAPI void TclOOClassSetFilters(Tcl_Interp *interp,
|
||||
Class *classPtr, int numFilters,
|
||||
Tcl_Obj *const *filters);
|
||||
/* 14 */
|
||||
EXTERN void TclOOObjectSetMixins(Object *oPtr, int numMixins,
|
||||
TCLAPI void TclOOObjectSetMixins(Object *oPtr, int numMixins,
|
||||
Class *const *mixins);
|
||||
/* 15 */
|
||||
EXTERN void TclOOClassSetMixins(Tcl_Interp *interp,
|
||||
TCLAPI void TclOOClassSetMixins(Tcl_Interp *interp,
|
||||
Class *classPtr, int numMixins,
|
||||
Class *const *mixins);
|
||||
|
||||
@@ -174,6 +163,4 @@ extern const TclOOIntStubs *tclOOIntStubsPtr;
|
||||
|
||||
/* !END!: Do not edit above this line. */
|
||||
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#define TCL_STORAGE_CLASS DLLIMPORT
|
||||
#endif /* _TCLOOINTDECLS */
|
||||
|
||||
+46
-67
@@ -618,6 +618,47 @@ TclIsSpaceProc(
|
||||
return CHAR_TYPE(byte) & (TYPE_SPACE) || byte == '\n';
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclIsBareword--
|
||||
*
|
||||
* Report whether byte is one that can be part of a "bareword".
|
||||
* This concept is named in expression parsing, where it determines
|
||||
* what can be a legal function name, but is the same definition used
|
||||
* in determining what variable names can be parsed as variable
|
||||
* substitutions without the benefit of enclosing braces. The set of
|
||||
* ASCII chars that are accepted are the numeric chars ('0'-'9'),
|
||||
* the alphabetic chars ('a'-'z', 'A'-'Z') and underscore ('_').
|
||||
*
|
||||
* Results:
|
||||
* Returns 1, if byte is in the accepted set of chars, 0 otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclIsBareword(
|
||||
char byte)
|
||||
{
|
||||
if (byte < '0' || byte > 'z') {
|
||||
return 0;
|
||||
}
|
||||
if (byte <= '9' || byte >= 'a') {
|
||||
return 1;
|
||||
}
|
||||
if (byte == '_') {
|
||||
return 1;
|
||||
}
|
||||
if (byte < 'A' || byte > 'Z') {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1346,9 +1387,7 @@ Tcl_ParseVarName(
|
||||
{
|
||||
Tcl_Token *tokenPtr;
|
||||
register const char *src;
|
||||
unsigned char c;
|
||||
int varIndex, offset;
|
||||
Tcl_UniChar ch;
|
||||
int varIndex;
|
||||
unsigned array;
|
||||
|
||||
if ((numBytes == 0) || (start == NULL)) {
|
||||
@@ -1431,22 +1470,12 @@ Tcl_ParseVarName(
|
||||
tokenPtr->numComponents = 0;
|
||||
|
||||
while (numBytes) {
|
||||
if (Tcl_UtfCharComplete(src, numBytes)) {
|
||||
offset = Tcl_UtfToUniChar(src, &ch);
|
||||
} else {
|
||||
char utfBytes[TCL_UTF_MAX];
|
||||
|
||||
memcpy(utfBytes, src, (size_t) numBytes);
|
||||
utfBytes[numBytes] = '\0';
|
||||
offset = Tcl_UtfToUniChar(utfBytes, &ch);
|
||||
}
|
||||
c = UCHAR(ch);
|
||||
if (isalnum(c) || (c == '_')) { /* INTL: ISO only, UCHAR. */
|
||||
src += offset;
|
||||
numBytes -= offset;
|
||||
if (TclIsBareword(*src)) {
|
||||
src += 1;
|
||||
numBytes -= 1;
|
||||
continue;
|
||||
}
|
||||
if ((c == ':') && (numBytes != 1) && (src[1] == ':')) {
|
||||
if ((src[0] == ':') && (numBytes != 1) && (src[1] == ':')) {
|
||||
src += 2;
|
||||
numBytes -= 2;
|
||||
while (numBytes && (*src == ':')) {
|
||||
@@ -2496,56 +2525,6 @@ TclObjCommandComplete(
|
||||
return CommandComplete(script, length);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclIsLocalScalar --
|
||||
*
|
||||
* Check to see if a given string is a legal scalar variable name with no
|
||||
* namespace qualifiers or substitutions.
|
||||
*
|
||||
* Results:
|
||||
* Returns 1 if the variable is a local scalar.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclIsLocalScalar(
|
||||
const char *src,
|
||||
int len)
|
||||
{
|
||||
const char *p;
|
||||
const char *lastChar = src + (len - 1);
|
||||
|
||||
for (p=src ; p<=lastChar ; p++) {
|
||||
if ((CHAR_TYPE(*p) != TYPE_NORMAL)
|
||||
&& (CHAR_TYPE(*p) != TYPE_COMMAND_END)) {
|
||||
/*
|
||||
* TCL_COMMAND_END is returned for the last character of the
|
||||
* string. By this point we know it isn't an array or namespace
|
||||
* reference.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (*p == '(') {
|
||||
if (*lastChar == ')') { /* We have an array element */
|
||||
return 0;
|
||||
}
|
||||
} else if (*p == ':') {
|
||||
if ((p != lastChar) && *(p+1) == ':') { /* qualified name */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
|
||||
+9
-15
@@ -512,7 +512,7 @@ TclFSGetPathType(
|
||||
|
||||
if (PATHFLAGS(pathPtr) == 0) {
|
||||
/* The path is not absolute... */
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
/* ... on Windows we must make another call to determine whether
|
||||
* it's relative or volumerelative [Bug 2571597]. */
|
||||
return TclGetPathType(pathPtr, filesystemPtrPtr, driveNameLengthPtr,
|
||||
@@ -1956,7 +1956,7 @@ Tcl_FSGetNormalizedPath(
|
||||
/*
|
||||
* We have a refCount on the cwd.
|
||||
*/
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
} else if (type == TCL_PATH_VOLUME_RELATIVE) {
|
||||
/*
|
||||
* Only Windows has volume-relative paths.
|
||||
@@ -1969,7 +1969,7 @@ Tcl_FSGetNormalizedPath(
|
||||
return NULL;
|
||||
}
|
||||
pureNormalized = 0;
|
||||
#endif /* __WIN32__ */
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2437,19 +2437,13 @@ SetFsPathFromAny(
|
||||
}
|
||||
TclDecrRefCount(parts);
|
||||
} else {
|
||||
/*
|
||||
* Simple case. "rest" is relative path. Just join it. The
|
||||
* "rest" object will be freed when Tcl_FSJoinToPath returns
|
||||
* (unless something else claims a refCount on it).
|
||||
*/
|
||||
Tcl_Obj *pair[2];
|
||||
|
||||
Tcl_Obj *joined;
|
||||
Tcl_Obj *rest = Tcl_NewStringObj(name+split+1, -1);
|
||||
|
||||
Tcl_IncrRefCount(transPtr);
|
||||
joined = Tcl_FSJoinToPath(transPtr, 1, &rest);
|
||||
TclDecrRefCount(transPtr);
|
||||
transPtr = joined;
|
||||
pair[0] = transPtr;
|
||||
pair[1] = Tcl_NewStringObj(name+split+1, -1);
|
||||
transPtr = TclJoinPath(2, pair);
|
||||
Tcl_DecrRefCount(pair[0]);
|
||||
Tcl_DecrRefCount(pair[1]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -50,7 +50,7 @@ extern "C" {
|
||||
* Exported function declarations:
|
||||
*/
|
||||
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
/* 0 */
|
||||
EXTERN TCHAR * Tcl_WinUtfToTChar(const char *str, int len,
|
||||
Tcl_DString *dsPtr);
|
||||
@@ -75,7 +75,7 @@ typedef struct TclPlatStubs {
|
||||
int magic;
|
||||
void *hooks;
|
||||
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */
|
||||
char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */
|
||||
#endif /* WIN */
|
||||
@@ -97,7 +97,7 @@ extern const TclPlatStubs *tclPlatStubsPtr;
|
||||
* Inline function declarations:
|
||||
*/
|
||||
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
#define Tcl_WinUtfToTChar \
|
||||
(tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */
|
||||
#define Tcl_WinTCharToUtf \
|
||||
|
||||
+14
-246
@@ -15,7 +15,6 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclOOInt.h"
|
||||
|
||||
/*
|
||||
* Variables that are part of the [apply] command implementation and which
|
||||
@@ -41,9 +40,6 @@ static void InitResolvedLocals(Tcl_Interp *interp,
|
||||
ByteCode *codePtr, Var *defPtr,
|
||||
Namespace *nsPtr);
|
||||
static void InitLocalCache(Proc *procPtr);
|
||||
static int PushProcCallFrame(ClientData clientData,
|
||||
register Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[], int isLambda);
|
||||
static void ProcBodyDup(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr);
|
||||
static void ProcBodyFree(Tcl_Obj *objPtr);
|
||||
static int ProcWrongNumArgs(Tcl_Interp *interp, int skip);
|
||||
@@ -92,10 +88,10 @@ static const Tcl_ObjType levelReferenceType = {
|
||||
*
|
||||
* Internally, ptr1 is a pointer to a Proc instance that is not bound to a
|
||||
* command name, and ptr2 is a pointer to the namespace that the Proc instance
|
||||
* will execute within.
|
||||
* will execute within. IF YOU CHANGE THIS, CHECK IN tclDisassemble.c TOO.
|
||||
*/
|
||||
|
||||
static const Tcl_ObjType lambdaType = {
|
||||
const Tcl_ObjType tclLambdaType = {
|
||||
"lambdaExpr", /* name */
|
||||
FreeLambdaInternalRep, /* freeIntRepProc */
|
||||
DupLambdaInternalRep, /* dupIntRepProc */
|
||||
@@ -221,7 +217,7 @@ Tcl_ProcObjCmd(
|
||||
*
|
||||
* This code is nearly identical to the #280 code in SetLambdaFromAny, see
|
||||
* this file. The differences are the different index of the body in the
|
||||
* line array of the context, and the lamdba code requires some special
|
||||
* line array of the context, and the lambda code requires some special
|
||||
* processing. Find a way to factor the common elements into a single
|
||||
* function.
|
||||
*/
|
||||
@@ -1571,7 +1567,7 @@ InitArgsAndLocals(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* PushProcCallFrame --
|
||||
* TclPushProcCallFrame --
|
||||
*
|
||||
* Compiles a proc body if necessary, then pushes a CallFrame suitable
|
||||
* for executing it.
|
||||
@@ -1586,8 +1582,8 @@ InitArgsAndLocals(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
PushProcCallFrame(
|
||||
int
|
||||
TclPushProcCallFrame(
|
||||
ClientData clientData, /* Record describing procedure to be
|
||||
* interpreted. */
|
||||
register Tcl_Interp *interp,/* Interpreter in which procedure was
|
||||
@@ -1708,7 +1704,7 @@ TclNRInterpProc(
|
||||
* procedure. */
|
||||
Tcl_Obj *const objv[]) /* Argument value objects. */
|
||||
{
|
||||
int result = PushProcCallFrame(clientData, interp, objc, objv,
|
||||
int result = TclPushProcCallFrame(clientData, interp, objc, objv,
|
||||
/*isLambda*/ 0);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
@@ -2443,7 +2439,7 @@ DupLambdaInternalRep(
|
||||
|
||||
procPtr->refCount++;
|
||||
Tcl_IncrRefCount(nsObjPtr);
|
||||
copyPtr->typePtr = &lambdaType;
|
||||
copyPtr->typePtr = &tclLambdaType;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2480,7 +2476,7 @@ SetLambdaFromAny(
|
||||
|
||||
/*
|
||||
* Convert objPtr to list type first; if it cannot be converted, or if its
|
||||
* length is not 2, then it cannot be converted to lambdaType.
|
||||
* length is not 2, then it cannot be converted to tclLambdaType.
|
||||
*/
|
||||
|
||||
result = TclListObjGetElements(NULL, objPtr, &objc, &objv);
|
||||
@@ -2626,14 +2622,14 @@ SetLambdaFromAny(
|
||||
/*
|
||||
* Free the list internalrep of objPtr - this will free argsPtr, but
|
||||
* bodyPtr retains a reference from the Proc structure. Then finish the
|
||||
* conversion to lambdaType.
|
||||
* conversion to tclLambdaType.
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
|
||||
objPtr->internalRep.twoPtrValue.ptr1 = procPtr;
|
||||
objPtr->internalRep.twoPtrValue.ptr2 = nsObjPtr;
|
||||
objPtr->typePtr = &lambdaType;
|
||||
objPtr->typePtr = &tclLambdaType;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2684,12 +2680,12 @@ TclNRApplyObjCmd(
|
||||
}
|
||||
|
||||
/*
|
||||
* Set lambdaPtr, convert it to lambdaType in the current interp if
|
||||
* Set lambdaPtr, convert it to tclLambdaType in the current interp if
|
||||
* necessary.
|
||||
*/
|
||||
|
||||
lambdaPtr = objv[1];
|
||||
if (lambdaPtr->typePtr == &lambdaType) {
|
||||
if (lambdaPtr->typePtr == &tclLambdaType) {
|
||||
procPtr = lambdaPtr->internalRep.twoPtrValue.ptr1;
|
||||
}
|
||||
|
||||
@@ -2767,7 +2763,7 @@ TclNRApplyObjCmd(
|
||||
}
|
||||
extraPtr->isRootEnsemble = isRootEnsemble;
|
||||
|
||||
result = PushProcCallFrame(procPtr, interp, objc, objv, 1);
|
||||
result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1);
|
||||
if (result == TCL_OK) {
|
||||
TclNRAddCallback(interp, ApplyNR2, extraPtr, NULL, NULL, NULL);
|
||||
result = TclNRInterpProcCore(interp, objv[1], 2, &MakeLambdaError);
|
||||
@@ -2826,234 +2822,6 @@ MakeLambdaError(
|
||||
(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_DisassembleObjCmd --
|
||||
*
|
||||
* Implementation of the "::tcl::unsupported::disassemble" command. This
|
||||
* command is not documented, but will disassemble procedures, lambda
|
||||
* terms and general scripts. Note that will compile terms if necessary
|
||||
* in order to disassemble them.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Tcl_DisassembleObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
static const char *const types[] = {
|
||||
"lambda", "method", "objmethod", "proc", "script", NULL
|
||||
};
|
||||
enum Types {
|
||||
DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC,
|
||||
DISAS_SCRIPT
|
||||
};
|
||||
int idx, result;
|
||||
Tcl_Obj *codeObjPtr = NULL;
|
||||
Proc *procPtr = NULL;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Object *oPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "type ...");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], types, "type", 0, &idx)!=TCL_OK){
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
switch ((enum Types) idx) {
|
||||
case DISAS_LAMBDA: {
|
||||
Command cmd;
|
||||
Tcl_Obj *nsObjPtr;
|
||||
Tcl_Namespace *nsPtr;
|
||||
|
||||
/*
|
||||
* Compile (if uncompiled) and disassemble a lambda term.
|
||||
*/
|
||||
|
||||
if (objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "lambdaTerm");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objv[2]->typePtr == &lambdaType) {
|
||||
procPtr = objv[2]->internalRep.twoPtrValue.ptr1;
|
||||
}
|
||||
if (procPtr == NULL || procPtr->iPtr != (Interp *) interp) {
|
||||
result = SetLambdaFromAny(interp, objv[2]);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
procPtr = objv[2]->internalRep.twoPtrValue.ptr1;
|
||||
}
|
||||
|
||||
memset(&cmd, 0, sizeof(Command));
|
||||
nsObjPtr = objv[2]->internalRep.twoPtrValue.ptr2;
|
||||
result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
cmd.nsPtr = (Namespace *) nsPtr;
|
||||
procPtr->cmdPtr = &cmd;
|
||||
result = PushProcCallFrame(procPtr, interp, objc, objv, 1);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
TclPopStackFrame(interp);
|
||||
codeObjPtr = procPtr->bodyPtr;
|
||||
break;
|
||||
}
|
||||
case DISAS_PROC:
|
||||
if (objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "procName");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2]));
|
||||
if (procPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't a procedure", TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC",
|
||||
TclGetString(objv[2]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile (if uncompiled) and disassemble a procedure.
|
||||
*/
|
||||
|
||||
result = PushProcCallFrame(procPtr, interp, 2, objv+1, 1);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
TclPopStackFrame(interp);
|
||||
codeObjPtr = procPtr->bodyPtr;
|
||||
break;
|
||||
case DISAS_SCRIPT:
|
||||
/*
|
||||
* Compile and disassemble a script.
|
||||
*/
|
||||
|
||||
if (objc != 3) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "script");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((objv[2]->typePtr != &tclByteCodeType)
|
||||
&& (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
codeObjPtr = objv[2];
|
||||
break;
|
||||
|
||||
case DISAS_CLASS_METHOD:
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "className methodName");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the body of a class method.
|
||||
*/
|
||||
|
||||
oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (oPtr->classPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" is not a class", TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
|
||||
TclGetString(objv[2]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods,
|
||||
(char *) objv[3]);
|
||||
goto methodBody;
|
||||
case DISAS_OBJECT_METHOD:
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "objectName methodName");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the body of an instance method.
|
||||
*/
|
||||
|
||||
oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
|
||||
if (oPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (oPtr->methodsPtr == NULL) {
|
||||
goto unknownMethod;
|
||||
}
|
||||
hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[3]);
|
||||
|
||||
/*
|
||||
* Compile (if necessary) and disassemble a method body.
|
||||
*/
|
||||
|
||||
methodBody:
|
||||
if (hPtr == NULL) {
|
||||
unknownMethod:
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"unknown method \"%s\"", TclGetString(objv[3])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
|
||||
TclGetString(objv[3]), NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr));
|
||||
if (procPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"body not available for this kind of method", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
|
||||
"METHODTYPE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
|
||||
Command cmd;
|
||||
|
||||
/*
|
||||
* Yes, this is ugly, but we need to pass the namespace in to the
|
||||
* compiler in two places.
|
||||
*/
|
||||
|
||||
cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
|
||||
procPtr->cmdPtr = &cmd;
|
||||
result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
|
||||
(Namespace *) oPtr->namespacePtr, "body of method",
|
||||
TclGetString(objv[3]));
|
||||
procPtr->cmdPtr = NULL;
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
codeObjPtr = procPtr->bodyPtr;
|
||||
break;
|
||||
default:
|
||||
CLANG_ASSERT(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the actual disassembly.
|
||||
*/
|
||||
|
||||
if (((ByteCode *) codeObjPtr->internalRep.twoPtrValue.ptr1)->flags
|
||||
& TCL_BYTECODE_PRECOMPILED) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"may not disassemble prebuilt bytecode", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
|
||||
"BYTECODE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, TclDisassembleByteCodeObj(codeObjPtr));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
|
||||
+2
-1
@@ -946,7 +946,8 @@ CompileRegexp(
|
||||
* Tcl_RegExpExecObj to optionally do a fast match (avoids RE engine).
|
||||
*/
|
||||
|
||||
if (TclReToGlob(NULL, string, length, &stringBuf, &exact) == TCL_OK) {
|
||||
if (TclReToGlob(NULL, string, length, &stringBuf, &exact,
|
||||
NULL) == TCL_OK) {
|
||||
regexpPtr->globObjPtr = TclDStringToObj(&stringBuf);
|
||||
Tcl_IncrRefCount(regexpPtr->globObjPtr);
|
||||
} else {
|
||||
|
||||
Executable → Regular
+79
-18
@@ -1123,7 +1123,8 @@ Tcl_AppendLimitedToObj(
|
||||
if (ellipsis == NULL) {
|
||||
ellipsis = "...";
|
||||
}
|
||||
toCopy = Tcl_UtfPrev(bytes+limit+1-strlen(ellipsis), bytes) - bytes;
|
||||
toCopy = (bytes == NULL) ? limit
|
||||
: Tcl_UtfPrev(bytes+limit+1-strlen(ellipsis), bytes) - bytes;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1281,23 +1282,43 @@ Tcl_AppendObjToObj(
|
||||
|
||||
if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep)
|
||||
&& TclIsPureByteArray(appendObjPtr)) {
|
||||
unsigned char *bytesSrc;
|
||||
int lengthSrc, lengthTotal;
|
||||
|
||||
/*
|
||||
* We do not assume that objPtr and appendObjPtr must be distinct!
|
||||
* This makes this code a bit more complex than it otherwise would be,
|
||||
* but in turn makes it much safer.
|
||||
* You might expect the code here to be
|
||||
*
|
||||
* bytes = Tcl_GetByteArrayFromObj(appendObjPtr, &length);
|
||||
* TclAppendBytesToByteArray(objPtr, bytes, length);
|
||||
*
|
||||
* and essentially all of the time that would be fine. However,
|
||||
* it would run into trouble in the case where objPtr and
|
||||
* appendObjPtr point to the same thing. That may never be a
|
||||
* good idea. It seems to violate Copy On Write, and we don't
|
||||
* have any tests for the situation, since making any Tcl commands
|
||||
* that call Tcl_AppendObjToObj() do that appears impossible
|
||||
* (They honor Copy On Write!). For the sake of extensions that
|
||||
* go off into that realm, though, here's a more complex approach
|
||||
* that can handle all the cases.
|
||||
*/
|
||||
|
||||
/* Get lengths */
|
||||
int lengthSrc;
|
||||
|
||||
(void) Tcl_GetByteArrayFromObj(objPtr, &length);
|
||||
(void) Tcl_GetByteArrayFromObj(appendObjPtr, &lengthSrc);
|
||||
lengthTotal = length + lengthSrc;
|
||||
if (((length > lengthSrc) ? length : lengthSrc) > lengthTotal) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
}
|
||||
bytesSrc = Tcl_GetByteArrayFromObj(appendObjPtr, NULL);
|
||||
TclAppendBytesToByteArray(objPtr, bytesSrc, lengthSrc);
|
||||
|
||||
/* Grow buffer enough for the append */
|
||||
TclAppendBytesToByteArray(objPtr, NULL, lengthSrc);
|
||||
|
||||
/* Reset objPtr back to the original value */
|
||||
Tcl_SetByteArrayLength(objPtr, length);
|
||||
|
||||
/*
|
||||
* Now do the append knowing that buffer growth cannot cause
|
||||
* any trouble.
|
||||
*/
|
||||
|
||||
TclAppendBytesToByteArray(objPtr,
|
||||
Tcl_GetByteArrayFromObj(appendObjPtr, NULL), lengthSrc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1415,7 +1436,7 @@ AppendUnicodeToUnicodeRep(
|
||||
* the reallocs below.
|
||||
*/
|
||||
|
||||
if (unicode >= stringPtr->unicode
|
||||
if (unicode && unicode >= stringPtr->unicode
|
||||
&& unicode <= stringPtr->unicode + stringPtr->maxChars) {
|
||||
offset = unicode - stringPtr->unicode;
|
||||
}
|
||||
@@ -1437,8 +1458,10 @@ AppendUnicodeToUnicodeRep(
|
||||
* trailing null.
|
||||
*/
|
||||
|
||||
memmove(stringPtr->unicode + stringPtr->numChars, unicode,
|
||||
appendNumChars * sizeof(Tcl_UniChar));
|
||||
if (unicode) {
|
||||
memmove(stringPtr->unicode + stringPtr->numChars, unicode,
|
||||
appendNumChars * sizeof(Tcl_UniChar));
|
||||
}
|
||||
stringPtr->unicode[numChars] = 0;
|
||||
stringPtr->numChars = numChars;
|
||||
stringPtr->allocated = 0;
|
||||
@@ -1577,7 +1600,7 @@ AppendUtfToUtfRep(
|
||||
* the reallocs below.
|
||||
*/
|
||||
|
||||
if (bytes >= objPtr->bytes
|
||||
if (bytes && bytes >= objPtr->bytes
|
||||
&& bytes <= objPtr->bytes + objPtr->length) {
|
||||
offset = bytes - objPtr->bytes;
|
||||
}
|
||||
@@ -1605,7 +1628,9 @@ AppendUtfToUtfRep(
|
||||
stringPtr->numChars = -1;
|
||||
stringPtr->hasUnicode = 0;
|
||||
|
||||
memmove(objPtr->bytes + oldLength, bytes, numBytes);
|
||||
if (bytes) {
|
||||
memmove(objPtr->bytes + oldLength, bytes, numBytes);
|
||||
}
|
||||
objPtr->bytes[newLength] = 0;
|
||||
objPtr->length = newLength;
|
||||
}
|
||||
@@ -2635,6 +2660,38 @@ Tcl_ObjPrintf(
|
||||
return objPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclGetStringStorage --
|
||||
*
|
||||
* Returns the string storage space of a Tcl_Obj.
|
||||
*
|
||||
* Results:
|
||||
* The pointer value objPtr->bytes is returned and the number of bytes
|
||||
* allocated there is written to *sizePtr (if known).
|
||||
*
|
||||
* Side effects:
|
||||
* May set objPtr->bytes.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
TclGetStringStorage(
|
||||
Tcl_Obj *objPtr,
|
||||
unsigned int *sizePtr)
|
||||
{
|
||||
String *stringPtr;
|
||||
|
||||
if (objPtr->typePtr != &tclStringType || objPtr->bytes == NULL) {
|
||||
return TclGetStringFromObj(objPtr, (int *)sizePtr);
|
||||
}
|
||||
|
||||
stringPtr = GET_STRING(objPtr);
|
||||
*sizePtr = stringPtr->allocated;
|
||||
return objPtr->bytes;
|
||||
}
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
@@ -2828,7 +2885,11 @@ ExtendUnicodeRepWithString(
|
||||
}
|
||||
|
||||
stringPtr->hasUnicode = 1;
|
||||
stringPtr->numChars = needed;
|
||||
if (bytes) {
|
||||
stringPtr->numChars = needed;
|
||||
} else {
|
||||
numAppendChars = 0;
|
||||
}
|
||||
for (dst=stringPtr->unicode + numOrigChars; numAppendChars-- > 0; dst++) {
|
||||
bytes += TclUtfToUniChar(bytes, dst);
|
||||
}
|
||||
|
||||
+1
-26
@@ -23,32 +23,7 @@
|
||||
* UTF-8 literal string containing all Unicode space characters. [TIP #413]
|
||||
*/
|
||||
|
||||
#define DEFAULT_TRIM_SET \
|
||||
"\x09\x0a\x0b\x0c\x0d " /* ASCII */\
|
||||
"\xc0\x80" /* nul (U+0000) */\
|
||||
"\xc2\x85" /* next line (U+0085) */\
|
||||
"\xc2\xa0" /* non-breaking space (U+00a0) */\
|
||||
"\xe1\x9a\x80" /* ogham space mark (U+1680) */ \
|
||||
"\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */\
|
||||
"\xe2\x80\x80" /* en quad (U+2000) */\
|
||||
"\xe2\x80\x81" /* em quad (U+2001) */\
|
||||
"\xe2\x80\x82" /* en space (U+2002) */\
|
||||
"\xe2\x80\x83" /* em space (U+2003) */\
|
||||
"\xe2\x80\x84" /* three-per-em space (U+2004) */\
|
||||
"\xe2\x80\x85" /* four-per-em space (U+2005) */\
|
||||
"\xe2\x80\x86" /* six-per-em space (U+2006) */\
|
||||
"\xe2\x80\x87" /* figure space (U+2007) */\
|
||||
"\xe2\x80\x88" /* punctuation space (U+2008) */\
|
||||
"\xe2\x80\x89" /* thin space (U+2009) */\
|
||||
"\xe2\x80\x8a" /* hair space (U+200a) */\
|
||||
"\xe2\x80\x8b" /* zero width space (U+200b) */\
|
||||
"\xe2\x80\xa8" /* line separator (U+2028) */\
|
||||
"\xe2\x80\xa9" /* paragraph separator (U+2029) */\
|
||||
"\xe2\x80\xaf" /* narrow no-break space (U+202f) */\
|
||||
"\xe2\x81\x9f" /* medium mathematical space (U+205f) */\
|
||||
"\xe2\x81\xa0" /* word joiner (U+2060) */\
|
||||
"\xe3\x80\x80" /* ideographic space (U+3000) */\
|
||||
"\xef\xbb\xbf" /* zero width no-break space (U+feff) */
|
||||
MODULE_SCOPE const char tclDefaultTrimSet[];
|
||||
|
||||
/*
|
||||
* The whitespace trimming set used when [concat]enating. This is a subset of
|
||||
|
||||
+23
-15
@@ -44,6 +44,9 @@
|
||||
#define TclBackgroundException Tcl_BackgroundException
|
||||
#undef Tcl_SetIntObj
|
||||
#undef TclpInetNtoa
|
||||
#undef TclWinGetServByName
|
||||
#undef TclWinGetSockOpt
|
||||
#undef TclWinSetSockOpt
|
||||
|
||||
/* See bug 510001: TclSockMinimumBuffers needs plat imp */
|
||||
#ifdef _WIN64
|
||||
@@ -90,7 +93,7 @@ static unsigned short TclWinNToHS(unsigned short ns) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __WIN32__
|
||||
#ifdef _WIN32
|
||||
# define TclUnixWaitForFile 0
|
||||
# define TclUnixCopyFile 0
|
||||
# define TclUnixOpenTemporaryFile 0
|
||||
@@ -111,7 +114,8 @@ TclpIsAtty(int fd)
|
||||
return isatty(fd);
|
||||
}
|
||||
|
||||
int
|
||||
#define TclWinGetPlatformId winGetPlatformId
|
||||
static int
|
||||
TclWinGetPlatformId()
|
||||
{
|
||||
/* Don't bother to determine the real platform on cygwin,
|
||||
@@ -127,27 +131,31 @@ void *TclWinGetTclInstance()
|
||||
return hInstance;
|
||||
}
|
||||
|
||||
int
|
||||
#define TclWinSetSockOpt winSetSockOpt
|
||||
static int
|
||||
TclWinSetSockOpt(SOCKET s, int level, int optname,
|
||||
const char *optval, int optlen)
|
||||
{
|
||||
return setsockopt((int) s, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int
|
||||
#define TclWinGetSockOpt winGetSockOpt
|
||||
static int
|
||||
TclWinGetSockOpt(SOCKET s, int level, int optname,
|
||||
char *optval, int *optlen)
|
||||
{
|
||||
return getsockopt((int) s, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
struct servent *
|
||||
#define TclWinGetServByName winGetServByName
|
||||
static struct servent *
|
||||
TclWinGetServByName(const char *name, const char *proto)
|
||||
{
|
||||
return getservbyname(name, proto);
|
||||
}
|
||||
|
||||
char *
|
||||
#define TclWinNoBackslash winNoBackslash
|
||||
static char *
|
||||
TclWinNoBackslash(char *path)
|
||||
{
|
||||
char *p;
|
||||
@@ -557,7 +565,7 @@ static const TclIntStubs tclIntStubs = {
|
||||
static const TclIntPlatStubs tclIntPlatStubs = {
|
||||
TCL_STUB_MAGIC,
|
||||
0,
|
||||
#if !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
TclGetAndDetachPids, /* 0 */
|
||||
TclpCloseFile, /* 1 */
|
||||
TclpCreateCommandChannel, /* 2 */
|
||||
@@ -590,7 +598,7 @@ static const TclIntPlatStubs tclIntPlatStubs = {
|
||||
TclWinCPUID, /* 29 */
|
||||
TclUnixOpenTemporaryFile, /* 30 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
TclWinConvertError, /* 0 */
|
||||
TclWinConvertWSAError, /* 1 */
|
||||
TclWinGetServByName, /* 2 */
|
||||
@@ -661,7 +669,7 @@ static const TclIntPlatStubs tclIntPlatStubs = {
|
||||
static const TclPlatStubs tclPlatStubs = {
|
||||
TCL_STUB_MAGIC,
|
||||
0,
|
||||
#if defined(__WIN32__) || defined(__CYGWIN__) /* WIN */
|
||||
#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
|
||||
Tcl_WinUtfToTChar, /* 0 */
|
||||
Tcl_WinTCharToUtf, /* 1 */
|
||||
#endif /* WIN */
|
||||
@@ -758,19 +766,19 @@ const TclStubs tclStubs = {
|
||||
Tcl_DbCkalloc, /* 6 */
|
||||
Tcl_DbCkfree, /* 7 */
|
||||
Tcl_DbCkrealloc, /* 8 */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
Tcl_CreateFileHandler, /* 9 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) /* WIN */
|
||||
#if defined(_WIN32) /* WIN */
|
||||
0, /* 9 */
|
||||
#endif /* WIN */
|
||||
#ifdef MAC_OSX_TCL /* MACOSX */
|
||||
Tcl_CreateFileHandler, /* 9 */
|
||||
#endif /* MACOSX */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
Tcl_DeleteFileHandler, /* 10 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) /* WIN */
|
||||
#if defined(_WIN32) /* WIN */
|
||||
0, /* 10 */
|
||||
#endif /* WIN */
|
||||
#ifdef MAC_OSX_TCL /* MACOSX */
|
||||
@@ -932,10 +940,10 @@ const TclStubs tclStubs = {
|
||||
Tcl_GetMaster, /* 164 */
|
||||
Tcl_GetNameOfExecutable, /* 165 */
|
||||
Tcl_GetObjResult, /* 166 */
|
||||
#if !defined(__WIN32__) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
|
||||
Tcl_GetOpenFile, /* 167 */
|
||||
#endif /* UNIX */
|
||||
#if defined(__WIN32__) /* WIN */
|
||||
#if defined(_WIN32) /* WIN */
|
||||
0, /* 167 */
|
||||
#endif /* WIN */
|
||||
#ifdef MAC_OSX_TCL /* MACOSX */
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* tclStubLibTbl.c --
|
||||
*
|
||||
* Stub object that will be statically linked into extensions that want
|
||||
* to access Tcl.
|
||||
*
|
||||
* Copyright (c) 1998-1999 by Scriptics Corporation.
|
||||
* Copyright (c) 1998 Paul Duffin.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclInitStubTable --
|
||||
*
|
||||
* Initialize the stub table, using the structure pointed at
|
||||
* by the "version" argument.
|
||||
*
|
||||
* Results:
|
||||
* Outputs the value of the "version" argument.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets the stub table pointers.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
MODULE_SCOPE const char *
|
||||
TclInitStubTable(
|
||||
const char *version) /* points to the version field of a
|
||||
TclStubInfoType structure variable. */
|
||||
{
|
||||
tclStubsPtr = ((const TclStubInfoType *) version)->stubs;
|
||||
|
||||
if (tclStubsPtr->hooks) {
|
||||
tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
|
||||
tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
|
||||
tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
|
||||
} else {
|
||||
tclPlatStubsPtr = NULL;
|
||||
tclIntStubsPtr = NULL;
|
||||
tclIntPlatStubsPtr = NULL;
|
||||
}
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 78
|
||||
* End:
|
||||
*/
|
||||
+51
-10
@@ -201,8 +201,9 @@ static int EncodingFromUtfProc(ClientData clientData,
|
||||
int *dstCharsPtr);
|
||||
static void ExitProcEven(ClientData clientData);
|
||||
static void ExitProcOdd(ClientData clientData);
|
||||
static int GetTimesCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int GetTimesObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static void MainLoop(void);
|
||||
static int NoopCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
@@ -219,6 +220,9 @@ static void SpecialFree(char *blockPtr);
|
||||
static int StaticInitProc(Tcl_Interp *interp);
|
||||
static int TestasyncCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int TestbytestringObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int TestcmdinfoCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int TestcmdtokenCmd(ClientData dummy,
|
||||
@@ -414,7 +418,7 @@ static int TestNRELevels(ClientData clientData,
|
||||
static int TestInterpResolverCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
#if defined(HAVE_CPUID) || defined(__WIN32__)
|
||||
#if defined(HAVE_CPUID) || defined(_WIN32)
|
||||
static int TestcpuidCmd(ClientData dummy,
|
||||
Tcl_Interp* interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -556,9 +560,10 @@ Tcltest_Init(
|
||||
* Create additional commands and math functions for testing Tcl.
|
||||
*/
|
||||
|
||||
Tcl_CreateCommand(interp, "gettimes", GetTimesCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "gettimes", GetTimesObjCmd, NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "noop", NoopCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testbytestring", TestbytestringObjCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
|
||||
NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testfilesystem", TestFilesystemObjCmd,
|
||||
@@ -681,7 +686,7 @@ Tcltest_Init(
|
||||
NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "testexitmainloop", TestexitmainloopCmd,
|
||||
NULL, NULL);
|
||||
#if defined(HAVE_CPUID) || defined(__WIN32__)
|
||||
#if defined(HAVE_CPUID) || defined(_WIN32)
|
||||
Tcl_CreateObjCommand(interp, "testcpuid", TestcpuidCmd,
|
||||
(ClientData) 0, NULL);
|
||||
#endif
|
||||
@@ -4717,7 +4722,7 @@ TestgetvarfullnameCmd(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* GetTimesCmd --
|
||||
* GetTimesObjCmd --
|
||||
*
|
||||
* This procedure implements the "gettimes" command. It is used for
|
||||
* computing the time needed for various basic operations such as reading
|
||||
@@ -4733,11 +4738,11 @@ TestgetvarfullnameCmd(
|
||||
*/
|
||||
|
||||
static int
|
||||
GetTimesCmd(
|
||||
GetTimesObjCmd(
|
||||
ClientData unused, /* Unused. */
|
||||
Tcl_Interp *interp, /* The current interpreter. */
|
||||
int argc, /* The number of arguments. */
|
||||
const char **argv) /* The argument strings. */
|
||||
int notused1, /* Number of arguments. */
|
||||
Tcl_Obj *const notused2[]) /* The argument objects. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
int i, n;
|
||||
@@ -4948,6 +4953,42 @@ NoopObjCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TestbytestringObjCmd --
|
||||
*
|
||||
* This object-based procedure constructs a string which can
|
||||
* possibly contain invalid UTF-8 bytes.
|
||||
*
|
||||
* Results:
|
||||
* Returns the TCL_OK result code.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
TestbytestringObjCmd(
|
||||
ClientData unused, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* The argument objects. */
|
||||
{
|
||||
int n;
|
||||
const char *p;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "bytearray");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
p = (const char *)Tcl_GetByteArrayFromObj(objv[1], &n);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(p, n));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -6648,7 +6689,7 @@ TestNumUtfCharsCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#if defined(HAVE_CPUID) || defined(__WIN32__)
|
||||
#if defined(HAVE_CPUID) || defined(_WIN32)
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
|
||||
+12
-3
@@ -339,8 +339,9 @@ Tcl_ConditionFinalize(
|
||||
*
|
||||
* TclFinalizeThreadData --
|
||||
*
|
||||
* This function cleans up the thread-local storage. This is called once
|
||||
* for each thread.
|
||||
* This function cleans up the thread-local storage. Secondary, it cleans
|
||||
* thread alloc cache.
|
||||
* This is called once for each thread before thread exits.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
@@ -352,9 +353,17 @@ Tcl_ConditionFinalize(
|
||||
*/
|
||||
|
||||
void
|
||||
TclFinalizeThreadData(void)
|
||||
TclFinalizeThreadData(int quick)
|
||||
{
|
||||
TclFinalizeThreadDataThread();
|
||||
#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
|
||||
if (!quick) {
|
||||
/*
|
||||
* Quick exit principle makes it useless to terminate allocators
|
||||
*/
|
||||
TclFinalizeThreadAllocThread();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -217,10 +217,11 @@ GetCache(void)
|
||||
|
||||
cachePtr = TclpGetAllocCache();
|
||||
if (cachePtr == NULL) {
|
||||
cachePtr = calloc(1, sizeof(Cache));
|
||||
cachePtr = TclpSysAlloc(sizeof(Cache), 0);
|
||||
if (cachePtr == NULL) {
|
||||
Tcl_Panic("alloc: could not allocate new cache");
|
||||
}
|
||||
memset(cachePtr, 0, sizeof(Cache));
|
||||
Tcl_MutexLock(listLockPtr);
|
||||
cachePtr->nextPtr = firstCachePtr;
|
||||
firstCachePtr = cachePtr;
|
||||
@@ -287,7 +288,7 @@ TclFreeAllocCache(
|
||||
*nextPtrPtr = cachePtr->nextPtr;
|
||||
cachePtr->nextPtr = NULL;
|
||||
Tcl_MutexUnlock(listLockPtr);
|
||||
free(cachePtr);
|
||||
TclpSysFree(cachePtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -332,7 +333,7 @@ TclpAlloc(
|
||||
|
||||
/*
|
||||
* Increment the requested size to include room for the Block structure.
|
||||
* Call malloc() directly if the required amount is greater than the
|
||||
* Call TclpSysAlloc() directly if the required amount is greater than the
|
||||
* largest block, otherwise pop the smallest block large enough,
|
||||
* allocating more blocks if necessary.
|
||||
*/
|
||||
@@ -344,7 +345,7 @@ TclpAlloc(
|
||||
#endif
|
||||
if (size > MAXALLOC) {
|
||||
bucket = NBUCKETS;
|
||||
blockPtr = malloc(size);
|
||||
blockPtr = TclpSysAlloc(size, 0);
|
||||
if (blockPtr != NULL) {
|
||||
cachePtr->totalAssigned += reqSize;
|
||||
}
|
||||
@@ -407,7 +408,7 @@ TclpFree(
|
||||
bucket = blockPtr->sourceBucket;
|
||||
if (bucket == NBUCKETS) {
|
||||
cachePtr->totalAssigned -= blockPtr->blockReqSize;
|
||||
free(blockPtr);
|
||||
TclpSysFree(blockPtr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -472,7 +473,7 @@ TclpRealloc(
|
||||
/*
|
||||
* If the block is not a system block and fits in place, simply return the
|
||||
* existing pointer. Otherwise, if the block is a system block and the new
|
||||
* size would also require a system block, call realloc() directly.
|
||||
* size would also require a system block, call TclpSysRealloc() directly.
|
||||
*/
|
||||
|
||||
blockPtr = Ptr2Block(ptr);
|
||||
@@ -495,7 +496,7 @@ TclpRealloc(
|
||||
} else if (size > MAXALLOC) {
|
||||
cachePtr->totalAssigned -= blockPtr->blockReqSize;
|
||||
cachePtr->totalAssigned += reqSize;
|
||||
blockPtr = realloc(blockPtr, size);
|
||||
blockPtr = TclpSysRealloc(blockPtr, size);
|
||||
if (blockPtr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -567,7 +568,7 @@ TclThreadAllocObj(void)
|
||||
Tcl_Obj *newObjsPtr;
|
||||
|
||||
cachePtr->numObjects = numMove = NOBJALLOC;
|
||||
newObjsPtr = malloc(sizeof(Tcl_Obj) * numMove);
|
||||
newObjsPtr = TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0);
|
||||
if (newObjsPtr == NULL) {
|
||||
Tcl_Panic("alloc: could not allocate %d new objects", numMove);
|
||||
}
|
||||
@@ -964,7 +965,7 @@ GetBlocks(
|
||||
|
||||
if (blockPtr == NULL) {
|
||||
size = MAXALLOC;
|
||||
blockPtr = malloc(size);
|
||||
blockPtr = TclpSysAlloc(size, 0);
|
||||
if (blockPtr == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1023,6 +1024,33 @@ TclFinalizeThreadAlloc(void)
|
||||
TclpFreeAllocCache(NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclFinalizeThreadAllocThread --
|
||||
*
|
||||
* This procedure is used to destroy single thread private resources used
|
||||
* in this file.
|
||||
* Called in TclpFinalizeThreadData when a thread exits (Tcl_FinalizeThread).
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TclFinalizeThreadAllocThread(void)
|
||||
{
|
||||
Cache *cachePtr = TclpGetAllocCache();
|
||||
if (cachePtr != NULL) {
|
||||
TclpFreeAllocCache(cachePtr);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !(TCL_THREADS && USE_THREAD_ALLOC) */
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#ifdef _WIN32
|
||||
|
||||
/*
|
||||
* The information about each joinable thread is remembered in a structure as
|
||||
@@ -305,7 +305,7 @@ TclSignalExitThread(
|
||||
|
||||
Tcl_MutexUnlock(&threadPtr->threadMutex);
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
|
||||
@@ -2511,6 +2511,9 @@ TclObjCallVarTraces(
|
||||
if (!part1Ptr) {
|
||||
part1Ptr = localName(iPtr->varFramePtr, index);
|
||||
}
|
||||
if (!part1Ptr) {
|
||||
Tcl_Panic("Cannot trace a variable with no name");
|
||||
}
|
||||
part1 = TclGetString(part1Ptr);
|
||||
part2 = part2Ptr? TclGetString(part2Ptr) : NULL;
|
||||
|
||||
|
||||
+1154
-1066
File diff suppressed because it is too large
Load Diff
+93
-21
@@ -111,7 +111,11 @@ static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr);
|
||||
static int SetEndOffsetFromAny(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
static void UpdateStringOfEndOffset(Tcl_Obj *objPtr);
|
||||
|
||||
static int FindElement(Tcl_Interp *interp, const char *string,
|
||||
int stringLength, const char *typeStr,
|
||||
const char *typeCode, const char **elementPtr,
|
||||
const char **nextPtr, int *sizePtr,
|
||||
int *literalPtr);
|
||||
/*
|
||||
* The following is the Tcl object type definition for an object that
|
||||
* represents a list index in the form, "end-offset". It is used as a
|
||||
@@ -237,7 +241,7 @@ const Tcl_ObjType tclEndOffsetType = {
|
||||
* of either braces or quotes to delimit it.
|
||||
*
|
||||
* This collection of parsing rules is implemented in the routine
|
||||
* TclFindElement().
|
||||
* FindElement().
|
||||
*
|
||||
* In order to produce lists that can be parsed by these rules, we need the
|
||||
* ability to distinguish between characters that are part of a list element
|
||||
@@ -505,9 +509,70 @@ TclFindElement(
|
||||
* does not/does require a call to
|
||||
* TclCopyAndCollapse() by the caller. */
|
||||
{
|
||||
const char *p = list;
|
||||
return FindElement(interp, list, listLength, "list", "LIST", elementPtr,
|
||||
nextPtr, sizePtr, literalPtr);
|
||||
}
|
||||
|
||||
int
|
||||
TclFindDictElement(
|
||||
Tcl_Interp *interp, /* Interpreter to use for error reporting. If
|
||||
* NULL, then no error message is left after
|
||||
* errors. */
|
||||
const char *dict, /* Points to the first byte of a string
|
||||
* containing a Tcl dictionary with zero or
|
||||
* more keys and values (possibly in
|
||||
* braces). */
|
||||
int dictLength, /* Number of bytes in the dict's string. */
|
||||
const char **elementPtr, /* Where to put address of first significant
|
||||
* character in the first element (i.e., key
|
||||
* or value) of dict. */
|
||||
const char **nextPtr, /* Fill in with location of character just
|
||||
* after all white space following end of
|
||||
* element (next arg or end of list). */
|
||||
int *sizePtr, /* If non-zero, fill in with size of
|
||||
* element. */
|
||||
int *literalPtr) /* If non-zero, fill in with non-zero/zero to
|
||||
* indicate that the substring of *sizePtr
|
||||
* bytes starting at **elementPtr is/is not
|
||||
* the literal key or value and therefore
|
||||
* does not/does require a call to
|
||||
* TclCopyAndCollapse() by the caller. */
|
||||
{
|
||||
return FindElement(interp, dict, dictLength, "dict", "DICTIONARY",
|
||||
elementPtr, nextPtr, sizePtr, literalPtr);
|
||||
}
|
||||
|
||||
static int
|
||||
FindElement(
|
||||
Tcl_Interp *interp, /* Interpreter to use for error reporting. If
|
||||
* NULL, then no error message is left after
|
||||
* errors. */
|
||||
const char *string, /* Points to the first byte of a string
|
||||
* containing a Tcl list or dictionary with
|
||||
* zero or more elements (possibly in
|
||||
* braces). */
|
||||
int stringLength, /* Number of bytes in the string. */
|
||||
const char *typeStr, /* The name of the type of thing we are
|
||||
* parsing, for error messages. */
|
||||
const char *typeCode, /* The type code for thing we are parsing, for
|
||||
* error messages. */
|
||||
const char **elementPtr, /* Where to put address of first significant
|
||||
* character in first element. */
|
||||
const char **nextPtr, /* Fill in with location of character just
|
||||
* after all white space following end of
|
||||
* argument (next arg or end of list/dict). */
|
||||
int *sizePtr, /* If non-zero, fill in with size of
|
||||
* element. */
|
||||
int *literalPtr) /* If non-zero, fill in with non-zero/zero to
|
||||
* indicate that the substring of *sizePtr
|
||||
* bytes starting at **elementPtr is/is not
|
||||
* the literal list/dict element and therefore
|
||||
* does not/does require a call to
|
||||
* TclCopyAndCollapse() by the caller. */
|
||||
{
|
||||
const char *p = string;
|
||||
const char *elemStart; /* Points to first byte of first element. */
|
||||
const char *limit; /* Points just after list's last byte. */
|
||||
const char *limit; /* Points just after list/dict's last byte. */
|
||||
int openBraces = 0; /* Brace nesting level during parse. */
|
||||
int inQuotes = 0;
|
||||
int size = 0; /* lint. */
|
||||
@@ -517,11 +582,11 @@ TclFindElement(
|
||||
|
||||
/*
|
||||
* Skim off leading white space and check for an opening brace or quote.
|
||||
* We treat embedded NULLs in the list as bytes belonging to a list
|
||||
* element.
|
||||
* We treat embedded NULLs in the list/dict as bytes belonging to a list
|
||||
* element (or dictionary key or value).
|
||||
*/
|
||||
|
||||
limit = (list + listLength);
|
||||
limit = (string + stringLength);
|
||||
while ((p < limit) && (TclIsSpaceProc(*p))) {
|
||||
p++;
|
||||
}
|
||||
@@ -582,9 +647,9 @@ TclFindElement(
|
||||
p2++;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"list element in braces followed by \"%.*s\" "
|
||||
"instead of space", (int) (p2-p), p));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "JUNK",
|
||||
"%s element in braces followed by \"%.*s\" "
|
||||
"instead of space", typeStr, (int) (p2-p), p));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "JUNK",
|
||||
NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
@@ -651,9 +716,9 @@ TclFindElement(
|
||||
p2++;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"list element in quotes followed by \"%.*s\" "
|
||||
"instead of space", (int) (p2-p), p));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "JUNK",
|
||||
"%s element in quotes followed by \"%.*s\" "
|
||||
"instead of space", typeStr, (int) (p2-p), p));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "JUNK",
|
||||
NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
@@ -664,23 +729,23 @@ TclFindElement(
|
||||
}
|
||||
|
||||
/*
|
||||
* End of list: terminate element.
|
||||
* End of list/dict: terminate element.
|
||||
*/
|
||||
|
||||
if (p == limit) {
|
||||
if (openBraces != 0) {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unmatched open brace in list", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "BRACE",
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"unmatched open brace in %s", typeStr));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "BRACE",
|
||||
NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
} else if (inQuotes) {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unmatched open quote in list", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "LIST", "QUOTE",
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"unmatched open quote in %s", typeStr));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "QUOTE",
|
||||
NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
@@ -4184,7 +4249,8 @@ TclReToGlob(
|
||||
const char *reStr,
|
||||
int reStrLen,
|
||||
Tcl_DString *dsPtr,
|
||||
int *exactPtr)
|
||||
int *exactPtr,
|
||||
int *quantifiersFoundPtr)
|
||||
{
|
||||
int anchorLeft, anchorRight, lastIsStar, numStars;
|
||||
char *dsStr, *dsStrStart;
|
||||
@@ -4192,6 +4258,9 @@ TclReToGlob(
|
||||
|
||||
strEnd = reStr + reStrLen;
|
||||
Tcl_DStringInit(dsPtr);
|
||||
if (quantifiersFoundPtr != NULL) {
|
||||
*quantifiersFoundPtr = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* "***=xxx" == "*xxx*", watch for glob-sensitive chars.
|
||||
@@ -4304,6 +4373,9 @@ TclReToGlob(
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if (quantifiersFoundPtr != NULL) {
|
||||
*quantifiersFoundPtr = 1;
|
||||
}
|
||||
anchorLeft = 0; /* prevent exact match */
|
||||
if (p+1 < strEnd) {
|
||||
if (p[1] == '*') {
|
||||
|
||||
+7
-5
@@ -1958,6 +1958,9 @@ TclPtrSetVar(
|
||||
Tcl_IncrRefCount(oldValuePtr); /* Since var is ref */
|
||||
}
|
||||
Tcl_AppendObjToObj(oldValuePtr, newValuePtr);
|
||||
if (newValuePtr->refCount == 0) {
|
||||
Tcl_DecrRefCount(newValuePtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (newValuePtr != oldValuePtr) {
|
||||
@@ -4402,8 +4405,8 @@ ObjMakeUpvar(
|
||||
|| !HasLocalVars(varFramePtr)
|
||||
|| (strstr(TclGetString(myNamePtr), "::") != NULL))) {
|
||||
Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
|
||||
"bad variable name \"%s\": upvar won't create "
|
||||
"namespace variable that refers to procedure variable",
|
||||
"bad variable name \"%s\": can't create namespace "
|
||||
"variable that refers to procedure variable",
|
||||
TclGetString(myNamePtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "INVERTED", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -4503,9 +4506,8 @@ TclPtrObjMakeUpvar(
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
|
||||
"bad variable name \"%s\": upvar won't create a"
|
||||
" scalar variable that looks like an array element",
|
||||
myName));
|
||||
"bad variable name \"%s\": can't create a scalar "
|
||||
"variable that looks like an array element", myName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "UPVAR", "LOCAL_ELEMENT",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
|
||||
+12
-44
@@ -26,7 +26,7 @@
|
||||
* interface, even if that is mostly true).
|
||||
*/
|
||||
|
||||
#define TCL_ZLIB_VERSION "2.0"
|
||||
#define TCL_ZLIB_VERSION "2.0.1"
|
||||
|
||||
/*
|
||||
* Magic flags used with wbits fields to indicate that we're handling the gzip
|
||||
@@ -643,7 +643,6 @@ Tcl_ZlibStreamInit(
|
||||
int e;
|
||||
ZlibStreamHandle *zshPtr = NULL;
|
||||
Tcl_DString cmdname;
|
||||
Tcl_CmdInfo cmdinfo;
|
||||
GzipHeader *gzHeaderPtr = NULL;
|
||||
|
||||
switch (mode) {
|
||||
@@ -769,8 +768,8 @@ Tcl_ZlibStreamInit(
|
||||
Tcl_DStringInit(&cmdname);
|
||||
TclDStringAppendLiteral(&cmdname, "::tcl::zlib::streamcmd_");
|
||||
TclDStringAppendObj(&cmdname, Tcl_GetObjResult(interp));
|
||||
if (Tcl_GetCommandInfo(interp, Tcl_DStringValue(&cmdname),
|
||||
&cmdinfo) == 1) {
|
||||
if (Tcl_FindCommand(interp, Tcl_DStringValue(&cmdname),
|
||||
NULL, 0) != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"BUG: Stream command name already exists", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "BUG", "EXISTING_CMD", NULL);
|
||||
@@ -2911,6 +2910,10 @@ ZlibTransformClose(
|
||||
* Release all memory.
|
||||
*/
|
||||
|
||||
if (cd->compDictObj) {
|
||||
Tcl_DecrRefCount(cd->compDictObj);
|
||||
cd->compDictObj = NULL;
|
||||
}
|
||||
Tcl_DStringFree(&cd->decompressed);
|
||||
|
||||
if (cd->inBuffer) {
|
||||
@@ -2994,47 +2997,18 @@ ZlibTransformInput(
|
||||
*/
|
||||
|
||||
if (readBytes < 0) {
|
||||
/*
|
||||
* Report errors to caller. The state of the seek system is
|
||||
* unchanged!
|
||||
*/
|
||||
|
||||
if ((Tcl_GetErrno() == EAGAIN) && (gotBytes > 0)) {
|
||||
/*
|
||||
* EAGAIN is a special situation. If we had some data before
|
||||
* we report that instead of the request to re-try.
|
||||
*/
|
||||
|
||||
/* See ReflectInput() in tclIORTrans.c */
|
||||
if (Tcl_InputBlocked(cd->parent) && (gotBytes > 0)) {
|
||||
return gotBytes;
|
||||
}
|
||||
|
||||
*errorCodePtr = Tcl_GetErrno();
|
||||
return -1;
|
||||
} else if (readBytes == 0) {
|
||||
}
|
||||
if (readBytes == 0) {
|
||||
/*
|
||||
* Check wether we hit on EOF in 'parent' or not. If not,
|
||||
* differentiate between blocking and non-blocking modes. In
|
||||
* non-blocking mode we ran temporarily out of data. Signal this
|
||||
* to the caller via EWOULDBLOCK and error return (-1). In the
|
||||
* other cases we simply return what we got and let the caller
|
||||
* wait for more. On the other hand, if we got an EOF we have to
|
||||
* convert and flush all waiting partial data.
|
||||
*/
|
||||
|
||||
if (!Tcl_Eof(cd->parent)) {
|
||||
/*
|
||||
* The state of the seek system is unchanged!
|
||||
*/
|
||||
|
||||
if ((gotBytes == 0) && (cd->flags & ASYNC)) {
|
||||
*errorCodePtr = EWOULDBLOCK;
|
||||
return -1;
|
||||
}
|
||||
return gotBytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* (Semi-)Eof in parent.
|
||||
* Eof in parent.
|
||||
*
|
||||
* Now this is a bit different. The partial data waiting is
|
||||
* converted and returned.
|
||||
@@ -3052,12 +3026,6 @@ ZlibTransformInput(
|
||||
|
||||
return gotBytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reset eof, force caller to drain result buffer.
|
||||
*/
|
||||
|
||||
((Channel *) cd->parent)->state->flags &= ~CHANNEL_EOF;
|
||||
} else /* readBytes > 0 */ {
|
||||
/*
|
||||
* Transform the read chunk, which was not empty. Anything we get
|
||||
|
||||
+4
-4
@@ -1227,8 +1227,8 @@ proc ::tcl::clock::scan { args } {
|
||||
}
|
||||
default {
|
||||
return -code error \
|
||||
-errorcode [list CLOCK badSwitch $flag] \
|
||||
"bad switch \"$flag\",\
|
||||
-errorcode [list CLOCK badOption $flag] \
|
||||
"bad option \"$flag\",\
|
||||
must be -base, -format, -gmt, -locale or -timezone"
|
||||
}
|
||||
}
|
||||
@@ -4295,8 +4295,8 @@ proc ::tcl::clock::add { clockval args } {
|
||||
set timezone $b
|
||||
}
|
||||
default {
|
||||
throw [list CLOCK badSwitch $a] \
|
||||
"bad switch \"$a\",\
|
||||
throw [list CLOCK badOption $a] \
|
||||
"bad option \"$a\",\
|
||||
must be -gmt, -locale or -timezone"
|
||||
}
|
||||
}
|
||||
|
||||
Executable → Regular
+3
-2
@@ -16,7 +16,7 @@
|
||||
if {[info commands package] == ""} {
|
||||
error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]"
|
||||
}
|
||||
package require -exact Tcl 8.6.1
|
||||
package require -exact Tcl 8.6.3
|
||||
|
||||
# Compute the auto path to use in this interpreter.
|
||||
# The values on the path come from several locations:
|
||||
@@ -398,7 +398,8 @@ proc unknown args {
|
||||
return -code error "ambiguous command name \"$name\": [lsort $cmds]"
|
||||
}
|
||||
}
|
||||
return -code error "invalid command name \"$name\""
|
||||
return -code error -errorcode [list TCL LOOKUP COMMAND $name] \
|
||||
"invalid command name \"$name\""
|
||||
}
|
||||
|
||||
# auto_load --
|
||||
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user