Compare commits
773
Commits
bug-3525762
...
mig-err
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd0bf3e350 | ||
|
|
7754effa64 | ||
|
|
0d214a0a14 | ||
|
|
4087d33e18 | ||
|
|
8533669f18 | ||
|
|
8a7422b2db | ||
|
|
524556581a | ||
|
|
c9152240b9 | ||
|
|
d6ec1e9bfc | ||
|
|
b49ab44beb | ||
|
|
a5d25d127e | ||
|
|
d22d1ef546 | ||
|
|
952dfe7d9a | ||
|
|
b2dabdc1eb | ||
|
|
bc33fd2059 | ||
|
|
a8a9d42601 | ||
|
|
d223d51178 | ||
|
|
7fbeaf9528 | ||
|
|
2c5cd34ebe | ||
|
|
13adf38211 | ||
|
|
88af143aea | ||
|
|
9b6ebeae02 | ||
|
|
5bce11a1c8 | ||
|
|
32cc5d8d3c | ||
|
|
679963704f | ||
|
|
32df42787e | ||
|
|
0cf062c388 | ||
|
|
207412c303 | ||
|
|
bf368d9079 | ||
|
|
45c7f36909 | ||
|
|
285dd19c62 | ||
|
|
240695b9f5 | ||
|
|
3aba154e26 | ||
|
|
1bef171761 | ||
|
|
a7affdff05 | ||
|
|
8ddb48c272 | ||
|
|
3ce1c8d98b | ||
|
|
ef5aee8d47 | ||
|
|
ca4329f20b | ||
|
|
8d4878fee6 | ||
|
|
b0465ff0e8 | ||
|
|
f9651e0da6 | ||
|
|
18ab8f43a0 | ||
|
|
77014e3f62 | ||
|
|
46821e04b6 | ||
|
|
51e5bda476 | ||
|
|
656b2b4f87 | ||
|
|
0fbd4e16a9 | ||
|
|
c0845253a0 | ||
|
|
38ba6bd5d4 | ||
|
|
0c64074372 | ||
|
|
53eb119d0b | ||
|
|
8751239349 | ||
|
|
bf14f11c63 | ||
|
|
d12ee9da30 | ||
|
|
78d91cb253 | ||
|
|
66c2909694 | ||
|
|
65013d771a | ||
|
|
4b67a9506b | ||
|
|
74cca07e35 | ||
|
|
e2e451e2e5 | ||
|
|
ed156a09fa | ||
|
|
8f40b2b313 | ||
|
|
21bd9cf5ad | ||
|
|
ebbf7144d2 | ||
|
|
fac8f9d0ae | ||
|
|
f3a3f7b9e8 | ||
|
|
a2afb09b3c | ||
|
|
81a67b9cf4 | ||
|
|
569360bf40 | ||
|
|
59e42de547 | ||
|
|
fa7a06447d | ||
|
|
b13b1c6020 | ||
|
|
d67ebaffd4 | ||
|
|
8890130ab8 | ||
|
|
093fb49d43 | ||
|
|
0ccb6618bd | ||
|
|
989c5bb9a4 | ||
|
|
94ada5d31f | ||
|
|
af92fc0c28 | ||
|
|
4557297b08 | ||
|
|
1d29f93257 | ||
|
|
9918a06afa | ||
|
|
e1c8f78ed0 | ||
|
|
b9a522a6bf | ||
|
|
eace9319cb | ||
|
|
eb7f17ba98 | ||
|
|
2f1b92ba12 | ||
|
|
6428006e92 | ||
|
|
78a3c34ca2 | ||
|
|
c13ee047c8 | ||
|
|
c1784e6b4c | ||
|
|
498562a0e5 | ||
|
|
15f02f424c | ||
|
|
c20c0a1e75 | ||
|
|
6d80a782d0 | ||
|
|
2fd9e3776b | ||
|
|
a8c55de8fc | ||
|
|
16df5aebc9 | ||
|
|
cebb11e97e | ||
|
|
8a282bbf9e | ||
|
|
5e55e0d280 | ||
|
|
bd8d73a7d5 | ||
|
|
b361c43c61 | ||
|
|
9f45d4d696 | ||
|
|
aa34213e75 | ||
|
|
b54c784f20 | ||
|
|
5af462da66 | ||
|
|
c46c79caa2 | ||
|
|
2adea0d04e | ||
|
|
7720b5d9df | ||
|
|
f894c98ebc | ||
|
|
1aa7610988 | ||
|
|
02929519ba | ||
|
|
49e8fc13b0 | ||
|
|
22f216f372 | ||
|
|
55563ee093 | ||
|
|
7442eb42a1 | ||
|
|
38ee3de94f | ||
|
|
c9c4a3ad02 | ||
|
|
43e62982f4 | ||
|
|
59aff80a90 | ||
|
|
5240308ed2 | ||
|
|
0dcab1bed4 | ||
|
|
85ca4a31a0 | ||
|
|
553348c5f3 | ||
|
|
658b4c0ee7 | ||
|
|
41d3318c10 | ||
|
|
8354804874 | ||
|
|
bf4c66a207 | ||
|
|
70d1d20609 | ||
|
|
b7ab8113fe | ||
|
|
80108bef0e | ||
|
|
e2ddd4a2fd | ||
|
|
96295b0151 | ||
|
|
7cd225ff30 | ||
|
|
fa84674fb9 | ||
|
|
a1beeadf6c | ||
|
|
fcf174f284 | ||
|
|
29dd55c971 | ||
|
|
52e06a03d8 | ||
|
|
8f22bd9be0 | ||
|
|
5d659010d2 | ||
|
|
8e1d78b43a | ||
|
|
db0645ad80 | ||
|
|
7e68d373c1 | ||
|
|
00451a175e | ||
|
|
6e2667d4d2 | ||
|
|
2ab23f6186 | ||
|
|
b670d49ae2 | ||
|
|
858c24761a | ||
|
|
70e9e19b64 | ||
|
|
cbfb51846d | ||
|
|
91d791cd85 | ||
|
|
adb756a95a | ||
|
|
491f1691e5 | ||
|
|
a24ce60075 | ||
|
|
134609fd57 | ||
|
|
f7a0d6fdbe | ||
|
|
b93728a301 | ||
|
|
c8318a69ff | ||
|
|
41ace1ce41 | ||
|
|
4c439c45ea | ||
|
|
5b9c4d9393 | ||
|
|
212fc8e012 | ||
|
|
a47366b842 | ||
|
|
1892e61aa6 | ||
|
|
daf66f3418 | ||
|
|
e1adc46245 | ||
|
|
192c0b4b69 | ||
|
|
0119f508e2 | ||
|
|
e2c63e97bc | ||
|
|
275cdefdd7 | ||
|
|
4a2c3d9ab9 | ||
|
|
59c308ebf0 | ||
|
|
920dfb2f56 | ||
|
|
f14b389544 | ||
|
|
0aeb86cee1 | ||
|
|
04b42c6d46 | ||
|
|
762f642867 | ||
|
|
e770d85db6 | ||
|
|
2e074de52a | ||
|
|
73cbb5ef6f | ||
|
|
2b18d7d019 | ||
|
|
63c50fda84 | ||
|
|
a61f0f3aa3 | ||
|
|
b8076815be | ||
|
|
cb3e2cac34 | ||
|
|
a8ea141350 | ||
|
|
3c4956ece0 | ||
|
|
cee0989147 | ||
|
|
20058bf813 | ||
|
|
c3bb46df16 | ||
|
|
1f0fc6d0b1 | ||
|
|
071105233b | ||
|
|
fcba3b601b | ||
|
|
5e8aae6bdc | ||
|
|
2354c488dc | ||
|
|
c06ccc92c0 | ||
|
|
c23935f0c4 | ||
|
|
a271a46238 | ||
|
|
1ff71889ea | ||
|
|
bcd546207d | ||
|
|
afe5dfc938 | ||
|
|
893f9c7cc6 | ||
|
|
6734623337 | ||
|
|
ea58b7b66f | ||
|
|
7635c56e5d | ||
|
|
1c5b833a43 | ||
|
|
5f3314ac7b | ||
|
|
4ffdb51e34 | ||
|
|
23cac7b42c | ||
|
|
24650f8e9d | ||
|
|
d8ae9915dd | ||
|
|
474d2cb11a | ||
|
|
57c33f7587 | ||
|
|
498d315304 | ||
|
|
a26191b7b2 | ||
|
|
051bf96db1 | ||
|
|
9aab4c1bac | ||
|
|
299d4abd03 | ||
|
|
5b64a7d24c | ||
|
|
efdc17a4d5 | ||
|
|
626e22c982 | ||
|
|
842e894ac5 | ||
|
|
9123f8f93e | ||
|
|
20ad704b92 | ||
|
|
ba7ee97d3a | ||
|
|
f679fe87ab | ||
|
|
3ba55d4c91 | ||
|
|
53690d2607 | ||
|
|
ad3ee62cd3 | ||
|
|
55d5fb55a2 | ||
|
|
335ddd20ca | ||
|
|
ca3ab36dfd | ||
|
|
96e7bb4e24 | ||
|
|
5c0961e758 | ||
|
|
109f50dfe1 | ||
|
|
398787d859 | ||
|
|
85167c88b6 | ||
|
|
b2e0789f6b | ||
|
|
9b474d56b9 | ||
|
|
ec58b631ce | ||
|
|
e55f7c6612 | ||
|
|
8a8dee7bde | ||
|
|
2bd81c6785 | ||
|
|
e219c6140a | ||
|
|
f6be9e19c2 | ||
|
|
688210c291 | ||
|
|
83d0e64e99 | ||
|
|
a3bc9d0e44 | ||
|
|
49dd27a4ea | ||
|
|
b9c17fff37 | ||
|
|
c74d12c2e0 | ||
|
|
ac3ebfbd49 | ||
|
|
02dd785b16 | ||
|
|
9ef6a75daf | ||
|
|
f17426d59e | ||
|
|
acd9d78458 | ||
|
|
d82d84f004 | ||
|
|
5c68347747 | ||
|
|
eeb982f501 | ||
|
|
ecec3a1a0b | ||
|
|
040b7a730e | ||
|
|
ee5f41d141 | ||
|
|
71560be819 | ||
|
|
05d8b59183 | ||
|
|
bedb57a468 | ||
|
|
0d71be4a7e | ||
|
|
d25cf46468 | ||
|
|
e1019374e0 | ||
|
|
1c889c0352 | ||
|
|
f7bae6ac60 | ||
|
|
8122cb706d | ||
|
|
41128611bf | ||
|
|
13ba95be10 | ||
|
|
734725f73e | ||
|
|
c705d5b937 | ||
|
|
225c3d3e5f | ||
|
|
706e42d83b | ||
|
|
8dfd4b7f02 | ||
|
|
ee55e87c47 | ||
|
|
d764a87552 | ||
|
|
129d93bc40 | ||
|
|
247a043a05 | ||
|
|
db601d75b9 | ||
|
|
8a9731657e | ||
|
|
966e9c3477 | ||
|
|
7927604b94 | ||
|
|
a584e5f052 | ||
|
|
54e225f382 | ||
|
|
e5c614fc2d | ||
|
|
aaac3316a4 | ||
|
|
0af0c0e973 | ||
|
|
532e6f0c8e | ||
|
|
6e458bffe0 | ||
|
|
6c99b4f545 | ||
|
|
7e90ca9d19 | ||
|
|
37f4435517 | ||
|
|
28f6f6deb5 | ||
|
|
8eb29f16f2 | ||
|
|
495bfd5d18 | ||
|
|
c02571fab0 | ||
|
|
e4c33dab06 | ||
|
|
43a3d8d594 | ||
|
|
40ea3f744a | ||
|
|
2481948f74 | ||
|
|
23612cace5 | ||
|
|
136930901b | ||
|
|
161a608442 | ||
|
|
8a674af97d | ||
|
|
8e96e8eea3 | ||
|
|
b193d124e8 | ||
|
|
b38a57ebda | ||
|
|
9b4651ad57 | ||
|
|
edee53b6af | ||
|
|
970b7acdfa | ||
|
|
43da7a5b40 | ||
|
|
bafa7f02dd | ||
|
|
56d71ce11b | ||
|
|
f7baa52775 | ||
|
|
b488ca3be7 | ||
|
|
3f859f646f | ||
|
|
3c28c417ab | ||
|
|
0c7b5c9b40 | ||
|
|
8416c08156 | ||
|
|
c760786541 | ||
|
|
161982db4e | ||
|
|
363a1ece67 | ||
|
|
948ab1397d | ||
|
|
a8de846af3 | ||
|
|
e429c48342 | ||
|
|
2ca93d18ba | ||
|
|
12fdfe05d5 | ||
|
|
4c4a017eee | ||
|
|
ae28d1f6a8 | ||
|
|
332ce7d5fb | ||
|
|
f2eb738e24 | ||
|
|
8441410b37 | ||
|
|
1c6a48f8f3 | ||
|
|
a75ca077a7 | ||
|
|
3c125234b7 | ||
|
|
88425983f1 | ||
|
|
08c0a5401e | ||
|
|
96b22f2bf9 | ||
|
|
3bb8b9504c | ||
|
|
2aaae6b3fe | ||
|
|
4471683c22 | ||
|
|
975546b642 | ||
|
|
d8906fe61c | ||
|
|
2ba5e62a84 | ||
|
|
55f99c2640 | ||
|
|
bec5db4b0d | ||
|
|
9eb8788318 | ||
|
|
1e083956ea | ||
|
|
1590419e21 | ||
|
|
525f6bfa54 | ||
|
|
fe63595036 | ||
|
|
ebe5881e58 | ||
|
|
e44afcc1bc | ||
|
|
67b1e2f4c4 | ||
|
|
3eb17a40ef | ||
|
|
a574ca01f5 | ||
|
|
b50a5c6126 | ||
|
|
65881fd810 | ||
|
|
79180834a7 | ||
|
|
496e8dc792 | ||
|
|
796e60b235 | ||
|
|
25ea4d4aeb | ||
|
|
da7aef611c | ||
|
|
47f4e0b416 | ||
|
|
4596fb2059 | ||
|
|
dcb740cc83 | ||
|
|
95c0607a29 | ||
|
|
7f0a3ff10c | ||
|
|
5c94189d52 | ||
|
|
59e88c2cfc | ||
|
|
4c3a4ca226 | ||
|
|
fd818f0e4d | ||
|
|
2e71ce4f91 | ||
|
|
108d7b7870 | ||
|
|
1365d5dfb2 | ||
|
|
0bfd4d207f | ||
|
|
98b9b2bdbd | ||
|
|
7122c1dbde | ||
|
|
55d33ae172 | ||
|
|
b3655e630c | ||
|
|
67924be061 | ||
|
|
e1f580d443 | ||
|
|
96773e263c | ||
|
|
1b1df98eb9 | ||
|
|
9e62407743 | ||
|
|
40b25cfec8 | ||
|
|
b3f490fa84 | ||
|
|
932d890807 | ||
|
|
06222bb9df | ||
|
|
79503b8aa1 | ||
|
|
6d47648771 | ||
|
|
9c36a65837 | ||
|
|
f8238e5ef9 | ||
|
|
4c681f294b | ||
|
|
a074f8f61a | ||
|
|
926ab55b30 | ||
|
|
27afab02c1 | ||
|
|
f6d1c13f66 | ||
|
|
ffdb1309cb | ||
|
|
234ec885dc | ||
|
|
23f6ebe4d9 | ||
|
|
4e74361197 | ||
|
|
d91cd78b69 | ||
|
|
1e2e2f72bd | ||
|
|
124e26e763 | ||
|
|
cbe9080dcf | ||
|
|
063747525b | ||
|
|
b63fcbf8cf | ||
|
|
b60533f355 | ||
|
|
426550b55b | ||
|
|
f8d1f02180 | ||
|
|
1e5b4c061f | ||
|
|
c7b9c3391a | ||
|
|
167434d6d4 | ||
|
|
33cc01511d | ||
|
|
730bfc3631 | ||
|
|
3489422b6e | ||
|
|
628fcd07f4 | ||
|
|
031d307b32 | ||
|
|
74297e0bde | ||
|
|
acc782b047 | ||
|
|
6fd899f81b | ||
|
|
d7c58ac85d | ||
|
|
7d95f08678 | ||
|
|
d1b509b35a | ||
|
|
8e6d6ece42 | ||
|
|
62fc28c429 | ||
|
|
a59b6e0bf7 | ||
|
|
ecec90b4aa | ||
|
|
7224021d3b | ||
|
|
693626defa | ||
|
|
6aad9eb523 | ||
|
|
13147008eb | ||
|
|
d8bae8d8c1 | ||
|
|
b8d984dbc8 | ||
|
|
3ac4803203 | ||
|
|
a8d394eeaf | ||
|
|
1121067971 | ||
|
|
8c5e0f4fee | ||
|
|
4479d5c373 | ||
|
|
73f7530a3a | ||
|
|
c525f5049c | ||
|
|
47b9d4a19f | ||
|
|
bc7cee752d | ||
|
|
c52f523493 | ||
|
|
dd6a751ee0 | ||
|
|
be65403d57 | ||
|
|
033e2fe7da | ||
|
|
a1fc920b69 | ||
|
|
20366bea81 | ||
|
|
ddc7eec6c2 | ||
|
|
067435f0b2 | ||
|
|
631e846bb6 | ||
|
|
8861cda5d7 | ||
|
|
1466ca42b6 | ||
|
|
ec6d997075 | ||
|
|
9802446e9b | ||
|
|
12ba946ca1 | ||
|
|
7a32096dec | ||
|
|
1c81ef2ad1 | ||
|
|
3b747083f1 | ||
|
|
3e9f1f5719 | ||
|
|
ace3976e29 | ||
|
|
03ea56e25c | ||
|
|
82dcdb4011 | ||
|
|
271039f275 | ||
|
|
f85f2e89ee | ||
|
|
57da469029 | ||
|
|
1839e70313 | ||
|
|
3722d1577d | ||
|
|
780280cdf8 | ||
|
|
05e74155cd | ||
|
|
3b813e5546 | ||
|
|
952d089c19 | ||
|
|
a3af17ef6c | ||
|
|
7fef4f4ce4 | ||
|
|
f1d27388e7 | ||
|
|
ecb3629055 | ||
|
|
ff13d5626d | ||
|
|
e3e7dc6897 | ||
|
|
b5ec699722 | ||
|
|
d252b8fc1e | ||
|
|
d521fd1d52 | ||
|
|
643148e686 | ||
|
|
b9fb903b7c | ||
|
|
f2ef7ef789 | ||
|
|
53dc051854 | ||
|
|
56ce2a7854 | ||
|
|
19d41b2b6f | ||
|
|
7dc4922c65 | ||
|
|
22613b0163 | ||
|
|
ed5e3b4192 | ||
|
|
65ab77e824 | ||
|
|
35a3fb2155 | ||
|
|
3e32c29d6b | ||
|
|
d4161feaa0 | ||
|
|
6e1b4d4409 | ||
|
|
cff3f68212 | ||
|
|
37ed20e412 | ||
|
|
ae35f4623c | ||
|
|
5cf1a97427 | ||
|
|
27b1d80199 | ||
|
|
ea82b18705 | ||
|
|
1c3690e9e9 | ||
|
|
c74c2f1871 | ||
|
|
5544f2d202 | ||
|
|
4251999f9f | ||
|
|
1609352174 | ||
|
|
faaeca2728 | ||
|
|
3a373b19c5 | ||
|
|
bcabe7b71a | ||
|
|
17b68f7410 | ||
|
|
344b537adf | ||
|
|
c8e2aecc76 | ||
|
|
cba291422b | ||
|
|
ba776cf37c | ||
|
|
c20615834f | ||
|
|
eb236be451 | ||
|
|
d7b27b173d | ||
|
|
1356fb1b5f | ||
|
|
9286aa68b6 | ||
|
|
2ad96804fc | ||
|
|
dfa149ae19 | ||
|
|
fa335aff06 | ||
|
|
47d7c0ec21 | ||
|
|
93a8b9f8d8 | ||
|
|
2d522392ef | ||
|
|
55fc719ff8 | ||
|
|
c61aecbfb1 | ||
|
|
9ecc267c8a | ||
|
|
9eebb0a267 | ||
|
|
7c408c64e5 | ||
|
|
2a758e696b | ||
|
|
4e94b05936 | ||
|
|
395cf94395 | ||
|
|
05904e5ffb | ||
|
|
5c22ee49d8 | ||
|
|
657ded5397 | ||
|
|
e04894e55e | ||
|
|
ad3c0d8add | ||
|
|
d3ed87e022 | ||
|
|
09ad23e61e | ||
|
|
92740dd904 | ||
|
|
4a91c94dd7 | ||
|
|
f83bfff6e1 | ||
|
|
e1e93f5ffe | ||
|
|
28049f564d | ||
|
|
d9e114d750 | ||
|
|
2f637c7fa9 | ||
|
|
3b5f83b80b | ||
|
|
46bc5ba547 | ||
|
|
bf64344945 | ||
|
|
1986497dc3 | ||
|
|
2aeedfc2b2 | ||
|
|
fd5b9630b9 | ||
|
|
b0ddc613f3 | ||
|
|
abeb1a6a1e | ||
|
|
4b87d73b63 | ||
|
|
144e5850fb | ||
|
|
7976f45d25 | ||
|
|
483000c00d | ||
|
|
22494dcc59 | ||
|
|
4919dfddfb | ||
|
|
c091db675b | ||
|
|
88acd72e58 | ||
|
|
20266f1569 | ||
|
|
ea8dfc429f | ||
|
|
66adad9c26 | ||
|
|
afcb6fb00b | ||
|
|
08bec1c1e8 | ||
|
|
365f431b63 | ||
|
|
a70bdc9ec1 | ||
|
|
efc9e0e6ca | ||
|
|
d6aa0064e6 | ||
|
|
9b6e819687 | ||
|
|
519f757fd5 | ||
|
|
74a34ce6ef | ||
|
|
d180ccb164 | ||
|
|
c38be115ff | ||
|
|
4b11d5fe7f | ||
|
|
37658e808d | ||
|
|
eb57e9b430 | ||
|
|
a5acd67f20 | ||
|
|
190dfdabb0 | ||
|
|
1288067da0 | ||
|
|
5ae31d17ae | ||
|
|
1bacfee38c | ||
|
|
f77bac1076 | ||
|
|
efe98906ec | ||
|
|
50f846b8e0 | ||
|
|
000c4e19b1 | ||
|
|
327d5a1c1c | ||
|
|
a6843cfc17 | ||
|
|
e53523e7b8 | ||
|
|
f649ad264b | ||
|
|
024c0f6699 | ||
|
|
ac80e53da8 | ||
|
|
58bfc87855 | ||
|
|
f87a57887e | ||
|
|
ea7d4357a4 | ||
|
|
4be019c999 | ||
|
|
fbe64c30e2 | ||
|
|
f9a41451e7 | ||
|
|
f18232040a | ||
|
|
5537e62301 | ||
|
|
bf7612099a | ||
|
|
170f9fa2af | ||
|
|
4224d0a2e6 | ||
|
|
ee31f09c47 | ||
|
|
c1da4a3f28 | ||
|
|
1f97759a72 | ||
|
|
1aa6cc94a8 | ||
|
|
0dad4c48f5 | ||
|
|
6127c8f5c0 | ||
|
|
a4cd5432c4 | ||
|
|
25caae0015 | ||
|
|
025299dede | ||
|
|
3759b05ed0 | ||
|
|
1b40349158 | ||
|
|
ee7e6c078d | ||
|
|
ef36cd63db | ||
|
|
f18a3e61b0 | ||
|
|
4bbe9861de | ||
|
|
a723a46ec9 | ||
|
|
343b3d72bd | ||
|
|
dd5bdcf5e9 | ||
|
|
a6f3b4e7ff | ||
|
|
03225cdf46 | ||
|
|
1f0d829593 | ||
|
|
82d0f7a675 | ||
|
|
bda5eebce5 | ||
|
|
5a8367e149 | ||
|
|
93a473b9ee | ||
|
|
af02adc5a9 | ||
|
|
52c7ab0373 | ||
|
|
a02181c703 | ||
|
|
f0648d0658 | ||
|
|
d751107a26 | ||
|
|
d6600f4d5a | ||
|
|
057f1e5bbc | ||
|
|
75b72ab54e | ||
|
|
9e9ad50f58 | ||
|
|
0d84d7ab79 | ||
|
|
d851eb3fd4 | ||
|
|
efccf3e3bb | ||
|
|
e06ad27aa9 | ||
|
|
3521b194df | ||
|
|
791853ac4a | ||
|
|
6f7aaeb8e6 | ||
|
|
4a79be06d2 | ||
|
|
e98268ee0c | ||
|
|
1563392fa5 | ||
|
|
85b247ce0e | ||
|
|
c1ba2e5839 | ||
|
|
993123b38c | ||
|
|
25bcd62025 | ||
|
|
aca79fe51d | ||
|
|
3cd5ae270a | ||
|
|
0d69fac523 | ||
|
|
d3d03e5a92 | ||
|
|
8840e39029 | ||
|
|
2fdbb7fad7 | ||
|
|
760e4960e0 | ||
|
|
5bb1c03773 | ||
|
|
c9e3b7680f | ||
|
|
71d3c142a8 | ||
|
|
4fae3f908d | ||
|
|
e01a596aaf | ||
|
|
44cc892358 | ||
|
|
7be161a74f | ||
|
|
c1c857a816 | ||
|
|
87e7bd0fc9 | ||
|
|
d8427a64ce | ||
|
|
f742566442 | ||
|
|
ef3e03d018 | ||
|
|
b55dd2c9f0 | ||
|
|
41fcd549f7 | ||
|
|
695934f8e8 | ||
|
|
638e88055f | ||
|
|
da206716d0 | ||
|
|
b755b8b9f8 | ||
|
|
8a40056c10 | ||
|
|
e8273026f8 | ||
|
|
66b9701595 | ||
|
|
a3e13bdce2 | ||
|
|
1434262700 | ||
|
|
f0047f95e1 | ||
|
|
91da54ded2 | ||
|
|
1b90958d38 | ||
|
|
0fcbc26adf | ||
|
|
b032d3f798 | ||
|
|
0152e72816 | ||
|
|
d4bfab7a67 | ||
|
|
c0050dd5cd | ||
|
|
5d1214f529 | ||
|
|
8ed8b52c6b | ||
|
|
63849db562 | ||
|
|
37642292de | ||
|
|
eaf04cc2de | ||
|
|
4d5127aca4 | ||
|
|
b49f1ffb1b | ||
|
|
bba49ba498 | ||
|
|
2f46625fe9 | ||
|
|
0a40e59f2c | ||
|
|
e148310a7b | ||
|
|
802ec0e3d4 | ||
|
|
a93dd7ca1a | ||
|
|
12ef999bc6 | ||
|
|
8de77e3a6b | ||
|
|
ae1f7964a9 | ||
|
|
66ee899817 | ||
|
|
05d7bc083c | ||
|
|
7a3a3d5b14 | ||
|
|
b3ab23dcc3 | ||
|
|
6df2a3163a | ||
|
|
ce46249d9a | ||
|
|
e9f21014db | ||
|
|
264682feab | ||
|
|
a7a559b304 | ||
|
|
ce3b0976b6 | ||
|
|
cf6c3f1e24 | ||
|
|
2b24dada59 | ||
|
|
7d14e74015 | ||
|
|
86296a0366 | ||
|
|
7b8435af94 | ||
|
|
ae3ca8f5a7 | ||
|
|
aded3c9f91 | ||
|
|
fab65a4115 | ||
|
|
286580c577 | ||
|
|
494a614936 | ||
|
|
c8e8e61fcc | ||
|
|
937f040a7f | ||
|
|
4a61476888 | ||
|
|
720fc8cc34 | ||
|
|
7b864a3d91 | ||
|
|
aae531d780 | ||
|
|
f2e45587d3 | ||
|
|
25cd849a61 | ||
|
|
884ea95c53 | ||
|
|
4cc68c3c06 | ||
|
|
4443d92ca2 | ||
|
|
34b81fea59 | ||
|
|
f0e80d448f | ||
|
|
2fffc3d3e9 | ||
|
|
bd225549d9 | ||
|
|
bfa17c4303 | ||
|
|
c8619c8ec8 | ||
|
|
db602191b0 | ||
|
|
1c974eb626 | ||
|
|
b474131fd6 | ||
|
|
dab3544492 | ||
|
|
56756de072 | ||
|
|
03a345e867 | ||
|
|
3027444baf | ||
|
|
ad27974fb0 | ||
|
|
794c4bc874 | ||
|
|
129b4229f0 | ||
|
|
95eb3ddcaa | ||
|
|
aa40191938 | ||
|
|
0a41daed74 | ||
|
|
a4c60c3914 | ||
|
|
354910b5c5 | ||
|
|
d9cfa9ca3b | ||
|
|
e021bca54d | ||
|
|
17e289ab9d | ||
|
|
4683dce51c |
+2
-2
@@ -746,7 +746,7 @@
|
||||
|
||||
* doc/trace.n: minor doc cleanup
|
||||
|
||||
2000-09-06 André Pönitz <poenitz@htwm.de>
|
||||
2000-09-06 André Pönitz <poenitz@htwm.de>
|
||||
|
||||
* doc/*.n: added or changed "SEE ALSO:" section
|
||||
|
||||
@@ -1086,7 +1086,7 @@
|
||||
* unix/tcl.m4 (SC_ENABLE_GCC): Don't set CC=gcc before running
|
||||
AC_PROG_CC if CC is already set.
|
||||
|
||||
2000-07-13 André Pönitz <poenitz@mathematik.tu-chemnitz.de>
|
||||
2000-07-13 André Pönitz <poenitz@mathematik.tu-chemnitz.de>
|
||||
|
||||
* doc/lappend.n:
|
||||
* doc/lindex.n:
|
||||
|
||||
+1
-1
@@ -939,7 +939,7 @@
|
||||
version of Tcl with Cygwin gcc. Users should compile with Mingw gcc
|
||||
instead.
|
||||
|
||||
2001-11-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
|
||||
2001-11-06 Andreas Kupries <andreas_kupries@users.sourceforge.net>
|
||||
|
||||
* generic/tclIO.c (ReadChars): Fixed [Bug 478856] reported by Stuart
|
||||
Cassoff <stwo@users.sourceforge.net>. The bug caused loss of
|
||||
|
||||
+1
-1
@@ -3284,7 +3284,7 @@
|
||||
|
||||
2003-01-10 Vince Darley <vincentdarley@users.sourceforge.net>
|
||||
|
||||
* generic/tclIOUtil.c:
|
||||
* generic/tclIOUtil.c:
|
||||
* win/tclWinInt.h:
|
||||
* win/tclWinInit.c: fix to new WinTcl crash on exit with vfs,
|
||||
introduced on 2002-12-06. Encodings must be cleaned up after the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
README: Tcl
|
||||
This is the Tcl 8.6b2 source distribution.
|
||||
This is the Tcl 8.6.0 source distribution.
|
||||
http://tcl.sourceforge.net/
|
||||
You can get any source release of Tcl from the file distributions
|
||||
link at the above URL.
|
||||
|
||||
@@ -126,7 +126,7 @@ Tcl_Eval.
|
||||
that came after version 3.3 was released.
|
||||
|
||||
40. 5/17/91 Changed tests to conform to Mary Ann May-Pumphrey's approach.
|
||||
|
||||
|
||||
41. 5/23/91 Massive revision to Tcl parser to simplify the implementation
|
||||
of string and floating-point support in expressions. Newlines inside
|
||||
[] are now treated as command separators rather than word separators
|
||||
@@ -260,7 +260,7 @@ argument (before file name), for consistency with other Tcl commands.
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
72. 8/20/91 Changed format of information in $errorInfo variable:
|
||||
comments such as
|
||||
comments such as
|
||||
("while" body line 1)
|
||||
are now on separate lines from commands being executed.
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
@@ -1192,7 +1192,7 @@ under some dynamic loading systems (e.g. SunOS 4.1 and Windows).
|
||||
6/8/95 (feature change) Modified interface to Tcl_Main to pass in the
|
||||
address of the application-specific initialization procedure.
|
||||
Tcl_AppInit is no longer hardwired into Tcl_Main. This is needed
|
||||
in order to make Tcl a shared library.
|
||||
in order to make Tcl a shared library.
|
||||
|
||||
6/8/95 (feature change) Modified Makefile so that the installed versions
|
||||
of tclsh and libtcl.a have version number in them (e.g. tclsh7.4 and
|
||||
@@ -1616,7 +1616,7 @@ file name. Under Windows '95, this is incorrectly interpreted as a UNC
|
||||
path. They delays came from the network timeouts needed to determine that
|
||||
the file name was invalid. Tcl_TranslateFileName now suppresses duplicate
|
||||
slashes that aren't at the beginning of the file name. (SS)
|
||||
|
||||
|
||||
1/25/96 (bug fix) Changed exec and open to create children so they are
|
||||
attached to the application's console if it exists. (SS)
|
||||
|
||||
@@ -2254,21 +2254,21 @@ version of Tcl. It's quite a bit faster than MetroWerk's version. (RJ)
|
||||
8/26/96 (documentation update) Removed old change bars (for all changes
|
||||
in Tcl 7.5 and earlier releases) from manual entries. (JO)
|
||||
|
||||
8/27/96 (enhancement) The exec and open commands behave better and work in
|
||||
more situations under Windows NT and Windows 95. Documentation describes
|
||||
8/27/96 (enhancement) The exec and open commands behave better and work in
|
||||
more situations under Windows NT and Windows 95. Documentation describes
|
||||
what is still lacking. (CS)
|
||||
|
||||
8/27/96 (enhancement) The Windows makefiles will now compile even if the
|
||||
compiler is not in the path and/or the compiler's environment variables
|
||||
have not been set up. (CS)
|
||||
have not been set up. (CS)
|
||||
|
||||
8/27/96 (configuration improvement) The Windows resource files are
|
||||
8/27/96 (configuration improvement) The Windows resource files are
|
||||
automatically updated when the version/patch level changes. The header file
|
||||
now has a comment that reminds the user which other files must be manually
|
||||
updated when the version/patch level changes. (CS)
|
||||
|
||||
8/28/96 (new feature) Added file manipulation features (copy, rename, delete,
|
||||
mkdir) that are supported on all platforms. They are implemented as
|
||||
mkdir) that are supported on all platforms. They are implemented as
|
||||
subcommands to the "file" command. See the documentation for the "file"
|
||||
command for more information. (JH)
|
||||
|
||||
@@ -2371,7 +2371,7 @@ the Tcl script in the fileevent wasn't closing the socket immediately. (JL)
|
||||
package goes in a separate subdirectory of a directory in
|
||||
$tcl_pkgPath). These directories are included in auto_path by
|
||||
default.
|
||||
- Changed the package auto-loader to look for pkgIndex.tcl files
|
||||
- Changed the package auto-loader to look for pkgIndex.tcl files
|
||||
not only in the auto_path directories but also in their immediate
|
||||
children. This should make it easier to install and uninstall
|
||||
packages (don't have to change auto_path or merge pkgIndex.tcl
|
||||
@@ -2621,7 +2621,7 @@ lookups of keyword arguments. (JO)
|
||||
|
||||
1/12/97 (new feature) Serial IO channel drivers for Windows and Unix,
|
||||
available by using Tcl open command to open pseudo-files like "com1:" or
|
||||
"/dev/ttya". New option to Tcl fconfigure command for serial files:
|
||||
"/dev/ttya". New option to Tcl fconfigure command for serial files:
|
||||
"-mode baud,parity,data,stop" to specify baud rate, parity, data bits, and
|
||||
stop bits. Serial IO is not yet available on Mac.
|
||||
|
||||
@@ -2701,7 +2701,7 @@ to Feb 31.) The code now will return the last valid day of the
|
||||
month in these situations. Thanks to Hume Smith for sending in
|
||||
this bug fix. (RJ)
|
||||
|
||||
2/10/97 (feature change) Eliminated Tcl_StringObjAppend and
|
||||
2/10/97 (feature change) Eliminated Tcl_StringObjAppend and
|
||||
Tcl_StringObjAppendObj procedures, replaced them with Tcl_AppendToObj
|
||||
and Tcl_AppendStringsToObj procedures. Added new procedure
|
||||
Tcl_SetObjLength. (JO)
|
||||
@@ -3068,7 +3068,7 @@ compilation errors from "invoked from within" to "while compiling". (BL)
|
||||
modified the interpreter result even if there was no error.
|
||||
- The argument parsing procedure used by several compile procedures
|
||||
always treated "]" as end of a command: e.g., "set a ]" would fail.
|
||||
- Changed errorInfo traceback message for compilation errors from
|
||||
- Changed errorInfo traceback message for compilation errors from
|
||||
"invoked from within" to "while compiling".
|
||||
- Problem initializing Tcl object managers during interpreter creation.
|
||||
- Added check and error message if formal parameter to a procedure is
|
||||
@@ -3143,7 +3143,7 @@ is leaked to safe interps. Error message fixes for interp sub commands.
|
||||
Likewise changes in safealias.tcl; tcl_safeCreateInterp can now be called
|
||||
without argument to generate the slave name (like in interp create). (DL)
|
||||
|
||||
7/10/97 (bug fixes) Bytecode compiler now generates more detailed
|
||||
7/10/97 (bug fixes) Bytecode compiler now generates more detailed
|
||||
command location information: subcommands as well as commands now have
|
||||
location information. This means command trace procedures now get the
|
||||
correct source string for each command in their command parameter. (BL)
|
||||
@@ -3181,7 +3181,7 @@ malloc and free. (SS)
|
||||
sourcing/loading (see safe.n) to hide pathnames, use virtual
|
||||
paths tokens instead, improved security in several respects and made it
|
||||
more tunable. Multi level interp loading can work too now. Package auto
|
||||
loading now works in safe interps as long as the package directory is in
|
||||
loading now works in safe interps as long as the package directory is in
|
||||
the auto_path (no deep crawling allowed in safe interps). (DL)
|
||||
*** POTENTIAL INCOMPATIBILITY with previous alpha and beta releases ***
|
||||
|
||||
@@ -3209,7 +3209,7 @@ exists" command returns 0 for them. (BL)
|
||||
7/29/97 (feature change) Changed the http package to use the ::http
|
||||
namespace. http_get renamed to http::geturl, http_config renamed to
|
||||
http::config, http_formatQuery renamed to http::formatQuery.
|
||||
It now provides the 2.0 version of the package.
|
||||
It now provides the 2.0 version of the package.
|
||||
The 1.0 version is still available with the old names.
|
||||
*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b2 but not with Tcl 7.6 ***
|
||||
|
||||
@@ -3273,7 +3273,7 @@ except that the default precision is 12 instead of 6. (JO)
|
||||
----------------- Released 8.0, 8/18/97 -----------------------
|
||||
|
||||
8/19/97 (bug fix) Minimal fix for glob -nocomplain bugs:
|
||||
"glob -nocomplain unreadableDir/*" was generating an anonymous
|
||||
"glob -nocomplain unreadableDir/*" was generating an anonymous
|
||||
error. More in depth fixes will come with 8.1. (DL).
|
||||
|
||||
8/20/97 (bug fix) Removed check for FLT_MIN in binary command so
|
||||
@@ -3318,7 +3318,7 @@ does not prevent stack overflow by multi-interps recursion or aliasing} (DL)
|
||||
9/11/97 (bug fix) An uninitialized variable in Tcl_WaitPid caused
|
||||
pipes to fail to report eof properly under Windows. (SS)
|
||||
|
||||
9/12/97 (bug fix) "exec" was misidentifying some DOS executables as not
|
||||
9/12/97 (bug fix) "exec" was misidentifying some DOS executables as not
|
||||
executable. (CCS)
|
||||
|
||||
9/14/97 (bug fix) Was using the wrong structure in sizeof operation in
|
||||
@@ -3342,7 +3342,7 @@ Roseman for the pointer on the fix.) (RJ)
|
||||
cause the compare function to run off the end of an array if the
|
||||
number only contained 0's. (Thanks to Greg Couch for the report.) (RJ)
|
||||
|
||||
9/18/97 (bug fix) TclFinalizeEnvironment was not cleaning up
|
||||
9/18/97 (bug fix) TclFinalizeEnvironment was not cleaning up
|
||||
properly. (DL, JI)
|
||||
|
||||
9/18/97 (bug fix) Fixed long-standing bug where an "array get" command
|
||||
@@ -3378,9 +3378,9 @@ Now you can "join $list \0" for instance. (DL)
|
||||
non-existent directory, exec would fail when trying to create its temporary
|
||||
files. (CCS)
|
||||
|
||||
10/9/97 (bug fix) Under mac and windows, "info hostname" would crash if
|
||||
10/9/97 (bug fix) Under mac and windows, "info hostname" would crash if
|
||||
sockets were installed but the hostname could not be determined anyhow.
|
||||
Tcl_GetHostName() was returning NULL when it should have been returning
|
||||
Tcl_GetHostName() was returning NULL when it should have been returning
|
||||
an empty string. (CCS)
|
||||
|
||||
10/10/97 (bug fix) "file attribute /" returned error on windows. (CCS)
|
||||
@@ -3468,7 +3468,7 @@ around to be really closed in this case. (JL)
|
||||
12/8/97 (bug fix) Need to protect the channel in a fileevent so that it
|
||||
is not deleted before the fileevent handler returns. (CS, JL)
|
||||
|
||||
12/18/97 (bug fix) In the opt argument parsing package: if the description
|
||||
12/18/97 (bug fix) In the opt argument parsing package: if the description
|
||||
had only flags, the "too many arguments" case was not detected. The default
|
||||
value was not used for the special "args" ending argument. (DL)
|
||||
|
||||
@@ -3511,7 +3511,7 @@ that could lead to a crash. (SS)
|
||||
non-local variable references. (SS)
|
||||
|
||||
6/25/98 (new features) Added name resolution hooks to support [incr Tcl].
|
||||
There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks.
|
||||
There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks.
|
||||
With this changes it should be possible to dynamically load [incr Tcl]
|
||||
as an extension. (MM)
|
||||
|
||||
@@ -3539,7 +3539,7 @@ TclAccessInsertProc, TclStatInsertProc, & TclOpenFileChannelInsertProc
|
||||
insert pointers to such routines; TclAccessDeleteProc, TclStatDeleteProc,
|
||||
& TclOpenFileChannelDeleteProc delete pointers to such routines. See
|
||||
the file generic/tclIOUtils.c for more details. (SKS)
|
||||
|
||||
|
||||
7/1/98 (enhancement) Added a new internal C variable
|
||||
tclPreInitScript. This is a pointer to a string that may hold an
|
||||
initialization script; If this pointer is non-NULL it is evaluated in
|
||||
@@ -3623,7 +3623,7 @@ internal representation holds a pointer to a Proc structure. Extended
|
||||
TclCreateProc to take both strings and "procbody". (EMS)
|
||||
|
||||
10/13/98 (bug fix) The "info complete" command can now handle strings
|
||||
with NULLs embedded. Thanks to colin@field.medicine.adelaide.edu.au
|
||||
with NULLs embedded. Thanks to colin@field.medicine.adelaide.edu.au
|
||||
for providing this fix. (RJ)
|
||||
|
||||
10/13/98 (bug fix) The "lsort -dictionary" command did not properly
|
||||
@@ -3691,7 +3691,7 @@ by default. Fixed socket code so it turns off this bit right after
|
||||
creation so sockets aren't kept open by exec'ed processes. [Bug: 892]
|
||||
Thanks to Kevin Kenny for this fix. (SS)
|
||||
|
||||
1/11/98 (bug fix) On HP, "info sharedlibextension" was returning
|
||||
1/11/98 (bug fix) On HP, "info sharedlibextension" was returning
|
||||
empty string on static apps. It now always returns ".sl". (RJ)
|
||||
|
||||
1/28/99 (configure change) Now support -pipe option on gcc. (RJ)
|
||||
@@ -3736,7 +3736,7 @@ panic. (stanton)
|
||||
|
||||
2/2/99 (feature change/bug fix) Changed the behavior of "file
|
||||
extension" so that it splits at the last period. Now the extension of
|
||||
a file like "foo..o" is ".o" instead of "..o" as in previous versions.
|
||||
a file like "foo..o" is ".o" instead of "..o" as in previous versions.
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
----------------- Released 8.0.5, 3/9/99 -------------------------
|
||||
@@ -3757,15 +3757,15 @@ a file like "foo..o" is ".o" instead of "..o" as in previous versions.
|
||||
of a UTF-8 string remains \0. Thus Tcl strings once again do not
|
||||
contain null bytes, except for termination bytes.
|
||||
- For Java compatibility, "\uXXXX" is used in Tcl to enter a Unicode
|
||||
character. "\u0000" through "\uffff" are acceptable Unicode
|
||||
characters.
|
||||
character. "\u0000" through "\uffff" are acceptable Unicode
|
||||
characters.
|
||||
- "\xXX" is used to enter a small Unicode character (between 0 and 255)
|
||||
in Tcl.
|
||||
- Tcl automatically translates between UTF-8 and the normal encoding for
|
||||
the platform during interactions with the system.
|
||||
- The fconfigure command now supports a -encoding option for specifying
|
||||
the encoding of an open file or socket. Tcl will automatically
|
||||
translate between the specified encoding and UTF-8 during I/O.
|
||||
translate between the specified encoding and UTF-8 during I/O.
|
||||
See the directory library/encoding to find out what encodings are
|
||||
supported (eventually there will be an "encoding" command that
|
||||
makes this information more accessible).
|
||||
@@ -3839,7 +3839,7 @@ imported procedures as well as procedures defined in a namespace. (BL)
|
||||
in place of Tcl_GetStringFromObj() if the string representation's length
|
||||
isn't needed. (BL)
|
||||
|
||||
12/18/97 (bug fix) In the opt argument parsing package: if the description
|
||||
12/18/97 (bug fix) In the opt argument parsing package: if the description
|
||||
had only flags, the "too many arguments" case was not detected. The default
|
||||
value was not used for the special "args" ending argument. (DL)
|
||||
|
||||
@@ -3849,11 +3849,11 @@ procs now in auto.tcl and package.tcl can be autoloaded if needed. (DL)
|
||||
1/7/98 (enhancement) tcltest made at install time will search for it's
|
||||
init.tcl where it is, even when using virtual path compilation. (DL)
|
||||
|
||||
1/8/98 (os bug workaround) when needed, using a replacement for memcmp so
|
||||
1/8/98 (os bug workaround) when needed, using a replacement for memcmp so
|
||||
string compare "char with high bit set" "char w/o high bit set" returns
|
||||
the expected value on all platforms. (DL)
|
||||
|
||||
1/8/98 (unix portability/configure) building from .../unix/targetName/
|
||||
1/8/98 (unix portability/configure) building from .../unix/targetName/
|
||||
subdirectories and simply using "../configure" should now work fine. (DL)
|
||||
|
||||
1/14/98 (enhancement) Added new regular expression package that
|
||||
@@ -3885,7 +3885,7 @@ to generate direct loading package indexes (such those you need
|
||||
if you use namespaces and plan on using namespace import just after
|
||||
package require). pkg_mkIndex still has limitations regarding
|
||||
package dependencies but errors are now ignored and with -direct, correct
|
||||
package indexes can be generated even if there are dependencies as long
|
||||
package indexes can be generated even if there are dependencies as long
|
||||
as the "package provide" are done early enough in the files. (DL)
|
||||
|
||||
1/28/98 (enhancement) Performance tuning of regexp and regsub. (CCS)
|
||||
@@ -3909,7 +3909,7 @@ continue to use the argv array after calling Tcl_OpenCommandChannel(). (CCS)
|
||||
2/1/98 (bug fix) More bugs with %Z in format string argument to strftime():
|
||||
1. Borland always returned empty string.
|
||||
2. MSVC always returned the timezone string for the current time, not the
|
||||
timezone string for the specified time.
|
||||
timezone string for the specified time.
|
||||
3. With MSVC, "clock format 0 -format %Z -gmt 1" would return "GMT" the first
|
||||
time it was called, but would return the current timezone string on all
|
||||
subsequent calls. (CCS)
|
||||
@@ -3931,7 +3931,7 @@ root directory was returning error. (CCS)
|
||||
determine the attributes for a file. Previously it would return different
|
||||
error messages on Unix vs. Windows vs. Mac. (CCS)
|
||||
|
||||
2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler
|
||||
2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler
|
||||
would reach outside the range of allocated memory. Improved the array
|
||||
lookup algorithm in set compilation. (DL)
|
||||
|
||||
@@ -3939,13 +3939,13 @@ lookup algorithm in set compilation. (DL)
|
||||
deprecated and ignored. The part1 is always parsed when the part2 argument
|
||||
is NULL. This is to avoid a pattern of errors for extension writers converting
|
||||
from string based Tcl_SetVar() to new Tcl_SetObjVar2() and who could easily
|
||||
forget to provide the flag and thus get code working for normal variables
|
||||
forget to provide the flag and thus get code working for normal variables
|
||||
but not for array elements. The performance hit is minimal. A side effect
|
||||
of that change is that is is no longer possible to create scalar variables
|
||||
that can't be accessed by tcl scripts because of their invalid name
|
||||
(ending with parenthesis). Likewise it is also parsed and checked to
|
||||
ensure that you don't create array elements of array whose name is a valid
|
||||
array element because they would not be accessible from scripts anyway.
|
||||
that can't be accessed by tcl scripts because of their invalid name
|
||||
(ending with parenthesis). Likewise it is also parsed and checked to
|
||||
ensure that you don't create array elements of array whose name is a valid
|
||||
array element because they would not be accessible from scripts anyway.
|
||||
Note: There is still duplicate array elements parsing code. (DL)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
@@ -3991,7 +3991,7 @@ registry call. (CCS)
|
||||
2/11/98 (enhancement) Eliminate the TCL_USE_TIMEZONE_VAR definition from
|
||||
configure.in, because it was the same information as the already existing
|
||||
HAVE_TM_ZONE definition. The lack of HAVE_TM_ZONE is used to work around a
|
||||
Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1"
|
||||
Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1"
|
||||
produces the local timezone string instead of "GMT". (CCS)
|
||||
|
||||
2/11/98 (bug fix) Memleaks and dereferencing of uninitialized memory in
|
||||
@@ -4349,7 +4349,7 @@ strings that are already null terminated. [Bug: 1793] (stanton)
|
||||
|
||||
5/3/99 (new feature) Applied Jeff Hobbs's string patch which includes
|
||||
the following changes:
|
||||
- added new subcommands: equal, repeat, map, is, replace
|
||||
- added new subcommands: equal, repeat, map, is, replace
|
||||
- added -length option to "string compare|equal"
|
||||
- added -nocase option to "string compare|equal|match"
|
||||
- string and list indices can be an integer or end?-integer?.
|
||||
@@ -4378,7 +4378,7 @@ improvements for many Tcl scripts. [Bug: 1063] (stanton)
|
||||
encoding subfield from the LANG/LC_ALL environment variables in cases
|
||||
where the locale is not found in the built-in locale table. It also
|
||||
attempts to initialize the locale subsystem so X11 is happy. [Bug: 1989]
|
||||
(stanton)
|
||||
(stanton)
|
||||
|
||||
5/14/99 (bug fix) Applied the patch to fix 100-year and 400-year
|
||||
boundaries in leap year code, from Isaac Hollander. [Bug: 2066] (redman)
|
||||
@@ -4466,7 +4466,7 @@ harness package. Modified test files to use new tcltest package.
|
||||
|
||||
6/26/99 (new feature) Applied patch from Peter Hardie to add poke
|
||||
command to dde and changed the dde package version number to
|
||||
1.1. (redman)
|
||||
1.1. (redman)
|
||||
|
||||
6/28/99 (bug fix) Applied patch from Peter Hardie to fix problem in
|
||||
Tcl_GetIndexFromObj() when the key being passed is the empty string.
|
||||
@@ -4529,7 +4529,7 @@ notation for opening serial ports on Windows. (redman)
|
||||
instead of the platform-specific "size_t", primarily after SunOS 4
|
||||
users could no longer compile. (redman)
|
||||
|
||||
7/22/99 (bug fix) Fixed crashing during "array set a(b) {}".
|
||||
7/22/99 (bug fix) Fixed crashing during "array set a(b) {}".
|
||||
[Bug: 2427] (redman)
|
||||
|
||||
7/22/99 (bug fix) The install-sh script must be given execute
|
||||
@@ -4564,7 +4564,7 @@ pack-old.n [Bug: 2469]. Patches from Don Porter. (redman)
|
||||
7/29/99 (bug fix) Allow tcl to open CON and NUL, even for redirection
|
||||
of std channels. [Bug: 2393 2392 2209 2458] (redman)
|
||||
|
||||
7/30/99 (bug fix) Applied fixed Trf patch from Andreas Kupries.
|
||||
7/30/99 (bug fix) Applied fixed Trf patch from Andreas Kupries.
|
||||
[Bug: 2386] (hobbs)
|
||||
|
||||
7/30/99 (bug fix) Fixed bug in info complete. [Bug: 2383 2466] (hobbs)
|
||||
@@ -4574,7 +4574,7 @@ provided by James Dennett. [Bug: 2450] (redman)
|
||||
|
||||
7/30/99 (bug fix) Fixed launching of 16bit applications on Win9x from
|
||||
wish. The command line was being primed with tclpip82.dll, but it was
|
||||
ignored later.
|
||||
ignored later.
|
||||
|
||||
7/30/99 (bug fix) Added functions to stub table, patch provided by Jan
|
||||
Nijtmans. [Bug: 2445] (hobbs)
|
||||
@@ -4587,7 +4587,7 @@ thread's stack space. (redman)
|
||||
--------------- Released 8.2b2, August 5, 1999 ----------------------
|
||||
|
||||
8/4/99 (bug fix) Applied patches supplied by Henry Spencer to greatly
|
||||
enhance performance of certain classes of regular expressions.
|
||||
enhance performance of certain classes of regular expressions.
|
||||
[Bug: 2440 2447] (stanton)
|
||||
|
||||
8/5/99 (doc change) Made it clear that tcl_pkgPath was not set for
|
||||
@@ -4601,7 +4601,7 @@ terminated in tclLiteral.c. [Bug: 2496] (hobbs)
|
||||
8/9/99 (bug fix) Fixed test suite to handle larger integers
|
||||
(64bit). Patch from Don Porter. (hobbs)
|
||||
|
||||
8/9/99 (documentation fix) Clarified Tcl_DecrRefCount docs
|
||||
8/9/99 (documentation fix) Clarified Tcl_DecrRefCount docs
|
||||
[Bug: 1952]. Clarified array pattern docs [Bug: 1330]. Fixed clock docs
|
||||
[Bug: 693]. Fixed formatting errors [Bug: 2188 2189]. Fixed doc error
|
||||
in tclvars.n [Bug: 2042]. (hobbs)
|
||||
@@ -4661,7 +4661,7 @@ and in testthread code. No more known (reported) mem leaks for Tcl
|
||||
built using gcc on Solaris 2.5.1. Also none reported for Tcl on NT
|
||||
(using Purify 6.0). (hobbs)
|
||||
|
||||
10/30/99 (bug fix) fixed improper bytecode handling of
|
||||
10/30/99 (bug fix) fixed improper bytecode handling of
|
||||
'eval {set array($unknownvar) 5}' (also for incr) (hobbs)
|
||||
|
||||
10/30/99 (bug fix) fixed event/io threading problems by making
|
||||
@@ -5115,7 +5115,7 @@ bits for Tcl_UniChar though) (hobbs)
|
||||
2001-05-30 (new feature)[TIP 15] Tcl_GetMathFuncInfo, Tcl_ListMathFuncs,
|
||||
Tcl_InfoObjCmd, InfoFunctionsCmd APIs (fellows)
|
||||
|
||||
2001-06-08 (bug fix,feature enhancement)[219170,414936] all Tcl_Panic
|
||||
2001-06-08 (bug fix,feature enhancement)[219170,414936] all Tcl_Panic
|
||||
definitions brought into agreement (porter)
|
||||
|
||||
2001-06-12 (bug fix)[219232] regexp returned non-matching sub-pairs to have
|
||||
@@ -5284,7 +5284,7 @@ compiles to 0 bytecodes (sofer)
|
||||
|
||||
2001-09-13 (new feature) Old ChangeLog entries => ChangeLog.1999 (hobbs)
|
||||
|
||||
2001-09-17 (new feature) compiling with TCL_COMPILE_DEBUG now required to
|
||||
2001-09-17 (new feature) compiling with TCL_COMPILE_DEBUG now required to
|
||||
enable all compile and execution tracing (sofer)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
@@ -5566,7 +5566,7 @@ options to configure (max)
|
||||
|
||||
2002-07-30 (bug fix)[584603] WriteChars infinite loop non-UTF-8 string (kupries)
|
||||
|
||||
2002-08-04 (new feature)[584051,580433,585105,582429][TIP 27] Tcl interfaces
|
||||
2002-08-04 (new feature)[584051,580433,585105,582429][TIP 27] Tcl interfaces
|
||||
are now fully CONST-ified. Use the symbols USE_NON_CONST or
|
||||
USE_COMPAT_CONST to select interfaces with fewer changes.
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
@@ -5576,7 +5576,7 @@ options to configure (max)
|
||||
=> tcltest 2.2
|
||||
|
||||
2002-08-07 (bug fix)[587488] mem leak with USE_THREAD_ALLOC (sofer,sass)
|
||||
|
||||
|
||||
2002-08-07 (feature enhancement)[584794,584650,472576] boolean values
|
||||
are no longer always re-parsed from string. (sofer)
|
||||
|
||||
@@ -5710,7 +5710,7 @@ packages in multiple interps.
|
||||
|
||||
2003-02-01 (bug fix)[675356] [clock clicks {}]; [clock clicks -] - syntax errs
|
||||
|
||||
2003-02-01 (bug fix)[656660] MT-safety for [clock format]
|
||||
2003-02-01 (bug fix)[656660] MT-safety for [clock format]
|
||||
|
||||
2003-02-03 (bug fix)[651271] command rename traces get fully-qualified names
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
@@ -5929,7 +5929,7 @@ various odd regexp "can't happen" bugs.
|
||||
|
||||
2003-12-09 (platform support)[852369] update errno usage for recent glibc
|
||||
|
||||
2003-12-12 (bug fix)[858937] fix for [file normalize ~nobody]
|
||||
2003-12-12 (bug fix)[858937] fix for [file normalize ~nobody]
|
||||
|
||||
2003-12-17 (bug fix)[839519] fixed two memory leaks (vasiljevic)
|
||||
|
||||
@@ -5944,7 +5944,7 @@ various odd regexp "can't happen" bugs.
|
||||
|
||||
2004-02-12 (feature enhancement) update HP-11 build libs setup
|
||||
|
||||
2004-02-17 (bug fix)[849514,859251] corrected [file normailze] of $link/..
|
||||
2004-02-17 (bug fix)[849514,859251] corrected [file normailze] of $link/..
|
||||
|
||||
2004-02-17 (bug fix)[772288] Unix std channels forced to exist at startup.
|
||||
|
||||
@@ -6037,7 +6037,7 @@ in this changeset (new minor version) rather than bug fixes:
|
||||
* [TIP #139] documented portions of Tcl's namespace C APIs
|
||||
|
||||
* [TIP #148] correct [list]-quoting of the '#' character
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
For scripts that assume a particular (buggy) string rep for lists.
|
||||
|
||||
* [TIP #156] add "root locale" to msgcat
|
||||
@@ -6532,7 +6532,7 @@ Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
|
||||
|
||||
2005-07-22 (enhancement)[1237755] 8.4 features in script library (fradin,porter)
|
||||
|
||||
2005-07-24 (new feature) configure macros SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)
|
||||
2005-07-24 (new feature) configure macros SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)
|
||||
2005-07-26 (bug fix)[1047286] cmd delete traces during namespace delete (porter)
|
||||
|
||||
2005-07-26 (new unix feature)[1231015] ${prefix}/share on ::tcl_pkgPath (dejong)
|
||||
@@ -6627,7 +6627,7 @@ registered by [package ifneeded] provides the version it claims (lavana,porter)
|
||||
|
||||
2005-11-09 (bug fix)[1350293,1350291] [after $negative $script] fixed (kenny)
|
||||
|
||||
2005-11-12 (bug fix)[1352734,1354540,1355942,1355342] [namespace delete]
|
||||
2005-11-12 (bug fix)[1352734,1354540,1355942,1355342] [namespace delete]
|
||||
issues with [namespace path] and command delete traces (sofer,fellows)
|
||||
|
||||
2005-11-18 (bug fix)[1358369] URL parsing standards compliance (wu,fellows)
|
||||
@@ -6756,7 +6756,7 @@ naked-fork safe on Tiger (steffen)
|
||||
2006-06-20 (internal change) Dropped the internal routines used to hook into
|
||||
filesystem operations back in the pre-Tcl_Filesystem days. (porter)
|
||||
***POTENTIAL INCOMPATIBILITY***
|
||||
For extensions and programs that have never migrated to the supported Tcl 8.4
|
||||
For extensions and programs that have never migrated to the supported Tcl 8.4
|
||||
interface for virtual filesystems
|
||||
|
||||
2006-07-05 (enhancement) Expression parser rewrite avoids stack overflow,
|
||||
@@ -7603,7 +7603,7 @@ avoid otherwise very tricky multi-thread finalization bugs. (staplin,ferrieux)
|
||||
|
||||
2009-10-04 (bug fix)[2569449] Core Foundation memory bug in Tiger (steffen)
|
||||
|
||||
2009-10-06 (bug fix) repair intrep loss in slave interp evaluations
|
||||
2009-10-06 (bug fix) repair intrep loss in slave interp evaluations
|
||||
introduced by first versions of the NRE conversion (nadkarni,porter)
|
||||
|
||||
2009-10-06 (bug fix)[1941434] broken tclTomMath.h includes (porter)
|
||||
@@ -7976,17 +7976,190 @@ Many more Tcl built-in command errors now set an -errorcode.
|
||||
like "nano()" instead of parsing as "nan o()" with missing op (duquette,porter)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2011-09-10 (bug fix)[3400658] wrong num args msg with TclOO (rsooltan,fellows)
|
||||
|
||||
2011-09-13 (bug fix)[3390638] solaris studio cc workaround (kechel,porter)
|
||||
|
||||
2011-09-13 (bug fix)[3405652] DTrace workaround (michelson,porter)
|
||||
|
||||
2011-09-16 (bug fix)[3391977] -headers overrides -type (ziegenhagen,fellows)
|
||||
=> http 2.7.7
|
||||
=> http 2.8.3
|
||||
|
||||
2011-09-16 (bug fix)[3400658] wrong num args msg with TclOO (rsooltan,fellows)
|
||||
2011-09-16 (TIP 388) New \Uhhhhhhhh syntax (nijtmans)
|
||||
|
||||
2011-10-06 (enhancement) bytecode compile [dict with] (fellows)
|
||||
|
||||
2011-10-11 (bug fix)[2935503] [file stat] returns bad mode (nadkarni,nijtmans)
|
||||
|
||||
2011-10-15 tzdata updated to Olson's tzdata2011l (iyer)
|
||||
2011-10-20 (bug fix)[3418547] cmd lits and custom resolvers (soberning,fellows)
|
||||
|
||||
--- Released 8.6b3, November 20, 2011 --- See ChangeLog for details ---
|
||||
2011-10-31 (bug fix)[3414754] EIAS violation in fs paths (porter)
|
||||
|
||||
2011-11-22 (bug fix)[3354324] Win: [file mtime] sets wrong time (nijtmans)
|
||||
|
||||
2011-11-30 (bug fix)[967195] Simply args passed to child processes (nijtmans)
|
||||
=> tcltest 2.3.4
|
||||
|
||||
2011-12-07 (bug fix)[3444754] fix [string tolower \u01C5] (nijtmans)
|
||||
|
||||
2011-12-11 (update)[3457031] Update [[:print:]] to Unicode 6.0 (nijtmans)
|
||||
|
||||
2011-12-24 (bug fix)[3464428] fix [string is graph \u0120] (nijtmans)
|
||||
|
||||
2012-01-08 (bug fix)[3470928] zoneinfo trouble with Windhoek data file (kenny)
|
||||
|
||||
2012-01-13 (bug fix)[3472316] fix retrieval of socket error (fellows)
|
||||
|
||||
2012-01-21 (bug fix)[3475667] [regexp] buffer read overflow (sebres)
|
||||
|
||||
2012-01-22 (bug fix)[3475264] [dict exists] return 0, not error (fellows)
|
||||
|
||||
2012-01-25 (bug fix)[3474460] [oo::copy] var resolution list (fellows)
|
||||
|
||||
2012-01-26 (bug fix)[3475569,3479689] mem corrupt in fs path (sebres,porter)
|
||||
|
||||
2012-01-30 (enhancement) improve bytecode compile of [catch] (fellows)
|
||||
|
||||
2012-02-02 (bug fix)[2974459,2879351,1951574,1852572,1661378,1613456] Fix
|
||||
problems where [file *able] would return false results on Win/Samba (porter)
|
||||
|
||||
2012-02-06 (bug fix)[3484621] bump bytecode epoch on exec traces (kuhn,sofer)
|
||||
|
||||
2012-02-15 (bug fix)[3487626] crash compiling [dict for] (fellows)
|
||||
|
||||
2012-02-15 (enhancement) bytecode compile [lrange],[lreplace] (fellows)
|
||||
|
||||
2012-02-17 (bug fix)[2233954] compile problem on AIX & Android (nijtmans)
|
||||
|
||||
2012-02-29 (bug fix)[3466099] BOM in Unicode (nijtmans)
|
||||
|
||||
2012-03-07 (bug fix)[3498327] RFC 3986 compliance (kupries)
|
||||
|
||||
2012-03-26 (TIP 380) New builtin class [oo::Slot] (fellows)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2012-03-27 (TIP 397) <cloned> method to extend [oo::copy] (fellows)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2012-03-27 (TIP 395) New subcommand [string is entier] (fellows)
|
||||
|
||||
2012-04-02 (TIP 396) New command [yieldto] (fellows)
|
||||
|
||||
2012-04-04 (bug fix)[3514761] crash combining objects and ensembles (fellows)
|
||||
|
||||
2012-04-09 (bug fix)[2712377] [info vars] and oo variables (fellows)
|
||||
|
||||
2012-04-09 (bug fix)[3396896] no dups in oo var lists (fellows)
|
||||
|
||||
2012-04-11 (bug fix)[3448512] [clock scan 1958-01-01] fail on Win (nijtmans)
|
||||
|
||||
2012-04-15 (bug fix)[3517696] fix flush of zlib chan xform (fellows)
|
||||
|
||||
2012-04-18 tzdata updated to Olson's tzdata2012c (kenny)
|
||||
|
||||
2012-04-28 (TIP 398) exit non-blocking chan without flush (ferrieux)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2012-05-02 (enhancement) Better use of Intel cpuid instruction (nijtmans)
|
||||
|
||||
2012-05-03 (bug fix)[3428753] Unbreak synchronous [socket -async] (porter)
|
||||
|
||||
2012-05-10 (bug fix)[2812981] force consistent config of Tcl+pkgs (ferrieux)
|
||||
|
||||
2012-05-10 (bug fix)[473946] correct send of special characters (nijtmans)
|
||||
|
||||
2012-05-17 (bug fix)[3445787] fix [file] ensemble in Safe Base (fellows)
|
||||
|
||||
2012-05-17 (bug fix)[2964715] fix [glob] in Safe Base (fellows)
|
||||
|
||||
2012-05-17 (bug fix)[3106532] proper [switch -indexvar] values (fellows)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2012-05-21 (TIP 106) New -binary option to [dde execute|poke] (oehlmann)
|
||||
=> dde 1.4.0
|
||||
|
||||
2012-05-23 (bug fix)[3525907] [zlib push decompress] & [chan event]
|
||||
(fellows,ferrieux,kupries)
|
||||
|
||||
2012-05-28 (bug fix)[3529949] Protect ~ paths in Safe Base (fellows)
|
||||
|
||||
2012-06-21 (bug fix)[3362446] [registry keys] failure (nijtmans)
|
||||
=> registry 1.3.0
|
||||
|
||||
2012-06-25 (bug fix)[3537605] [encoding dirs a b] error message (fellows)
|
||||
|
||||
2012-06-25 (bug fix)[3024359] crash when multi-thread concurrent [file system]
|
||||
and Tcl_FSMountsChanged(). (porter)
|
||||
|
||||
2012-06-29 (bug fix)[3536888] fix locale guessing (oehlmann,nijtmans)
|
||||
|
||||
2012-07-05 (bug fix)[1189293] make "<<" redirect binary safe (porter)
|
||||
|
||||
2012-07-08 (bug fix)[3531209] accept IPv6 URLs (max)
|
||||
=> http 2.8.4
|
||||
|
||||
2012-07-24 (bug fix) stop mem corruption in stacked channel events (max,porter)
|
||||
|
||||
2012-07-25 (bug fix)[3546275] [auto_execok] search match [exec] (danckaert)
|
||||
|
||||
2012-07-27 (update)[3464401] Support Unicode 6.2 (nijtmans)
|
||||
|
||||
2012-08-20 (bug fix)[3559678] [file normalize] EIAS failure (phao,dgp)
|
||||
|
||||
2012-08-25 (bug fix)[3561330] Ukranian translation of "March" (teterin)
|
||||
|
||||
2012-09-07 (TIP 404) New msgcat commands [mcflset], [mcflmset] (oehlmann)
|
||||
=> msgcat 1.5.0
|
||||
|
||||
Many revisions to better support a Cygwin environment (nijtmans)
|
||||
|
||||
Dropped support for OS X versions less than 10.4 (Tiger) (fellows)
|
||||
|
||||
--- Released 8.6b3, September 18, 2012 --- See ChangeLog for details ---
|
||||
|
||||
2012-09-20 (enhancement) full Unicode support (nijtmans)
|
||||
=> dde 1.4.0
|
||||
|
||||
2012-09-20 (enhancement) update bundled zlib to 1.2.7 (nijtmans)
|
||||
|
||||
2012-10-03 (bug fix) exit panic on stacked std channel (griffin,porter)
|
||||
|
||||
2012-10-14 (bug fix) [tcl::Bgerror] crash on non-dict options (nijtmans)
|
||||
|
||||
2012-10-16 (TIP 400) New [zlib] options to set compression dict (fellows)
|
||||
|
||||
2012-10-16 (TIP 405) New commands [lmap] and [dict map] (fellows)
|
||||
|
||||
2012-10-24 (enhancement) [dict unset] now bytecompiled (fellows)
|
||||
|
||||
2012-11-05 (TIP 413) Revisions to default [string trim*] trimset (nijtmans)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
2012-11-05 (enhancement) Now bytecompiled: [array exists], [array set],
|
||||
[array unset], [dict create], [dict exists], [dict merge], [format],
|
||||
[info commands], [info coroutine], [info level], [info object],
|
||||
[namespace current], [namespace code], [namespace qualifiers], [namespace tail],
|
||||
[namespace which], [regsub], [self], [string first], [string last],
|
||||
[string map], [string range], [tailcall], [yield]. (fellows)
|
||||
|
||||
2012-11-06 (bug fix)[3581754] avoid multiple callback on keep-alive (fellows)
|
||||
=> http 2.8.5
|
||||
|
||||
2012-11-07 tzdata updated to Olson's tzdata2012i (kenny)
|
||||
|
||||
2012-11-13 (bug fix)[3567063] thread fp settings from master (mistachkin)
|
||||
|
||||
2012-11-14 (bug fix)[2933003] tempfile creation in $TMPDIR (fellows)
|
||||
|
||||
2012-11-15 (TIP 416) New [load] options -global and -lazy (nijtmans)
|
||||
|
||||
2012-11-20 (bug fix)[3033307] base64 trail whitespace (kovalenko,goth)
|
||||
|
||||
2012-12-03 (bug fix) [configure] query broke init from argv (porter)
|
||||
=> tcltest 2.3.5
|
||||
|
||||
2012-12-13 (bug fix)[3595576] crash: [catch {} -> noSuchNs::var] (sofer,porter)
|
||||
|
||||
2012-12-13 (bug fix) crash: [zlib gunzip $data -header noSuchNs::var] (porter)
|
||||
|
||||
--- Released 8.6.0, December 20, 2012 --- See ChangeLog for details ---
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#ifndef _DIRENT
|
||||
#define _DIRENT
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
/*
|
||||
* Dirent structure, which holds information about a single
|
||||
* directory entry.
|
||||
|
||||
@@ -26,8 +26,6 @@
|
||||
#ifndef __dlfcn_h__
|
||||
#define __dlfcn_h__
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#ifndef _STRING
|
||||
#define _STRING
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
/*
|
||||
* The following #include is needed to define size_t. (This used to include
|
||||
* sys/stdtypes.h but that doesn't exist on older versions of SunOS, e.g.
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#ifndef _UNISTD
|
||||
#define _UNISTD
|
||||
|
||||
#include "tcl.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef NULL
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4
-4
@@ -107,7 +107,7 @@ with the value of \fIcode\fR. The \fB(Tcl_Obj *)\fR returned
|
||||
by \fBTcl_GetReturnOptions\fR points to an unshared
|
||||
\fBTcl_Obj\fR with reference count of zero. The dictionary
|
||||
may be written to, either adding, removing, or overwriting
|
||||
any entries in it, without the need to check for a shared object.
|
||||
any entries in it, without the need to check for a shared value.
|
||||
As with any \fBTcl_Obj\fR with reference count of zero, it is up to
|
||||
the caller to arrange for its disposal with \fBTcl_DecrRefCount\fR or
|
||||
to a reference to it via \fBTcl_IncrRefCount\fR (or one of the many
|
||||
@@ -232,7 +232,7 @@ the need for a null byte. If the \fBTcl_AddObjErrorInfo\fR
|
||||
interface is used at all, it should be with a negative \fIlength\fR value.
|
||||
.PP
|
||||
The procedure \fBTcl_SetObjErrorCode\fR is used to set the
|
||||
\fB\-errorcode\fR return option to the list object \fIerrorObjPtr\fR
|
||||
\fB\-errorcode\fR return option to the list value \fIerrorObjPtr\fR
|
||||
built up by the caller.
|
||||
\fBTcl_SetObjErrorCode\fR is typically invoked just
|
||||
before returning an error. If an error is
|
||||
@@ -242,7 +242,7 @@ the \fB\-errorcode\fR return option to \fBNONE\fR.
|
||||
.PP
|
||||
The procedure \fBTcl_SetErrorCode\fR is also used to set the
|
||||
\fB\-errorcode\fR return option. However, it takes one or more strings to
|
||||
record instead of an object. Otherwise, it is similar to
|
||||
record instead of a value. Otherwise, it is similar to
|
||||
\fBTcl_SetObjErrorCode\fR in behavior.
|
||||
.PP
|
||||
\fBTcl_SetErrorCodeVA\fR is the same as \fBTcl_SetErrorCode\fR except that
|
||||
@@ -309,4 +309,4 @@ most recent error seen in an interpreter.
|
||||
Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_Interp(3), Tcl_ResetResult(3),
|
||||
Tcl_SetErrno(3), tclvars(n)
|
||||
.SH KEYWORDS
|
||||
error, object, object result, stack, trace, variable
|
||||
error, value, value result, stack, trace, variable
|
||||
|
||||
+2
-2
@@ -30,7 +30,7 @@ Points to the Tcl_Obj in which to store, or from which to
|
||||
retrieve a boolean value.
|
||||
.AP Tcl_Interp *interp in/out
|
||||
If a boolean value cannot be retrieved,
|
||||
an error message is left in the interpreter's result object
|
||||
an error message is left in the interpreter's result value
|
||||
unless \fIinterp\fR is NULL.
|
||||
.AP int *boolPtr out
|
||||
Points to place where \fBTcl_GetBooleanFromObj\fR
|
||||
@@ -92,4 +92,4 @@ a \fBTCL_ERROR\fR return.
|
||||
Tcl_NewObj, Tcl_IsShared, Tcl_GetBoolean
|
||||
|
||||
.SH KEYWORDS
|
||||
boolean, object
|
||||
boolean, value
|
||||
|
||||
+23
-23
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl objects as a arrays of bytes
|
||||
Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl values as a arrays of bytes
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -27,65 +27,65 @@ unsigned char *
|
||||
.SH ARGUMENTS
|
||||
.AS "const unsigned char" *lengthPtr in/out
|
||||
.AP "const unsigned char" *bytes in
|
||||
The array of bytes used to initialize or set a byte-array object. May be NULL
|
||||
The array of bytes used to initialize or set a byte-array value. May be NULL
|
||||
even if \fIlength\fR is non-zero.
|
||||
.AP int length in
|
||||
The length of the array of bytes. It must be >= 0.
|
||||
.AP Tcl_Obj *objPtr in/out
|
||||
For \fBTcl_SetByteArrayObj\fR, this points to the object to be converted to
|
||||
For \fBTcl_SetByteArrayObj\fR, this points to the value to be converted to
|
||||
byte-array type. For \fBTcl_GetByteArrayFromObj\fR and
|
||||
\fBTcl_SetByteArrayLength\fR, this points to the object from which to get
|
||||
\fBTcl_SetByteArrayLength\fR, this points to the value from which to get
|
||||
the byte-array value; if \fIobjPtr\fR does not already point to a byte-array
|
||||
object, it will be converted to one.
|
||||
value, it will be converted to one.
|
||||
.AP int *lengthPtr out
|
||||
If non-NULL, filled with the length of the array of bytes in the object.
|
||||
If non-NULL, filled with the length of the array of bytes in the value.
|
||||
.BE
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
These procedures are used to create, modify, and read Tcl byte-array objects
|
||||
from C code. Byte-array objects are typically used to hold the
|
||||
These procedures are used to create, modify, and read Tcl byte-array values
|
||||
from C code. Byte-array values are typically used to hold the
|
||||
results of binary IO operations or data structures created with the
|
||||
\fBbinary\fR command. In Tcl, an array of bytes is not equivalent to a
|
||||
string. Conceptually, a string is an array of Unicode characters, while a
|
||||
byte-array is an array of 8-bit quantities with no implicit meaning.
|
||||
Accessor functions are provided to get the string representation of a
|
||||
byte-array or to convert an arbitrary object to a byte-array. Obtaining the
|
||||
string representation of a byte-array object (by calling
|
||||
byte-array or to convert an arbitrary value to a byte-array. Obtaining the
|
||||
string representation of a byte-array value (by calling
|
||||
\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
|
||||
one-to-one mapping between the bytes in the internal representation and the
|
||||
UTF-8 characters in the string representation.
|
||||
.PP
|
||||
\fBTcl_NewByteArrayObj\fR and \fBTcl_SetByteArrayObj\fR will
|
||||
create a new object of byte-array type or modify an existing object to have a
|
||||
byte-array type. Both of these procedures set the object's type to be
|
||||
byte-array and set the object's internal representation to a copy of the
|
||||
create a new value of byte-array type or modify an existing value to have a
|
||||
byte-array type. Both of these procedures set the value's type to be
|
||||
byte-array and set the value's internal representation to a copy of the
|
||||
array of bytes given by \fIbytes\fR. \fBTcl_NewByteArrayObj\fR returns a
|
||||
pointer to a newly allocated object with a reference count of zero.
|
||||
pointer to a newly allocated value with a reference count of zero.
|
||||
\fBTcl_SetByteArrayObj\fR invalidates any old string representation and, if
|
||||
the object is not already a byte-array object, frees any old internal
|
||||
the value is not already a byte-array value, frees any old internal
|
||||
representation. If \fIbytes\fR is NULL then the new byte array contains
|
||||
arbitrary values.
|
||||
.PP
|
||||
\fBTcl_GetByteArrayFromObj\fR converts a Tcl object to byte-array type and
|
||||
returns a pointer to the object's new internal representation as an array of
|
||||
\fBTcl_GetByteArrayFromObj\fR converts a Tcl value to byte-array type and
|
||||
returns a pointer to the value's new internal representation as an array of
|
||||
bytes. The length of this array is stored in \fIlengthPtr\fR if
|
||||
\fIlengthPtr\fR is non-NULL. The storage for the array of bytes is owned by
|
||||
the object and should not be freed. The contents of the array may be
|
||||
modified by the caller only if the object is not shared and the caller
|
||||
the value and should not be freed. The contents of the array may be
|
||||
modified by the caller only if the value is not shared and the caller
|
||||
invalidates the string representation.
|
||||
.PP
|
||||
\fBTcl_SetByteArrayLength\fR converts the Tcl object to byte-array type
|
||||
and changes the length of the object's internal representation as an
|
||||
\fBTcl_SetByteArrayLength\fR converts the Tcl value to byte-array type
|
||||
and changes the length of the value's internal representation as an
|
||||
array of bytes. If \fIlength\fR is greater than the space currently
|
||||
allocated for the array, the array is reallocated to the new length; the
|
||||
newly allocated bytes at the end of the array have arbitrary values. If
|
||||
\fIlength\fR is less than the space currently allocated for the array,
|
||||
the length of array is reduced to the new length. The return value is a
|
||||
pointer to the object's new array of bytes.
|
||||
pointer to the value's new array of bytes.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
|
||||
|
||||
.SH KEYWORDS
|
||||
object, byte array, utf, unicode, internationalization
|
||||
value, binary data, byte array, utf, unicode, internationalization
|
||||
|
||||
+3
-3
@@ -250,8 +250,8 @@ the default value of 4096 is returned.
|
||||
.PP
|
||||
\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
|
||||
will be allocated in subsequent operations on the channel to store input or
|
||||
output. The \fIsize\fR argument should be between ten and one million,
|
||||
allowing buffers of ten bytes to one million bytes. If \fIsize\fR is
|
||||
output. The \fIsize\fR argument should be between one and one million,
|
||||
allowing buffers of one byte to one million bytes. If \fIsize\fR is
|
||||
outside this range, \fBTcl_SetChannelBufferSize\fR sets the buffer size to
|
||||
4096.
|
||||
.PP
|
||||
@@ -846,7 +846,7 @@ the generic options error message string.
|
||||
.PP
|
||||
It always returns \fBTCL_ERROR\fR
|
||||
.PP
|
||||
An error message is generated in \fIinterp\fR's result object to
|
||||
An error message is generated in \fIinterp\fR's result value to
|
||||
indicate that a command was invoked with a bad option.
|
||||
The message has the form
|
||||
.CS
|
||||
|
||||
+6
-6
@@ -41,18 +41,18 @@ will call \fIproc\fR to process the command.
|
||||
It differs from \fBTcl_CreateObjCommand\fR in that a new string-based
|
||||
command is defined;
|
||||
that is, a command procedure is defined that takes an array of
|
||||
argument strings instead of objects.
|
||||
The object-based command procedures registered by \fBTcl_CreateObjCommand\fR
|
||||
argument strings instead of values.
|
||||
The value-based command procedures registered by \fBTcl_CreateObjCommand\fR
|
||||
can execute significantly faster than the string-based command procedures
|
||||
defined by \fBTcl_CreateCommand\fR.
|
||||
This is because they take Tcl objects as arguments
|
||||
and those objects can retain an internal representation that
|
||||
This is because they take Tcl values as arguments
|
||||
and those values can retain an internal representation that
|
||||
can be manipulated more efficiently.
|
||||
Also, Tcl's interpreter now uses objects internally.
|
||||
Also, Tcl's interpreter now uses values internally.
|
||||
In order to invoke a string-based command procedure
|
||||
registered by \fBTcl_CreateCommand\fR,
|
||||
it must generate and fetch a string representation
|
||||
from each argument object before the call.
|
||||
from each argument value before the call.
|
||||
New commands should be defined using \fBTcl_CreateObjCommand\fR.
|
||||
We support \fBTcl_CreateCommand\fR for backwards compatibility.
|
||||
.PP
|
||||
|
||||
+9
-2
@@ -10,6 +10,13 @@
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_CreateMathFunc, Tcl_GetMathFuncInfo, Tcl_ListMathFuncs \- Define, query and enumerate math functions for expressions
|
||||
.SH "NOTICE OF EVENTUAL DEPRECATION"
|
||||
.PP
|
||||
The \fBTcl_CreateMathFunc\fR and \fBTcl_GetMathFuncInfo\fR functions
|
||||
are rendered somewhat obsolete by the ability to create functions for
|
||||
expressions by placing commands in the \fBtcl::mathfunc\fR namespace,
|
||||
as described in the \fBmathfunc\fR manual page; the API described on
|
||||
this page is not expected to be maintained indefinitely.
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -146,9 +153,9 @@ will not be modified. The variable pointed to by \fInumArgsPointer\fR
|
||||
will contain -1, and no argument types will be stored in the variable
|
||||
pointed to by \fIargTypesPointer\fR.
|
||||
.PP
|
||||
\fBTcl_ListMathFuncs\fR returns a Tcl object containing a list of all
|
||||
\fBTcl_ListMathFuncs\fR returns a Tcl value containing a list of all
|
||||
the math functions defined in the interpreter whose name matches
|
||||
\fIpattern\fR. The returned object has a reference count of zero.
|
||||
\fIpattern\fR. The returned value has a reference count of zero.
|
||||
.SH "SEE ALSO"
|
||||
expr(n), info(n), Tcl_CreateObjCommand(3), Tcl_Free(3), Tcl_NewListObj(3)
|
||||
.SH KEYWORDS
|
||||
|
||||
+10
-10
@@ -64,7 +64,7 @@ The command must not have been deleted.
|
||||
Pointer to structure containing various information about a
|
||||
Tcl command.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
Object containing the name of a Tcl command.
|
||||
Value containing the name of a Tcl command.
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -102,10 +102,10 @@ will be copies of the \fIclientData\fR and \fIinterp\fR arguments given to
|
||||
\fBTcl_CreateObjCommand\fR. Typically, \fIclientData\fR points to an
|
||||
application-specific data structure that describes what to do when the
|
||||
command procedure is invoked. \fIObjc\fR and \fIobjv\fR describe the
|
||||
arguments to the command, \fIobjc\fR giving the number of argument objects
|
||||
arguments to the command, \fIobjc\fR giving the number of argument values
|
||||
(including the command name) and \fIobjv\fR giving the values of the
|
||||
arguments. The \fIobjv\fR array will contain \fIobjc\fR values, pointing to
|
||||
the argument objects. Unlike \fIargv\fR[\fIargv\fR] used in a
|
||||
the argument values. Unlike \fIargv\fR[\fIargv\fR] used in a
|
||||
string-based command procedure, \fIobjv\fR[\fIobjc\fR] will not contain NULL.
|
||||
.PP
|
||||
Additionally, when \fIproc\fR is invoked, it must not modify the contents
|
||||
@@ -115,9 +115,9 @@ cause memory to be lost and the runtime stack to be corrupted. The
|
||||
\fBconst\fR in the declaration of \fIobjv\fR will cause ANSI-compliant
|
||||
compilers to report any such attempted assignment as an error. However,
|
||||
it is acceptable to modify the internal representation of any individual
|
||||
object argument. For instance, the user may call
|
||||
value argument. For instance, the user may call
|
||||
\fBTcl_GetIntFromObj\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
|
||||
representation of that object; that call may change the type of the object
|
||||
representation of that value; that call may change the type of the value
|
||||
that \fIobjv\fR[\fB2\fR] points at, but will not change where
|
||||
\fIobjv\fR[\fB2\fR] points.
|
||||
.PP
|
||||
@@ -133,7 +133,7 @@ of the command,
|
||||
and in the case of \fBTCL_ERROR\fR this gives an error message.
|
||||
Before invoking a command procedure,
|
||||
\fBTcl_EvalObjEx\fR sets interpreter's result to
|
||||
point to an object representing an empty string, so simple
|
||||
point to a value representing an empty string, so simple
|
||||
commands can return an empty result by doing nothing at all.
|
||||
.PP
|
||||
The contents of the \fIobjv\fR array belong to Tcl and are not
|
||||
@@ -225,7 +225,7 @@ if \fIisNativeObjectProc\fR has the value 1.
|
||||
The fields \fIobjProc\fR and \fIobjClientData\fR
|
||||
have the same meaning as the \fIproc\fR and \fIclientData\fR
|
||||
arguments to \fBTcl_CreateObjCommand\fR;
|
||||
they hold information about the object-based command procedure
|
||||
they hold information about the value-based command procedure
|
||||
that the Tcl interpreter calls to implement the command.
|
||||
The fields \fIproc\fR and \fIclientData\fR
|
||||
hold information about the string-based command procedure
|
||||
@@ -235,7 +235,7 @@ this is the procedure passed to it;
|
||||
otherwise, this is a compatibility procedure
|
||||
registered by \fBTcl_CreateObjCommand\fR
|
||||
that simply calls the command's
|
||||
object-based procedure after converting its string arguments to Tcl objects.
|
||||
value-based procedure after converting its string arguments to Tcl values.
|
||||
The field \fIdeleteData\fR is the ClientData value
|
||||
to pass to \fIdeleteProc\fR; it is normally the same as
|
||||
\fIclientData\fR but may be set independently using the
|
||||
@@ -290,7 +290,7 @@ they need to keep it for a long time.
|
||||
\fBTcl_GetCommandFullName\fR produces the fully qualified name
|
||||
of a command from a command token.
|
||||
The name, including all namespace prefixes,
|
||||
is appended to the object specified by \fIobjPtr\fR.
|
||||
is appended to the value specified by \fIobjPtr\fR.
|
||||
.PP
|
||||
\fBTcl_GetCommandFromObj\fR returns a token for the command
|
||||
specified by the name in a \fBTcl_Obj\fR.
|
||||
@@ -299,4 +299,4 @@ Returns NULL if the command is not found.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3)
|
||||
.SH KEYWORDS
|
||||
bind, command, create, delete, namespace, object
|
||||
bind, command, create, delete, namespace, value
|
||||
|
||||
+11
-11
@@ -78,10 +78,10 @@ Count of additional arguments to pass to the alias command.
|
||||
Vector of strings, the additional arguments to pass to the alias command.
|
||||
This storage is owned by the caller.
|
||||
.AP int objc in
|
||||
Count of additional object arguments to pass to the alias object command.
|
||||
Count of additional value arguments to pass to the aliased command.
|
||||
.AP Tcl_Obj **objv in
|
||||
Vector of Tcl_Obj structures, the additional object arguments to pass to
|
||||
the alias object command.
|
||||
Vector of Tcl_Obj structures, the additional value arguments to pass to
|
||||
the aliased command.
|
||||
This storage is owned by the caller.
|
||||
.AP Tcl_Interp **targetInterpPtr in
|
||||
Pointer to location to store the address of the interpreter where a target
|
||||
@@ -97,11 +97,11 @@ Pointer to location to store a vector of strings, the additional arguments
|
||||
to pass to an alias. The location is in storage owned by the caller, the
|
||||
vector of strings is owned by the called function.
|
||||
.AP int *objcPtr out
|
||||
Pointer to location to store count of additional object arguments to be
|
||||
Pointer to location to store count of additional value arguments to be
|
||||
passed to the alias. The location is in storage owned by the caller.
|
||||
.AP Tcl_Obj ***objvPtr out
|
||||
Pointer to location to store a vector of Tcl_Obj structures, the additional
|
||||
arguments to pass to an object alias command. The location is in storage
|
||||
arguments to pass to an alias command. The location is in storage
|
||||
owned by the caller, the vector of Tcl_Obj structures is owned by the
|
||||
called function.
|
||||
.AP "const char" *cmdName in
|
||||
@@ -165,13 +165,13 @@ of the relative path succeeds, \fBTCL_OK\fR is returned, else
|
||||
\fBTCL_ERROR\fR is returned and the \fIresult\fR field in
|
||||
\fIaskingInterp\fR contains the error message.
|
||||
.PP
|
||||
\fBTcl_CreateAlias\fR creates an object command named \fIslaveCmd\fR in
|
||||
\fBTcl_CreateAlias\fR creates a command named \fIslaveCmd\fR in
|
||||
\fIslaveInterp\fR that when invoked, will cause the command \fItargetCmd\fR
|
||||
to be invoked in \fItargetInterp\fR. The arguments specified by the strings
|
||||
contained in \fIargv\fR are always prepended to any arguments supplied in the
|
||||
invocation of \fIslaveCmd\fR and passed to \fItargetCmd\fR.
|
||||
This operation returns \fBTCL_OK\fR if it succeeds, or \fBTCL_ERROR\fR if
|
||||
it fails; in that case, an error message is left in the object result
|
||||
it fails; in that case, an error message is left in the value result
|
||||
of \fIslaveInterp\fR.
|
||||
Note that there are no restrictions on the ancestry relationship (as
|
||||
created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
|
||||
@@ -179,7 +179,7 @@ created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
|
||||
restrictions on how they are related.
|
||||
.PP
|
||||
\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
|
||||
that it takes a vector of objects to pass as additional arguments instead
|
||||
that it takes a vector of values to pass as additional arguments instead
|
||||
of a vector of strings.
|
||||
.PP
|
||||
\fBTcl_GetAlias\fR returns information about an alias \fIaliasName\fR
|
||||
@@ -202,7 +202,7 @@ command, or the operation will return \fBTCL_ERROR\fR and leave an error
|
||||
message in the \fIresult\fR field in \fIinterp\fR.
|
||||
If an exposed command named \fIcmdName\fR already exists,
|
||||
the operation returns \fBTCL_ERROR\fR and leaves an error message in the
|
||||
object result of \fIinterp\fR.
|
||||
value result of \fIinterp\fR.
|
||||
If the operation succeeds, it returns \fBTCL_OK\fR.
|
||||
After executing this command, attempts to use \fIcmdName\fR in a call to
|
||||
\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will again succeed.
|
||||
@@ -212,10 +212,10 @@ exposed commands to the set of hidden commands, under the name
|
||||
\fIhiddenCmdName\fR.
|
||||
\fICmdName\fR must be the name of an existing exposed
|
||||
command, or the operation will return \fBTCL_ERROR\fR and leave an error
|
||||
message in the object result of \fIinterp\fR.
|
||||
message in the value result of \fIinterp\fR.
|
||||
Currently both \fIcmdName\fR and \fIhiddenCmdName\fR must not contain
|
||||
namespace qualifiers, or the operation will return \fBTCL_ERROR\fR and
|
||||
leave an error message in the object result of \fIinterp\fR.
|
||||
leave an error message in the value result of \fIinterp\fR.
|
||||
The \fICmdName\fR will be looked up in the global namespace, and not
|
||||
relative to the current namespace, even if the current namespace is not the
|
||||
global one.
|
||||
|
||||
+16
-16
@@ -9,7 +9,7 @@
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl objects as dictionaries
|
||||
Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl values as dictionaries
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -47,23 +47,23 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS Tcl_DictSearch "**valuePtrPtr" in/out
|
||||
.AP Tcl_Interp *interp in
|
||||
If an error occurs while converting an object to be a dictionary object,
|
||||
an error message is left in the interpreter's result object
|
||||
If an error occurs while converting a value to be a dictionary value,
|
||||
an error message is left in the interpreter's result value
|
||||
unless \fIinterp\fR is NULL.
|
||||
.AP Tcl_Obj *dictPtr in/out
|
||||
Points to the dictionary object to be manipulated.
|
||||
If \fIdictPtr\fR does not already point to a dictionary object,
|
||||
Points to the dictionary value to be manipulated.
|
||||
If \fIdictPtr\fR does not already point to a dictionary value,
|
||||
an attempt will be made to convert it to one.
|
||||
.AP Tcl_Obj *keyPtr in
|
||||
Points to the key for the key/value pair being manipulated within the
|
||||
dictionary object.
|
||||
dictionary value.
|
||||
.AP Tcl_Obj **keyPtrPtr out
|
||||
Points to a variable that will have the key from a key/value pair
|
||||
placed within it. May be NULL to indicate that the caller is not
|
||||
interested in the key.
|
||||
.AP Tcl_Obj *valuePtr in
|
||||
Points to the value for the key/value pair being manipulated within the
|
||||
dictionary object (or sub-object, in the case of
|
||||
dictionary value (or sub-value, in the case of
|
||||
\fBTcl_DictObjPutKeyList\fR.)
|
||||
.AP Tcl_Obj **valuePtrPtr out
|
||||
Points to a variable that will have the value from a key/value pair
|
||||
@@ -88,15 +88,15 @@ completed, and a zero otherwise.
|
||||
Indicates the number of keys that will be supplied in the \fIkeyv\fR
|
||||
array.
|
||||
.AP "Tcl_Obj *const" *keyv in
|
||||
Array of \fIkeyc\fR pointers to objects that
|
||||
Array of \fIkeyc\fR pointers to values that
|
||||
\fBTcl_DictObjPutKeyList\fR and \fBTcl_DictObjRemoveKeyList\fR will
|
||||
use to locate the key/value pair to manipulate within the
|
||||
sub-dictionaries of the main dictionary object passed to them.
|
||||
sub-dictionaries of the main dictionary value passed to them.
|
||||
.BE
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Tcl dictionary objects have an internal representation that supports
|
||||
Tcl dictionary values have an internal representation that supports
|
||||
efficient mapping from keys to values and which guarantees that the
|
||||
particular ordering of keys within the dictionary remains the same
|
||||
modulo any keys being deleted (which removes them from the order) or
|
||||
@@ -106,11 +106,11 @@ keys of the dictionary, and each will be followed (in the odd-valued
|
||||
index) by the value associated with that key.
|
||||
.PP
|
||||
The procedures described in this man page are used to
|
||||
create, modify, index, and iterate over dictionary objects from C code.
|
||||
create, modify, index, and iterate over dictionary values from C code.
|
||||
.PP
|
||||
\fBTcl_NewDictObj\fR creates a new, empty dictionary object. The
|
||||
string representation of the object will be invalid, and the reference
|
||||
count of the object will be zero.
|
||||
\fBTcl_NewDictObj\fR creates a new, empty dictionary value. The
|
||||
string representation of the value will be invalid, and the reference
|
||||
count of the value will be zero.
|
||||
.PP
|
||||
\fBTcl_DictObjGet\fR looks up the given key within the given
|
||||
dictionary and writes a pointer to the value associated with that key
|
||||
@@ -217,7 +217,7 @@ if (\fBTcl_DictObjFirst\fR(interp, objPtr, &search,
|
||||
for (; !done ; \fBTcl_DictObjNext\fR(&search, &key, &value, &done)) {
|
||||
/*
|
||||
* Note that strcmp() is not a good way of comparing
|
||||
* objects and is just used here for demonstration
|
||||
* values and is just used here for demonstration
|
||||
* purposes.
|
||||
*/
|
||||
if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) {
|
||||
@@ -231,4 +231,4 @@ return TCL_OK;
|
||||
.SH "SEE ALSO"
|
||||
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
|
||||
.SH KEYWORDS
|
||||
dict, dict object, dictionary, dictionary object, hash table, iteration, object
|
||||
dict, dict value, dictionary, dictionary value, hash table, iteration, value
|
||||
|
||||
+13
-13
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl objects as floating-point values
|
||||
Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl values as floating-point values
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -23,11 +23,11 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS Tcl_Interp doubleValue in/out
|
||||
.AP double doubleValue in
|
||||
A double-precision floating-point value used to initialize or set a Tcl object.
|
||||
A double-precision floating-point value used to initialize or set a Tcl value.
|
||||
.AP Tcl_Obj *objPtr in/out
|
||||
For \fBTcl_SetDoubleObj\fR, this points to the object in which to store a
|
||||
For \fBTcl_SetDoubleObj\fR, this points to the value in which to store a
|
||||
double value.
|
||||
For \fBTcl_GetDoubleFromObj\fR, this refers to the object
|
||||
For \fBTcl_GetDoubleFromObj\fR, this refers to the value
|
||||
from which to retrieve a double value.
|
||||
.AP Tcl_Interp *interp in/out
|
||||
When non-NULL, an error message is left here when double value retrieval fails.
|
||||
@@ -37,21 +37,21 @@ Points to place to store the double value obtained from \fIobjPtr\fR.
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
These procedures are used to create, modify, and read Tcl objects that
|
||||
These procedures are used to create, modify, and read Tcl values that
|
||||
hold double-precision floating-point values.
|
||||
.PP
|
||||
\fBTcl_NewDoubleObj\fR creates and returns a new Tcl object initialized to
|
||||
the double value \fIdoubleValue\fR. The returned Tcl object is unshared.
|
||||
\fBTcl_NewDoubleObj\fR creates and returns a new Tcl value initialized to
|
||||
the double value \fIdoubleValue\fR. The returned Tcl value is unshared.
|
||||
.PP
|
||||
\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl object pointed to
|
||||
\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl value pointed to
|
||||
by \fIobjPtr\fR to the double value \fIdoubleValue\fR. The \fIobjPtr\fR
|
||||
argument must point to an unshared Tcl object. Any attempt to set the value
|
||||
of a shared Tcl object violates Tcl's copy-on-write policy. Any existing
|
||||
string representation or internal representation in the unshared Tcl object
|
||||
argument must point to an unshared Tcl value. Any attempt to set the value
|
||||
of a shared Tcl value violates Tcl's copy-on-write policy. Any existing
|
||||
string representation or internal representation in the unshared Tcl value
|
||||
will be freed as a consequence of setting the new value.
|
||||
.PP
|
||||
\fBTcl_GetDoubleFromObj\fR attempts to retrieve a double value from the
|
||||
Tcl object \fIobjPtr\fR. If the attempt succeeds, then \fBTCL_OK\fR is
|
||||
Tcl value \fIobjPtr\fR. If the attempt succeeds, then \fBTCL_OK\fR is
|
||||
returned, and the double value is written to the storage pointed to by
|
||||
\fIdoublePtr\fR. If the attempt fails, then \fBTCL_ERROR\fR is returned,
|
||||
and if \fIinterp\fR is non-NULL, an error message is left in \fIinterp\fR.
|
||||
@@ -61,4 +61,4 @@ calls to \fBTcl_GetDoubleFromObj\fR more efficient.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
|
||||
.SH KEYWORDS
|
||||
double, double object, double type, internal representation, object, object type, string representation
|
||||
double, double value, double type, internal representation, value, value type, string representation
|
||||
|
||||
+10
-10
@@ -47,17 +47,17 @@ int
|
||||
Interpreter in which to execute the script. The interpreter's result is
|
||||
modified to hold the result or error message from the script.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
A Tcl object containing the script to execute.
|
||||
A Tcl value containing the script to execute.
|
||||
.AP int flags in
|
||||
ORed combination of flag bits that specify additional options.
|
||||
\fBTCL_EVAL_GLOBAL\fR and \fBTCL_EVAL_DIRECT\fR are currently supported.
|
||||
.AP "const char" *fileName in
|
||||
Name of a file containing a Tcl script.
|
||||
.AP int objc in
|
||||
The number of objects in the array pointed to by \fIobjPtr\fR;
|
||||
The number of values in the array pointed to by \fIobjPtr\fR;
|
||||
this is also the number of words in the command.
|
||||
.AP Tcl_Obj **objv in
|
||||
Points to an array of pointers to objects; each object holds the
|
||||
Points to an array of pointers to values; each value holds the
|
||||
value of a single word in the command to execute.
|
||||
.AP int numBytes in
|
||||
The number of bytes in \fIscript\fR, not including any
|
||||
@@ -83,7 +83,7 @@ If this is the first time \fIobjPtr\fR has been executed,
|
||||
its commands are compiled into bytecode instructions
|
||||
which are then executed. The
|
||||
bytecodes are saved in \fIobjPtr\fR so that the compilation step
|
||||
can be skipped if the object is evaluated again in the future.
|
||||
can be skipped if the value is evaluated again in the future.
|
||||
.PP
|
||||
The return value from \fBTcl_EvalObjEx\fR (and all the other procedures
|
||||
described here) is a Tcl completion code with
|
||||
@@ -111,15 +111,15 @@ which will be safely substituted by the Tcl interpreter into
|
||||
.PP
|
||||
\fBTcl_EvalObjv\fR executes a single pre-parsed command instead of a
|
||||
script. The \fIobjc\fR and \fIobjv\fR arguments contain the values
|
||||
of the words for the Tcl command, one word in each object in
|
||||
of the words for the Tcl command, one word in each value in
|
||||
\fIobjv\fR. \fBTcl_EvalObjv\fR evaluates the command and returns
|
||||
a completion code and result just like \fBTcl_EvalObjEx\fR.
|
||||
The caller of \fBTcl_EvalObjv\fR has to manage the reference count of the
|
||||
elements of \fIobjv\fR, insuring that the objects are valid until
|
||||
elements of \fIobjv\fR, insuring that the values are valid until
|
||||
\fBTcl_EvalObjv\fR returns.
|
||||
.PP
|
||||
\fBTcl_Eval\fR is similar to \fBTcl_EvalObjEx\fR except that the script to
|
||||
be executed is supplied as a string instead of an object and no compilation
|
||||
be executed is supplied as a string instead of a value and no compilation
|
||||
occurs. The string should be a proper UTF-8 string as converted by
|
||||
\fBTcl_ExternalToUtfDString\fR or \fBTcl_ExternalToUtf\fR when it is known
|
||||
to possibly contain upper ASCII characters whose possible combinations
|
||||
@@ -129,7 +129,7 @@ bytecodes. In situations where it is known that the script will never be
|
||||
executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
|
||||
\fBTcl_Eval\fR returns a completion code and result just like
|
||||
\fBTcl_EvalObjEx\fR. Note: for backward compatibility with versions before
|
||||
Tcl 8.0, \fBTcl_Eval\fR copies the object result in \fIinterp\fR to
|
||||
Tcl 8.0, \fBTcl_Eval\fR copies the value result in \fIinterp\fR to
|
||||
\fIinterp->result\fR (use is deprecated) where it can be accessed directly.
|
||||
This makes \fBTcl_Eval\fR somewhat slower than \fBTcl_EvalEx\fR, which
|
||||
does not do the copy.
|
||||
@@ -170,7 +170,7 @@ other procedures. If this flag bit is set, the script is not
|
||||
compiled to bytecodes; instead it is executed directly
|
||||
as is done by \fBTcl_EvalEx\fR. The
|
||||
\fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
|
||||
contents of an object are going to change immediately, so the
|
||||
contents of a value are going to change immediately, so the
|
||||
bytecodes will not be reused in a future execution. In this case,
|
||||
it is faster to execute the script directly.
|
||||
.TP 23
|
||||
@@ -208,4 +208,4 @@ This means that top-level applications should never see a return code
|
||||
from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.
|
||||
|
||||
.SH KEYWORDS
|
||||
execute, file, global, object, result, script
|
||||
execute, file, global, result, script, value
|
||||
|
||||
+4
-4
@@ -49,11 +49,11 @@ given by the \fIexpr\fR argument
|
||||
and return the result in one of four different forms.
|
||||
The expression can have any of the forms accepted by the \fBexpr\fR command.
|
||||
Note that these procedures have been largely replaced by the
|
||||
object-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
|
||||
value-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
|
||||
\fBTcl_ExprBooleanObj\fR, and \fBTcl_ExprObj\fR.
|
||||
Those object-based procedures evaluate an expression held in a Tcl object
|
||||
Those value-based procedures evaluate an expression held in a Tcl value
|
||||
instead of a string.
|
||||
The object argument can retain an internal representation
|
||||
The value argument can retain an internal representation
|
||||
that is more efficient to execute.
|
||||
.PP
|
||||
The \fIinterp\fR argument refers to an interpreter used to
|
||||
@@ -103,4 +103,4 @@ string stored in the interpreter's result.
|
||||
Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj
|
||||
|
||||
.SH KEYWORDS
|
||||
boolean, double, evaluate, expression, integer, object, string
|
||||
boolean, double, evaluate, expression, integer, value, string
|
||||
|
||||
+6
-6
@@ -29,7 +29,7 @@ int
|
||||
.AP Tcl_Interp *interp in
|
||||
Interpreter in whose context to evaluate \fIobjPtr\fR.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
Pointer to an object containing the expression to evaluate.
|
||||
Pointer to a value containing the expression to evaluate.
|
||||
.AP long *longPtr out
|
||||
Pointer to location in which to store the integer value of the
|
||||
expression.
|
||||
@@ -40,7 +40,7 @@ expression.
|
||||
Pointer to location in which to store the 0/1 boolean value of the
|
||||
expression.
|
||||
.AP Tcl_Obj **resultPtrPtr out
|
||||
Pointer to location in which to store a pointer to the object
|
||||
Pointer to location in which to store a pointer to the value
|
||||
that is the result of the expression.
|
||||
.BE
|
||||
|
||||
@@ -93,14 +93,14 @@ or
|
||||
or else an error occurs.
|
||||
.PP
|
||||
If \fBTcl_ExprObj\fR successfully evaluates the expression,
|
||||
it stores a pointer to the Tcl object
|
||||
it stores a pointer to the Tcl value
|
||||
containing the expression's value at \fI*resultPtrPtr\fR.
|
||||
In this case, the caller is responsible for calling
|
||||
\fBTcl_DecrRefCount\fR to decrement the object's reference count
|
||||
when it is finished with the object.
|
||||
\fBTcl_DecrRefCount\fR to decrement the value's reference count
|
||||
when it is finished with the value.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString, Tcl_GetObjResult
|
||||
|
||||
.SH KEYWORDS
|
||||
boolean, double, evaluate, expression, integer, object, string
|
||||
boolean, double, evaluate, expression, integer, value, string
|
||||
|
||||
+65
-64
@@ -86,7 +86,7 @@ int
|
||||
int
|
||||
\fBTcl_FSFileAttrsSet\fR(\fIinterp, int index, pathPtr, Tcl_Obj *objPtr\fR)
|
||||
.sp
|
||||
const char **
|
||||
const char *const *
|
||||
\fBTcl_FSFileAttrStrings\fR(\fIpathPtr, objPtrRef\fR)
|
||||
.sp
|
||||
int
|
||||
@@ -192,8 +192,8 @@ int
|
||||
Points to a structure containing the addresses of procedures that
|
||||
can be called to perform the various filesystem operations.
|
||||
.AP Tcl_Obj *pathPtr in
|
||||
The path represented by this object is used for the operation in
|
||||
question. If the object does not already have an internal \fBpath\fR
|
||||
The path represented by this value is used for the operation in
|
||||
question. If the value does not already have an internal \fBpath\fR
|
||||
representation, it will be converted to have one.
|
||||
.AP Tcl_Obj *srcPathPtr in
|
||||
As for \fIpathPtr\fR, but used for the source file for a copy or
|
||||
@@ -213,12 +213,12 @@ this structure will be returned. This parameter may be NULL.
|
||||
Interpreter to use either for results, evaluation, or reporting error
|
||||
messages.
|
||||
.AP ClientData clientData in
|
||||
The native description of the path object to create.
|
||||
The native description of the path value to create.
|
||||
.AP Tcl_Obj *firstPtr in
|
||||
The first of two path objects to compare. The object may be converted
|
||||
The first of two path values to compare. The value may be converted
|
||||
to \fBpath\fR type.
|
||||
.AP Tcl_Obj *secondPtr in
|
||||
The second of two path objects to compare. The object may be converted
|
||||
The second of two path values to compare. The value may be converted
|
||||
to \fBpath\fR type.
|
||||
.AP Tcl_Obj *listObj in
|
||||
The list of path elements to operate on with a \fBjoin\fR operation.
|
||||
@@ -226,12 +226,12 @@ The list of path elements to operate on with a \fBjoin\fR operation.
|
||||
If non-negative, the number of elements in the \fIlistObj\fR which should
|
||||
be joined together. If negative, then all elements are joined.
|
||||
.AP Tcl_Obj **errorPtr out
|
||||
In the case of an error, filled with an object containing the name of
|
||||
In the case of an error, filled with a value containing the name of
|
||||
the file which caused an error in the various copy/rename operations.
|
||||
.AP Tcl_Obj **objPtrRef out
|
||||
Filled with an object containing the result of the operation.
|
||||
Filled with a value containing the result of the operation.
|
||||
.AP Tcl_Obj *resultPtr out
|
||||
Pre-allocated object in which to store (using
|
||||
Pre-allocated value in which to store (using
|
||||
\fBTcl_ListObjAppendElement\fR) the list of
|
||||
files or directories which are successfully matched.
|
||||
.AP int mode in
|
||||
@@ -331,17 +331,17 @@ buffer is actually
|
||||
declared to be, allowing the same code to be used both on systems with
|
||||
and systems without support for files larger than 2GB in size.
|
||||
.PP
|
||||
The \fBTcl_FS\fR API is objectified and may cache internal
|
||||
The \fBTcl_FS\fR API is \fBTcl_Obj\fR-ified and may cache internal
|
||||
representations and other path-related strings (e.g.\ the current working
|
||||
directory). One side-effect of this is that one must not pass in objects
|
||||
directory). One side-effect of this is that one must not pass in values
|
||||
with a reference count of zero to any of these functions. If such calls were
|
||||
handled, they might result
|
||||
in memory leaks (under some circumstances, the filesystem code may wish
|
||||
to retain a reference to the passed in object, and so one must not assume
|
||||
that after any of these calls return, the object still has a reference count of
|
||||
to retain a reference to the passed in value, and so one must not assume
|
||||
that after any of these calls return, the value still has a reference count of
|
||||
zero - it may have been incremented) or in a direct segmentation fault
|
||||
(or other memory access error)
|
||||
due to the object being freed part way through the complex object
|
||||
due to the value being freed part way through the complex value
|
||||
manipulation required to ensure that the path is fully normalized and
|
||||
absolute for filesystem determination. The practical lesson to learn
|
||||
from this is that
|
||||
@@ -354,9 +354,9 @@ Tcl_DecrRefCount(path);
|
||||
.PP
|
||||
is wrong, and may cause memory errors. The \fIpath\fR must have its
|
||||
reference count incremented before passing it in, or
|
||||
decrementing it. For this reason, objects with a reference count of zero are
|
||||
decrementing it. For this reason, values with a reference count of zero are
|
||||
considered not to be valid filesystem paths and calling any Tcl_FS API
|
||||
function with such an object will result in no action being taken.
|
||||
function with such a value will result in no action being taken.
|
||||
.SS "FS API FUNCTIONS"
|
||||
\fBTcl_FSCopyFile\fR attempts to copy the file given by \fIsrcPathPtr\fR to the
|
||||
path name given by \fIdestPathPtr\fR. If the two paths given lie in the same
|
||||
@@ -484,7 +484,7 @@ If the \fItoPtr\fR is NULL, a
|
||||
action is performed. The result
|
||||
is a Tcl_Obj specifying the contents of the symbolic link given by
|
||||
\fIlinkNamePtr\fR, or NULL if the link could not be read. The result is owned
|
||||
by the caller, which should call Tcl_DecrRefCount when the result is no
|
||||
by the caller, which should call \fBTcl_DecrRefCount\fR when the result is no
|
||||
longer needed. If the \fItoPtr\fR is not NULL, Tcl should create a link
|
||||
of one of the types passed in in the \fIlinkAction\fR flag. This flag is
|
||||
an ORed combination of \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR.
|
||||
@@ -523,7 +523,7 @@ values of the file given.
|
||||
attributes\fR subcommand. The appropriate function for the filesystem to
|
||||
which \fIpathPtr\fR belongs will be called.
|
||||
.PP
|
||||
If the result is \fBTCL_OK\fR, then an object was placed in
|
||||
If the result is \fBTCL_OK\fR, then a value was placed in
|
||||
\fIobjPtrRef\fR, which
|
||||
will only be temporarily valid (unless \fBTcl_IncrRefCount\fR is called).
|
||||
.PP
|
||||
@@ -541,7 +541,7 @@ will take that list and first increment its reference count before using it.
|
||||
On completion of that use, Tcl will decrement its reference count. Hence if
|
||||
the list should be disposed of by Tcl when done, it should have a
|
||||
reference count of zero, and if the list should not be disposed of, the
|
||||
filesystem should ensure it retains a reference count to the object.
|
||||
filesystem should ensure it retains a reference count to the value.
|
||||
.PP
|
||||
\fBTcl_FSAccess\fR checks whether the process would be allowed to read,
|
||||
write or test for existence of the file (or other filesystem object)
|
||||
@@ -622,29 +622,29 @@ The separator is returned as a Tcl_Obj containing a string of length
|
||||
.PP
|
||||
\fBTcl_FSJoinPath\fR takes the given Tcl_Obj, which must be a valid
|
||||
list (which is allowed to have a reference count of zero), and returns the path
|
||||
object given by considering the first \fIelements\fR elements as valid path
|
||||
value given by considering the first \fIelements\fR elements as valid path
|
||||
segments (each path segment may be a complete path, a partial path or
|
||||
just a single possible directory or file name). If any path segment is
|
||||
actually an absolute path, then all prior path segments are discarded.
|
||||
If \fIelements\fR is less than 0, we use the entire list.
|
||||
.PP
|
||||
It is possible that the returned object is actually an element
|
||||
It is possible that the returned value is actually an element
|
||||
of the given list, so the caller should be careful to increment the
|
||||
reference count of the result before freeing the list.
|
||||
.PP
|
||||
The returned object, typically with a reference count of zero (but it
|
||||
The returned value, typically with a reference count of zero (but it
|
||||
could be shared
|
||||
under some conditions), contains the joined path. The caller must
|
||||
add a reference count to the object before using it. In particular, the
|
||||
returned object could be an element of the given list, so freeing the
|
||||
list might free the object prematurely if no reference count has been taken.
|
||||
If the number of elements is zero, then the returned object will be
|
||||
add a reference count to the value before using it. In particular, the
|
||||
returned value could be an element of the given list, so freeing the
|
||||
list might free the value prematurely if no reference count has been taken.
|
||||
If the number of elements is zero, then the returned value will be
|
||||
an empty-string Tcl_Obj.
|
||||
.PP
|
||||
\fBTcl_FSSplitPath\fR takes the given Tcl_Obj, which should be a valid path,
|
||||
and returns a Tcl list object containing each segment of that path as
|
||||
and returns a Tcl list value containing each segment of that path as
|
||||
an element.
|
||||
It returns a list object with a reference count of zero. If the
|
||||
It returns a list value with a reference count of zero. If the
|
||||
passed in \fIlenPtr\fR is non-NULL, the variable it points to will be
|
||||
updated to contain the number of elements in the returned list.
|
||||
.PP
|
||||
@@ -657,7 +657,7 @@ either path is NULL, 0 is always returned.
|
||||
from the given Tcl_Obj a unique normalized path representation, whose
|
||||
string value can be used as a unique identifier for the file.
|
||||
.PP
|
||||
It returns the normalized path object, owned by Tcl, or NULL if the path
|
||||
It returns the normalized path value, owned by Tcl, or NULL if the path
|
||||
was invalid or could otherwise not be successfully converted.
|
||||
Extraction of absolute, normalized paths is very efficient (because the
|
||||
filesystem operates on these representations internally), although the
|
||||
@@ -665,35 +665,36 @@ result when the filesystem contains numerous symbolic links may not be
|
||||
the most user-friendly version of a path. The return value is owned by
|
||||
Tcl and has a lifetime equivalent to that of the \fIpathPtr\fR passed in
|
||||
(unless that is a relative path, in which case the normalized path
|
||||
object may be freed any time the cwd changes) - the caller can of
|
||||
course increment the refCount if it wishes to maintain a copy for longer.
|
||||
value may be freed any time the cwd changes) - the caller can of
|
||||
course increment the reference count if it wishes to maintain a copy for longer.
|
||||
.PP
|
||||
\fBTcl_FSJoinToPath\fR takes the given object, which should usually be a
|
||||
\fBTcl_FSJoinToPath\fR takes the given value, which should usually be a
|
||||
valid path or NULL, and joins onto it the array of paths segments
|
||||
given.
|
||||
.PP
|
||||
Returns object, typically with refCount of zero (but it could be shared
|
||||
Returns a value, typically with reference count of zero (but it could be shared
|
||||
under some conditions), containing the joined path. The caller must
|
||||
add a refCount to the object before using it. If any of the objects
|
||||
passed into this function (pathPtr or path elements) have a refCount
|
||||
add a reference count to the value before using it. If any of the values
|
||||
passed into this function (\fIpathPtr\fR or \fIpath\fR elements) have
|
||||
a reference count
|
||||
of zero, they will be freed when this function returns.
|
||||
.PP
|
||||
\fBTcl_FSConvertToPathType\fR tries to convert the given Tcl_Obj to a valid
|
||||
Tcl path type, taking account of the fact that the cwd may have changed
|
||||
even if this object is already supposedly of the correct type.
|
||||
even if this value is already supposedly of the correct type.
|
||||
The filename may begin with
|
||||
.QW ~
|
||||
(to indicate current user's home directory) or
|
||||
.QW ~<user>
|
||||
(to indicate any user's home directory).
|
||||
.PP
|
||||
If the conversion succeeds (i.e.\ the object is a valid path in one of
|
||||
If the conversion succeeds (i.e.\ the value is a valid path in one of
|
||||
the current filesystems), then \fBTCL_OK\fR is returned. Otherwise
|
||||
\fBTCL_ERROR\fR is returned, and an error message may
|
||||
be left in the interpreter.
|
||||
.PP
|
||||
\fBTcl_FSGetInternalRep\fR extracts the internal representation of a given
|
||||
path object, in the given filesystem. If the path object belongs to a
|
||||
path value, in the given filesystem. If the path value belongs to a
|
||||
different filesystem, we return NULL. If the internal representation is
|
||||
currently NULL, we attempt to generate it, by calling the filesystem's
|
||||
\fBTcl_FSCreateInternalRepProc\fR.
|
||||
@@ -705,7 +706,7 @@ not require additional conversions.
|
||||
\fBTcl_FSGetTranslatedPath\fR attempts to extract the translated path
|
||||
from the given Tcl_Obj.
|
||||
.PP
|
||||
If the translation succeeds (i.e.\ the object is a valid path), then it is
|
||||
If the translation succeeds (i.e.\ the value is a valid path), then it is
|
||||
returned. Otherwise NULL will be returned, and an error message may be
|
||||
left in the interpreter. A
|
||||
.QW translated
|
||||
@@ -714,8 +715,8 @@ path is one which contains no
|
||||
or
|
||||
.QW ~user
|
||||
sequences (these have been expanded to their current
|
||||
representation in the filesystem). The object returned is owned by the
|
||||
caller, which must store it or call Tcl_DecrRefCount to ensure memory is
|
||||
representation in the filesystem). The value returned is owned by the
|
||||
caller, which must store it or call \fBTcl_DecrRefCount\fR to ensure memory is
|
||||
freed. This function is of little practical use, and
|
||||
\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
|
||||
better functions to use for most purposes.
|
||||
@@ -731,11 +732,11 @@ better functions to use for most purposes.
|
||||
usual obj->path->nativerep conversions. If some code retrieves a path
|
||||
in native form (from, e.g.\ \fBreadlink\fR or a native dialog), and that path
|
||||
is to be used at the Tcl level, then calling this function is an
|
||||
efficient way of creating the appropriate path object type.
|
||||
efficient way of creating the appropriate path value type.
|
||||
.PP
|
||||
The resulting object is a pure
|
||||
The resulting value is a pure
|
||||
.QW path
|
||||
object, which will only receive
|
||||
value, which will only receive
|
||||
a UTF-8 string representation if that is required by some Tcl code.
|
||||
.PP
|
||||
\fBTcl_FSGetNativePath\fR is for use by the Win/Unix native
|
||||
@@ -773,7 +774,7 @@ given path within that filesystem (which is filesystem dependent). The
|
||||
second element may be empty if the filesystem does not provide a
|
||||
further categorization of files.
|
||||
.PP
|
||||
A valid list object is returned, unless the path object is not
|
||||
A valid list value is returned, unless the path value is not
|
||||
recognized, when NULL will be returned.
|
||||
.PP
|
||||
\fBTcl_FSGetFileSystemForPath\fR returns a pointer to the
|
||||
@@ -1001,14 +1002,14 @@ The \fIversion\fR field should be set to \fBTCL_FILESYSTEM_VERSION_1\fR.
|
||||
.SS PATHINFILESYSTEMPROC
|
||||
.PP
|
||||
The \fIpathInFilesystemProc\fR field contains the address of a function
|
||||
which is called to determine whether a given path object belongs to this
|
||||
which is called to determine whether a given path value belongs to this
|
||||
filesystem or not. Tcl will only call the rest of the filesystem
|
||||
functions with a path for which this function has returned \fBTCL_OK\fR.
|
||||
If the path does not belong, -1 should be returned (the behavior of Tcl
|
||||
for any other return value is not defined). If \fBTCL_OK\fR is returned,
|
||||
then the optional \fIclientDataPtr\fR output parameter can be used to
|
||||
return an internal (filesystem specific) representation of the path,
|
||||
which will be cached inside the path object, and may be retrieved
|
||||
which will be cached inside the path value, and may be retrieved
|
||||
efficiently by the other filesystem functions. Tcl will simultaneously
|
||||
cache the fact that this path belongs to this filesystem. Such caches
|
||||
are invalidated when filesystem structures are added or removed from
|
||||
@@ -1022,7 +1023,7 @@ typedef int \fBTcl_FSPathInFilesystemProc\fR(
|
||||
.SS DUPINTERNALREPPROC
|
||||
.PP
|
||||
This function makes a copy of a path's internal representation, and is
|
||||
called when Tcl needs to duplicate a path object. If NULL, Tcl will
|
||||
called when Tcl needs to duplicate a path value. If NULL, Tcl will
|
||||
simply not copy the internal representation, which may then need to be
|
||||
regenerated later.
|
||||
.PP
|
||||
@@ -1042,8 +1043,8 @@ typedef void \fBTcl_FSFreeInternalRepProc\fR(
|
||||
.SS INTERNALTONORMALIZEDPROC
|
||||
.PP
|
||||
Function to convert internal representation to a normalized path. Only
|
||||
required if the filesystem creates pure path objects with no string/path
|
||||
representation. The return value is a Tcl object whose string
|
||||
required if the filesystem creates pure path values with no string/path
|
||||
representation. The return value is a Tcl value whose string
|
||||
representation is the normalized path.
|
||||
.PP
|
||||
.CS
|
||||
@@ -1052,9 +1053,9 @@ typedef Tcl_Obj *\fBTcl_FSInternalToNormalizedProc\fR(
|
||||
.CE
|
||||
.SS CREATEINTERNALREPPROC
|
||||
.PP
|
||||
Function to take a path object, and calculate an internal
|
||||
Function to take a path value, and calculate an internal
|
||||
representation for it, and store that native representation in the
|
||||
object. May be NULL if paths have no internal representation, or if
|
||||
value. May be NULL if paths have no internal representation, or if
|
||||
the \fITcl_FSPathInFilesystemProc\fR for this filesystem always
|
||||
immediately creates an internal representation for paths it accepts.
|
||||
.PP
|
||||
@@ -1066,7 +1067,7 @@ typedef ClientData \fBTcl_FSCreateInternalRepProc\fR(
|
||||
.PP
|
||||
Function to normalize a path. Should be implemented for all
|
||||
filesystems which can have multiple string representations for the same
|
||||
path object. In Tcl, every
|
||||
path value. In Tcl, every
|
||||
.QW path
|
||||
must have a single unique
|
||||
.QW normalized
|
||||
@@ -1078,7 +1079,7 @@ reference to a home directory such as
|
||||
.QW ~ ,
|
||||
a path containing symbolic
|
||||
links, etc). If the very last component in the path is a symbolic
|
||||
link, it should not be converted into the object it points to (but
|
||||
link, it should not be converted into the value it points to (but
|
||||
its case or other aspects should be made unique). All other path
|
||||
components should be converted from symbolic links. This one
|
||||
exception is required to agree with Tcl's semantics with \fBfile
|
||||
@@ -1122,7 +1123,7 @@ which is returned. A typical return value might be
|
||||
or
|
||||
.QW ftp .
|
||||
The Tcl_Obj result is owned by the filesystem and so Tcl will
|
||||
increment the refCount of that object if it wishes to retain a reference
|
||||
increment the reference count of that value if it wishes to retain a reference
|
||||
to it.
|
||||
.PP
|
||||
.CS
|
||||
@@ -1137,7 +1138,7 @@ different separator than the standard string
|
||||
.QW / .
|
||||
Amongst other
|
||||
uses, it is returned by the \fBfile separator\fR command. The
|
||||
return value should be an object with refCount of zero.
|
||||
return value should be a value with reference count of zero.
|
||||
.PP
|
||||
.CS
|
||||
typedef Tcl_Obj *\fBTcl_FSFilesystemSeparatorProc\fR(
|
||||
@@ -1256,7 +1257,7 @@ The return value is a standard Tcl result indicating whether an error
|
||||
occurred in the matching process. Error messages are placed in
|
||||
\fIinterp\fR, unless \fIinterp\fR in NULL in which case no error
|
||||
message need be generated; on a \fBTCL_OK\fR result, results should be
|
||||
added to the \fIresultPtr\fR object given (which can be assumed to be a
|
||||
added to the \fIresultPtr\fR value given (which can be assumed to be a
|
||||
valid unshared Tcl list). The matches added
|
||||
to \fIresultPtr\fR should include any path prefix given in \fIpathPtr\fR
|
||||
(this usually means they will be absolute path specifications).
|
||||
@@ -1326,7 +1327,7 @@ contents of a link. The result is a Tcl_Obj specifying the contents of
|
||||
the link given by \fIlinkNamePtr\fR, or NULL if the link could
|
||||
not be read. The result is owned by the caller (and should therefore
|
||||
have its ref count incremented before being returned). Any callers
|
||||
should call Tcl_DecrRefCount on this result when it is no longer needed.
|
||||
should call \fBTcl_DecrRefCount\fR on this result when it is no longer needed.
|
||||
If \fItoPtr\fR is not NULL, the function should attempt to create a link.
|
||||
The result in this case should be \fItoPtr\fR if the link was successful
|
||||
and NULL otherwise. In this case the result is not owned by the caller
|
||||
@@ -1344,16 +1345,16 @@ typedef Tcl_Obj *\fBTcl_FSListVolumesProc\fR(void);
|
||||
.CE
|
||||
.PP
|
||||
The result should be a list of volumes added by this filesystem, or
|
||||
NULL (or an empty list) if no volumes are provided. The result object
|
||||
NULL (or an empty list) if no volumes are provided. The result value
|
||||
is considered to be owned by the filesystem (not by Tcl's core), but
|
||||
should be given a refCount for Tcl. Tcl will use the contents of the
|
||||
list and then decrement that refCount. This allows filesystems to
|
||||
should be given a reference count for Tcl. Tcl will use the contents of the
|
||||
list and then decrement that reference count. This allows filesystems to
|
||||
choose whether they actually want to retain a
|
||||
.QW "master list"
|
||||
of volumes
|
||||
or not (if not, they generate the list on the fly and pass it to Tcl
|
||||
with a refCount of 1 and then forget about the list, if yes, then
|
||||
they simply increment the refCount of their master list and pass it
|
||||
with a reference count of 1 and then forget about the list, if yes, then
|
||||
they simply increment the reference count of their master list and pass it
|
||||
to Tcl which will copy the contents and then decrement the count back
|
||||
to where it was).
|
||||
.PP
|
||||
@@ -1379,7 +1380,7 @@ will take that list and first increment its reference count before using it.
|
||||
On completion of that use, Tcl will decrement its reference count. Hence if
|
||||
the list should be disposed of by Tcl when done, it should have a
|
||||
reference count of zero, and if the list should not be disposed of, the
|
||||
filesystem should ensure it returns an object with a reference count
|
||||
filesystem should ensure it returns a value with a reference count
|
||||
of at least one.
|
||||
.SS FILEATTRSGETPROC
|
||||
.PP
|
||||
|
||||
+12
-6
@@ -26,16 +26,22 @@ int
|
||||
Interpreter to use for error reporting; if NULL, then no message is
|
||||
provided on errors.
|
||||
.AP Tcl_Obj *objPtr in/out
|
||||
The string value of this object is used to search through \fItablePtr\fR.
|
||||
The string value of this value is used to search through \fItablePtr\fR.
|
||||
The internal representation is modified to hold the index of the matching
|
||||
table entry.
|
||||
.AP "const char *const" *tablePtr in
|
||||
An array of null-terminated strings. The end of the array is marked
|
||||
by a NULL string pointer.
|
||||
Note that references to the \fItablePtr\fR may be retained in the
|
||||
internal representation of \fIobjPtr\fR, so this should represent the
|
||||
address of a statically-allocated array.
|
||||
.AP "const void" *structTablePtr in
|
||||
An array of arbitrary type, typically some \fBstruct\fR type.
|
||||
The first member of the structure must be a null-terminated string.
|
||||
The size of the structure is given by \fIoffset\fR.
|
||||
Note that references to the \fIstructTablePtr\fR may be retained in the
|
||||
internal representation of \fIobjPtr\fR, so this should represent the
|
||||
address of a statically-allocated array of structures.
|
||||
.AP int offset in
|
||||
The offset to add to structTablePtr to get to the next entry.
|
||||
The end of the array is marked by a NULL string pointer.
|
||||
@@ -51,10 +57,10 @@ The index of the string in \fItablePtr\fR that matches the value of
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This procedure provides an efficient way for looking up keywords,
|
||||
switch names, option names, and similar things where the value of
|
||||
an object must be one of a predefined set of values.
|
||||
\fIObjPtr\fR is compared against each of
|
||||
These procedures provide an efficient way for looking up keywords,
|
||||
switch names, option names, and similar things where the literal value of
|
||||
a Tcl value must be chosen from a predefined set.
|
||||
\fBTcl_GetIndexFromObj\fR compares \fIobjPtr\fR against each of
|
||||
the strings in \fItablePtr\fR to find a match. A match occurs if
|
||||
\fIobjPtr\fR's string value is identical to one of the strings in
|
||||
\fItablePtr\fR, or if it is a non-empty unique abbreviation
|
||||
@@ -95,4 +101,4 @@ each of several array elements.
|
||||
.SH "SEE ALSO"
|
||||
prefix(n), Tcl_WrongNumArgs(3)
|
||||
.SH KEYWORDS
|
||||
index, object, table lookup
|
||||
index, option, value, table lookup
|
||||
|
||||
+4
-4
@@ -310,14 +310,14 @@ typedef Tcl_HashEntry *\fBTcl_AllocHashEntryProc\fR(
|
||||
void *\fIkeyPtr\fR);
|
||||
.CE
|
||||
.PP
|
||||
If this is NULL then Tcl_Alloc is used to allocate enough space for a
|
||||
If this is NULL then \fBTcl_Alloc\fR is used to allocate enough space for a
|
||||
Tcl_HashEntry, the key pointer is assigned to key.oneWordValue and the
|
||||
clientData is set to NULL. String keys and array keys use this function to
|
||||
allocate enough space for the entry and the key in one block, rather than
|
||||
doing it in two blocks. This saves space for a pointer to the key from the
|
||||
entry and another memory allocation. Tcl_Obj* keys use this function to
|
||||
allocate enough space for an entry and increment the reference count on the
|
||||
object.
|
||||
value.
|
||||
.PP
|
||||
The \fIfreeEntryProc\fR member contains the address of a function called to
|
||||
free space for an entry.
|
||||
@@ -327,8 +327,8 @@ typedef void \fBTcl_FreeHashEntryProc\fR(
|
||||
Tcl_HashEntry *\fIhPtr\fR);
|
||||
.CE
|
||||
.PP
|
||||
If this is NULL then Tcl_Free is used to free the space for the entry.
|
||||
If this is NULL then \fBTcl_Free\fR is used to free the space for the entry.
|
||||
Tcl_Obj* keys use this function to decrement the reference count on the
|
||||
object.
|
||||
value.
|
||||
.SH KEYWORDS
|
||||
hash table, key, lookup, search, value
|
||||
|
||||
+3
-3
@@ -63,9 +63,9 @@ Define the \fBUSE_TCL_STUBS\fR symbol. Typically, you would include the
|
||||
\fB\-DUSE_TCL_STUBS\fR flag when compiling the extension.
|
||||
.IP 3) 5
|
||||
Link the extension with the Tcl stubs library instead of the standard
|
||||
Tcl library. For example, to use the Tcl 8.1 ABI on Unix platforms,
|
||||
the library name is \fIlibtclstub8.1.a\fR; on Windows platforms, the
|
||||
library name is \fItclstub81.lib\fR.
|
||||
Tcl library. For example, to use the Tcl 8.6 ABI on Unix platforms,
|
||||
the library name is \fIlibtclstub8.6.a\fR; on Windows platforms, the
|
||||
library name is \fItclstub86.lib\fR.
|
||||
.PP
|
||||
If the extension also requires the Tk API, it must also call
|
||||
\fBTk_InitStubs\fR to initialize the Tk stubs interface and link
|
||||
|
||||
+16
-15
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl objects as integer values
|
||||
Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl values as integers
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -56,17 +56,17 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS Tcl_WideInt doubleValue in/out
|
||||
.AP int intValue in
|
||||
Integer value used to initialize or set a Tcl object.
|
||||
Integer value used to initialize or set a Tcl value.
|
||||
.AP long longValue in
|
||||
Long integer value used to initialize or set a Tcl object.
|
||||
Long integer value used to initialize or set a Tcl value.
|
||||
.AP Tcl_WideInt wideValue in
|
||||
Wide integer value used to initialize or set a Tcl object.
|
||||
Wide integer value used to initialize or set a Tcl value.
|
||||
.AP Tcl_Obj *objPtr in/out
|
||||
For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
|
||||
and \fBTcl_SetBignumObj\fR, this points to the object in which to store an
|
||||
and \fBTcl_SetBignumObj\fR, this points to the value in which to store an
|
||||
integral value. For \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
|
||||
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
|
||||
\fBTcl_TakeBignumFromObj\fR, this refers to the object from which
|
||||
\fBTcl_TakeBignumFromObj\fR, this refers to the value from which
|
||||
to retrieve an integral value.
|
||||
.AP Tcl_Interp *interp in/out
|
||||
When non-NULL, an error message is left here when integral value
|
||||
@@ -86,7 +86,7 @@ used to initialize a multi-precision integer value.
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
These procedures are used to create, modify, and read Tcl objects
|
||||
These procedures are used to create, modify, and read Tcl values
|
||||
that hold integral values.
|
||||
.PP
|
||||
The different routines exist to accommodate different integral types in C
|
||||
@@ -103,22 +103,22 @@ by the LibTomMath multiple-precision integer library.
|
||||
.PP
|
||||
The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR,
|
||||
and \fBTcl_NewBignumObj\fR routines each create and return a new
|
||||
Tcl object initialized to the integral value of the argument. The
|
||||
returned Tcl object is unshared.
|
||||
Tcl value initialized to the integral value of the argument. The
|
||||
returned Tcl value is unshared.
|
||||
.PP
|
||||
The \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
|
||||
and \fBTcl_SetBignumObj\fR routines each set the value of an existing
|
||||
Tcl object pointed to by \fIobjPtr\fR to the integral value provided
|
||||
Tcl value pointed to by \fIobjPtr\fR to the integral value provided
|
||||
by the other argument. The \fIobjPtr\fR argument must point to an
|
||||
unshared Tcl object. Any attempt to set the value of a shared Tcl object
|
||||
unshared Tcl value. Any attempt to set the value of a shared Tcl value
|
||||
violates Tcl's copy-on-write policy. Any existing string representation
|
||||
or internal representation in the unshared Tcl object will be freed
|
||||
or internal representation in the unshared Tcl value will be freed
|
||||
as a consequence of setting the new value.
|
||||
.PP
|
||||
The \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
|
||||
\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
|
||||
\fBTcl_TakeBignumFromObj\fR routines attempt to retrieve an integral
|
||||
value of the appropriate type from the Tcl object \fIobjPtr\fR. If the
|
||||
value of the appropriate type from the Tcl value \fIobjPtr\fR. If the
|
||||
attempt succeeds, then \fBTCL_OK\fR is returned, and the value is
|
||||
written to the storage provided by the caller. The attempt might
|
||||
fail if \fIobjPtr\fR does not hold an integral value, or if the
|
||||
@@ -127,7 +127,7 @@ then \fBTCL_ERROR\fR is returned, and if \fIinterp\fR is non-NULL,
|
||||
an error message is left in \fIinterp\fR. The \fBTcl_ObjType\fR
|
||||
of \fIobjPtr\fR may be changed to make subsequent calls to the
|
||||
same routine more efficient. Unlike the other functions,
|
||||
\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl object
|
||||
\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl value
|
||||
\fIobjPtr\fR to an empty string in the process of retrieving the
|
||||
multiple-precision integer value.
|
||||
.PP
|
||||
@@ -148,4 +148,5 @@ integer value in the \fBmp_int\fR value \fIbigValue\fR.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
|
||||
.SH KEYWORDS
|
||||
integer, integer object, integer type, internal representation, object, object type, string representation
|
||||
integer, integer value, integer type, internal representation, value,
|
||||
value type, string representation
|
||||
|
||||
+59
-58
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl objects as lists
|
||||
Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl values as lists
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -38,44 +38,44 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS "Tcl_Obj *const" *elemListPtr in/out
|
||||
.AP Tcl_Interp *interp in
|
||||
If an error occurs while converting an object to be a list object,
|
||||
an error message is left in the interpreter's result object
|
||||
If an error occurs while converting a value to be a list value,
|
||||
an error message is left in the interpreter's result value
|
||||
unless \fIinterp\fR is NULL.
|
||||
.AP Tcl_Obj *listPtr in/out
|
||||
Points to the list object to be manipulated.
|
||||
If \fIlistPtr\fR does not already point to a list object,
|
||||
Points to the list value to be manipulated.
|
||||
If \fIlistPtr\fR does not already point to a list value,
|
||||
an attempt will be made to convert it to one.
|
||||
.AP Tcl_Obj *elemListPtr in/out
|
||||
For \fBTcl_ListObjAppendList\fR, this points to a list object
|
||||
For \fBTcl_ListObjAppendList\fR, this points to a list value
|
||||
containing elements to be appended onto \fIlistPtr\fR.
|
||||
Each element of *\fIelemListPtr\fR will
|
||||
become a new element of \fIlistPtr\fR.
|
||||
If *\fIelemListPtr\fR is not NULL and
|
||||
does not already point to a list object,
|
||||
does not already point to a list value,
|
||||
an attempt will be made to convert it to one.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
For \fBTcl_ListObjAppendElement\fR,
|
||||
points to the Tcl object that will be appended to \fIlistPtr\fR.
|
||||
points to the Tcl value that will be appended to \fIlistPtr\fR.
|
||||
For \fBTcl_SetListObj\fR,
|
||||
this points to the Tcl object that will be converted to a list object
|
||||
this points to the Tcl value that will be converted to a list value
|
||||
containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR.
|
||||
.AP int *objcPtr in
|
||||
Points to location where \fBTcl_ListObjGetElements\fR
|
||||
stores the number of element objects in \fIlistPtr\fR.
|
||||
stores the number of element values in \fIlistPtr\fR.
|
||||
.AP Tcl_Obj ***objvPtr out
|
||||
A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
|
||||
of pointers to the element objects of \fIlistPtr\fR.
|
||||
of pointers to the element values of \fIlistPtr\fR.
|
||||
.AP int objc in
|
||||
The number of Tcl objects that \fBTcl_NewListObj\fR
|
||||
will insert into a new list object,
|
||||
The number of Tcl values that \fBTcl_NewListObj\fR
|
||||
will insert into a new list value,
|
||||
and \fBTcl_ListObjReplace\fR will insert into \fIlistPtr\fR.
|
||||
For \fBTcl_SetListObj\fR,
|
||||
the number of Tcl objects to insert into \fIobjPtr\fR.
|
||||
the number of Tcl values to insert into \fIobjPtr\fR.
|
||||
.AP "Tcl_Obj *const" objv[] in
|
||||
An array of pointers to objects.
|
||||
\fBTcl_NewListObj\fR will insert these objects into a new list object
|
||||
An array of pointers to values.
|
||||
\fBTcl_NewListObj\fR will insert these values into a new list value
|
||||
and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR.
|
||||
Each object will become a separate list element.
|
||||
Each value will become a separate list element.
|
||||
.AP int *intPtr out
|
||||
Points to location where \fBTcl_ListObjLength\fR
|
||||
stores the length of the list.
|
||||
@@ -85,7 +85,7 @@ is to return.
|
||||
The first element has index 0.
|
||||
.AP Tcl_Obj **objPtrPtr out
|
||||
Points to place where \fBTcl_ListObjIndex\fR is to store
|
||||
a pointer to the resulting list element object.
|
||||
a pointer to the resulting list element value.
|
||||
.AP int first in
|
||||
Index of the starting list element that \fBTcl_ListObjReplace\fR
|
||||
is to replace.
|
||||
@@ -97,85 +97,85 @@ is to replace.
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
Tcl list objects have an internal representation that supports
|
||||
Tcl list values have an internal representation that supports
|
||||
the efficient indexing and appending.
|
||||
The procedures described in this man page are used to
|
||||
create, modify, index, and append to Tcl list objects from C code.
|
||||
create, modify, index, and append to Tcl list values from C code.
|
||||
.PP
|
||||
\fBTcl_ListObjAppendList\fR and \fBTcl_ListObjAppendElement\fR
|
||||
both add one or more objects
|
||||
to the end of the list object referenced by \fIlistPtr\fR.
|
||||
\fBTcl_ListObjAppendList\fR appends each element of the list object
|
||||
both add one or more values
|
||||
to the end of the list value referenced by \fIlistPtr\fR.
|
||||
\fBTcl_ListObjAppendList\fR appends each element of the list value
|
||||
referenced by \fIelemListPtr\fR while
|
||||
\fBTcl_ListObjAppendElement\fR appends the single object
|
||||
\fBTcl_ListObjAppendElement\fR appends the single value
|
||||
referenced by \fIobjPtr\fR.
|
||||
Both procedures will convert the object referenced by \fIlistPtr\fR
|
||||
to a list object if necessary.
|
||||
Both procedures will convert the value referenced by \fIlistPtr\fR
|
||||
to a list value if necessary.
|
||||
If an error occurs during conversion,
|
||||
both procedures return \fBTCL_ERROR\fR and leave an error message
|
||||
in the interpreter's result object if \fIinterp\fR is not NULL.
|
||||
Similarly, if \fIelemListPtr\fR does not already refer to a list object,
|
||||
in the interpreter's result value if \fIinterp\fR is not NULL.
|
||||
Similarly, if \fIelemListPtr\fR does not already refer to a list value,
|
||||
\fBTcl_ListObjAppendList\fR will attempt to convert it to one
|
||||
and if an error occurs during conversion,
|
||||
will return \fBTCL_ERROR\fR
|
||||
and leave an error message in the interpreter's result object
|
||||
and leave an error message in the interpreter's result value
|
||||
if interp is not NULL.
|
||||
Both procedures invalidate any old string representation of \fIlistPtr\fR
|
||||
and, if it was converted to a list object,
|
||||
and, if it was converted to a list value,
|
||||
free any old internal representation.
|
||||
Similarly, \fBTcl_ListObjAppendList\fR frees any old internal representation
|
||||
of \fIelemListPtr\fR if it converts it to a list object.
|
||||
of \fIelemListPtr\fR if it converts it to a list value.
|
||||
After appending each element in \fIelemListPtr\fR,
|
||||
\fBTcl_ListObjAppendList\fR increments the element's reference count
|
||||
since \fIlistPtr\fR now also refers to it.
|
||||
For the same reason, \fBTcl_ListObjAppendElement\fR
|
||||
increments \fIobjPtr\fR's reference count.
|
||||
If no error occurs,
|
||||
the two procedures return \fBTCL_OK\fR after appending the objects.
|
||||
the two procedures return \fBTCL_OK\fR after appending the values.
|
||||
.PP
|
||||
\fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
|
||||
create a new object or modify an existing object to hold
|
||||
create a new value or modify an existing value to hold
|
||||
the \fIobjc\fR elements of the array referenced by \fIobjv\fR
|
||||
where each element is a pointer to a Tcl object.
|
||||
where each element is a pointer to a Tcl value.
|
||||
If \fIobjc\fR is less than or equal to zero,
|
||||
they return an empty object.
|
||||
The new object's string representation is left invalid.
|
||||
they return an empty value.
|
||||
The new value's string representation is left invalid.
|
||||
The two procedures increment the reference counts
|
||||
of the elements in \fIobjc\fR since the list object now refers to them.
|
||||
The new list object returned by \fBTcl_NewListObj\fR
|
||||
of the elements in \fIobjc\fR since the list value now refers to them.
|
||||
The new list value returned by \fBTcl_NewListObj\fR
|
||||
has reference count zero.
|
||||
.PP
|
||||
\fBTcl_ListObjGetElements\fR returns a count and a pointer to an array of
|
||||
the elements in a list object. It returns the count by storing it in the
|
||||
the elements in a list value. It returns the count by storing it in the
|
||||
address \fIobjcPtr\fR. Similarly, it returns the array pointer by storing
|
||||
it in the address \fIobjvPtr\fR.
|
||||
The memory pointed to is managed by Tcl and should not be freed or written
|
||||
to by the caller. If the list is empty, 0 is stored at \fIobjcPtr\fR
|
||||
and NULL at \fIobjvPtr\fR.
|
||||
If \fIlistPtr\fR is not already a list object, \fBTcl_ListObjGetElements\fR
|
||||
If \fIlistPtr\fR is not already a list value, \fBTcl_ListObjGetElements\fR
|
||||
will attempt to convert it to one; if the conversion fails, it returns
|
||||
\fBTCL_ERROR\fR and leaves an error message in the interpreter's result
|
||||
object if \fIinterp\fR is not NULL.
|
||||
value if \fIinterp\fR is not NULL.
|
||||
Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
|
||||
.PP
|
||||
\fBTcl_ListObjLength\fR returns the number of elements in the list object
|
||||
\fBTcl_ListObjLength\fR returns the number of elements in the list value
|
||||
referenced by \fIlistPtr\fR.
|
||||
It returns this count by storing an integer in the address \fIintPtr\fR.
|
||||
If the object is not already a list object,
|
||||
If the value is not already a list value,
|
||||
\fBTcl_ListObjLength\fR will attempt to convert it to one;
|
||||
if the conversion fails, it returns \fBTCL_ERROR\fR
|
||||
and leaves an error message in the interpreter's result object
|
||||
and leaves an error message in the interpreter's result value
|
||||
if \fIinterp\fR is not NULL.
|
||||
Otherwise it returns \fBTCL_OK\fR after storing the list's length.
|
||||
.PP
|
||||
The procedure \fBTcl_ListObjIndex\fR returns a pointer to the object
|
||||
The procedure \fBTcl_ListObjIndex\fR returns a pointer to the value
|
||||
at element \fIindex\fR in the list referenced by \fIlistPtr\fR.
|
||||
It returns this object by storing a pointer to it
|
||||
It returns this value by storing a pointer to it
|
||||
in the address \fIobjPtrPtr\fR.
|
||||
If \fIlistPtr\fR does not already refer to a list object,
|
||||
If \fIlistPtr\fR does not already refer to a list value,
|
||||
\fBTcl_ListObjIndex\fR will attempt to convert it to one;
|
||||
if the conversion fails, it returns \fBTCL_ERROR\fR
|
||||
and leaves an error message in the interpreter's result object
|
||||
and leaves an error message in the interpreter's result value
|
||||
if \fIinterp\fR is not NULL.
|
||||
If the index is out of range,
|
||||
that is, \fIindex\fR is negative or
|
||||
@@ -183,19 +183,19 @@ greater than or equal to the number of elements in the list,
|
||||
\fBTcl_ListObjIndex\fR stores a NULL in \fIobjPtrPtr\fR
|
||||
and returns \fBTCL_OK\fR.
|
||||
Otherwise it returns \fBTCL_OK\fR after storing the element's
|
||||
object pointer.
|
||||
value pointer.
|
||||
The reference count for the list element is not incremented;
|
||||
the caller must do that if it needs to retain a pointer to the element.
|
||||
.PP
|
||||
\fBTcl_ListObjReplace\fR replaces zero or more elements
|
||||
of the list referenced by \fIlistPtr\fR
|
||||
with the \fIobjc\fR objects in the array referenced by \fIobjv\fR.
|
||||
If \fIlistPtr\fR does not point to a list object,
|
||||
with the \fIobjc\fR values in the array referenced by \fIobjv\fR.
|
||||
If \fIlistPtr\fR does not point to a list value,
|
||||
\fBTcl_ListObjReplace\fR will attempt to convert it to one;
|
||||
if the conversion fails, it returns \fBTCL_ERROR\fR
|
||||
and leaves an error message in the interpreter's result object
|
||||
and leaves an error message in the interpreter's result value
|
||||
if \fIinterp\fR is not NULL.
|
||||
Otherwise, it returns \fBTCL_OK\fR after replacing the objects.
|
||||
Otherwise, it returns \fBTCL_OK\fR after replacing the values.
|
||||
If \fIobjv\fR is NULL, no new elements are added.
|
||||
If the argument \fIfirst\fR is zero or negative,
|
||||
it refers to the first element.
|
||||
@@ -210,13 +210,13 @@ designated by \fIfirst\fR.
|
||||
old string representation.
|
||||
The reference counts of any elements inserted from \fIobjv\fR
|
||||
are incremented since the resulting list now refers to them.
|
||||
Similarly, the reference counts for any replaced objects are decremented.
|
||||
Similarly, the reference counts for any replaced values are decremented.
|
||||
.PP
|
||||
Because \fBTcl_ListObjReplace\fR combines
|
||||
both element insertion and deletion,
|
||||
it can be used to implement a number of list operations.
|
||||
For example, the following code inserts the \fIobjc\fR objects
|
||||
referenced by the array of object pointers \fIobjv\fR
|
||||
For example, the following code inserts the \fIobjc\fR values
|
||||
referenced by the array of value pointers \fIobjv\fR
|
||||
just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
|
||||
.PP
|
||||
.CS
|
||||
@@ -224,7 +224,7 @@ result = \fBTcl_ListObjReplace\fR(interp, listPtr, index, 0,
|
||||
objc, objv);
|
||||
.CE
|
||||
.PP
|
||||
Similarly, the following code appends the \fIobjc\fR objects
|
||||
Similarly, the following code appends the \fIobjc\fR values
|
||||
referenced by the array \fIobjv\fR
|
||||
to the end of the list \fIlistPtr\fR:
|
||||
.PP
|
||||
@@ -247,4 +247,5 @@ result = \fBTcl_ListObjReplace\fR(interp, listPtr, first, count,
|
||||
.SH "SEE ALSO"
|
||||
Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjResult(3)
|
||||
.SH KEYWORDS
|
||||
append, index, insert, internal representation, length, list, list object, list type, object, object type, replace, string representation
|
||||
append, index, insert, internal representation, length, list, list value,
|
||||
list type, value, value type, replace, string representation
|
||||
|
||||
+2
-1
@@ -31,7 +31,8 @@ Array of names of symbols to be resolved during the load of the library, or
|
||||
NULL if no symbols are to be resolved. If an array is given, the last entry in
|
||||
the array must be NULL.
|
||||
.AP int flags in
|
||||
Reserved for future expansion. Must be 0.
|
||||
The value should normally be 0, but \fITCL_LOAD_GLOBAL\fR or \fITCL_LOAD_LAZY\fR
|
||||
or a combination of those two is allowed as well.
|
||||
.AP void *procPtrs out
|
||||
Points to an array that will hold the addresses of the functions described in
|
||||
the \fIsymbols\fR argument. Should be NULL if no symbols are to be resolved.
|
||||
|
||||
@@ -57,7 +57,7 @@ is \fBNULL\fR, then no procedure is called before the command is deleted.
|
||||
.AP int objc in
|
||||
Count of parameters provided to the implementation of a command.
|
||||
.AP Tcl_Obj **objv in
|
||||
Pointer to an array of Tcl objects. Each object holds the value of a
|
||||
Pointer to an array of Tcl values. Each value holds the value of a
|
||||
single word in the command to execute.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
Pointer to a Tcl_Obj whose value is a script or expression to execute.
|
||||
@@ -141,7 +141,7 @@ trampoline.
|
||||
.PP
|
||||
\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
|
||||
resolution is already known. The \fIcmd\fR parameter gives a
|
||||
\fBTcl_Command\fR object (returned from \fBTcl_CreateObjCommand\fR or
|
||||
\fBTcl_Command\fR token (returned from \fBTcl_CreateObjCommand\fR or
|
||||
\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
|
||||
the trampoline; this command must match the word in \fIobjv[0]\fR.
|
||||
The remaining arguments are as for \fBTcl_NREvalObj\fR.
|
||||
@@ -295,7 +295,7 @@ int
|
||||
int result)
|
||||
{
|
||||
/* \fIdata[0] .. data[3]\fR are the four words of data
|
||||
* passed to \fBTcl_NREvalObj\fR */
|
||||
* passed to \fBTcl_NRAddCallback\fR */
|
||||
|
||||
\fI... postprocessing ...\fR
|
||||
|
||||
@@ -323,6 +323,6 @@ and the second is for use when there is already a trampoline in place.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
|
||||
.SH KEYWORDS
|
||||
stackless, nonrecursive, execute, command, global, object, result, script
|
||||
stackless, nonrecursive, execute, command, global, value, result, script
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2008 by Kevin B. Kenny
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ if no such callback is to be performed.
|
||||
The namespace to be manipulated, or NULL (for other than
|
||||
\fBTcl_DeleteNamespace\fR) to manipulate the current namespace.
|
||||
.AP Tcl_Obj *objPtr out
|
||||
A reference to an unshared object to which the function output will be
|
||||
A reference to an unshared value to which the function output will be
|
||||
written.
|
||||
.AP "const char" *pattern in
|
||||
The glob-style pattern (see \fBTcl_StringMatch\fR) that describes the
|
||||
|
||||
+90
-88
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_Obj 3 8.5 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl objects
|
||||
Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl values
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -30,35 +30,36 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS Tcl_Obj *objPtr
|
||||
.AP Tcl_Obj *objPtr in
|
||||
Points to an object;
|
||||
Points to a value;
|
||||
must have been the result of a previous call to \fBTcl_NewObj\fR.
|
||||
.BE
|
||||
.SH INTRODUCTION
|
||||
.PP
|
||||
This man page presents an overview of Tcl objects and how they are used.
|
||||
It also describes generic procedures for managing Tcl objects.
|
||||
These procedures are used to create and copy objects,
|
||||
and increment and decrement the count of references (pointers) to objects.
|
||||
This man page presents an overview of Tcl values (called \fBTcl_Obj\fRs for
|
||||
historical reasons) and how they are used.
|
||||
It also describes generic procedures for managing Tcl values.
|
||||
These procedures are used to create and copy values,
|
||||
and increment and decrement the count of references (pointers) to values.
|
||||
The procedures are used in conjunction with ones
|
||||
that operate on specific types of objects such as
|
||||
that operate on specific types of values such as
|
||||
\fBTcl_GetIntFromObj\fR and \fBTcl_ListObjAppendElement\fR.
|
||||
The individual procedures are described along with the data structures
|
||||
they manipulate.
|
||||
.PP
|
||||
Tcl's \fIdual-ported\fR objects provide a general-purpose mechanism
|
||||
Tcl's \fIdual-ported\fR values provide a general-purpose mechanism
|
||||
for storing and exchanging Tcl values.
|
||||
They largely replace the use of strings in Tcl.
|
||||
For example, they are used to store variable values,
|
||||
command arguments, command results, and scripts.
|
||||
Tcl objects behave like strings but also hold an internal representation
|
||||
Tcl values behave like strings but also hold an internal representation
|
||||
that can be manipulated more efficiently.
|
||||
For example, a Tcl list is now represented as an object
|
||||
For example, a Tcl list is now represented as a value
|
||||
that holds the list's string representation
|
||||
as well as an array of pointers to the objects for each list element.
|
||||
Dual-ported objects avoid most runtime type conversions.
|
||||
as well as an array of pointers to the values for each list element.
|
||||
Dual-ported values avoid most runtime type conversions.
|
||||
They also improve the speed of many operations
|
||||
since an appropriate representation is immediately available.
|
||||
The compiler itself uses Tcl objects to
|
||||
The compiler itself uses Tcl values to
|
||||
cache the instruction bytecodes resulting from compiling scripts.
|
||||
.PP
|
||||
The two representations are a cache of each other and are computed lazily.
|
||||
@@ -73,39 +74,39 @@ between integers and strings.
|
||||
Only when it needs a string representing the variable's value,
|
||||
say to print it,
|
||||
will the program regenerate the string representation from the integer.
|
||||
Although objects contain an internal representation,
|
||||
Although values contain an internal representation,
|
||||
their semantics are defined in terms of strings:
|
||||
an up-to-date string can always be obtained,
|
||||
and any change to the object will be reflected in that string
|
||||
when the object's string representation is fetched.
|
||||
and any change to the value will be reflected in that string
|
||||
when the value's string representation is fetched.
|
||||
Because of this representation invalidation and regeneration,
|
||||
it is dangerous for extension writers to access
|
||||
\fBTcl_Obj\fR fields directly.
|
||||
It is better to access Tcl_Obj information using
|
||||
procedures like \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR.
|
||||
.PP
|
||||
Objects are allocated on the heap
|
||||
Values are allocated on the heap
|
||||
and are referenced using a pointer to their \fBTcl_Obj\fR structure.
|
||||
Objects are shared as much as possible.
|
||||
Values are shared as much as possible.
|
||||
This significantly reduces storage requirements
|
||||
because some objects such as long lists are very large.
|
||||
because some values such as long lists are very large.
|
||||
Also, most Tcl values are only read and never modified.
|
||||
This is especially true for procedure arguments,
|
||||
which can be shared between the caller and the called procedure.
|
||||
Assignment and argument binding is done by
|
||||
simply assigning a pointer to the value.
|
||||
Reference counting is used to determine when it is safe to
|
||||
reclaim an object's storage.
|
||||
reclaim a value's storage.
|
||||
.PP
|
||||
Tcl objects are typed.
|
||||
An object's internal representation is controlled by its type.
|
||||
Tcl values are typed.
|
||||
A value's internal representation is controlled by its type.
|
||||
Several types are predefined in the Tcl core
|
||||
including integer, double, list, and bytecode.
|
||||
Extension writers can extend the set of types
|
||||
by defining their own \fBTcl_ObjType\fR structs.
|
||||
.SH "THE TCL_OBJ STRUCTURE"
|
||||
.PP
|
||||
Each Tcl object is represented by a \fBTcl_Obj\fR structure
|
||||
Each Tcl value is represented by a \fBTcl_Obj\fR structure
|
||||
which is defined as follows.
|
||||
.PP
|
||||
.CS
|
||||
@@ -132,7 +133,7 @@ typedef struct Tcl_Obj {
|
||||
.CE
|
||||
.PP
|
||||
The \fIbytes\fR and the \fIlength\fR members together hold
|
||||
an object's UTF-8 string representation,
|
||||
a value's UTF-8 string representation,
|
||||
which is a \fIcounted string\fR not containing null bytes (UTF-8 null
|
||||
characters should be encoded as a two byte sequence: 192, 128.)
|
||||
\fIbytes\fR points to the first byte of the string representation.
|
||||
@@ -142,31 +143,31 @@ at offset \fIlength\fR;
|
||||
this allows string representations
|
||||
to be treated as conventional null-terminated C strings.
|
||||
C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
|
||||
an object's string representation.
|
||||
a value's string representation.
|
||||
If \fIbytes\fR is NULL,
|
||||
the string representation is invalid.
|
||||
.PP
|
||||
An object's type manages its internal representation.
|
||||
A value's type manages its internal representation.
|
||||
The member \fItypePtr\fR points to the Tcl_ObjType structure
|
||||
that describes the type.
|
||||
If \fItypePtr\fR is NULL,
|
||||
the internal representation is invalid.
|
||||
.PP
|
||||
The \fIinternalRep\fR union member holds
|
||||
an object's internal representation.
|
||||
a value's internal representation.
|
||||
This is either a (long) integer, a double-precision floating-point number,
|
||||
a pointer to a value containing additional information
|
||||
needed by the object's type to represent the object, a Tcl_WideInt
|
||||
needed by the value's type to represent the value, a Tcl_WideInt
|
||||
integer, two arbitrary pointers, or a pair made up of an unsigned long
|
||||
integer and a pointer.
|
||||
.PP
|
||||
The \fIrefCount\fR member is used to tell when it is safe to free
|
||||
an object's storage.
|
||||
It holds the count of active references to the object.
|
||||
a value's storage.
|
||||
It holds the count of active references to the value.
|
||||
Maintaining the correct reference count is a key responsibility
|
||||
of extension writers.
|
||||
Reference counting is discussed below
|
||||
in the section \fBSTORAGE MANAGEMENT OF OBJECTS\fR.
|
||||
in the section \fBSTORAGE MANAGEMENT OF VALUES\fR.
|
||||
.PP
|
||||
Although extension writers can directly access
|
||||
the members of a Tcl_Obj structure,
|
||||
@@ -176,21 +177,21 @@ read or update \fIrefCount\fR directly;
|
||||
they should use macros such as
|
||||
\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
|
||||
.PP
|
||||
A key property of Tcl objects is that they hold two representations.
|
||||
An object typically starts out containing only a string representation:
|
||||
A key property of Tcl values is that they hold two representations.
|
||||
A value typically starts out containing only a string representation:
|
||||
it is untyped and has a NULL \fItypePtr\fR.
|
||||
An object containing an empty string or a copy of a specified string
|
||||
A value containing an empty string or a copy of a specified string
|
||||
is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
|
||||
An object's string value is gotten with
|
||||
A value's string value is gotten with
|
||||
\fBTcl_GetStringFromObj\fR or \fBTcl_GetString\fR
|
||||
and changed with \fBTcl_SetStringObj\fR.
|
||||
If the object is later passed to a procedure like \fBTcl_GetIntFromObj\fR
|
||||
If the value is later passed to a procedure like \fBTcl_GetIntFromObj\fR
|
||||
that requires a specific internal representation,
|
||||
the procedure will create one and set the object's \fItypePtr\fR.
|
||||
the procedure will create one and set the value's \fItypePtr\fR.
|
||||
The internal representation is computed from the string representation.
|
||||
An object's two representations are duals of each other:
|
||||
A value's two representations are duals of each other:
|
||||
changes made to one are reflected in the other.
|
||||
For example, \fBTcl_ListObjReplace\fR will modify an object's
|
||||
For example, \fBTcl_ListObjReplace\fR will modify a value's
|
||||
internal representation and the next call to \fBTcl_GetStringFromObj\fR
|
||||
or \fBTcl_GetString\fR will reflect that change.
|
||||
.PP
|
||||
@@ -203,43 +204,43 @@ so that it is only regenerated if it is needed later.
|
||||
Most C programmers never have to be concerned with how this is done
|
||||
and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
|
||||
\fBTcl_ListObjIndex\fR.
|
||||
Programmers that implement their own object types
|
||||
Programmers that implement their own value types
|
||||
must check for invalid representations
|
||||
and mark representations invalid when necessary.
|
||||
The procedure \fBTcl_InvalidateStringRep\fR is used
|
||||
to mark an object's string representation invalid and to
|
||||
to mark a value's string representation invalid and to
|
||||
free any storage associated with the old string representation.
|
||||
.PP
|
||||
Objects usually remain one type over their life,
|
||||
but occasionally an object must be converted from one type to another.
|
||||
For example, a C program might build up a string in an object
|
||||
Values usually remain one type over their life,
|
||||
but occasionally a value must be converted from one type to another.
|
||||
For example, a C program might build up a string in a value
|
||||
with repeated calls to \fBTcl_AppendToObj\fR,
|
||||
and then call \fBTcl_ListObjIndex\fR to extract a list element from
|
||||
the object.
|
||||
The same object holding the same string value
|
||||
the value.
|
||||
The same value holding the same string value
|
||||
can have several different internal representations
|
||||
at different times.
|
||||
Extension writers can also force an object to be converted from one type
|
||||
Extension writers can also force a value to be converted from one type
|
||||
to another using the \fBTcl_ConvertToType\fR procedure.
|
||||
Only programmers that create new object types need to be concerned
|
||||
Only programmers that create new value types need to be concerned
|
||||
about how this is done.
|
||||
A procedure defined as part of the object type's implementation
|
||||
creates a new internal representation for an object
|
||||
A procedure defined as part of the value type's implementation
|
||||
creates a new internal representation for a value
|
||||
and changes its \fItypePtr\fR.
|
||||
See the man page for \fBTcl_RegisterObjType\fR
|
||||
to see how to create a new object type.
|
||||
.SH "EXAMPLE OF THE LIFETIME OF AN OBJECT"
|
||||
to see how to create a new value type.
|
||||
.SH "EXAMPLE OF THE LIFETIME OF A VALUE"
|
||||
.PP
|
||||
As an example of the lifetime of an object,
|
||||
As an example of the lifetime of a value,
|
||||
consider the following sequence of commands:
|
||||
.PP
|
||||
.CS
|
||||
\fBset x 123\fR
|
||||
.CE
|
||||
.PP
|
||||
This assigns to \fIx\fR an untyped object whose
|
||||
This assigns to \fIx\fR an untyped value whose
|
||||
\fIbytes\fR member points to \fB123\fR and \fIlength\fR member contains 3.
|
||||
The object's \fItypePtr\fR member is NULL.
|
||||
The value's \fItypePtr\fR member is NULL.
|
||||
.PP
|
||||
.CS
|
||||
\fBputs "x is $x"\fR
|
||||
@@ -252,16 +253,16 @@ and is fetched for the command.
|
||||
\fBincr x\fR
|
||||
.CE
|
||||
.PP
|
||||
The \fBincr\fR command first gets an integer from \fIx\fR's object
|
||||
The \fBincr\fR command first gets an integer from \fIx\fR's value
|
||||
by calling \fBTcl_GetIntFromObj\fR.
|
||||
This procedure checks whether the object is already an integer object.
|
||||
Since it is not, it converts the object
|
||||
by setting the object's \fIinternalRep.longValue\fR member
|
||||
This procedure checks whether the value is already an integer value.
|
||||
Since it is not, it converts the value
|
||||
by setting the value's \fIinternalRep.longValue\fR member
|
||||
to the integer \fB123\fR
|
||||
and setting the object's \fItypePtr\fR
|
||||
and setting the value's \fItypePtr\fR
|
||||
to point to the integer Tcl_ObjType structure.
|
||||
Both representations are now valid.
|
||||
\fBincr\fR increments the object's integer internal representation
|
||||
\fBincr\fR increments the value's integer internal representation
|
||||
then invalidates its string representation
|
||||
(by calling \fBTcl_InvalidateStringRep\fR)
|
||||
since the string representation
|
||||
@@ -271,31 +272,31 @@ no longer corresponds to the internal representation.
|
||||
\fBputs "x is now $x"\fR
|
||||
.CE
|
||||
.PP
|
||||
The string representation of \fIx\fR's object is needed
|
||||
The string representation of \fIx\fR's value is needed
|
||||
and is recomputed.
|
||||
The string representation is now \fB124\fR
|
||||
and both representations are again valid.
|
||||
.SH "STORAGE MANAGEMENT OF OBJECTS"
|
||||
.SH "STORAGE MANAGEMENT OF VALUES"
|
||||
.PP
|
||||
Tcl objects are allocated on the heap and are shared as much as possible
|
||||
Tcl values are allocated on the heap and are shared as much as possible
|
||||
to reduce storage requirements.
|
||||
Reference counting is used to determine when an object is
|
||||
Reference counting is used to determine when a value is
|
||||
no longer needed and can safely be freed.
|
||||
An object just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
|
||||
A value just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
|
||||
has \fIrefCount\fR 0.
|
||||
The macro \fBTcl_IncrRefCount\fR increments the reference count
|
||||
when a new reference to the object is created.
|
||||
when a new reference to the value is created.
|
||||
The macro \fBTcl_DecrRefCount\fR decrements the count
|
||||
when a reference is no longer needed and,
|
||||
if the object's reference count drops to zero, frees its storage.
|
||||
An object shared by different code or data structures has
|
||||
if the value's reference count drops to zero, frees its storage.
|
||||
A value shared by different code or data structures has
|
||||
\fIrefCount\fR greater than 1.
|
||||
Incrementing an object's reference count ensures that
|
||||
Incrementing a value's reference count ensures that
|
||||
it will not be freed too early or have its value change accidentally.
|
||||
.PP
|
||||
As an example, the bytecode interpreter shares argument objects
|
||||
between calling and called Tcl procedures to avoid having to copy objects.
|
||||
It assigns the call's argument objects to the procedure's
|
||||
As an example, the bytecode interpreter shares argument values
|
||||
between calling and called Tcl procedures to avoid having to copy values.
|
||||
It assigns the call's argument values to the procedure's
|
||||
formal parameter variables.
|
||||
In doing so, it calls \fBTcl_IncrRefCount\fR to increment
|
||||
the reference count of each argument since there is now a new
|
||||
@@ -303,31 +304,31 @@ reference to it from the formal parameter.
|
||||
When the called procedure returns,
|
||||
the interpreter calls \fBTcl_DecrRefCount\fR to decrement
|
||||
each argument's reference count.
|
||||
When an object's reference count drops less than or equal to zero,
|
||||
When a value's reference count drops less than or equal to zero,
|
||||
\fBTcl_DecrRefCount\fR reclaims its storage.
|
||||
Most command procedures do not have to be concerned about
|
||||
reference counting since they use an object's value immediately
|
||||
and do not retain a pointer to the object after they return.
|
||||
However, if they do retain a pointer to an object in a data structure,
|
||||
reference counting since they use a value's value immediately
|
||||
and do not retain a pointer to the value after they return.
|
||||
However, if they do retain a pointer to a value in a data structure,
|
||||
they must be careful to increment its reference count
|
||||
since the retained pointer is a new reference.
|
||||
.PP
|
||||
Command procedures that directly modify objects
|
||||
Command procedures that directly modify values
|
||||
such as those for \fBlappend\fR and \fBlinsert\fR must be careful to
|
||||
copy a shared object before changing it.
|
||||
They must first check whether the object is shared
|
||||
copy a shared value before changing it.
|
||||
They must first check whether the value is shared
|
||||
by calling \fBTcl_IsShared\fR.
|
||||
If the object is shared they must copy the object
|
||||
If the value is shared they must copy the value
|
||||
by using \fBTcl_DuplicateObj\fR;
|
||||
this returns a new duplicate of the original object
|
||||
this returns a new duplicate of the original value
|
||||
that has \fIrefCount\fR 0.
|
||||
If the object is not shared,
|
||||
If the value is not shared,
|
||||
the command procedure
|
||||
.QW "owns"
|
||||
the object and can safely modify it directly.
|
||||
the value and can safely modify it directly.
|
||||
For example, the following code appears in the command procedure
|
||||
that implements \fBlinsert\fR.
|
||||
This procedure modifies the list object passed to it in \fIobjv[1]\fR
|
||||
This procedure modifies the list value passed to it in \fIobjv[1]\fR
|
||||
by inserting \fIobjc-3\fR new elements before \fIindex\fR.
|
||||
.PP
|
||||
.CS
|
||||
@@ -340,11 +341,12 @@ result = Tcl_ListObjReplace(interp, listPtr, index, 0,
|
||||
.CE
|
||||
.PP
|
||||
As another example, \fBincr\fR's command procedure
|
||||
must check whether the variable's object is shared before
|
||||
must check whether the variable's value is shared before
|
||||
incrementing the integer in its internal representation.
|
||||
If it is shared, it needs to duplicate the object
|
||||
If it is shared, it needs to duplicate the value
|
||||
in order to avoid accidentally changing values in other data structures.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_ConvertToType(3), Tcl_GetIntFromObj(3), Tcl_ListObjAppendElement(3), Tcl_ListObjIndex(3), Tcl_ListObjReplace(3), Tcl_RegisterObjType(3)
|
||||
.SH KEYWORDS
|
||||
internal representation, object, object creation, object type, reference counting, string representation, type conversion
|
||||
internal representation, value, value creation, value type,
|
||||
reference counting, string representation, type conversion
|
||||
|
||||
+32
-31
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl object types
|
||||
Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType \- manipulate Tcl value types
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -26,31 +26,32 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS "const char" *typeName
|
||||
.AP "const Tcl_ObjType" *typePtr in
|
||||
Points to the structure containing information about the Tcl object type.
|
||||
Points to the structure containing information about the Tcl value type.
|
||||
This storage must live forever,
|
||||
typically by being statically allocated.
|
||||
.AP "const char" *typeName in
|
||||
The name of a Tcl object type that \fBTcl_GetObjType\fR should look up.
|
||||
The name of a Tcl value type that \fBTcl_GetObjType\fR should look up.
|
||||
.AP Tcl_Interp *interp in
|
||||
Interpreter to use for error reporting.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
For \fBTcl_AppendAllObjTypes\fR, this points to the object onto which
|
||||
it appends the name of each object type as a list element.
|
||||
For \fBTcl_ConvertToType\fR, this points to an object that
|
||||
For \fBTcl_AppendAllObjTypes\fR, this points to the value onto which
|
||||
it appends the name of each value type as a list element.
|
||||
For \fBTcl_ConvertToType\fR, this points to a value that
|
||||
must have been the result of a previous call to \fBTcl_NewObj\fR.
|
||||
.BE
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The procedures in this man page manage Tcl object types.
|
||||
They are used to register new object types, look up types,
|
||||
The procedures in this man page manage Tcl value types (sometimes
|
||||
referred to as object types or \fBTcl_ObjType\fRs for historical reasons).
|
||||
They are used to register new value types, look up types,
|
||||
and force conversions from one type to another.
|
||||
.PP
|
||||
\fBTcl_RegisterObjType\fR registers a new Tcl object type
|
||||
in the table of all object types that \fBTcl_GetObjType\fR
|
||||
can look up by name. There are other object types supported by Tcl
|
||||
\fBTcl_RegisterObjType\fR registers a new Tcl value type
|
||||
in the table of all value types that \fBTcl_GetObjType\fR
|
||||
can look up by name. There are other value types supported by Tcl
|
||||
as well, which Tcl chooses not to register. Extensions can likewise
|
||||
choose to register the object types they create or not.
|
||||
choose to register the value types they create or not.
|
||||
The argument \fItypePtr\fR points to a Tcl_ObjType structure that
|
||||
describes the new type by giving its name
|
||||
and by supplying pointers to four procedures
|
||||
@@ -65,13 +66,13 @@ in the section \fBTHE TCL_OBJTYPE STRUCTURE\fR below.
|
||||
with name \fItypeName\fR.
|
||||
It returns NULL if no type with that name is registered.
|
||||
.PP
|
||||
\fBTcl_AppendAllObjTypes\fR appends the name of each registered object type
|
||||
as a list element onto the Tcl object referenced by \fIobjPtr\fR.
|
||||
\fBTcl_AppendAllObjTypes\fR appends the name of each registered value type
|
||||
as a list element onto the Tcl value referenced by \fIobjPtr\fR.
|
||||
The return value is \fBTCL_OK\fR unless there was an error
|
||||
converting \fIobjPtr\fR to a list object;
|
||||
converting \fIobjPtr\fR to a list value;
|
||||
in that case \fBTCL_ERROR\fR is returned.
|
||||
.PP
|
||||
\fBTcl_ConvertToType\fR converts an object from one type to another
|
||||
\fBTcl_ConvertToType\fR converts a value from one type to another
|
||||
if possible.
|
||||
It creates a new internal representation for \fIobjPtr\fR
|
||||
appropriate for the target type \fItypePtr\fR
|
||||
@@ -79,7 +80,7 @@ and sets its \fItypePtr\fR member as determined by calling the
|
||||
\fItypePtr->setFromAnyProc\fR routine.
|
||||
Any internal representation for \fIobjPtr\fR's old type is freed.
|
||||
If an error occurs during conversion, it returns \fBTCL_ERROR\fR
|
||||
and leaves an error message in the result object for \fIinterp\fR
|
||||
and leaves an error message in the result value for \fIinterp\fR
|
||||
unless \fIinterp\fR is NULL.
|
||||
Otherwise, it returns \fBTCL_OK\fR.
|
||||
Passing a NULL \fIinterp\fR allows this procedure to be used
|
||||
@@ -94,7 +95,7 @@ use of another related Tcl_ObjType, if it sees fit.
|
||||
.VE 8.5
|
||||
.SH "THE TCL_OBJTYPE STRUCTURE"
|
||||
.PP
|
||||
Extension writers can define new object types by defining four
|
||||
Extension writers can define new value types by defining four
|
||||
procedures and
|
||||
initializing a Tcl_ObjType structure to describe the type.
|
||||
Extension writers may also pass a pointer to their Tcl_ObjType
|
||||
@@ -119,12 +120,12 @@ When a type is registered, this is the name used by callers
|
||||
of \fBTcl_GetObjType\fR to lookup the type. For unregistered
|
||||
types, the \fIname\fR field is primarily of value for debugging.
|
||||
The remaining four members are pointers to procedures
|
||||
called by the generic Tcl object code:
|
||||
called by the generic Tcl value code:
|
||||
.SS "THE SETFROMANYPROC FIELD"
|
||||
.PP
|
||||
The \fIsetFromAnyProc\fR member contains the address of a function
|
||||
called to create a valid internal representation
|
||||
from an object's string representation.
|
||||
from a value's string representation.
|
||||
.PP
|
||||
.CS
|
||||
typedef int \fBTcl_SetFromAnyProc\fR(
|
||||
@@ -134,7 +135,7 @@ typedef int \fBTcl_SetFromAnyProc\fR(
|
||||
.PP
|
||||
If an internal representation cannot be created from the string,
|
||||
it returns \fBTCL_ERROR\fR and puts a message
|
||||
describing the error in the result object for \fIinterp\fR
|
||||
describing the error in the result value for \fIinterp\fR
|
||||
unless \fIinterp\fR is NULL.
|
||||
If \fIsetFromAnyProc\fR is successful,
|
||||
it stores the new internal representation,
|
||||
@@ -169,7 +170,7 @@ should \fInot\fR be registered.
|
||||
.PP
|
||||
The \fIupdateStringProc\fR member contains the address of a function
|
||||
called to create a valid string representation
|
||||
from an object's internal representation.
|
||||
from a value's internal representation.
|
||||
.PP
|
||||
.CS
|
||||
typedef void \fBTcl_UpdateStringProc\fR(
|
||||
@@ -203,7 +204,7 @@ or other similar routines ask for the string representation.
|
||||
.SS "THE DUPINTREPPROC FIELD"
|
||||
.PP
|
||||
The \fIdupIntRepProc\fR member contains the address of a function
|
||||
called to copy an internal representation from one object to another.
|
||||
called to copy an internal representation from one value to another.
|
||||
.PP
|
||||
.CS
|
||||
typedef void \fBTcl_DupInternalRepProc\fR(
|
||||
@@ -215,7 +216,7 @@ typedef void \fBTcl_DupInternalRepProc\fR(
|
||||
internal representation.
|
||||
Before the call,
|
||||
\fIsrcPtr\fR's internal representation is valid and \fIdupPtr\fR's is not.
|
||||
\fIsrcPtr\fR's object type determines what
|
||||
\fIsrcPtr\fR's value type determines what
|
||||
copying its internal representation means.
|
||||
.PP
|
||||
For example, the \fIdupIntRepProc\fR for the Tcl integer type
|
||||
@@ -226,7 +227,7 @@ reasonably can.
|
||||
.SS "THE FREEINTREPPROC FIELD"
|
||||
.PP
|
||||
The \fIfreeIntRepProc\fR member contains the address of a function
|
||||
that is called when an object is freed.
|
||||
that is called when a value is freed.
|
||||
.PP
|
||||
.CS
|
||||
typedef void \fBTcl_FreeInternalRepProc\fR(
|
||||
@@ -234,22 +235,22 @@ typedef void \fBTcl_FreeInternalRepProc\fR(
|
||||
.CE
|
||||
.PP
|
||||
The \fIfreeIntRepProc\fR function can deallocate the storage
|
||||
for the object's internal representation
|
||||
and do other type-specific processing necessary when an object is freed.
|
||||
for the value's internal representation
|
||||
and do other type-specific processing necessary when a value is freed.
|
||||
.PP
|
||||
For example, the list type's \fIfreeIntRepProc\fR respects
|
||||
the storage sharing scheme established by the \fIdupIntRepProc\fR
|
||||
so that it only frees storage when the last object sharing it
|
||||
so that it only frees storage when the last value sharing it
|
||||
is being freed.
|
||||
.PP
|
||||
The \fIfreeIntRepProc\fR member can be set to NULL
|
||||
to indicate that the internal representation does not require freeing.
|
||||
The \fIfreeIntRepProc\fR implementation must not access the
|
||||
\fIbytes\fR member of the object, since Tcl makes its own internal
|
||||
uses of that field during object deletion. The defined tasks for
|
||||
\fIbytes\fR member of the value, since Tcl makes its own internal
|
||||
uses of that field during value deletion. The defined tasks for
|
||||
the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR
|
||||
member.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3)
|
||||
.SH KEYWORDS
|
||||
internal representation, object, object type, string representation, type conversion
|
||||
internal representation, value, value type, string representation, type conversion
|
||||
|
||||
+13
-13
@@ -152,24 +152,24 @@ The pattern to match on, passed to Tcl_StringMatch, or NULL.
|
||||
A Tcl channel for input or output. Must have been the return value
|
||||
from a procedure such as \fBTcl_OpenFileChannel\fR.
|
||||
.AP Tcl_Obj *readObjPtr in/out
|
||||
A pointer to a Tcl Object in which to store the characters read from the
|
||||
A pointer to a Tcl value in which to store the characters read from the
|
||||
channel.
|
||||
.AP int charsToRead in
|
||||
The number of characters to read from the channel. If the channel's encoding
|
||||
is \fBbinary\fR, this is equivalent to the number of bytes to read from the
|
||||
channel.
|
||||
.AP int appendFlag in
|
||||
If non-zero, data read from the channel will be appended to the object.
|
||||
Otherwise, the data will replace the existing contents of the object.
|
||||
If non-zero, data read from the channel will be appended to the value.
|
||||
Otherwise, the data will replace the existing contents of the value.
|
||||
.AP char *readBuf out
|
||||
A buffer in which to store the bytes read from the channel.
|
||||
.AP int bytesToRead in
|
||||
The number of bytes to read from the channel. The buffer \fIreadBuf\fR must
|
||||
be large enough to hold this many bytes.
|
||||
.AP Tcl_Obj *lineObjPtr in/out
|
||||
A pointer to a Tcl object in which to store the line read from the
|
||||
A pointer to a Tcl value in which to store the line read from the
|
||||
channel. The line read will be appended to the current value of the
|
||||
object.
|
||||
value.
|
||||
.AP Tcl_DString *lineRead in/out
|
||||
A pointer to a Tcl dynamic string in which to store the line read from the
|
||||
channel. Must have been initialized by the caller. The line read will be
|
||||
@@ -182,7 +182,7 @@ Length of the input
|
||||
Flag indicating whether the input should be added to the end or
|
||||
beginning of the channel buffer.
|
||||
.AP Tcl_Obj *writeObjPtr in
|
||||
A pointer to a Tcl Object whose contents will be output to the channel.
|
||||
A pointer to a Tcl value whose contents will be output to the channel.
|
||||
.AP "const char" *charBuf in
|
||||
A buffer containing the characters to output to the channel.
|
||||
.AP "const char" *byteBuf in
|
||||
@@ -239,7 +239,7 @@ returns NULL and records a POSIX error code that can be
|
||||
retrieved with \fBTcl_GetErrno\fR.
|
||||
In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
|
||||
leaves an error message in \fIinterp\fR's result after any error.
|
||||
As of Tcl 8.4, the object-based API \fBTcl_FSOpenFileChannel\fR should
|
||||
As of Tcl 8.4, the value-based API \fBTcl_FSOpenFileChannel\fR should
|
||||
be used in preference to \fBTcl_OpenFileChannel\fR wherever possible.
|
||||
.PP
|
||||
The newly created channel is not registered in the supplied interpreter; to
|
||||
@@ -305,7 +305,7 @@ open for reading and writing.
|
||||
.PP
|
||||
\fBTcl_GetChannelNames\fR and \fBTcl_GetChannelNamesEx\fR write the
|
||||
names of the registered channels to the interpreter's result as a
|
||||
list object. \fBTcl_GetChannelNamesEx\fR will filter these names
|
||||
list value. \fBTcl_GetChannelNamesEx\fR will filter these names
|
||||
according to the \fIpattern\fR. If \fIpattern\fR is NULL, then it
|
||||
will not do any filtering. The return value is \fBTCL_OK\fR if no
|
||||
errors occurred writing to the result, otherwise it is \fBTCL_ERROR\fR,
|
||||
@@ -435,7 +435,7 @@ platform-specific modes are described in the manual entry for the Tcl
|
||||
As a performance optimization, when reading from a channel with the encoding
|
||||
\fBbinary\fR, the bytes are not converted to UTF-8 as they are read.
|
||||
Instead, they are stored in \fIreadObjPtr\fR's internal representation as a
|
||||
byte-array object. The string representation of this object will only be
|
||||
byte-array value. The string representation of this value will only be
|
||||
constructed if it is needed (e.g., because of a call to
|
||||
\fBTcl_GetStringFromObj\fR). In this way, byte-oriented data can be read
|
||||
from a channel, manipulated by calling \fBTcl_GetByteArrayFromObj\fR and
|
||||
@@ -484,7 +484,7 @@ of input unavailability.
|
||||
.PP
|
||||
\fBTcl_Gets\fR is the same as \fBTcl_GetsObj\fR except the resulting
|
||||
characters are appended to the dynamic string given by
|
||||
\fIlineRead\fR rather than a Tcl object.
|
||||
\fIlineRead\fR rather than a Tcl value.
|
||||
.SH "TCL_UNGETS"
|
||||
.PP
|
||||
\fBTcl_Ungets\fR is used to add data to the input queue of a channel,
|
||||
@@ -523,14 +523,14 @@ end-of-line sequences according to the \fB\-translation\fR option for the
|
||||
channel. This is done even if the channel has no encoding.
|
||||
.PP
|
||||
\fBTcl_WriteObj\fR is similar to \fBTcl_WriteChars\fR except it
|
||||
accepts a Tcl object whose contents will be output to the channel. The
|
||||
accepts a Tcl value whose contents will be output to the channel. The
|
||||
UTF-8 characters in \fIwriteObjPtr\fR's string representation are converted
|
||||
to the channel's encoding and queued for output to \fIchannel\fR.
|
||||
As a performance optimization, when writing to a channel with the encoding
|
||||
\fBbinary\fR, UTF-8 characters are not converted as they are written.
|
||||
Instead, the bytes in \fIwriteObjPtr\fR's internal representation as a
|
||||
byte-array object are written to the channel. The byte-array representation
|
||||
of the object will be constructed if it is needed. In this way,
|
||||
byte-array value are written to the channel. The byte-array representation
|
||||
of the value will be constructed if it is needed. In this way,
|
||||
byte-oriented data can be read from a channel, manipulated by calling
|
||||
\fBTcl_GetByteArrayFromObj\fR and related functions, and then written to a
|
||||
channel without the expense of ever converting to or from UTF-8.
|
||||
|
||||
+2
-2
@@ -134,7 +134,7 @@ typedef int (\fBTcl_ArgvFuncProc\fR)(
|
||||
.PP
|
||||
The result is a boolean value indicating whether to consume the following
|
||||
argument. The \fIclientData\fR is the value from the table entry, the
|
||||
\fIobjPtr\fR is the object that represents the following argument or NULL if
|
||||
\fIobjPtr\fR is the value that represents the following argument or NULL if
|
||||
there are no following arguments at all, and the \fIdstPtr\fR argument to the
|
||||
\fBTcl_ArgvFuncProc\fR is the location to write the parsed value to.
|
||||
.RE
|
||||
@@ -186,7 +186,7 @@ marks all following arguments to be left unprocessed. The \fIsrcPtr\fR,
|
||||
.
|
||||
This argument takes a following string value argument. A pointer to the string
|
||||
will be stored at \fIdstPtr\fR; the string inside will have a lifetime linked
|
||||
to the lifetime of the string representation of the argument object that it
|
||||
to the lifetime of the string representation of the argument value that it
|
||||
came from, and so should be copied if it needs to be retained. The
|
||||
\fIsrcPtr\fR and \fIclientData\fR fields are ignored.
|
||||
.SH "SEE ALSO"
|
||||
|
||||
+2
-2
@@ -194,9 +194,9 @@ result; it can be retrieved using \fBTcl_GetObjResult\fR.
|
||||
.PP
|
||||
\fBTcl_EvalTokens\fR differs from \fBTcl_EvalTokensStandard\fR only in
|
||||
the return convention used: it returns the result in a new Tcl_Obj.
|
||||
The reference count of the object returned as result has been
|
||||
The reference count of the value returned as result has been
|
||||
incremented, so the caller must
|
||||
invoke \fBTcl_DecrRefCount\fR when it is finished with the object.
|
||||
invoke \fBTcl_DecrRefCount\fR when it is finished with the value.
|
||||
If an error or other exception occurs while evaluating the tokens
|
||||
(such as a reference to a non-existent variable) then the return value
|
||||
is NULL and an error message is left in \fIinterp\fR's result. The use
|
||||
|
||||
+3
-3
@@ -20,7 +20,7 @@ int
|
||||
.AP Tcl_Interp *interp in
|
||||
Tcl interpreter in which to evaluate command.
|
||||
.AP Tcl_Obj *cmdPtr in
|
||||
Points to a Tcl object containing a command (or sequence of commands)
|
||||
Points to a Tcl value containing a command (or sequence of commands)
|
||||
to execute.
|
||||
.AP int flags in
|
||||
An OR'ed combination of flag bits. \fBTCL_NO_EVAL\fR means record the
|
||||
@@ -35,7 +35,7 @@ on the history list and then execute it using \fBTcl_EvalObjEx\fR
|
||||
(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set
|
||||
in \fIflags\fR).
|
||||
It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
|
||||
as well as a result object containing additional information
|
||||
as well as a result value containing additional information
|
||||
(a result value or error message)
|
||||
that can be retrieved using \fBTcl_GetObjResult\fR.
|
||||
If you do not want the command recorded on the history list then
|
||||
@@ -50,4 +50,4 @@ the command is recorded without being evaluated.
|
||||
Tcl_EvalObjEx, Tcl_GetObjResult
|
||||
|
||||
.SH KEYWORDS
|
||||
command, event, execute, history, interpreter, object, record
|
||||
command, event, execute, history, interpreter, value, record
|
||||
|
||||
+3
-3
@@ -44,9 +44,9 @@ If the \fIflags\fR argument contains the \fBTCL_NO_EVAL\fR bit then
|
||||
the command is recorded without being evaluated.
|
||||
.PP
|
||||
Note that \fBTcl_RecordAndEval\fR has been largely replaced by the
|
||||
object-based procedure \fBTcl_RecordAndEvalObj\fR.
|
||||
That object-based procedure records and optionally executes
|
||||
a command held in a Tcl object instead of a string.
|
||||
value-based procedure \fBTcl_RecordAndEvalObj\fR.
|
||||
That value-based procedure records and optionally executes
|
||||
a command held in a Tcl value instead of a string.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
Tcl_RecordAndEvalObj
|
||||
|
||||
+9
-9
@@ -45,12 +45,12 @@ void
|
||||
Tcl interpreter to use for error reporting. The interpreter may be
|
||||
NULL if no error reporting is desired.
|
||||
.AP Tcl_Obj *textObj in/out
|
||||
Refers to the object from which to get the text to search. The
|
||||
internal representation of the object may be converted to a form that
|
||||
Refers to the value from which to get the text to search. The
|
||||
internal representation of the value may be converted to a form that
|
||||
can be efficiently searched.
|
||||
.AP Tcl_Obj *patObj in/out
|
||||
Refers to the object from which to get a regular expression. The
|
||||
compiled regular expression is cached in the object.
|
||||
Refers to the value from which to get a regular expression. The
|
||||
compiled regular expression is cached in the value.
|
||||
.AP char *text in
|
||||
Text to search for a match with a regular expression.
|
||||
.AP "const char" *pattern in
|
||||
@@ -110,7 +110,7 @@ If an error occurs in the matching process (e.g. \fIpattern\fR
|
||||
is not a valid regular expression) then \fBTcl_RegExpMatch\fR
|
||||
returns \-1 and leaves an error message in the interpreter result.
|
||||
\fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
|
||||
operates on the Tcl objects \fItextObj\fR and \fIpatObj\fR instead of
|
||||
operates on the Tcl values \fItextObj\fR and \fIpatObj\fR instead of
|
||||
UTF strings.
|
||||
\fBTcl_RegExpMatchObj\fR is generally more efficient than
|
||||
\fBTcl_RegExpMatch\fR, so it is the preferred interface.
|
||||
@@ -164,18 +164,18 @@ If there is no range corresponding to \fIindex\fR then NULL
|
||||
is stored in \fI*startPtr\fR and \fI*endPtr\fR.
|
||||
.PP
|
||||
\fBTcl_GetRegExpFromObj\fR, \fBTcl_RegExpExecObj\fR, and
|
||||
\fBTcl_RegExpGetInfo\fR are object interfaces that provide the most
|
||||
\fBTcl_RegExpGetInfo\fR are value interfaces that provide the most
|
||||
direct control of Henry Spencer's regular expression library. For
|
||||
users that need to modify compilation and execution options directly,
|
||||
it is recommended that you use these interfaces instead of calling the
|
||||
internal regexp functions. These interfaces handle the details of UTF
|
||||
to Unicode translations as well as providing improved performance
|
||||
through caching in the pattern and string objects.
|
||||
through caching in the pattern and string values.
|
||||
.PP
|
||||
\fBTcl_GetRegExpFromObj\fR attempts to return a compiled regular
|
||||
expression from the \fIpatObj\fR. If the object does not already
|
||||
expression from the \fIpatObj\fR. If the value does not already
|
||||
contain a compiled regular expression it will attempt to create one
|
||||
from the string in the object and assign it to the internal
|
||||
from the string in the value and assign it to the internal
|
||||
representation of the \fIpatObj\fR. The return value of this function
|
||||
is of type \fBTcl_RegExp\fR. The return value is a token for this
|
||||
compiled form, which can be used in subsequent calls to
|
||||
|
||||
+2
-2
@@ -96,12 +96,12 @@ or \fBTcl_DiscardInterpState\fR to avoid a memory leak. Once
|
||||
the \fBTcl_InterpState\fR token is passed to one of them, the
|
||||
token is no longer valid and should not be used anymore.
|
||||
.PP
|
||||
\fBTcl_SaveResult\fR moves the string and object results
|
||||
\fBTcl_SaveResult\fR moves the string and value results
|
||||
of \fIinterp\fR into the location specified by \fIstatePtr\fR.
|
||||
\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
|
||||
leaves the result in its normal empty initialized state.
|
||||
.PP
|
||||
\fBTcl_RestoreResult\fR moves the string and object results from
|
||||
\fBTcl_RestoreResult\fR moves the string and value results from
|
||||
\fIstatePtr\fR back into \fIinterp\fR. Any result or error that was
|
||||
already in the interpreter will be cleared. The \fIstatePtr\fR is left
|
||||
in an uninitialized state and cannot be used until another call to
|
||||
|
||||
+4
-4
@@ -55,12 +55,12 @@ arrange for their return as errors. The POSIX error codes set by a driver are
|
||||
used now if and only if no messages are present.
|
||||
.PP
|
||||
\fBTcl_SetChannelError\fR stores error information in the bypass area of the
|
||||
specified channel. The number of references to the \fBmsg\fR object goes up by
|
||||
specified channel. The number of references to the \fBmsg\fR value goes up by
|
||||
one. Previously stored information will be discarded, by releasing the
|
||||
reference held by the channel. The channel reference must not be NULL.
|
||||
.PP
|
||||
\fBTcl_SetChannelErrorInterp\fR stores error information in the bypass area of
|
||||
the specified interpreter. The number of references to the \fBmsg\fR object
|
||||
the specified interpreter. The number of references to the \fBmsg\fR value
|
||||
goes up by one. Previously stored information will be discarded, by releasing
|
||||
the reference held by the interpreter. The interpreter reference must not be
|
||||
NULL.
|
||||
@@ -72,7 +72,7 @@ NULL, until an intervening invocation of \fBTcl_SetChannelError\fR with a
|
||||
non-NULL message. The \fImsgPtr\fR must not be NULL. The reference count of
|
||||
the message is not touched. The reference previously held by the channel is
|
||||
now held by the caller of the function and it is its responsibility to release
|
||||
that reference when it is done with the object.
|
||||
that reference when it is done with the value.
|
||||
.PP
|
||||
\fBTcl_GetChannelErrorInterp\fR places either the error message held in the
|
||||
bypass area of the specified interpreter into \fImsgPtr\fR, or NULL; and
|
||||
@@ -82,7 +82,7 @@ return NULL, until an intervening invocation of
|
||||
not be NULL. The reference count of the message is not touched. The reference
|
||||
previously held by the interpreter is now held by the caller of the function
|
||||
and it is its responsibility to release that reference when it is done with
|
||||
the object.
|
||||
the value.
|
||||
.PP
|
||||
Which functions of a channel driver are allowed to use which bypass function
|
||||
is listed below, as is which functions of the public channel API may leave a
|
||||
|
||||
+21
-21
@@ -42,7 +42,7 @@ const char *
|
||||
.AP Tcl_Interp *interp out
|
||||
Interpreter whose result is to be modified or read.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
Object value to become result for \fIinterp\fR.
|
||||
Tcl value to become result for \fIinterp\fR.
|
||||
.AP char *result in
|
||||
String value to become result for \fIinterp\fR or to be
|
||||
appended to the existing result.
|
||||
@@ -74,32 +74,32 @@ information as well.
|
||||
.PP
|
||||
The procedures described here are utilities for manipulating the
|
||||
result value in a Tcl interpreter.
|
||||
The interpreter result may be either a Tcl object or a string.
|
||||
The interpreter result may be either a Tcl value or a string.
|
||||
For example, \fBTcl_SetObjResult\fR and \fBTcl_SetResult\fR
|
||||
set the interpreter result to, respectively, an object and a string.
|
||||
set the interpreter result to, respectively, a value and a string.
|
||||
Similarly, \fBTcl_GetObjResult\fR and \fBTcl_GetStringResult\fR
|
||||
return the interpreter result as an object and as a string.
|
||||
The procedures always keep the string and object forms
|
||||
return the interpreter result as a value and as a string.
|
||||
The procedures always keep the string and value forms
|
||||
of the interpreter result consistent.
|
||||
For example, if \fBTcl_SetObjResult\fR is called to set
|
||||
the result to an object,
|
||||
the result to a value,
|
||||
then \fBTcl_GetStringResult\fR is called,
|
||||
it will return the object's string value.
|
||||
it will return the value's string representation.
|
||||
.PP
|
||||
\fBTcl_SetObjResult\fR
|
||||
arranges for \fIobjPtr\fR to be the result for \fIinterp\fR,
|
||||
replacing any existing result.
|
||||
The result is left pointing to the object
|
||||
The result is left pointing to the value
|
||||
referenced by \fIobjPtr\fR.
|
||||
\fIobjPtr\fR's reference count is incremented
|
||||
since there is now a new reference to it from \fIinterp\fR.
|
||||
The reference count for any old result object
|
||||
is decremented and the old result object is freed if no
|
||||
The reference count for any old result value
|
||||
is decremented and the old result value is freed if no
|
||||
references to it remain.
|
||||
.PP
|
||||
\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as an object.
|
||||
The object's reference count is not incremented;
|
||||
if the caller needs to retain a long-term pointer to the object
|
||||
\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as a value.
|
||||
The value's reference count is not incremented;
|
||||
if the caller needs to retain a long-term pointer to the value
|
||||
they should use \fBTcl_IncrRefCount\fR to increment its reference count
|
||||
in order to keep it from being freed too early or accidentally changed.
|
||||
.PP
|
||||
@@ -115,19 +115,19 @@ and \fBTcl_SetResult\fR
|
||||
re-initializes \fIinterp\fR's result to point to an empty string.
|
||||
.PP
|
||||
\fBTcl_GetStringResult\fR returns the result for \fIinterp\fR as a string.
|
||||
If the result was set to an object by a \fBTcl_SetObjResult\fR call,
|
||||
the object form will be converted to a string and returned.
|
||||
If the object's string representation contains null bytes,
|
||||
If the result was set to a value by a \fBTcl_SetObjResult\fR call,
|
||||
the value form will be converted to a string and returned.
|
||||
If the value's string representation contains null bytes,
|
||||
this conversion will lose information.
|
||||
For this reason, programmers are encouraged to
|
||||
write their code to use the new object API procedures
|
||||
write their code to use the new value API procedures
|
||||
and to call \fBTcl_GetObjResult\fR instead.
|
||||
.PP
|
||||
\fBTcl_ResetResult\fR clears the result for \fIinterp\fR
|
||||
and leaves the result in its normal empty initialized state.
|
||||
If the result is an object,
|
||||
If the result is a value,
|
||||
its reference count is decremented and the result is left
|
||||
pointing to an unshared object representing an empty string.
|
||||
pointing to an unshared value representing an empty string.
|
||||
If the result is a dynamically allocated string, its memory is free*d
|
||||
and the result is left as a empty string.
|
||||
\fBTcl_ResetResult\fR also clears the error state managed by
|
||||
@@ -167,7 +167,7 @@ The source interpreter will have its result reset by this operation.
|
||||
Use of the following procedures (is deprecated
|
||||
since they manipulate the Tcl result as a string.
|
||||
Procedures such as \fBTcl_SetObjResult\fR
|
||||
that manipulate the result as an object
|
||||
that manipulate the result as a value
|
||||
can be significantly more efficient.
|
||||
.PP
|
||||
\fBTcl_AppendElement\fR is similar to \fBTcl_AppendResult\fR in
|
||||
@@ -252,4 +252,4 @@ the value of \fIresult\fR passed to \fBTcl_SetResult\fR.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_AddErrorInfo, Tcl_CreateObjCommand, Tcl_SetErrorCode, Tcl_Interp
|
||||
.SH KEYWORDS
|
||||
append, command, element, list, object, result, return value, interpreter
|
||||
append, command, element, list, value, result, return value, interpreter
|
||||
|
||||
+4
-4
@@ -57,7 +57,7 @@ to specify a variable in a particular namespace.
|
||||
If non-NULL, gives name of element within array; in this
|
||||
case \fIname1\fR must refer to an array variable.
|
||||
.AP Tcl_Obj *newValuePtr in
|
||||
Points to a Tcl object containing the new value for the variable.
|
||||
Points to a Tcl value containing the new value for the variable.
|
||||
.AP int flags in
|
||||
OR-ed combination of bits providing additional information. See below
|
||||
for valid values.
|
||||
@@ -71,12 +71,12 @@ an array.
|
||||
New value for variable, specified as a null-terminated string.
|
||||
A copy of this value is stored in the variable.
|
||||
.AP Tcl_Obj *part1Ptr in
|
||||
Points to a Tcl object containing the variable's name.
|
||||
Points to a Tcl value containing the variable's name.
|
||||
The name may include a series of \fB::\fR namespace qualifiers
|
||||
to specify a variable in a particular namespace.
|
||||
May refer to a scalar variable or an element of an array variable.
|
||||
.AP Tcl_Obj *part2Ptr in
|
||||
If non-NULL, points to an object containing the name of an element
|
||||
If non-NULL, points to a value containing the name of an element
|
||||
within an array and \fIpart1Ptr\fR must refer to an array variable.
|
||||
.BE
|
||||
|
||||
@@ -246,4 +246,4 @@ array is removed.
|
||||
Tcl_GetObjResult, Tcl_GetStringResult, Tcl_TraceVar
|
||||
|
||||
.SH KEYWORDS
|
||||
array, get variable, interpreter, object, scalar, set, unset, variable
|
||||
array, get variable, interpreter, scalar, set, unset, value, variable
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ A pointer to an initialized \fBTcl_DString\fR to which the result of
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
These procedures have been superseded by the objectified procedures in
|
||||
These procedures have been superseded by the Tcl-value-aware procedures in
|
||||
the \fBFileSystem\fR man page, which are more efficient.
|
||||
.PP
|
||||
These procedures may be used to disassemble and reassemble file
|
||||
|
||||
+51
-51
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_StringObj 3 8.1 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_NewStringObj, Tcl_NewUnicodeObj, Tcl_SetStringObj, Tcl_SetUnicodeObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_GetUnicodeFromObj, Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange, Tcl_AppendToObj, Tcl_AppendUnicodeToObj, Tcl_AppendObjToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendLimitedToObj, Tcl_Format, Tcl_AppendFormatToObj, Tcl_ObjPrintf, Tcl_AppendPrintfToObj, Tcl_SetObjLength, Tcl_AttemptSetObjLength, Tcl_ConcatObj \- manipulate Tcl objects as strings
|
||||
Tcl_NewStringObj, Tcl_NewUnicodeObj, Tcl_SetStringObj, Tcl_SetUnicodeObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_GetUnicodeFromObj, Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange, Tcl_AppendToObj, Tcl_AppendUnicodeToObj, Tcl_AppendObjToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendLimitedToObj, Tcl_Format, Tcl_AppendFormatToObj, Tcl_ObjPrintf, Tcl_AppendPrintfToObj, Tcl_SetObjLength, Tcl_AttemptSetObjLength, Tcl_ConcatObj \- manipulate Tcl values as strings
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -88,7 +88,7 @@ Tcl_Obj *
|
||||
.AS "const Tcl_UniChar" *appendObjPtr in/out
|
||||
.AP "const char" *bytes in
|
||||
Points to the first byte of an array of UTF-8-encoded bytes
|
||||
used to set or append to a string object.
|
||||
used to set or append to a string value.
|
||||
This byte array may contain embedded null characters
|
||||
unless \fInumChars\fR is negative. (Applications needing null bytes
|
||||
should represent them as the two-byte sequence \fI\e700\e600\fR, use
|
||||
@@ -96,32 +96,32 @@ should represent them as the two-byte sequence \fI\e700\e600\fR, use
|
||||
the string is a collection of uninterpreted bytes.)
|
||||
.AP int length in
|
||||
The number of bytes to copy from \fIbytes\fR when
|
||||
initializing, setting, or appending to a string object.
|
||||
initializing, setting, or appending to a string value.
|
||||
If negative, all bytes up to the first null are used.
|
||||
.AP "const Tcl_UniChar" *unicode in
|
||||
Points to the first byte of an array of Unicode characters
|
||||
used to set or append to a string object.
|
||||
used to set or append to a string value.
|
||||
This byte array may contain embedded null characters
|
||||
unless \fInumChars\fR is negative.
|
||||
.AP int numChars in
|
||||
The number of Unicode characters to copy from \fIunicode\fR when
|
||||
initializing, setting, or appending to a string object.
|
||||
initializing, setting, or appending to a string value.
|
||||
If negative, all characters up to the first null character are used.
|
||||
.AP int index in
|
||||
The index of the Unicode character to return.
|
||||
.AP int first in
|
||||
The index of the first Unicode character in the Unicode range to be
|
||||
returned as a new object.
|
||||
returned as a new value.
|
||||
.AP int last in
|
||||
The index of the last Unicode character in the Unicode range to be
|
||||
returned as a new object.
|
||||
returned as a new value.
|
||||
.AP Tcl_Obj *objPtr in/out
|
||||
Points to an object to manipulate.
|
||||
Points to a value to manipulate.
|
||||
.AP Tcl_Obj *appendObjPtr in
|
||||
The object to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
|
||||
The value to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
|
||||
.AP int *lengthPtr out
|
||||
If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
|
||||
the length of an object's string representation.
|
||||
the length of a value's string representation.
|
||||
.AP "const char" *string in
|
||||
Null-terminated string value to append to \fIobjPtr\fR.
|
||||
.AP va_list argList in
|
||||
@@ -139,46 +139,46 @@ Format control string including % conversion specifiers.
|
||||
.AP int objc in
|
||||
The number of elements to format or concatenate.
|
||||
.AP Tcl_Obj *objv[] in
|
||||
The array of objects to format or concatenate.
|
||||
The array of values to format or concatenate.
|
||||
.AP int newLength in
|
||||
New length for the string value of \fIobjPtr\fR, not including the
|
||||
final null character.
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The procedures described in this manual entry allow Tcl objects to
|
||||
The procedures described in this manual entry allow Tcl values to
|
||||
be manipulated as string values. They use the internal representation
|
||||
of the object to store additional information to make the string
|
||||
of the value to store additional information to make the string
|
||||
manipulations more efficient. In particular, they make a series of
|
||||
append operations efficient by allocating extra storage space for the
|
||||
string so that it does not have to be copied for each append.
|
||||
Also, indexing and length computations are optimized because the
|
||||
Unicode string representation is calculated and cached as needed.
|
||||
When using the \fBTcl_Append*\fR family of functions where the
|
||||
interpreter's result is the object being appended to, it is important
|
||||
interpreter's result is the value being appended to, it is important
|
||||
to call Tcl_ResetResult first to ensure you are not unintentionally
|
||||
appending to existing data in the result object.
|
||||
appending to existing data in the result value.
|
||||
.PP
|
||||
\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new object
|
||||
or modify an existing object to hold a copy of the string given by
|
||||
\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new value
|
||||
or modify an existing value to hold a copy of the string given by
|
||||
\fIbytes\fR and \fIlength\fR. \fBTcl_NewUnicodeObj\fR and
|
||||
\fBTcl_SetUnicodeObj\fR create a new object or modify an existing
|
||||
object to hold a copy of the Unicode string given by \fIunicode\fR and
|
||||
\fBTcl_SetUnicodeObj\fR create a new value or modify an existing
|
||||
value to hold a copy of the Unicode string given by \fIunicode\fR and
|
||||
\fInumChars\fR. \fBTcl_NewStringObj\fR and \fBTcl_NewUnicodeObj\fR
|
||||
return a pointer to a newly created object with reference count zero.
|
||||
All four procedures set the object to hold a copy of the specified
|
||||
return a pointer to a newly created value with reference count zero.
|
||||
All four procedures set the value to hold a copy of the specified
|
||||
string. \fBTcl_SetStringObj\fR and \fBTcl_SetUnicodeObj\fR free any
|
||||
old string representation as well as any old internal representation
|
||||
of the object.
|
||||
of the value.
|
||||
.PP
|
||||
\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return an object's
|
||||
\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return a value's
|
||||
string representation. This is given by the returned byte pointer and
|
||||
(for \fBTcl_GetStringFromObj\fR) length, which is stored in
|
||||
\fIlengthPtr\fR if it is non-NULL. If the object's UTF string
|
||||
\fIlengthPtr\fR if it is non-NULL. If the value's UTF string
|
||||
representation is invalid (its byte pointer is NULL), the string
|
||||
representation is regenerated from the object's internal
|
||||
representation is regenerated from the value's internal
|
||||
representation. The storage referenced by the returned byte pointer
|
||||
is owned by the object manager. It is passed back as a writable
|
||||
is owned by the value manager. It is passed back as a writable
|
||||
pointer so that extension author creating their own \fBTcl_ObjType\fR
|
||||
will be able to modify the string representation within the
|
||||
\fBTcl_UpdateStringProc\fR of their \fBTcl_ObjType\fR. Except for that
|
||||
@@ -194,45 +194,45 @@ The procedure \fBTcl_GetString\fR is used in the common case
|
||||
where the caller does not need the length of the string
|
||||
representation.
|
||||
.PP
|
||||
\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return an object's
|
||||
\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return a value's
|
||||
value as a Unicode string. This is given by the returned pointer and
|
||||
(for \fBTcl_GetUnicodeFromObj\fR) length, which is stored in
|
||||
\fIlengthPtr\fR if it is non-NULL. The storage referenced by the returned
|
||||
byte pointer is owned by the object manager and should not be modified by
|
||||
byte pointer is owned by the value manager and should not be modified by
|
||||
the caller. The procedure \fBTcl_GetUnicode\fR is used in the common case
|
||||
where the caller does not need the length of the unicode string
|
||||
representation.
|
||||
.PP
|
||||
\fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
|
||||
object's Unicode representation.
|
||||
value's Unicode representation.
|
||||
.PP
|
||||
\fBTcl_GetRange\fR returns a newly created object comprised of the
|
||||
\fBTcl_GetRange\fR returns a newly created value comprised of the
|
||||
characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
|
||||
object's Unicode representation. If the object's Unicode
|
||||
value's Unicode representation. If the value's Unicode
|
||||
representation is invalid, the Unicode representation is regenerated
|
||||
from the object's string representation.
|
||||
from the value's string representation.
|
||||
.PP
|
||||
\fBTcl_GetCharLength\fR returns the number of characters (as opposed
|
||||
to bytes) in the string object.
|
||||
to bytes) in the string value.
|
||||
.PP
|
||||
\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
|
||||
\fIlength\fR to the string representation of the object specified by
|
||||
\fIobjPtr\fR. If the object has an invalid string representation,
|
||||
\fIlength\fR to the string representation of the value specified by
|
||||
\fIobjPtr\fR. If the value has an invalid string representation,
|
||||
then an attempt is made to convert \fIbytes\fR is to the Unicode
|
||||
format. If the conversion is successful, then the converted form of
|
||||
\fIbytes\fR is appended to the object's Unicode representation.
|
||||
Otherwise, the object's Unicode representation is invalidated and
|
||||
\fIbytes\fR is appended to the value's Unicode representation.
|
||||
Otherwise, the value's Unicode representation is invalidated and
|
||||
converted to the UTF format, and \fIbytes\fR is appended to the
|
||||
object's new string representation.
|
||||
value's new string representation.
|
||||
.PP
|
||||
\fBTcl_AppendUnicodeToObj\fR appends the Unicode string given by
|
||||
\fIunicode\fR and \fInumChars\fR to the object specified by
|
||||
\fIobjPtr\fR. If the object has an invalid Unicode representation,
|
||||
\fIunicode\fR and \fInumChars\fR to the value specified by
|
||||
\fIobjPtr\fR. If the value has an invalid Unicode representation,
|
||||
then \fIunicode\fR is converted to the UTF format and appended to the
|
||||
object's string representation. Appends are optimized to handle
|
||||
value's string representation. Appends are optimized to handle
|
||||
repeated appends relatively efficiently (it over-allocates the string
|
||||
or Unicode space to avoid repeated reallocations and copies of
|
||||
object's string value).
|
||||
value's string value).
|
||||
.PP
|
||||
\fBTcl_AppendObjToObj\fR is similar to \fBTcl_AppendToObj\fR, but it
|
||||
appends the string or Unicode value (whichever exists and is best
|
||||
@@ -345,14 +345,14 @@ functionality is needed.
|
||||
.PP
|
||||
The \fBTcl_SetObjLength\fR procedure changes the length of the
|
||||
string value of its \fIobjPtr\fR argument. If the \fInewLength\fR
|
||||
argument is greater than the space allocated for the object's
|
||||
argument is greater than the space allocated for the value's
|
||||
string, then the string space is reallocated and the old value
|
||||
is copied to the new space; the bytes between the old length of
|
||||
the string and the new length may have arbitrary values.
|
||||
If the \fInewLength\fR argument is less than the current length
|
||||
of the object's string, with \fIobjPtr->length\fR is reduced without
|
||||
of the value's string, with \fIobjPtr->length\fR is reduced without
|
||||
reallocating the string space; the original allocated size for the
|
||||
string is recorded in the object, so that the string length can be
|
||||
string is recorded in the value, so that the string length can be
|
||||
enlarged in a subsequent call to \fBTcl_SetObjLength\fR without
|
||||
reallocating storage. In all cases \fBTcl_SetObjLength\fR leaves
|
||||
a null character at \fIobjPtr->bytes[newLength]\fR.
|
||||
@@ -361,24 +361,24 @@ a null character at \fIobjPtr->bytes[newLength]\fR.
|
||||
\fBTcl_SetObjLength\fR except that if sufficient memory to satisfy the
|
||||
request cannot be allocated, it does not cause the Tcl interpreter to
|
||||
\fBpanic\fR. Thus, if \fInewLength\fR is greater than the space
|
||||
allocated for the object's string, and there is not enough memory
|
||||
allocated for the value's string, and there is not enough memory
|
||||
available to satisfy the request, \fBTcl_AttemptSetObjLength\fR will take
|
||||
no action and return 0 to indicate failure. If there is enough memory
|
||||
to satisfy the request, \fBTcl_AttemptSetObjLength\fR behaves just like
|
||||
\fBTcl_SetObjLength\fR and returns 1 to indicate success.
|
||||
.PP
|
||||
The \fBTcl_ConcatObj\fR function returns a new string object whose
|
||||
The \fBTcl_ConcatObj\fR function returns a new string value whose
|
||||
value is the space-separated concatenation of the string
|
||||
representations of all of the objects in the \fIobjv\fR
|
||||
representations of all of the values in the \fIobjv\fR
|
||||
array. \fBTcl_ConcatObj\fR eliminates leading and trailing white space
|
||||
as it copies the string representations of the \fIobjv\fR array to the
|
||||
result. If an element of the \fIobjv\fR array consists of nothing but
|
||||
white space, then that object is ignored entirely. This white-space
|
||||
white space, then that value is ignored entirely. This white-space
|
||||
removal was added to make the output of the \fBconcat\fR command
|
||||
cleaner-looking. \fBTcl_ConcatObj\fR returns a pointer to a
|
||||
newly-created object whose ref count is zero.
|
||||
newly-created value whose ref count is zero.
|
||||
.SH "SEE ALSO"
|
||||
Tcl_NewObj(3), Tcl_IncrRefCount(3), Tcl_DecrRefCount(3), format(n), sprintf(3)
|
||||
.SH KEYWORDS
|
||||
append, internal representation, object, object type, string object,
|
||||
append, internal representation, value, value type, string value,
|
||||
string type, string representation, concat, concatenate, unicode
|
||||
|
||||
+3
-3
@@ -8,7 +8,7 @@
|
||||
.TH Tcl_SubstObj 3 8.4 Tcl "Tcl Library Procedures"
|
||||
.BS
|
||||
.SH NAME
|
||||
Tcl_SubstObj \- perform substitutions on Tcl objects
|
||||
Tcl_SubstObj \- perform substitutions on Tcl values
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
\fB#include <tcl.h>\fR
|
||||
@@ -22,7 +22,7 @@ Interpreter in which to execute Tcl scripts and lookup variables. If
|
||||
an error occurs, the interpreter's result is modified to hold an error
|
||||
message.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
A Tcl object containing the string to perform substitutions on.
|
||||
A Tcl value containing the string to perform substitutions on.
|
||||
.AP int flags in
|
||||
ORed combination of flag bits that specify which substitutions to
|
||||
perform. The flags \fBTCL_SUBST_COMMANDS\fR,
|
||||
@@ -36,7 +36,7 @@ The \fBTcl_SubstObj\fR function is used to perform substitutions on
|
||||
strings in the fashion of the \fBsubst\fR command. It gets the value
|
||||
of the string contained in \fIobjPtr\fR and scans it, copying
|
||||
characters and performing the chosen substitutions as it goes to an
|
||||
output object which is returned as the result of the function. In the
|
||||
output value which is returned as the result of the function. In the
|
||||
event of an error occurring during the execution of a command or
|
||||
variable substitution, the function returns NULL and an error message
|
||||
is left in \fIinterp\fR's result.
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ version of \fBTcl_InitMemory\fR to add the \fBmemory\fR command to Tcl.
|
||||
\fBTCL_MEM_DEBUG\fR must be either left defined for all modules or undefined
|
||||
for all modules that are going to be linked together. If they are not, link
|
||||
errors will occur, with either \fBTcl_DbCkfree\fR and \fBTcl_DbCkalloc\fR or
|
||||
\fBTcl_Ckalloc\fR and \fBTcl_Ckfree\fR being undefined.
|
||||
\fBTcl_Alloc\fR and \fBTcl_Free\fR being undefined.
|
||||
.PP
|
||||
Once memory debugging support has been compiled into Tcl, the C
|
||||
functions \fBTcl_ValidateAllMemory\fR, and \fBTcl_DumpActiveMemory\fR,
|
||||
|
||||
+36
-8
@@ -49,9 +49,11 @@ int
|
||||
.sp
|
||||
int
|
||||
\fBTcl_ZlibStreamGet\fR(\fIzshandle, dataObj, count\fR)
|
||||
.sp
|
||||
\fBTcl_ZlibStreamSetCompressionDictionary\fR(\fIzshandle, compDict\fR)
|
||||
.fi
|
||||
.SH ARGUMENTS
|
||||
.AS Tcl_ZlibStream *zshandlePtr out
|
||||
.AS Tcl_ZlibStream zshandle in
|
||||
.AP Tcl_Interp *interp in
|
||||
The interpreter to store resulting compressed or uncompressed data in. Also
|
||||
where any error messages are written. For \fBTcl_ZlibStreamInit\fR, this can
|
||||
@@ -64,7 +66,7 @@ addition, for decompression only, \fBTCL_ZLIB_FORMAT_AUTO\fR may also be
|
||||
chosen which can automatically detect whether the compressed data was in zlib
|
||||
or gzip format.
|
||||
.AP Tcl_Obj *dataObj in/out
|
||||
A byte-array object containing the data to be compressed or decompressed, or
|
||||
A byte-array value containing the data to be compressed or decompressed, or
|
||||
to which the data extracted from the stream is appended when passed to
|
||||
\fBTcl_ZlibStreamGet\fR.
|
||||
.AP int level in
|
||||
@@ -108,6 +110,13 @@ trailer demanded by the format is written.
|
||||
.AP int count in
|
||||
The maximum number of bytes to get from the stream, or -1 to get all remaining
|
||||
bytes from the stream's buffers.
|
||||
.AP Tcl_Obj *compDict in
|
||||
A byte array value that is the compression dictionary to use with the stream.
|
||||
Note that this is \fInot a Tcl dictionary\fR, and it is recommended that this
|
||||
only ever be used with streams that were created with their \fIformat\fR set
|
||||
to \fBTCL_ZLIB_FORMAT_ZLIB\fR because the other formats have no mechanism to
|
||||
indicate whether a compression dictionary was present other than to fail on
|
||||
decompression.
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
These functions form the interface from the Tcl library to the Zlib
|
||||
@@ -122,7 +131,7 @@ the dictionary is only used when the \fIformat\fR parameter is
|
||||
\fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. For details of the
|
||||
contents of the dictionary, see the \fBGZIP OPTIONS DICTIONARY\fR section
|
||||
below. Upon success, both functions leave the resulting compressed or
|
||||
decompressed data in a byte-array object that is the Tcl interpreter's result;
|
||||
decompressed data in a byte-array value that is the Tcl interpreter's result;
|
||||
the returned value is a standard Tcl result code.
|
||||
.PP
|
||||
\fBTcl_ZlibAdler32\fR and \fBTcl_ZlibCRC32\fR compute checksums on arrays of
|
||||
@@ -154,7 +163,7 @@ the \fBGZIP OPTIONS DICTIONARY\fR section below) can be given via the
|
||||
headers, and on decompression allows discovery of the existing headers. Note
|
||||
that the dictionary will be written to on decompression once sufficient data
|
||||
has been read to have a complete header. This means that the dictionary must
|
||||
be an unshared object in that case; a blank object created with
|
||||
be an unshared value in that case; a blank value created with
|
||||
\fBTcl_NewObj\fR is suggested.
|
||||
.PP
|
||||
Once a stream has been constructed, \fBTcl_ZlibStreamPut\fR is used to add
|
||||
@@ -162,8 +171,8 @@ data to the stream and \fBTcl_ZlibStreamGet\fR is used to retrieve data from
|
||||
the stream after processing. Both return normal Tcl result codes and leave an
|
||||
error message in the result of the interpreter that the stream is registered
|
||||
with in the error case (if such a registration has been performed). With
|
||||
\fBTcl_ZlibStreamPut\fR, the data buffer object passed to it should not be
|
||||
modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer object
|
||||
\fBTcl_ZlibStreamPut\fR, the data buffer value passed to it should not be
|
||||
modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer value
|
||||
passed to it will have the data bytes appended to it. Internally to the
|
||||
stream, data is kept compressed so as to minimize the cost of buffer space.
|
||||
.PP
|
||||
@@ -172,6 +181,25 @@ uncompressed data according to the format, and \fBTcl_ZlibStreamEof\fR returns
|
||||
a boolean value indicating whether the end of the uncompressed data has been
|
||||
reached.
|
||||
.PP
|
||||
\fBTcl_ZlibStreamSetCompressionDictionary\fR is used to control the
|
||||
compression dictionary used with the stream, a compression dictionary being an
|
||||
array of bytes (such as might be created with \fBTcl_NewByteArrayObj\fR) that
|
||||
is used to initialize the compression engine rather than leaving it to create
|
||||
it on the fly from the data being compressed. Setting a compression dictionary
|
||||
allows for more efficient compression in the case where the start of the data
|
||||
is highly regular, but it does require both the compressor and the
|
||||
decompressor to agreee on the value to use. Compression dictionaries are only
|
||||
fully supported for zlib-format data; on compression, they must be set before
|
||||
any data is sent in with \fBTcl_ZlibStreamPut\fR, and on decompression they
|
||||
should be set when \fBTcl_ZlibStreamGet\fR produces an \fBerror\fR with its
|
||||
\fB\-errorcode\fR set to
|
||||
.QW "\fBZLIB NEED_DICT\fI code\fR" ;
|
||||
the \fIcode\fR will be the Adler-32 checksum (see \fBTcl_ZlibAdler32\fR) of
|
||||
the compression dictionary sought. (Note that this is only true for
|
||||
zlib-format streams; gzip streams ignore compression dictionaries as the
|
||||
format specification doesn't permit them, and raw streams just produce a data
|
||||
error if the compression dictionary is missing or incorrect.)
|
||||
.PP
|
||||
If you wish to clear a stream and reuse it for a new compression or
|
||||
decompression action, \fBTcl_ZlibStreamReset\fR will do this and return a
|
||||
normal Tcl result code to indicate whether it was successful; if the stream is
|
||||
@@ -187,9 +215,9 @@ and \fBTcl_ZlibStreamInit\fR is used to pass a dictionary of options about
|
||||
that is used to describe the gzip header in the compressed data. When creating
|
||||
compressed data, the dictionary is read and when unpacking compressed data the
|
||||
dictionary is written (in which case the \fIdictObj\fR parameter must refer to
|
||||
an unshared dictionary object).
|
||||
an unshared dictionary value).
|
||||
.PP
|
||||
The following fields in the dictionary object are understood. All other fields
|
||||
The following fields in the dictionary value are understood. All other fields
|
||||
are ignored. No field is required when creating a gzip-format stream.
|
||||
.TP
|
||||
\fBcomment\fR
|
||||
|
||||
+7
-7
@@ -18,7 +18,7 @@ Tcl_WrongNumArgs \- generate standard error message for wrong number of argument
|
||||
.AS "Tcl_Obj *const" *message
|
||||
.AP Tcl_Interp interp in
|
||||
Interpreter in which error will be reported: error message gets stored
|
||||
in its result object.
|
||||
in its result value.
|
||||
.AP int objc in
|
||||
Number of leading arguments from \fIobjv\fR to include in error
|
||||
message.
|
||||
@@ -34,13 +34,13 @@ of the command. This argument may be NULL.
|
||||
\fBTcl_WrongNumArgs\fR is a utility procedure that is invoked by
|
||||
command procedures when they discover that they have received the
|
||||
wrong number of arguments. \fBTcl_WrongNumArgs\fR generates a
|
||||
standard error message and stores it in the result object of
|
||||
standard error message and stores it in the result value of
|
||||
\fIinterp\fR. The message includes the \fIobjc\fR initial
|
||||
elements of \fIobjv\fR plus \fImessage\fR. For example, if
|
||||
\fIobjv\fR consists of the values \fBfoo\fR and \fBbar\fR,
|
||||
\fIobjc\fR is 1, and \fImessage\fR is
|
||||
.QW "\fBfileName count\fR"
|
||||
then \fIinterp\fR's result object will be set to the following
|
||||
then \fIinterp\fR's result value will be set to the following
|
||||
string:
|
||||
.PP
|
||||
.CS
|
||||
@@ -57,17 +57,17 @@ wrong # args: should be "foo bar fileName count"
|
||||
\fBstring\fR and the Tk widget commands, which use the first argument
|
||||
as a subcommand.
|
||||
.PP
|
||||
Some of the objects in the \fIobjv\fR array may be abbreviations for
|
||||
Some of the values in the \fIobjv\fR array may be abbreviations for
|
||||
a subcommand. The command
|
||||
\fBTcl_GetIndexFromObj\fR will convert the abbreviated string object
|
||||
\fBTcl_GetIndexFromObj\fR will convert the abbreviated string value
|
||||
into an \fIindexObject\fR. If an error occurs in the parsing of the
|
||||
subcommand we would like to use the full subcommand name rather than
|
||||
the abbreviation. If the \fBTcl_WrongNumArgs\fR command finds any
|
||||
\fIindexObjects\fR in the \fIobjv\fR array it will use the full subcommand
|
||||
name in the error message instead of the abbreviated name that was
|
||||
originally passed in. Using the above example, let us assume that
|
||||
\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the object
|
||||
is now an indexObject because it was passed to
|
||||
\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the value
|
||||
is now an \fIindexObject\fR because it was passed to
|
||||
\fBTcl_GetIndexFromObj\fR. In this case the error message would be:
|
||||
.PP
|
||||
.CS
|
||||
|
||||
@@ -83,12 +83,14 @@ asynchronous invocation. The command returns an error message if the
|
||||
script did not run, unless the \fB\-async\fR flag was used, in which case
|
||||
the command returns immediately with no error.
|
||||
.VS 8.6
|
||||
The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
|
||||
string is sent. Combining \fB-binary\fR with the result of
|
||||
\fBencoding convertto\fR may be used to send data in arbitrary encodings.
|
||||
Without the \fB\-binary\fR option all data will be sent in unicode. For
|
||||
dde clients which don't implement the CF_UNICODE clipboard format, this
|
||||
will automatically be translated to the system encoding. You can use
|
||||
the \fB\-binary\fR option in combination with the result of
|
||||
\fBencoding convertto\fR to send data in any other encoding.
|
||||
.VE 8.6
|
||||
.TP
|
||||
\fBdde poke ?\fB\-binary\fR? \fIservice topic item data\fR
|
||||
\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
|
||||
.
|
||||
\fBdde poke\fR passes the \fIdata\fR to the server indicated by
|
||||
\fIservice\fR using the \fItopic\fR and \fIitem\fR specified. Typically,
|
||||
@@ -98,8 +100,11 @@ on. The \fIitem\fR is also application specific and is often not used, but
|
||||
it must always be non-null. The \fIdata\fR field is given to the remote
|
||||
application.
|
||||
.VS 8.6
|
||||
The \fB\-binary\fR option treats \fIdata\fR as binary data, otherwise an utf-8
|
||||
string is sent.
|
||||
Without the \fB\-binary\fR option all data will be sent in unicode. For
|
||||
dde clients which don't implement the CF_UNICODE clipboard format, this
|
||||
will automatically be translated to the system encoding. You can use
|
||||
the \fB\-binary\fR option in combination with the result of
|
||||
\fBencoding convertto\fR to send data in any other encoding.
|
||||
.VE 8.6
|
||||
.TP
|
||||
\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
|
||||
|
||||
+1
-1
@@ -152,7 +152,7 @@ and
|
||||
operates identically to
|
||||
.QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
|
||||
.TP
|
||||
\fBsuperclass\fI ?\fI\-slotOperation\fR? \fR?\fIclassName ...\fR?
|
||||
\fBsuperclass\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
|
||||
.VS
|
||||
This slot (see \fBSLOTTED DEFINITIONS\fR below)
|
||||
.VE
|
||||
|
||||
+27
-2
@@ -147,6 +147,31 @@ 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.
|
||||
.TP
|
||||
\fBdict map \fR{\fIkeyVar valueVar\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
|
||||
two-element list of variable names (for the key and value respectively of each
|
||||
mapping in the dictionary), the second the dictionary value to iterate across,
|
||||
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
|
||||
variable at that point. The result of the \fBdict map\fR command is the
|
||||
accumulator dictionary after all keys have been iterated over.
|
||||
.RS
|
||||
.PP
|
||||
If the evaluation of the body for any particular step generates a \fBbreak\fR,
|
||||
no further pairs from the dictionary will be iterated over and the \fBdict
|
||||
map\fR command will terminate successfully immediately. If the evaluation of
|
||||
the body for a particular step generates a \fBcontinue\fR result, the current
|
||||
iteration is aborted and the accumulator dictionary is not modified. The order
|
||||
of iteration is the natural order of the dictionary (typically the order in
|
||||
which the keys were added to the dictionary; the order is the same as that
|
||||
used in \fBdict for\fR).
|
||||
.RE
|
||||
.TP
|
||||
\fBdict merge \fR?\fIdictionaryValue ...\fR?
|
||||
.
|
||||
Return a dictionary that contains the contents of each of the
|
||||
@@ -408,9 +433,9 @@ puts $foo
|
||||
# prints: \fIa b foo {a b} bar 2 baz 3\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
append(n), array(n), foreach(n), incr(n), list(n), lappend(n), set(n)
|
||||
append(n), array(n), foreach(n), mapeach(n), incr(n), list(n), lappend(n), set(n)
|
||||
.SH KEYWORDS
|
||||
dictionary, create, update, lookup, iterate, filter
|
||||
dictionary, create, update, lookup, iterate, filter, map
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" End:
|
||||
|
||||
+28
-3
@@ -39,9 +39,9 @@ additional operators not found in C.
|
||||
.SS OPERANDS
|
||||
.PP
|
||||
A Tcl expression consists of a combination of operands, operators,
|
||||
and parentheses.
|
||||
parentheses and commas.
|
||||
White space may be used between the operands and operators and
|
||||
parentheses; it is ignored by the expression's instructions.
|
||||
parentheses (or commas); it is ignored by the expression's instructions.
|
||||
Where possible, operands are interpreted as integer values.
|
||||
Integer values may be specified in decimal (the normal case), in binary
|
||||
(if the first two characters of the operand are \fB0b\fR), in octal
|
||||
@@ -134,7 +134,20 @@ Multiply, divide, remainder. None of these operators may be
|
||||
applied to string operands, and remainder may be applied only
|
||||
to integers.
|
||||
The remainder will always have the same sign as the divisor and
|
||||
an absolute value smaller than the divisor.
|
||||
an absolute value smaller than the absolute value of the divisor.
|
||||
.RS
|
||||
.PP
|
||||
When applied to integers, the division and remainder operators can be
|
||||
considered to partition the number line into a sequence of equal-sized
|
||||
adjacent non-overlapping pieces where each piece is the size of the divisor;
|
||||
the division result identifies which piece the divisor lay within, and the
|
||||
remainder result identifies where within that piece the divisor lay. A
|
||||
consequence of this is that the result of
|
||||
.QW "-57 \fB/\fR 10"
|
||||
is always -6, and the result of
|
||||
.QW "-57 \fB%\fR 10"
|
||||
is always 3.
|
||||
.RE
|
||||
.TP 20
|
||||
\fB+\0\0\-\fR
|
||||
.
|
||||
@@ -270,6 +283,18 @@ rules for resolving functions in namespaces. Either
|
||||
current]::tcl::mathfunc::sin\fR will satisfy the request, and others
|
||||
may as well (depending on the current \fBnamespace path\fR setting).
|
||||
.PP
|
||||
Some mathematical functions have several arguments, separated by commas like in C. Thus:
|
||||
.PP
|
||||
.CS
|
||||
\fBexpr\fR {hypot($x,$y)}
|
||||
.CE
|
||||
.PP
|
||||
ends up as
|
||||
.PP
|
||||
.CS
|
||||
tcl::mathfunc::hypot $x $y
|
||||
.CE
|
||||
.PP
|
||||
See the \fBmathfunc\fR(n) manual page for the math functions that are
|
||||
available by default.
|
||||
.SS "TYPES, OVERFLOW, AND PRECISION"
|
||||
|
||||
+2
-2
@@ -72,8 +72,8 @@ initially set to \fBline\fR, and \fBstderr\fR is set to \fBnone\fR.
|
||||
.
|
||||
\fINewvalue\fR must be an integer; its value is used to set the size of
|
||||
buffers, in bytes, subsequently allocated for this channel to store input
|
||||
or output. \fINewvalue\fR must be between ten and one million, allowing
|
||||
buffers of ten to one million bytes in size.
|
||||
or output. \fINewvalue\fR must be between one and one million, allowing
|
||||
buffers of one to one million bytes in size.
|
||||
.TP
|
||||
\fB\-encoding\fR \fIname\fR
|
||||
.
|
||||
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2012 Trevor Davel
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH lmap n "" Tcl "Tcl Built-In Commands"
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
lmap \- Iterate over all elements in one or more lists and collect results
|
||||
.SH SYNOPSIS
|
||||
\fBlmap \fIvarname list body\fR
|
||||
.br
|
||||
\fBlmap \fIvarlist1 list1\fR ?\fIvarlist2 list2 ...\fR? \fIbody\fR
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
The \fBlmap\fR command implements a loop where the loop variable(s) take on
|
||||
values from one or more lists, and the loop returns a list of results
|
||||
collected from each iteration.
|
||||
.PP
|
||||
In the simplest case there is one loop variable, \fIvarname\fR, and one list,
|
||||
\fIlist\fR, that is a list of values to assign to \fIvarname\fR. The
|
||||
\fIbody\fR argument is a Tcl script. For each element of \fIlist\fR (in order
|
||||
from first to last), \fBlmap\fR assigns the contents of the element to
|
||||
\fIvarname\fR as if the \fBlindex\fR command had been used to extract the
|
||||
element, then calls the Tcl interpreter to execute \fIbody\fR. If execution of
|
||||
the body completes normally then the result of the body is appended to an
|
||||
accumulator list. \fBlmap\fR returns the accumulator list.
|
||||
.PP
|
||||
In the general case there can be more than one value list (e.g., \fIlist1\fR
|
||||
and \fIlist2\fR), and each value list can be associated with a list of loop
|
||||
variables (e.g., \fIvarlist1\fR and \fIvarlist2\fR). During each iteration of
|
||||
the loop the variables of each \fIvarlist\fR are assigned consecutive values
|
||||
from the corresponding \fIlist\fR. Values in each \fIlist\fR are used in order
|
||||
from first to last, and each value is used exactly once. The total number of
|
||||
loop iterations is large enough to use up all the values from all the value
|
||||
lists. If a value list does not contain enough elements for each of its loop
|
||||
variables in each iteration, empty values are used for the missing elements.
|
||||
.PP
|
||||
The \fBbreak\fR and \fBcontinue\fR statements may be invoked inside
|
||||
\fIbody\fR, with the same effect as in the \fBfor\fR and \fBforeach\fR
|
||||
commands. In these cases the body does not complete normally and the result is
|
||||
not appended to the accumulator list.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
Zip lists together:
|
||||
.PP
|
||||
.CS
|
||||
set list1 {a b c d}
|
||||
set list2 {1 2 3 4}
|
||||
set zipped [\fBlmap\fR a $list1 b $list2 {list $a $b}]
|
||||
# The value of zipped is "{a 1} {b 2} {c 3} {d 4}"
|
||||
.CE
|
||||
.PP
|
||||
Filter a list to remove odd values:
|
||||
.PP
|
||||
.CS
|
||||
set values {1 2 3 4 5 6 7 8}
|
||||
proc isEven {n} {expr {($n % 2) == 0}}
|
||||
set goodOnes [\fBlmap\fR x $values {expr {
|
||||
[isEven $x] ? $x : [continue]
|
||||
}}]
|
||||
# The value of goodOnes is "2 4 6 8"
|
||||
.CE
|
||||
.PP
|
||||
Take a prefix from a list based on the contents of the list:
|
||||
.PP
|
||||
.CS
|
||||
set values {8 7 6 5 4 3 2 1}
|
||||
proc isGood {counter} {expr {$n > 3}}
|
||||
set prefix [\fBlmap\fR x $values {expr {
|
||||
[isGood $x] ? $x : [break]
|
||||
}}]
|
||||
# The value of prefix is "8 7 6 5 4"
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
break(n), continue(n), for(n), foreach(n), while(n)
|
||||
.SH KEYWORDS
|
||||
foreach, iteration, list, loop, map
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" End:
|
||||
+19
-3
@@ -11,11 +11,11 @@
|
||||
.SH NAME
|
||||
load \- Load machine code and initialize new commands
|
||||
.SH SYNOPSIS
|
||||
\fBload \fIfileName\fR
|
||||
\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName\fR
|
||||
.br
|
||||
\fBload \fIfileName packageName\fR
|
||||
\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName\fR
|
||||
.br
|
||||
\fBload \fIfileName packageName interp\fR
|
||||
\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName interp\fR
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -104,6 +104,22 @@ Otherwise, the \fBload\fR command searches for a dynamically loaded
|
||||
package by that name, and uses it if it is found. If several
|
||||
different files have been \fBload\fRed with different versions of
|
||||
the package, Tcl picks the file that was loaded first.
|
||||
.PP
|
||||
If \fB\-global\fR is specified preceding the filename, all symbols
|
||||
found in the shared library are exported for global use by other
|
||||
libraries. The option \fB\-lazy\fR delays the actual loading of
|
||||
symbols until their first actual use. The options may be abbreviated.
|
||||
The option \fB\-\-\fR indicates the end of the options, and should
|
||||
be used if you wish to use a filename which starts with \fB\-\fR
|
||||
and you provide a packageName to the \fBload\fR command.
|
||||
.PP
|
||||
On platforms which do not support the \fB\-global\fR or \fB\-lazy\fR
|
||||
options, the options still exist but have no effect. Note that use
|
||||
of the \fB\-global\fR or \fB\-lazy\fR option may lead to crashes
|
||||
in your application later (in case of symbol conflicts resp. missing
|
||||
symbols), which cannot be detected during the \fBload\fR. So, only
|
||||
use this when you know what you are doing, you will not get a nice
|
||||
error message when something is wrong with the loaded library.
|
||||
.SH "PORTABILITY ISSUES"
|
||||
.TP
|
||||
\fBWindows\fR\0\0\0\0\0
|
||||
|
||||
+10
-5
@@ -126,14 +126,19 @@ will be an integer.
|
||||
.TP
|
||||
\fB%\fR \fInumber number\fR
|
||||
.
|
||||
Returns the integral modulus of the first argument with respect to the second.
|
||||
Each \fInumber\fR must have an integral value. Note that Tcl defines this
|
||||
operation exactly even for negative numbers, so that the following equality
|
||||
holds true:
|
||||
Returns the integral modulus (i.e., remainder) of the first argument
|
||||
with respect to the second.
|
||||
Each \fInumber\fR must have an integral value.
|
||||
Also, the sign of the result will be the same as the sign of the second
|
||||
\fInumber\fR, which must not be zero.
|
||||
.RS
|
||||
.PP
|
||||
Note that Tcl defines this operation exactly even for negative numbers, so
|
||||
that the following command returns a true value (omitting the namespace for
|
||||
clarity):
|
||||
.PP
|
||||
.CS
|
||||
(\fIx \fB/ \fIy\fR) \fB* \fIy \fB== \fIx \fB\-\fR (\fIx \fB% \fIy\fR)
|
||||
\fB==\fR [\fB*\fR [\fB/\fI x y\fR] \fIy\fR] [\fB\-\fI x\fR [\fB%\fI x y\fR]]
|
||||
.CE
|
||||
.RE
|
||||
.TP
|
||||
|
||||
+39
-10
@@ -5,7 +5,7 @@
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
'\"
|
||||
.so man.macros
|
||||
.TH "msgcat" n 1.4 msgcat "Tcl Bundled Packages"
|
||||
.TH "msgcat" n 1.5 msgcat "Tcl Bundled Packages"
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
@@ -13,7 +13,7 @@ msgcat \- Tcl message catalog
|
||||
.SH SYNOPSIS
|
||||
\fBpackage require Tcl 8.5\fR
|
||||
.sp
|
||||
\fBpackage require msgcat 1.4.2\fR
|
||||
\fBpackage require msgcat 1.5.0\fR
|
||||
.sp
|
||||
\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
|
||||
.sp
|
||||
@@ -29,6 +29,12 @@ msgcat \- Tcl message catalog
|
||||
.sp
|
||||
\fB::msgcat::mcmset \fIlocale src-trans-list\fR
|
||||
.sp
|
||||
.VS "TIP 404"
|
||||
\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
|
||||
.sp
|
||||
\fB::msgcat::mcflmset \fIsrc-trans-list\fR
|
||||
.VE "TIP 404"
|
||||
.sp
|
||||
\fB::msgcat::mcunknown \fIlocale src-string\fR
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
@@ -131,6 +137,26 @@ translate-string ...\fR?} \fB::msgcat::mcmset\fR can be significantly
|
||||
faster than multiple invocations of \fB::msgcat::mcset\fR. The function
|
||||
returns the number of translations set.
|
||||
.TP
|
||||
\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
|
||||
.VS "TIP 404"
|
||||
Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR in the
|
||||
current namespace for the locale implied by the name of the message catalog
|
||||
being loaded via \fB::msgcat::mcload\fR. If \fItranslate-string\fR is not
|
||||
specified, \fIsrc-string\fR is used for both. The function returns
|
||||
\fItranslate-string\fR.
|
||||
.VE "TIP 404"
|
||||
.TP
|
||||
\fB::msgcat::mcflmset \fIsrc-trans-list\fR
|
||||
.VS "TIP 404"
|
||||
Sets the translation for multiple source strings in \fIsrc-trans-list\fR in
|
||||
the current namespace for the locale implied by the name of the message
|
||||
catalog being loaded via \fB::msgcat::mcload\fR. \fIsrc-trans-list\fR must
|
||||
have an even number of elements and is in the form {\fIsrc-string
|
||||
translate-string\fR ?\fIsrc-string translate-string ...\fR?}
|
||||
\fB::msgcat::mcflmset\fR can be significantly faster than multiple invocations
|
||||
of \fB::msgcat::mcflset\fR. The function returns the number of translations set.
|
||||
.VE "TIP 404"
|
||||
.TP
|
||||
\fB::msgcat::mcunknown \fIlocale src-string\fR
|
||||
.
|
||||
This routine is called by \fB::msgcat::mc\fR in the case when
|
||||
@@ -175,11 +201,14 @@ to extract its parts. The initial locale is then set by calling
|
||||
language[_country][_modifier]
|
||||
.CE
|
||||
.PP
|
||||
On Windows, if none of those environment variables is set, msgcat will
|
||||
attempt to extract locale information from the
|
||||
registry. If all these attempts to discover an initial locale
|
||||
from the user's environment fail, msgcat defaults to an initial
|
||||
locale of
|
||||
On Windows and Cygwin, if none of those environment variables is set,
|
||||
msgcat will attempt to extract locale information from the registry.
|
||||
From Windows Vista on, the RFC4747 locale name "lang-script-country-options"
|
||||
is transformed to the locale as "lang_country_script" (Example:
|
||||
sr-Latn-CS -> sr_cs_latin). For Windows XP, the language id is
|
||||
transformed analoguously (Example: 0c1a -> sr_yu_cyrillic).
|
||||
If all these attempts to discover an initial locale from the user's
|
||||
environment fail, msgcat defaults to an initial locale of
|
||||
.QW C .
|
||||
.PP
|
||||
When a locale is specified by the user, a
|
||||
@@ -283,15 +312,15 @@ cause peculiar behavior, such as marking the message file as
|
||||
.QW hidden
|
||||
on Unix file systems.
|
||||
.IP [3]
|
||||
The file contains a series of calls to \fBmcset\fR and
|
||||
\fBmcmset\fR, setting the necessary translation strings
|
||||
The file contains a series of calls to \fBmcflset\fR and
|
||||
\fBmcflmset\fR, setting the necessary translation strings
|
||||
for the language, likely enclosed in a \fBnamespace eval\fR
|
||||
so that all source strings are tied to the namespace of
|
||||
the package. For example, a short \fBes.msg\fR might contain:
|
||||
.PP
|
||||
.CS
|
||||
namespace eval ::mypackage {
|
||||
\fB::msgcat::mcset\fR es "Free Beer!" "Cerveza Gracias!"
|
||||
\fB::msgcat::mcflset\fR "Free Beer!" "Cerveza Gracias!"
|
||||
}
|
||||
.CE
|
||||
.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
.BS
|
||||
'\" Note: do not modify the .SH NAME line immediately below!
|
||||
.SH NAME
|
||||
next \- invoke superclass method implementations
|
||||
next, nextto \- invoke superclass method implementations
|
||||
.SH SYNOPSIS
|
||||
.nf
|
||||
package require TclOO
|
||||
|
||||
+4
-4
@@ -67,7 +67,7 @@ The following commands are provided in the master interpreter:
|
||||
\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
|
||||
Creates a safe interpreter, installs the aliases described in the section
|
||||
\fBALIASES\fR and initializes the auto-loading and package mechanism as
|
||||
specified by the supplied \fBoptions\fR.
|
||||
specified by the supplied \fIoptions\fR.
|
||||
See the \fBOPTIONS\fR section below for a description of the
|
||||
optional arguments.
|
||||
If the \fIslave\fR argument is omitted, a name will be generated.
|
||||
@@ -293,9 +293,9 @@ executing.
|
||||
The only valid file names arguments
|
||||
for the \fBsource\fR and \fBload\fR aliases provided to the slave
|
||||
are path in the form of
|
||||
\fB[file join \fR\fItoken filename\fR\fB]\fR (i.e. when using the
|
||||
native file path formats: \fItoken\fR\fB/\fR\fIfilename\fR
|
||||
on Unix and \fItoken\fR\fB\e\fIfilename\fR on Windows),
|
||||
\fB[file join \fItoken filename\fB]\fR (i.e. when using the
|
||||
native file path formats: \fItoken\fB/\fIfilename\fR
|
||||
on Unix and \fItoken\fB\e\fIfilename\fR on Windows),
|
||||
where \fItoken\fR is representing one of the directories
|
||||
of the \fIaccessPath\fR list and \fIfilename\fR is
|
||||
one file in that directory (no sub directories access are allowed).
|
||||
|
||||
+36
-28
@@ -19,24 +19,6 @@ string \- Manipulate strings
|
||||
Performs one of several string operations, depending on \fIoption\fR.
|
||||
The legal \fIoption\fRs (which may be abbreviated) are:
|
||||
.TP
|
||||
\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. In almost all cases, you should use the
|
||||
\fBstring length\fR operation (including determining the length of a
|
||||
Tcl ByteArray object). Refer to the \fBTcl_NumUtfChars\fR manual
|
||||
entry for more details on the UTF\-8 representation.
|
||||
.RS
|
||||
.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.
|
||||
.RE
|
||||
.TP
|
||||
\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length int\fR? \fIstring1 string2\fR
|
||||
.
|
||||
Perform a character-by-character comparison of strings \fIstring1\fR
|
||||
@@ -149,7 +131,8 @@ Any Unicode printing character, including space.
|
||||
.IP \fBpunct\fR 12
|
||||
Any Unicode punctuation character.
|
||||
.IP \fBspace\fR 12
|
||||
Any Unicode space character.
|
||||
Any Unicode whitespace character, zero width space (U+200b),
|
||||
word joiner (U+2060) and 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.
|
||||
@@ -198,9 +181,9 @@ will return \fB1\fR.
|
||||
.
|
||||
Returns a decimal string giving the number of characters in
|
||||
\fIstring\fR. Note that this is not necessarily the same as the
|
||||
number of bytes used to store the string. If the object is a
|
||||
ByteArray object (such as those returned from reading a binary encoded
|
||||
channel), then this will return the actual byte length of the object.
|
||||
number of bytes used to store the string. If the value is a
|
||||
byte array value (such as those returned from reading a binary encoded
|
||||
channel), then this will return the actual byte length of the value.
|
||||
.TP
|
||||
\fBstring map\fR ?\fB\-nocase\fR? \fImapping string\fR
|
||||
.
|
||||
@@ -335,22 +318,47 @@ specified using the forms described in \fBSTRING INDICES\fR.
|
||||
.
|
||||
Returns a value equal to \fIstring\fR except that any leading or
|
||||
trailing characters present in the string given by \fIchars\fR are removed. If
|
||||
\fIchars\fR is not specified then white space is removed (spaces,
|
||||
tabs, newlines, and carriage returns).
|
||||
\fIchars\fR is not specified then white space is removed (any character
|
||||
for which \fBstring is space\fR returns 1, and "\0").
|
||||
.TP
|
||||
\fBstring trimleft \fIstring\fR ?\fIchars\fR?
|
||||
.
|
||||
Returns a value equal to \fIstring\fR except that any leading
|
||||
characters present in the string given by \fIchars\fR are removed. If
|
||||
\fIchars\fR is not specified then white space is removed (spaces,
|
||||
tabs, newlines, and carriage returns).
|
||||
\fIchars\fR is not specified then white space is removed (any character
|
||||
for which \fBstring is space\fR returns 1, and "\0").
|
||||
.TP
|
||||
\fBstring trimright \fIstring\fR ?\fIchars\fR?
|
||||
.
|
||||
Returns a value equal to \fIstring\fR except that any trailing
|
||||
characters present in the string given by \fIchars\fR are removed. If
|
||||
\fIchars\fR is not specified then white space is removed (spaces,
|
||||
tabs, newlines, and carriage returns).
|
||||
\fIchars\fR is not specified then white space is removed (any character
|
||||
for which \fBstring is space\fR returns 1, and "\0").
|
||||
.SS "OBSOLETE SUBCOMMANDS"
|
||||
.PP
|
||||
These subcommands are currently supported, but are likely to go away in a
|
||||
future release as their functionality is either virtually never used or highly
|
||||
misleading.
|
||||
.TP
|
||||
\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.
|
||||
.RS
|
||||
.PP
|
||||
In almost all cases, you should use the
|
||||
\fBstring length\fR operation (including determining the length of a
|
||||
Tcl byte array value). Refer to the \fBTcl_NumUtfChars\fR manual
|
||||
entry for more details on the UTF\-8 representation.
|
||||
.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.
|
||||
.RE
|
||||
.TP
|
||||
\fBstring wordend \fIstring charIndex\fR
|
||||
.
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
.SH NAME
|
||||
tclsh \- Simple shell containing Tcl interpreter
|
||||
.SH SYNOPSIS
|
||||
\fBtclsh\fR ?-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
|
||||
\fBtclsh\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ error will occur.
|
||||
For \fBleave\fR and \fBleavestep\fR operations:
|
||||
.PP
|
||||
.CS
|
||||
\fIcommand command-string code result op\fR
|
||||
\fIcommandPrefix command-string code result op\fR
|
||||
.CE
|
||||
.PP
|
||||
\fICommand-string\fR gives the complete current command being
|
||||
|
||||
+103
-33
@@ -1,5 +1,5 @@
|
||||
'\"
|
||||
'\" Copyright (c) 2008 Donal K. Fellows
|
||||
'\" Copyright (c) 2008-2012 Donal K. Fellows
|
||||
'\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
@@ -170,6 +170,13 @@ the
|
||||
.QW "\fIoptions ...\fR"
|
||||
to the \fBzlib push\fR command:
|
||||
.TP
|
||||
\fB\-dictionary\fI binData\fR
|
||||
.VS "TIP 400"
|
||||
Sets the compression dictionary to use when working with compressing or
|
||||
decompressing the data to be \fIbinData\fR. Not valid for transformations that
|
||||
work with gzip-format data.
|
||||
.VE
|
||||
.TP
|
||||
\fB\-header\fI dictionary\fR
|
||||
.
|
||||
Passes a description of the gzip header to create, in the same format that
|
||||
@@ -179,15 +186,33 @@ Passes a description of the gzip header to create, in the same format that
|
||||
.
|
||||
How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
|
||||
(maximally compressed).
|
||||
'\".TP
|
||||
'\"\fB\-limit\fI readaheadLimit\fR
|
||||
'\".
|
||||
'\"The maximum number of bytes ahead to read.
|
||||
'\"\fITODO: not yet implemented!\fR
|
||||
.TP
|
||||
\fB\-limit\fI readaheadLimit\fR
|
||||
.
|
||||
The maximum number of bytes ahead to read when decompressing. This defaults to
|
||||
1, which ensures that data is always decompressed correctly, but may be
|
||||
increased to improve performance. This is more useful when the channel is
|
||||
non-blocking.
|
||||
.PP
|
||||
Both compressing and decompressing channel transformations add extra
|
||||
configuration options that may be accessed through \fBchan configure\fR. Each
|
||||
option is either a read-only or a write-only option. The options are:
|
||||
configuration options that may be accessed through \fBchan configure\fR. The
|
||||
options are:
|
||||
.TP
|
||||
\fB\-checksum\fI checksum\fR
|
||||
.
|
||||
This read-only option gets the current checksum for the uncompressed data that
|
||||
the compression engine has seen so far. It is valid for both compressing and
|
||||
decompressing transforms, but not for the raw inflate and deflate formats. The
|
||||
compression algorithm depends on what format is being produced or consumed.
|
||||
.TP
|
||||
\fB\-dictionary\fI binData\fR
|
||||
.VS "TIP 400"
|
||||
This read-write options gets or sets the compression dictionary to use when
|
||||
working with compressing or decompressing the data to be \fIbinData\fR. It is
|
||||
not valid for transformations that work with gzip-format data, and should not
|
||||
normally be set on compressing transformations other than at the point where
|
||||
the transformation is stacked.
|
||||
.VE
|
||||
.TP
|
||||
\fB\-flush\fI type\fR
|
||||
.
|
||||
@@ -198,62 +223,80 @@ expensive flush respectively. Flushing degrades the compression ratio, but
|
||||
makes it easier for a decompressor to recover more of the file in the case of
|
||||
data corruption.
|
||||
.TP
|
||||
\fB\-checksum\fR
|
||||
.
|
||||
This read-only option, valid for both compressing and decompressing
|
||||
transforms, gets the current checksum for the uncompressed data that the
|
||||
compression engine has seen so far. The compression algorithm depends on what
|
||||
format is being produced or consumed.
|
||||
.TP
|
||||
\fB\-header\fR
|
||||
\fB\-header\fI dictionary\fR
|
||||
.
|
||||
This read-only option, only valid for decompressing transforms that are
|
||||
processing gzip-format data, returns the dictionary describing the header read
|
||||
off the data stream.
|
||||
.TP
|
||||
\fB\-limit\fI readaheadLimit\fR
|
||||
.
|
||||
This read-write option is used by decompressing channels to control the
|
||||
maximum number of bytes ahead to read from the underlying data source. This
|
||||
defaults to 1, which ensures that data is always decompressed correctly, but
|
||||
may be increased to improve performance. This is more useful when the channel
|
||||
is non-blocking.
|
||||
.RE
|
||||
.SS "STREAMING SUBCOMMAND"
|
||||
.TP
|
||||
\fBzlib stream\fI mode\fR ?\fIlevel\fR?
|
||||
\fBzlib stream\fI mode\fR ?\fIoptions\fR?
|
||||
.
|
||||
Creates a streaming compression or decompression command based on the
|
||||
\fImode\fR, and return the name of the command. For a description of how that
|
||||
command works, see \fBSTREAMING INSTANCE COMMAND\fR below. The following modes
|
||||
are supported:
|
||||
and \fIoptions\fR are supported:
|
||||
.RS
|
||||
.TP
|
||||
\fBzlib stream compress\fR ?\fIlevel\fR?
|
||||
\fBzlib stream compress\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
|
||||
.
|
||||
The stream will be a compressing stream that produces zlib-format output,
|
||||
using compression level \fIlevel\fR (if specified) which will be an integer
|
||||
from 0 to 9.
|
||||
from 0 to 9,
|
||||
.VS "TIP 400"
|
||||
and the compression dictionary \fIbindata\fR (if specified).
|
||||
.VE
|
||||
.TP
|
||||
\fBzlib stream decompress\fR
|
||||
\fBzlib stream decompress\fR ?\fB\-dictionary \fIbindata\fR?
|
||||
.
|
||||
The stream will be a decompressing stream that takes zlib-format input and
|
||||
produces uncompressed output.
|
||||
.VS "TIP 400"
|
||||
If \fIbindata\fR is supplied, it is a compression dictionary to use if
|
||||
required.
|
||||
.VE
|
||||
.TP
|
||||
\fBzlib stream deflate\fR ?\fIlevel\fR?
|
||||
\fBzlib stream deflate\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
|
||||
.
|
||||
The stream will be a compressing stream that produces raw output, using
|
||||
compression level \fIlevel\fR (if specified) which will be an integer from 0
|
||||
to 9.
|
||||
to 9,
|
||||
.VS "TIP 400"
|
||||
and the compression dictionary \fIbindata\fR (if specified). Note that
|
||||
the raw compressed data includes no metadata about what compression
|
||||
dictionary was used, if any; that is a feature of the zlib-format data.
|
||||
.VE
|
||||
.TP
|
||||
\fBzlib stream gunzip\fR
|
||||
.
|
||||
The stream will be a decompressing stream that takes gzip-format input and
|
||||
produces uncompressed output.
|
||||
.TP
|
||||
\fBzlib stream gzip\fR ?\fIlevel\fR?
|
||||
\fBzlib stream gzip\fR ?\fB\-header \fIheader\fR? ?\fB\-level \fIlevel\fR?
|
||||
.
|
||||
The stream will be a compressing stream that produces gzip-format output,
|
||||
using compression level \fIlevel\fR (if specified) which will be an integer
|
||||
from 0 to 9.
|
||||
'\" TODO: Header dictionary!
|
||||
from 0 to 9, and the header descriptor dictionary \fIheader\fR (if specified;
|
||||
for keys see \fBzlib gzip\fR).
|
||||
.TP
|
||||
\fBzlib stream inflate\fR
|
||||
\fBzlib stream inflate\fR ?\fB\-dictionary \fIbindata\fR?
|
||||
.
|
||||
The stream will be a decompressing stream that takes raw compressed input and
|
||||
produces uncompressed output.
|
||||
.VS "TIP 400"
|
||||
If \fIbindata\fR is supplied, it is a compression dictionary to use. Note that
|
||||
there are no checks in place to determine whether the compression dictionary
|
||||
is correct.
|
||||
.VE
|
||||
.RE
|
||||
.SS "CHECKSUMMING SUBCOMMANDS"
|
||||
.TP
|
||||
@@ -276,10 +319,10 @@ the transformed data.
|
||||
The full set of subcommands supported by a streaming instance command,
|
||||
\fIstream\fR, is as follows:
|
||||
.TP
|
||||
\fIstream \fBadd\fR ?\fIoption\fR? \fIdata\fR
|
||||
\fIstream \fBadd\fR ?\fIoption...\fR? \fIdata\fR
|
||||
.
|
||||
A short-cut for
|
||||
.QW "\fIstream \fBput \fIoption data\fR"
|
||||
.QW "\fIstream \fBput \fR?\fIoption...\fR? \fIdata\fR"
|
||||
followed by
|
||||
.QW "\fIstream \fBget\fR" .
|
||||
.TP
|
||||
@@ -317,15 +360,27 @@ A short-cut for
|
||||
Return up to \fIcount\fR bytes from \fIstream\fR's internal buffers with the
|
||||
transformation applied. If \fIcount\fR is omitted, the entire contents of the
|
||||
buffers are returned.
|
||||
.
|
||||
\fIstream \fBheader\fR
|
||||
.
|
||||
Return the gzip header description dictionary extracted from the stream. Only
|
||||
supported for streams created with their \fImode\fR parameter set to
|
||||
\fBgunzip\fR.
|
||||
.TP
|
||||
\fIstream \fBput\fR ?\fIoption\fR? \fIdata\fR
|
||||
\fIstream \fBput\fR ?\fIoption...\fR? \fIdata\fR
|
||||
.
|
||||
Append the contents of the binary string \fIdata\fR to \fIstream\fR's internal
|
||||
buffers while applying the transformation. If present, \fIoption\fR must be
|
||||
one of the following (or an unambiguous prefix) which are used to modify the
|
||||
buffers while applying the transformation. The following \fIoption\fRs are
|
||||
supported (or an unambiguous prefix of them), which are used to modify the
|
||||
way in which the transformation is applied:
|
||||
.RS
|
||||
.TP
|
||||
\fB\-dictionary\fI binData\fR
|
||||
.VS "TIP 400"
|
||||
Sets the compression dictionary to use when working with compressing or
|
||||
decompressing the data to be \fIbinData\fR.
|
||||
.VE
|
||||
.TP
|
||||
\fB\-finalize\fR
|
||||
.
|
||||
Mark the stream as finished, ensuring that all bytes have been wholly
|
||||
@@ -333,12 +388,22 @@ compressed or decompressed. For gzip streams, this also ensures that the
|
||||
footer is written to the stream. The stream will need to be reset before
|
||||
having more data written to it after this, though data can still be read out
|
||||
of the stream with the \fBget\fR subcommand.
|
||||
.RS
|
||||
.PP
|
||||
This option is mutually exclusive with the \fB\-flush\fR and \fB\-fullflush\fR
|
||||
options.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-flush\fR
|
||||
.
|
||||
Ensure that a decompressor consuming the bytes that the current (compressing)
|
||||
stream is producing will be able to produce all the bytes that have been
|
||||
compressed so far, at some performance penalty.
|
||||
.RS
|
||||
.PP
|
||||
This option is mutually exclusive with the \fB\-finalize\fR and
|
||||
\fB\-fullflush\fR options.
|
||||
.RE
|
||||
.TP
|
||||
\fB\-fullflush\fR
|
||||
.
|
||||
@@ -346,6 +411,11 @@ Ensure that not only can a decompressor handle all the bytes produced so far
|
||||
(as with \fB\-flush\fR above) but also that it can restart from this point if
|
||||
it detects that the stream is partially corrupt. This incurs a substantial
|
||||
performance penalty.
|
||||
.RS
|
||||
.PP
|
||||
This option is mutually exclusive with the \fB\-finalize\fR and \fB\-flush\fR
|
||||
options.
|
||||
.RE
|
||||
.RE
|
||||
.TP
|
||||
\fIstream \fBreset\fR
|
||||
@@ -384,7 +454,7 @@ $\fIstrm \fBclose\fR
|
||||
.SH "SEE ALSO"
|
||||
binary(n), chan(n), encoding(n), Tcl_ZlibDeflate(3), RFC1950 \- RFC1952
|
||||
.SH "KEYWORDS"
|
||||
compress, decompress, deflate, gzip, inflate
|
||||
compress, decompress, deflate, gzip, inflate, zlib
|
||||
'\" Local Variables:
|
||||
'\" mode: nroff
|
||||
'\" End:
|
||||
|
||||
@@ -354,13 +354,14 @@ static const chr punctCharTable[] = {
|
||||
*/
|
||||
|
||||
static const crange spaceRangeTable[] = {
|
||||
{0x9, 0xd}, {0x2000, 0x200a}
|
||||
{0x9, 0xd}, {0x2000, 0x200b}
|
||||
};
|
||||
|
||||
#define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
|
||||
|
||||
static const chr spaceCharTable[] = {
|
||||
0x20, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f, 0x3000
|
||||
0x20, 0x85, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f,
|
||||
0x2060, 0x3000, 0xfeff
|
||||
};
|
||||
|
||||
#define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr))
|
||||
@@ -617,7 +618,7 @@ static const crange graphRangeTable[] = {
|
||||
{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, 0x20b9}, {0x20d0, 0x20f0},
|
||||
{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},
|
||||
|
||||
@@ -2318,6 +2318,12 @@ declare 629 {
|
||||
int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr)
|
||||
}
|
||||
|
||||
# TIP #400
|
||||
declare 630 {
|
||||
void Tcl_ZlibStreamSetCompressionDictionary(Tcl_ZlibStream zhandle,
|
||||
Tcl_Obj *compressionDictionaryObj)
|
||||
}
|
||||
|
||||
# ----- BASELINE -- FOR -- 8.6.0 ----- #
|
||||
|
||||
##############################################################################
|
||||
|
||||
+29
-15
@@ -51,17 +51,15 @@ extern "C" {
|
||||
* win/README (not patchlevel) (sections 0 and 2)
|
||||
* unix/tcl.spec (1 LOC patch)
|
||||
* tools/tcl.hpj.in (not patchlevel, for windows installer)
|
||||
* tools/tcl.wse.in (for windows installer)
|
||||
* tools/tclSplash.bmp (not patchlevel)
|
||||
*/
|
||||
|
||||
#define TCL_MAJOR_VERSION 8
|
||||
#define TCL_MINOR_VERSION 6
|
||||
#define TCL_RELEASE_LEVEL TCL_BETA_RELEASE
|
||||
#define TCL_RELEASE_SERIAL 2
|
||||
#define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
|
||||
#define TCL_RELEASE_SERIAL 0
|
||||
|
||||
#define TCL_VERSION "8.6"
|
||||
#define TCL_PATCH_LEVEL "8.6b2"
|
||||
#define TCL_PATCH_LEVEL "8.6.0"
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -500,7 +498,9 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
|
||||
* accessed with Tcl_GetObjResult() and Tcl_SetObjResult().
|
||||
*/
|
||||
|
||||
typedef struct Tcl_Interp {
|
||||
typedef struct Tcl_Interp
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
{
|
||||
/* TIP #330: Strongly discourage extensions from using the string
|
||||
* result. */
|
||||
#ifdef USE_INTERP_RESULT
|
||||
@@ -517,8 +517,8 @@ typedef struct Tcl_Interp {
|
||||
* Tcl_Eval must free it before executing next
|
||||
* command. */
|
||||
#else
|
||||
char *unused3 TCL_DEPRECATED_API("bad field access");
|
||||
void (*unused4) (char *) TCL_DEPRECATED_API("bad field access");
|
||||
char *resultDontUse; /* Don't use in extensions! */
|
||||
void (*freeProcDontUse) (char *); /* Don't use in extensions! */
|
||||
#endif
|
||||
#ifdef USE_INTERP_ERRORLINE
|
||||
int errorLine TCL_DEPRECATED_API("use Tcl_GetErrorLine/Tcl_SetErrorLine");
|
||||
@@ -526,9 +526,11 @@ typedef struct Tcl_Interp {
|
||||
* line number within the command where the
|
||||
* error occurred (1 if first line). */
|
||||
#else
|
||||
int unused5 TCL_DEPRECATED_API("bad field access");
|
||||
int errorLineDontUse; /* Don't use in extensions! */
|
||||
#endif
|
||||
} Tcl_Interp;
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
Tcl_Interp;
|
||||
|
||||
typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
|
||||
typedef struct Tcl_Channel_ *Tcl_Channel;
|
||||
@@ -852,10 +854,7 @@ typedef struct Tcl_Obj {
|
||||
* whether an object is shared (i.e. has reference count > 1). Note: clients
|
||||
* should use Tcl_DecrRefCount() when they are finished using an object, and
|
||||
* should never call TclFreeObj() directly. TclFreeObj() is only defined and
|
||||
* made public in tcl.h to support Tcl_DecrRefCount's macro definition. Note
|
||||
* also that Tcl_DecrRefCount() refers to the parameter "obj" twice. This
|
||||
* means that you should avoid calling it with an expression that is expensive
|
||||
* to compute or has side effects.
|
||||
* made public in tcl.h to support Tcl_DecrRefCount's macro definition.
|
||||
*/
|
||||
|
||||
void Tcl_IncrRefCount(Tcl_Obj *objPtr);
|
||||
@@ -1069,6 +1068,8 @@ typedef struct Tcl_DString {
|
||||
#define TCL_EVAL_INVOKE 0x080000
|
||||
#define TCL_CANCEL_UNWIND 0x100000
|
||||
#define TCL_EVAL_NOERR 0x200000
|
||||
#define TCL_EVAL_REDIRECT 0x400000
|
||||
|
||||
|
||||
/*
|
||||
* Special freeProc values that may be passed to Tcl_SetResult (see the man
|
||||
@@ -2358,6 +2359,14 @@ typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
|
||||
#define TCL_ZLIB_FULLFLUSH 3
|
||||
#define TCL_ZLIB_FINALIZE 4
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* Definitions needed for the Tcl_LoadFile function. [TIP #416]
|
||||
*/
|
||||
|
||||
#define TCL_LOAD_GLOBAL 1
|
||||
#define TCL_LOAD_LAZY 2
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
* Single public declaration for NRE.
|
||||
@@ -2494,7 +2503,12 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
* http://c2.com/cgi/wiki?TrivialDoWhileLoop
|
||||
*/
|
||||
# define Tcl_DecrRefCount(objPtr) \
|
||||
do { if (--(objPtr)->refCount <= 0) TclFreeObj(objPtr); } while(0)
|
||||
do { \
|
||||
Tcl_Obj *_objPtr = (objPtr); \
|
||||
if (--(_objPtr)->refCount <= 0) { \
|
||||
TclFreeObj(_objPtr); \
|
||||
} \
|
||||
} while(0)
|
||||
# define Tcl_IsShared(objPtr) \
|
||||
((objPtr)->refCount > 1)
|
||||
#endif
|
||||
|
||||
+30
-4
@@ -265,7 +265,7 @@ static int CheckStrictlyPositive(Tcl_Interp*, int);
|
||||
static ByteCode * CompileAssembleObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
static void CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*,
|
||||
TalInstDesc*);
|
||||
const TalInstDesc*);
|
||||
static int DefineLabel(AssemblyEnv* envPtr, const char* label);
|
||||
static void DeleteMirrorJumpTable(JumptableInfo* jtPtr);
|
||||
static void DupAssembleCodeInternalRep(Tcl_Obj* src,
|
||||
@@ -350,7 +350,7 @@ static const Tcl_ObjType assembleCodeType = {
|
||||
* Source instructions recognized in the Tcl Assembly Language (TAL)
|
||||
*/
|
||||
|
||||
TalInstDesc TalInstructionTable[] = {
|
||||
static const TalInstDesc TalInstructionTable[] = {
|
||||
/* PUSH must be first, see the code near the end of TclAssembleCode */
|
||||
{"push", ASSEM_PUSH, (INST_PUSH1<<8
|
||||
| INST_PUSH4), 0, 1},
|
||||
@@ -362,6 +362,10 @@ TalInstDesc TalInstructionTable[] = {
|
||||
| INST_APPEND_ARRAY4), 2, 1},
|
||||
{"appendArrayStk", ASSEM_1BYTE, INST_APPEND_ARRAY_STK, 3, 1},
|
||||
{"appendStk", ASSEM_1BYTE, INST_APPEND_STK, 2, 1},
|
||||
{"arrayExistsImm", ASSEM_LVT4, INST_ARRAY_EXISTS_IMM, 0, 1},
|
||||
{"arrayExistsStk", ASSEM_1BYTE, INST_ARRAY_EXISTS_STK, 1, 1},
|
||||
{"arrayMakeImm", ASSEM_LVT4, INST_ARRAY_MAKE_IMM, 0, 0},
|
||||
{"arrayMakeStk", ASSEM_1BYTE, INST_ARRAY_MAKE_STK, 1, 0},
|
||||
{"beginCatch", ASSEM_BEGIN_CATCH,
|
||||
INST_BEGIN_CATCH4, 0, 0},
|
||||
{"bitand", ASSEM_1BYTE, INST_BITAND, 2, 1},
|
||||
@@ -369,7 +373,10 @@ TalInstDesc TalInstructionTable[] = {
|
||||
{"bitor", ASSEM_1BYTE, INST_BITOR, 2, 1},
|
||||
{"bitxor", ASSEM_1BYTE, INST_BITXOR, 2, 1},
|
||||
{"concat", ASSEM_CONCAT1, INST_CONCAT1, INT_MIN,1},
|
||||
{"coroName", ASSEM_1BYTE, INST_COROUTINE_NAME, 0, 1},
|
||||
{"currentNamespace",ASSEM_1BYTE, INST_NS_CURRENT, 0, 1},
|
||||
{"dictAppend", ASSEM_LVT4, INST_DICT_APPEND, 2, 1},
|
||||
{"dictExists", ASSEM_DICT_GET, INST_DICT_EXISTS, INT_MIN,1},
|
||||
{"dictExpand", ASSEM_1BYTE, INST_DICT_EXPAND, 3, 1},
|
||||
{"dictGet", ASSEM_DICT_GET, INST_DICT_GET, INT_MIN,1},
|
||||
{"dictIncrImm", ASSEM_SINT4_LVT4,
|
||||
@@ -406,6 +413,8 @@ TalInstDesc TalInstructionTable[] = {
|
||||
{"incrStk", ASSEM_1BYTE, INST_INCR_SCALAR_STK, 2, 1},
|
||||
{"incrStkImm", ASSEM_SINT1, INST_INCR_SCALAR_STK_IMM,
|
||||
1, 1},
|
||||
{"infoLevelArgs", ASSEM_1BYTE, INST_INFO_LEVEL_ARGS, 1, 1},
|
||||
{"infoLevelNumber", ASSEM_1BYTE, INST_INFO_LEVEL_NUM, 0, 1},
|
||||
{"invokeStk", ASSEM_INVOKE, (INST_INVOKE_STK1 << 8
|
||||
| INST_INVOKE_STK4), INT_MIN,1},
|
||||
{"jump", ASSEM_JUMP, INST_JUMP1, 0, 0},
|
||||
@@ -457,6 +466,7 @@ TalInstDesc TalInstructionTable[] = {
|
||||
0, 1},
|
||||
{"pushResult", ASSEM_1BYTE, INST_PUSH_RESULT, 0, 1},
|
||||
{"regexp", ASSEM_REGEXP, INST_REGEXP, 2, 1},
|
||||
{"resolveCmd", ASSEM_1BYTE, INST_RESOLVE_COMMAND, 1, 1},
|
||||
{"reverse", ASSEM_REVERSE, INST_REVERSE, INT_MIN,-1-0},
|
||||
{"rshift", ASSEM_1BYTE, INST_RSHIFT, 2, 1},
|
||||
{"store", ASSEM_LVT, (INST_STORE_SCALAR1<<8
|
||||
@@ -467,11 +477,19 @@ TalInstDesc TalInstructionTable[] = {
|
||||
{"storeStk", ASSEM_1BYTE, INST_STORE_SCALAR_STK, 2, 1},
|
||||
{"strcmp", ASSEM_1BYTE, INST_STR_CMP, 2, 1},
|
||||
{"streq", ASSEM_1BYTE, INST_STR_EQ, 2, 1},
|
||||
{"strfind", ASSEM_1BYTE, INST_STR_FIND, 2, 1},
|
||||
{"strindex", ASSEM_1BYTE, INST_STR_INDEX, 2, 1},
|
||||
{"strlen", ASSEM_1BYTE, INST_STR_LEN, 1, 1},
|
||||
{"strmap", ASSEM_1BYTE, INST_STR_MAP, 3, 1},
|
||||
{"strmatch", ASSEM_BOOL, INST_STR_MATCH, 2, 1},
|
||||
{"strneq", ASSEM_1BYTE, INST_STR_NEQ, 2, 1},
|
||||
{"strrange", ASSEM_1BYTE, INST_STR_RANGE, 3, 1},
|
||||
{"strrfind", ASSEM_1BYTE, INST_STR_FIND_LAST, 2, 1},
|
||||
{"sub", ASSEM_1BYTE, INST_SUB, 2, 1},
|
||||
{"tclooClass", ASSEM_1BYTE, INST_TCLOO_CLASS, 1, 1},
|
||||
{"tclooIsObject", ASSEM_1BYTE, INST_TCLOO_IS_OBJECT, 1, 1},
|
||||
{"tclooNamespace", ASSEM_1BYTE, INST_TCLOO_NS, 1, 1},
|
||||
{"tclooSelf", ASSEM_1BYTE, INST_TCLOO_SELF, 0, 1},
|
||||
{"tryCvtToNumeric", ASSEM_1BYTE, INST_TRY_CVT_TO_NUMERIC,1, 1},
|
||||
{"uminus", ASSEM_1BYTE, INST_UMINUS, 1, 1},
|
||||
{"unset", ASSEM_BOOL_LVT4,INST_UNSET_SCALAR, 0, 0},
|
||||
@@ -481,6 +499,8 @@ TalInstDesc TalInstructionTable[] = {
|
||||
{"uplus", ASSEM_1BYTE, INST_UPLUS, 1, 1},
|
||||
{"upvar", ASSEM_LVT4, INST_UPVAR, 2, 1},
|
||||
{"variable", ASSEM_LVT4, INST_VARIABLE, 1, 0},
|
||||
{"verifyDict", ASSEM_1BYTE, INST_DICT_VERIFY, 1, 0},
|
||||
{"yield", ASSEM_1BYTE, INST_YIELD, 1, 1},
|
||||
{NULL, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -499,7 +519,13 @@ static const unsigned char NonThrowingByteCodes[] = {
|
||||
INST_OVER, /* 95 */
|
||||
INST_PUSH_RETURN_OPTIONS, /* 108 */
|
||||
INST_REVERSE, /* 126 */
|
||||
INST_NOP /* 132 */
|
||||
INST_NOP, /* 132 */
|
||||
INST_STR_MAP, /* 143 */
|
||||
INST_STR_FIND, /* 144 */
|
||||
INST_COROUTINE_NAME, /* 149 */
|
||||
INST_NS_CURRENT, /* 151 */
|
||||
INST_INFO_LEVEL_NUM, /* 152 */
|
||||
INST_RESOLVE_COMMAND /* 154 */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1768,7 +1794,7 @@ static void
|
||||
CompileEmbeddedScript(
|
||||
AssemblyEnv* assemEnvPtr, /* Assembly environment */
|
||||
Tcl_Token* tokenPtr, /* Tcl_Token containing the script */
|
||||
TalInstDesc* instPtr) /* Instruction that determines whether
|
||||
const TalInstDesc* instPtr) /* Instruction that determines whether
|
||||
* the script is 'expr' or 'eval' */
|
||||
{
|
||||
CompileEnv* envPtr = assemEnvPtr->envPtr;
|
||||
|
||||
+311
-189
@@ -81,8 +81,6 @@ TCL_DECLARE_MUTEX(cancelLock)
|
||||
* are used to save the evaluation state between NR calls to each coro.
|
||||
*/
|
||||
|
||||
static const CorContext NULL_CONTEXT = {NULL, NULL, NULL, NULL};
|
||||
|
||||
#define SAVE_CONTEXT(context) \
|
||||
(context).framePtr = iPtr->framePtr; \
|
||||
(context).varFramePtr = iPtr->varFramePtr; \
|
||||
@@ -133,11 +131,11 @@ static Tcl_Obj * GetCommandSource(Interp *iPtr, int objc,
|
||||
Tcl_Obj *const objv[], int lookup);
|
||||
static void MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
|
||||
int actual, Tcl_Obj *const *objv);
|
||||
static Tcl_NRPostProc NRCoroutineActivateCallback;
|
||||
static Tcl_NRPostProc NRCoroutineCallerCallback;
|
||||
static Tcl_NRPostProc NRCoroutineExitCallback;
|
||||
static int NRCommand(ClientData data[], Tcl_Interp *interp, int result);
|
||||
|
||||
static Tcl_NRPostProc NRRunObjProc;
|
||||
static Tcl_NRPostProc NRTailcallEval;
|
||||
static Tcl_ObjCmdProc OldMathFuncProc;
|
||||
static void OldMathFuncDeleteProc(ClientData clientData);
|
||||
static void ProcessUnexpectedResult(Tcl_Interp *interp,
|
||||
@@ -164,10 +162,10 @@ static Tcl_NRPostProc TEOV_RestoreVarFrame;
|
||||
static Tcl_NRPostProc TEOV_RunLeaveTraces;
|
||||
static Tcl_NRPostProc YieldToCallback;
|
||||
|
||||
static void ClearTailcall(Tcl_Interp *interp,
|
||||
struct NRE_callback *tailcallPtr);
|
||||
static Tcl_ObjCmdProc NRCoroInjectObjCmd;
|
||||
|
||||
static inline void SpliceDeferred(Tcl_Interp *interp);
|
||||
|
||||
MODULE_SCOPE const TclStubs tclStubs;
|
||||
|
||||
/*
|
||||
@@ -219,7 +217,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"expr", Tcl_ExprObjCmd, TclCompileExprCmd, TclNRExprObjCmd, 1},
|
||||
{"for", Tcl_ForObjCmd, TclCompileForCmd, TclNRForObjCmd, 1},
|
||||
{"foreach", Tcl_ForeachObjCmd, TclCompileForeachCmd, TclNRForeachCmd, 1},
|
||||
{"format", Tcl_FormatObjCmd, NULL, NULL, 1},
|
||||
{"format", Tcl_FormatObjCmd, TclCompileFormatCmd, NULL, 1},
|
||||
{"global", Tcl_GlobalObjCmd, TclCompileGlobalCmd, NULL, 1},
|
||||
{"if", Tcl_IfObjCmd, TclCompileIfCmd, TclNRIfObjCmd, 1},
|
||||
{"incr", Tcl_IncrObjCmd, TclCompileIncrCmd, NULL, 1},
|
||||
@@ -230,6 +228,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"linsert", Tcl_LinsertObjCmd, NULL, NULL, 1},
|
||||
{"list", Tcl_ListObjCmd, TclCompileListCmd, NULL, 1},
|
||||
{"llength", Tcl_LlengthObjCmd, TclCompileLlengthCmd, NULL, 1},
|
||||
{"lmap", Tcl_LmapObjCmd, TclCompileLmapCmd, TclNRLmapCmd, 1},
|
||||
{"lrange", Tcl_LrangeObjCmd, TclCompileLrangeCmd, NULL, 1},
|
||||
{"lrepeat", Tcl_LrepeatObjCmd, NULL, NULL, 1},
|
||||
{"lreplace", Tcl_LreplaceObjCmd, TclCompileLreplaceCmd, NULL, 1},
|
||||
@@ -240,7 +239,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"package", Tcl_PackageObjCmd, NULL, NULL, 1},
|
||||
{"proc", Tcl_ProcObjCmd, NULL, NULL, 1},
|
||||
{"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, 1},
|
||||
{"regsub", Tcl_RegsubObjCmd, NULL, NULL, 1},
|
||||
{"regsub", Tcl_RegsubObjCmd, TclCompileRegsubCmd, NULL, 1},
|
||||
{"rename", Tcl_RenameObjCmd, NULL, NULL, 1},
|
||||
{"return", Tcl_ReturnObjCmd, TclCompileReturnCmd, NULL, 1},
|
||||
{"scan", Tcl_ScanObjCmd, NULL, NULL, 1},
|
||||
@@ -248,7 +247,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"split", Tcl_SplitObjCmd, NULL, NULL, 1},
|
||||
{"subst", Tcl_SubstObjCmd, TclCompileSubstCmd, TclNRSubstObjCmd, 1},
|
||||
{"switch", Tcl_SwitchObjCmd, TclCompileSwitchCmd, TclNRSwitchObjCmd, 1},
|
||||
{"tailcall", NULL, NULL, TclNRTailcallObjCmd, 1},
|
||||
{"tailcall", NULL, TclCompileTailcallCmd, TclNRTailcallObjCmd, 1},
|
||||
{"throw", Tcl_ThrowObjCmd, TclCompileThrowCmd, NULL, 1},
|
||||
{"trace", Tcl_TraceObjCmd, NULL, NULL, 1},
|
||||
{"try", Tcl_TryObjCmd, TclCompileTryCmd, TclNRTryObjCmd, 1},
|
||||
@@ -257,7 +256,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"upvar", Tcl_UpvarObjCmd, TclCompileUpvarCmd, NULL, 1},
|
||||
{"variable", Tcl_VariableObjCmd, TclCompileVariableCmd, NULL, 1},
|
||||
{"while", Tcl_WhileObjCmd, TclCompileWhileCmd, TclNRWhileObjCmd, 1},
|
||||
{"yield", NULL, NULL, TclNRYieldObjCmd, 1},
|
||||
{"yield", NULL, TclCompileYieldCmd, TclNRYieldObjCmd, 1},
|
||||
{"yieldto", NULL, NULL, TclNRYieldToObjCmd, 1},
|
||||
|
||||
/*
|
||||
@@ -1557,12 +1556,16 @@ DeleteInterpProc(
|
||||
hPtr != NULL;
|
||||
hPtr = Tcl_NextHashEntry(&search)) {
|
||||
CmdFrame *cfPtr = Tcl_GetHashValue(hPtr);
|
||||
Proc *procPtr = (Proc *) Tcl_GetHashKey(iPtr->linePBodyPtr, hPtr);
|
||||
|
||||
if (cfPtr->type == TCL_LOCATION_SOURCE) {
|
||||
Tcl_DecrRefCount(cfPtr->data.eval.path);
|
||||
procPtr->iPtr = NULL;
|
||||
if (cfPtr) {
|
||||
if (cfPtr->type == TCL_LOCATION_SOURCE) {
|
||||
Tcl_DecrRefCount(cfPtr->data.eval.path);
|
||||
}
|
||||
ckfree(cfPtr->line);
|
||||
ckfree(cfPtr);
|
||||
}
|
||||
ckfree(cfPtr->line);
|
||||
ckfree(cfPtr);
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
}
|
||||
Tcl_DeleteHashTable(iPtr->linePBodyPtr);
|
||||
@@ -1704,9 +1707,9 @@ Tcl_HideCommand(
|
||||
*/
|
||||
|
||||
if (strstr(hiddenCmdToken, "::") != NULL) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot use namespace qualifiers in hidden command"
|
||||
" token (rename)", NULL);
|
||||
" token (rename)", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "HIDDENTOKEN", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1729,8 +1732,9 @@ Tcl_HideCommand(
|
||||
*/
|
||||
|
||||
if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
|
||||
Tcl_AppendResult(interp, "can only hide global namespace commands"
|
||||
" (use rename then hide)", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"can only hide global namespace commands (use rename then hide)",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "HIDE", "NON_GLOBAL", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1754,8 +1758,9 @@ Tcl_HideCommand(
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &isNew);
|
||||
if (!isNew) {
|
||||
Tcl_AppendResult(interp, "hidden command named \"", hiddenCmdToken,
|
||||
"\" already exists", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"hidden command named \"%s\" already exists",
|
||||
hiddenCmdToken));
|
||||
Tcl_SetErrorCode(interp, "TCL", "HIDE", "ALREADY_HIDDEN", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1857,8 +1862,9 @@ Tcl_ExposeCommand(
|
||||
*/
|
||||
|
||||
if (strstr(cmdName, "::") != NULL) {
|
||||
Tcl_AppendResult(interp, "cannot expose to a namespace "
|
||||
"(use expose to toplevel, then rename)", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot expose to a namespace (use expose to toplevel, then rename)",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "NON_GLOBAL", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1873,8 +1879,8 @@ Tcl_ExposeCommand(
|
||||
hPtr = Tcl_FindHashEntry(hiddenCmdTablePtr, hiddenCmdToken);
|
||||
}
|
||||
if (hPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "unknown hidden command \"", hiddenCmdToken,
|
||||
"\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"unknown hidden command \"%s\"", hiddenCmdToken));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN",
|
||||
hiddenCmdToken, NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -1893,9 +1899,9 @@ Tcl_ExposeCommand(
|
||||
* than 'nicely' erroring out ?
|
||||
*/
|
||||
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"trying to expose a non-global command namespace command",
|
||||
NULL);
|
||||
-1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1912,8 +1918,8 @@ Tcl_ExposeCommand(
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
|
||||
if (!isNew) {
|
||||
Tcl_AppendResult(interp, "exposed command \"", cmdName,
|
||||
"\" already exists", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"exposed command \"%s\" already exists", cmdName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "COMMAND_EXISTS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2493,9 +2499,10 @@ TclRenameCommand(
|
||||
cmd = Tcl_FindCommand(interp, oldName, NULL, /*flags*/ 0);
|
||||
cmdPtr = (Command *) cmd;
|
||||
if (cmdPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "can't ",
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't %s \"%s\": command doesn't exist",
|
||||
((newName == NULL)||(*newName == '\0'))? "delete":"rename",
|
||||
" \"", oldName, "\": command doesn't exist", NULL);
|
||||
oldName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2525,15 +2532,15 @@ TclRenameCommand(
|
||||
TCL_CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail);
|
||||
|
||||
if ((newNsPtr == NULL) || (newTail == NULL)) {
|
||||
Tcl_AppendResult(interp, "can't rename to \"", newName,
|
||||
"\": bad command name", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't rename to \"%s\": bad command name", newName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
|
||||
Tcl_AppendResult(interp, "can't rename to \"", newName,
|
||||
"\": command already exists", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't rename to \"%s\": command already exists", newName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "RENAME",
|
||||
"TARGET_EXISTS", NULL);
|
||||
result = TCL_ERROR;
|
||||
@@ -2608,7 +2615,7 @@ TclRenameCommand(
|
||||
Tcl_DStringInit(&newFullName);
|
||||
Tcl_DStringAppend(&newFullName, newNsPtr->fullName, -1);
|
||||
if (newNsPtr != iPtr->globalNsPtr) {
|
||||
Tcl_DStringAppend(&newFullName, "::", 2);
|
||||
TclDStringAppendLiteral(&newFullName, "::");
|
||||
}
|
||||
Tcl_DStringAppend(&newFullName, newTail, -1);
|
||||
cmdPtr->refCount++;
|
||||
@@ -3466,7 +3473,7 @@ Tcl_CreateMathFunc(
|
||||
data->clientData = clientData;
|
||||
|
||||
Tcl_DStringInit(&bigName);
|
||||
Tcl_DStringAppend(&bigName, "::tcl::mathfunc::", -1);
|
||||
TclDStringAppendLiteral(&bigName, "::tcl::mathfunc::");
|
||||
Tcl_DStringAppend(&bigName, name, -1);
|
||||
|
||||
Tcl_CreateObjCommand(interp, Tcl_DStringValue(&bigName),
|
||||
@@ -3534,9 +3541,9 @@ OldMathFuncProc(
|
||||
* We have a non-numeric argument.
|
||||
*/
|
||||
|
||||
Tcl_SetResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"argument to math function didn't have numeric value",
|
||||
TCL_STATIC);
|
||||
-1));
|
||||
TclCheckBadOctal(interp, Tcl_GetString(valuePtr));
|
||||
ckfree(args);
|
||||
return TCL_ERROR;
|
||||
@@ -3749,41 +3756,28 @@ Tcl_ListMathFuncs(
|
||||
Tcl_Interp *interp,
|
||||
const char *pattern)
|
||||
{
|
||||
Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
|
||||
Namespace *nsPtr;
|
||||
Namespace *dummy1NsPtr;
|
||||
Namespace *dummy2NsPtr;
|
||||
const char *dummyNamePtr;
|
||||
Tcl_Obj *result = Tcl_NewObj();
|
||||
Tcl_Obj *script = Tcl_NewStringObj("::info functions ", -1);
|
||||
Tcl_Obj *result;
|
||||
Tcl_InterpState state;
|
||||
|
||||
TclGetNamespaceForQualName(interp, "::tcl::mathfunc",
|
||||
globalNsPtr, TCL_FIND_ONLY_NS | TCL_GLOBAL_ONLY,
|
||||
&nsPtr, &dummy1NsPtr, &dummy2NsPtr, &dummyNamePtr);
|
||||
if (nsPtr == NULL) {
|
||||
return result;
|
||||
if (pattern) {
|
||||
Tcl_Obj *patternObj = Tcl_NewStringObj(pattern, -1);
|
||||
Tcl_Obj *arg = Tcl_NewListObj(1, &patternObj);
|
||||
|
||||
Tcl_AppendObjToObj(script, arg);
|
||||
Tcl_DecrRefCount(arg); /* Should tear down patternObj too */
|
||||
}
|
||||
|
||||
if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
|
||||
if (Tcl_FindHashEntry(&nsPtr->cmdTable, pattern) != NULL) {
|
||||
Tcl_ListObjAppendElement(NULL, result,
|
||||
Tcl_NewStringObj(pattern, -1));
|
||||
}
|
||||
state = Tcl_SaveInterpState(interp, TCL_OK);
|
||||
Tcl_IncrRefCount(script);
|
||||
if (TCL_OK == Tcl_EvalObjEx(interp, script, 0)) {
|
||||
result = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
|
||||
} else {
|
||||
Tcl_HashSearch cmdHashSearch;
|
||||
Tcl_HashEntry *cmdHashEntry =
|
||||
Tcl_FirstHashEntry(&nsPtr->cmdTable,&cmdHashSearch);
|
||||
|
||||
for (; cmdHashEntry != NULL;
|
||||
cmdHashEntry = Tcl_NextHashEntry(&cmdHashSearch)) {
|
||||
const char *cmdNamePtr =
|
||||
Tcl_GetHashKey(&nsPtr->cmdTable, cmdHashEntry);
|
||||
|
||||
if (pattern == NULL || Tcl_StringMatch(cmdNamePtr, pattern)) {
|
||||
Tcl_ListObjAppendElement(NULL, result,
|
||||
Tcl_NewStringObj(cmdNamePtr, -1));
|
||||
}
|
||||
}
|
||||
result = Tcl_NewObj();
|
||||
}
|
||||
Tcl_DecrRefCount(script);
|
||||
Tcl_RestoreInterpState(interp, state);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -3823,9 +3817,8 @@ TclInterpReady(
|
||||
*/
|
||||
|
||||
if (iPtr->flags & DELETED) {
|
||||
/* JJM - Superfluous Tcl_ResetResult call removed. */
|
||||
Tcl_AppendResult(interp,
|
||||
"attempt to call eval in deleted interpreter", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"attempt to call eval in deleted interpreter", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "IDELETE",
|
||||
"attempt to call eval in deleted interpreter", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -3853,8 +3846,8 @@ TclInterpReady(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
Tcl_AppendResult(interp,
|
||||
"too many nested evaluations (infinite loop?)", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"too many nested evaluations (infinite loop?)", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3988,8 +3981,7 @@ Tcl_Canceled(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, message, NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(message, -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "CANCEL", id, message, NULL);
|
||||
}
|
||||
|
||||
@@ -4182,15 +4174,14 @@ TclNREvalObjv(
|
||||
* finishes the source command and not just the target.
|
||||
*/
|
||||
|
||||
if (iPtr->evalFlags & TCL_EVAL_REDIRECT) {
|
||||
if (flags & TCL_EVAL_REDIRECT) {
|
||||
TclNRAddCallback(interp, NRCommand, NULL, INT2PTR(1), INT2PTR(objc), objv);
|
||||
iPtr->evalFlags &= ~TCL_EVAL_REDIRECT;
|
||||
} else {
|
||||
TclNRAddCallback(interp, NRCommand, NULL, NULL, INT2PTR(objc), objv);
|
||||
}
|
||||
cmdPtrPtr = (Command **) &(TOP_CB(interp)->data[0]);
|
||||
|
||||
TclNRSpliceDeferred(interp);
|
||||
SpliceDeferred(interp);
|
||||
|
||||
iPtr->numLevels++;
|
||||
result = TclInterpReady(interp);
|
||||
@@ -4311,6 +4302,7 @@ TclNREvalObjv(
|
||||
if (cmdPtr->nreProc) {
|
||||
TclNRAddCallback(interp, NRRunObjProc, cmdPtr,
|
||||
INT2PTR(objc), (ClientData) objv, NULL);
|
||||
|
||||
return TCL_OK;
|
||||
} else {
|
||||
return cmdPtr->objProc(cmdPtr->objClientData, interp, objc, objv);
|
||||
@@ -4334,7 +4326,7 @@ TclNRRunCallbacks(
|
||||
* are to be run. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
NRE_callback *callbackPtr;
|
||||
NRE_callback *cbPtr;
|
||||
Tcl_NRPostProc *procPtr;
|
||||
|
||||
/*
|
||||
@@ -4352,16 +4344,15 @@ TclNRRunCallbacks(
|
||||
}
|
||||
|
||||
while (TOP_CB(interp) != rootPtr) {
|
||||
callbackPtr = TOP_CB(interp);
|
||||
procPtr = callbackPtr->procPtr;
|
||||
TOP_CB(interp) = callbackPtr->nextPtr;
|
||||
result = procPtr(callbackPtr->data, interp, result);
|
||||
TCLNR_FREE(interp, callbackPtr);
|
||||
POP_CB(interp, cbPtr);
|
||||
procPtr = cbPtr->procPtr;
|
||||
result = procPtr(cbPtr->data, interp, result);
|
||||
FREE_CB(cbPtr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
NRCommand(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
@@ -4376,6 +4367,14 @@ NRCommand(
|
||||
}
|
||||
((Interp *)interp)->numLevels--;
|
||||
|
||||
/*
|
||||
* If there is a tailcall, schedule it
|
||||
*/
|
||||
|
||||
if (data[1] && (data[1] != INT2PTR(1))) {
|
||||
TclNRAddCallback(interp, TclNRTailcallEval, data[1], NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/* OPT ??
|
||||
* Do not interrupt a series of cleanups with async or limit checks:
|
||||
* just check at the end?
|
||||
@@ -4612,8 +4611,8 @@ TEOV_NotFound(
|
||||
|
||||
cmdPtr = TEOV_LookupCmdFromObj(interp, newObjv[0], lookupNsPtr);
|
||||
if (cmdPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "invalid command name \"",
|
||||
TclGetString(objv[0]), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"invalid command name \"%s\"", TclGetString(objv[0])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND",
|
||||
TclGetString(objv[0]), NULL);
|
||||
|
||||
@@ -4633,10 +4632,10 @@ TEOV_NotFound(
|
||||
savedNsPtr = varFramePtr->nsPtr;
|
||||
varFramePtr->nsPtr = lookupNsPtr;
|
||||
}
|
||||
TclNRDeferCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc),
|
||||
TclDeferCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc),
|
||||
newObjv, savedNsPtr, NULL);
|
||||
iPtr->evalFlags |= TCL_EVAL_REDIRECT;
|
||||
return TclNREvalObjv(interp, newObjc, newObjv, TCL_EVAL_NOERR, NULL);
|
||||
return TclNREvalObjv(interp, newObjc, newObjv, (TCL_EVAL_NOERR|TCL_EVAL_REDIRECT),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -6020,7 +6019,7 @@ TclNREvalObjEx(
|
||||
iPtr->cmdFramePtr = eoFramePtr;
|
||||
}
|
||||
|
||||
TclNRDeferCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
|
||||
TclDeferCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
|
||||
NULL, NULL);
|
||||
|
||||
ListObjGetElements(listPtr, objc, objv);
|
||||
@@ -6281,11 +6280,11 @@ ProcessUnexpectedResult(
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
if (returnCode == TCL_BREAK) {
|
||||
Tcl_AppendResult(interp,
|
||||
"invoked \"break\" outside of a loop", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"invoked \"break\" outside of a loop", -1));
|
||||
} else if (returnCode == TCL_CONTINUE) {
|
||||
Tcl_AppendResult(interp,
|
||||
"invoked \"continue\" outside of a loop", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"invoked \"continue\" outside of a loop", -1));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"command returned bad code: %d", returnCode));
|
||||
@@ -6620,7 +6619,8 @@ TclObjInvoke(
|
||||
}
|
||||
|
||||
if ((objc < 1) || (objv == NULL)) {
|
||||
Tcl_AppendResult(interp, "illegal argument vector", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"illegal argument vector", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -6638,8 +6638,8 @@ TclObjInvoke(
|
||||
hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
|
||||
}
|
||||
if (hPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "invalid hidden command name \"",
|
||||
cmdName, "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"invalid hidden command name \"%s\"", cmdName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN", cmdName,
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -7265,7 +7265,8 @@ ExprIsqrtFunc(
|
||||
return TCL_OK;
|
||||
|
||||
negarg:
|
||||
Tcl_SetResult(interp, "square root of negative argument", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"square root of negative argument", -1));
|
||||
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
|
||||
"domain error: argument not in valid range", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -8274,10 +8275,151 @@ Tcl_NRCmdSwap(
|
||||
* FIXME NRE!
|
||||
*/
|
||||
|
||||
//#define PR(x) fprint(stdout, x)
|
||||
#define PR(x)
|
||||
|
||||
void
|
||||
TclSpliceTailcall(
|
||||
TclDeferCallback(
|
||||
Tcl_Interp *interp,
|
||||
NRE_callback *tailcallPtr)
|
||||
Tcl_NRPostProc *postProcPtr,
|
||||
ClientData data0, ClientData data1,
|
||||
ClientData data2, ClientData data3)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
NRE_callback *cbPtr;
|
||||
|
||||
TclNRAddCallback(interp, postProcPtr, data0, data1,
|
||||
data2, data3);
|
||||
cbPtr = TOP_CB(interp);
|
||||
cbPtr->nextPtr = iPtr->deferredCallbacks;
|
||||
iPtr->deferredCallbacks = cbPtr;
|
||||
}
|
||||
|
||||
static void
|
||||
SpliceDeferred(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
PR("CALLED SpliceDeferred\n");
|
||||
return;
|
||||
/* STUPID: optimize a bit */
|
||||
#if 0
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
int deferred = iPtr->deferredCallbacks;
|
||||
NRE_callback *tosPtr = TOP_CB(interp), *runPtr;
|
||||
|
||||
if (deferred) {
|
||||
NRE_callback *tmp;
|
||||
int i;
|
||||
|
||||
tmp = ckalloc(deferred*sizeof(NRE_callback));
|
||||
|
||||
i = deferred;
|
||||
while (i--) {
|
||||
POP_CB(interp, runPtr);
|
||||
tmp[i] = *runPtr;
|
||||
}
|
||||
|
||||
ALLOC_CB(interp, runPtr);
|
||||
*runPtr = *tosPtr;
|
||||
|
||||
i = deferred;
|
||||
for (i=0; i < deferred; i++) {
|
||||
ALLOC_CB(interp, runPtr);
|
||||
*runPtr = tmp[i];
|
||||
}
|
||||
ckfree(tmp);
|
||||
iPtr->deferredCallbacks = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
TclNRStackBottom(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ExecEnv *eePtr = iPtr->execEnvPtr;
|
||||
NRE_stack *this = eePtr->NRStack;
|
||||
NRE_stack *prev = data[0];
|
||||
|
||||
PR("CALLED TclNRStackBottom\n");
|
||||
|
||||
if (!prev) {
|
||||
Tcl_Panic("Reached the NRE-stack bottom, should not happen!");
|
||||
}
|
||||
|
||||
/*
|
||||
* Go back to the previous stack.
|
||||
*/
|
||||
|
||||
eePtr->NRStack = prev;
|
||||
eePtr->callbackPtr = &prev->items[NRE_STACK_SIZE-1];
|
||||
|
||||
/*
|
||||
* Keep this stack in reserve. If this one had a successor, free that one:
|
||||
* we always keep just one in reserve.
|
||||
*/
|
||||
|
||||
if (this->next) {
|
||||
ckfree (this->next);
|
||||
this->next = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
NRE_callback *
|
||||
TclNewCallback(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ExecEnv *eePtr = iPtr->execEnvPtr;
|
||||
NRE_callback *cbPtr = eePtr->callbackPtr;
|
||||
NRE_stack *this = eePtr->NRStack;
|
||||
#if NEW
|
||||
if (!this || (cbPtr == &this->items[NRE_STACK_SIZE-1])) {
|
||||
PR("ALLOC\n");
|
||||
if (this && this->next) {
|
||||
eePtr->NRStack = this->next;
|
||||
} else {
|
||||
eePtr->NRStack = (NRE_stack *) ckalloc(sizeof(NRE_stack));
|
||||
eePtr->NRStack->next = NULL;
|
||||
}
|
||||
eePtr->callbackPtr = &eePtr->NRStack->items[-1];
|
||||
|
||||
TclNRAddCallback(interp, TclNRStackBottom, this, NULL, NULL, NULL);
|
||||
} else {
|
||||
PR("PUSH\n");
|
||||
}
|
||||
cbPtr++;
|
||||
cbPtr->nextPtr = eePtr->callbackPtr;
|
||||
eePtr->callbackPtr = cbPtr;
|
||||
#endif
|
||||
return eePtr->callbackPtr;
|
||||
}
|
||||
|
||||
NRE_callback *
|
||||
TclPopCallback(
|
||||
Tcl_Interp *interp)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ExecEnv *eePtr = iPtr->execEnvPtr;
|
||||
NRE_callback *cbPtr = eePtr->callbackPtr, *tmp;
|
||||
NRE_stack *this = eePtr->NRStack;
|
||||
int depth = cbPtr - &this->items[1];
|
||||
|
||||
PR("POP\n");
|
||||
--eePtr->callbackPtr;
|
||||
return cbPtr;
|
||||
}
|
||||
|
||||
/* ***************************************** */
|
||||
void
|
||||
TclSetTailcall(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *listPtr)
|
||||
{
|
||||
/*
|
||||
* Find the splicing spot: right before the NRCommand of the thing
|
||||
@@ -8296,8 +8438,14 @@ TclSpliceTailcall(
|
||||
Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!");
|
||||
}
|
||||
|
||||
tailcallPtr->nextPtr = runPtr->nextPtr;
|
||||
runPtr->nextPtr = tailcallPtr;
|
||||
if (runPtr->data[1]) {
|
||||
/*
|
||||
* A tailcall was already scheduled: clear it!
|
||||
*/
|
||||
Tcl_Obj *oldPtr = (Tcl_Obj *) runPtr->data[1];
|
||||
Tcl_DecrRefCount(oldPtr);
|
||||
}
|
||||
runPtr->data[1] = listPtr;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -8314,10 +8462,9 @@ TclNRTailcallObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (!iPtr->varFramePtr->isProcCallFrame) { /* or is upleveled */
|
||||
Tcl_SetResult(interp,
|
||||
"tailcall can only be called from a proc or lambda",
|
||||
TCL_STATIC);
|
||||
if (!(iPtr->varFramePtr->isProcCallFrame & 1)) { /* or is upleveled */
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"tailcall can only be called from a proc or lambda", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -8328,7 +8475,7 @@ TclNRTailcallObjCmd(
|
||||
*/
|
||||
|
||||
if (iPtr->varFramePtr->tailcallPtr) {
|
||||
ClearTailcall(interp, iPtr->varFramePtr->tailcallPtr);
|
||||
Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr);
|
||||
iPtr->varFramePtr->tailcallPtr = NULL;
|
||||
}
|
||||
|
||||
@@ -8343,40 +8490,39 @@ TclNRTailcallObjCmd(
|
||||
Tcl_Obj *listPtr, *nsObjPtr;
|
||||
Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
|
||||
Tcl_Namespace *ns1Ptr;
|
||||
NRE_callback *tailcallPtr;
|
||||
|
||||
listPtr = Tcl_NewListObj(objc-1, objv+1);
|
||||
Tcl_IncrRefCount(listPtr);
|
||||
/* The tailcall data is in a Tcl list: the first element is the
|
||||
* namespace, the rest the command to be tailcalled. */
|
||||
|
||||
listPtr = Tcl_NewListObj(objc, objv);
|
||||
|
||||
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
|
||||
if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
|
||||
|| (nsPtr != ns1Ptr)) {
|
||||
Tcl_Panic("Tailcall failed to find the proper namespace");
|
||||
}
|
||||
Tcl_IncrRefCount(nsObjPtr);
|
||||
|
||||
TclNRAddCallback(interp, NRTailcallEval, listPtr, nsObjPtr,
|
||||
NULL, NULL);
|
||||
tailcallPtr = TOP_CB(interp);
|
||||
TOP_CB(interp) = tailcallPtr->nextPtr;
|
||||
iPtr->varFramePtr->tailcallPtr = tailcallPtr;
|
||||
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
|
||||
|
||||
iPtr->varFramePtr->tailcallPtr = listPtr;
|
||||
}
|
||||
return TCL_RETURN;
|
||||
}
|
||||
|
||||
int
|
||||
NRTailcallEval(
|
||||
TclNRTailcallEval(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Obj *listPtr = data[0];
|
||||
Tcl_Obj *nsObjPtr = data[1];
|
||||
Tcl_Obj *listPtr = data[0], *nsObjPtr;
|
||||
Tcl_Namespace *nsPtr;
|
||||
int objc;
|
||||
Tcl_Obj **objv;
|
||||
|
||||
Tcl_ListObjGetElements(interp, listPtr, &objc, &objv);
|
||||
nsObjPtr = objv[0];
|
||||
|
||||
if (result == TCL_OK) {
|
||||
result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
|
||||
}
|
||||
@@ -8395,10 +8541,9 @@ NRTailcallEval(
|
||||
* Perform the tailcall
|
||||
*/
|
||||
|
||||
TclNRDeferCallback(interp, TailcallCleanup, listPtr, nsObjPtr, NULL,NULL);
|
||||
TclDeferCallback(interp, TailcallCleanup, listPtr, NULL, NULL,NULL);
|
||||
iPtr->lookupNsPtr = (Namespace *) nsPtr;
|
||||
ListObjGetElements(listPtr, objc, objv);
|
||||
return TclNREvalObjv(interp, objc, objv, 0, NULL);
|
||||
return TclNREvalObjv(interp, objc-1, objv+1, 0, NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -8408,19 +8553,8 @@ TailcallCleanup(
|
||||
int result)
|
||||
{
|
||||
Tcl_DecrRefCount((Tcl_Obj *) data[0]);
|
||||
Tcl_DecrRefCount((Tcl_Obj *) data[1]);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearTailcall(
|
||||
Tcl_Interp *interp,
|
||||
NRE_callback *tailcallPtr)
|
||||
{
|
||||
TailcallCleanup(tailcallPtr->data, interp, TCL_OK);
|
||||
TCLNR_FREE(interp, tailcallPtr);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tcl_NRAddCallback(
|
||||
@@ -8476,8 +8610,8 @@ TclNRYieldObjCmd(
|
||||
}
|
||||
|
||||
if (!corPtr) {
|
||||
Tcl_SetResult(interp, "yield can only be called in a coroutine",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"yield can only be called in a coroutine", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -8487,7 +8621,7 @@ TclNRYieldObjCmd(
|
||||
}
|
||||
|
||||
NRE_ASSERT(!COR_IS_SUSPENDED(corPtr));
|
||||
TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
|
||||
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
|
||||
clientData, NULL, NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -8510,8 +8644,8 @@ TclNRYieldToObjCmd(
|
||||
}
|
||||
|
||||
if (!corPtr) {
|
||||
Tcl_SetResult(interp, "yieldto can only be called in a coroutine",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"yieldto can only be called in a coroutine", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -8522,23 +8656,22 @@ TclNRYieldToObjCmd(
|
||||
* This is essentially code from TclNRTailcallObjCmd
|
||||
*/
|
||||
|
||||
listPtr = Tcl_NewListObj(objc-1, objv+1);
|
||||
Tcl_IncrRefCount(listPtr);
|
||||
listPtr = Tcl_NewListObj(objc, objv);
|
||||
|
||||
nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
|
||||
if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
|
||||
|| (nsPtr != ns1Ptr)) {
|
||||
Tcl_Panic("yieldto failed to find the proper namespace");
|
||||
}
|
||||
Tcl_IncrRefCount(nsObjPtr);
|
||||
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
|
||||
|
||||
|
||||
/*
|
||||
* Add the callback in the caller's env, then instruct TEBC to yield.
|
||||
*/
|
||||
|
||||
iPtr->execEnvPtr = corPtr->callerEEPtr;
|
||||
TclNRAddCallback(interp, YieldToCallback, corPtr, listPtr, nsObjPtr,
|
||||
NULL);
|
||||
TclNRAddCallback(interp, YieldToCallback, corPtr, listPtr, NULL, NULL);
|
||||
iPtr->execEnvPtr = corPtr->eePtr;
|
||||
|
||||
return TclNRYieldObjCmd(INT2PTR(CORO_ACTIVATE_YIELDM), interp, 1, objv);
|
||||
@@ -8550,20 +8683,7 @@ YieldToCallback(
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
/* CoroutineData *corPtr = data[0];*/
|
||||
Tcl_Obj *listPtr = data[1];
|
||||
ClientData nsPtr = data[2];
|
||||
NRE_callback *cbPtr;
|
||||
|
||||
/*
|
||||
* yieldTo: invoke the command using tailcall tech.
|
||||
*/
|
||||
|
||||
TclNRAddCallback(interp, NRTailcallEval, listPtr, nsPtr, NULL, NULL);
|
||||
cbPtr = TOP_CB(interp);
|
||||
TOP_CB(interp) = cbPtr->nextPtr;
|
||||
|
||||
TclSpliceTailcall(interp, cbPtr);
|
||||
TclSetTailcall(interp, (Tcl_Obj *) data[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -8591,7 +8711,7 @@ RewindCoroutine(
|
||||
corPtr->eePtr->rewind = 1;
|
||||
TclNRAddCallback(interp, RewindCoroutineCallback, state,
|
||||
NULL, NULL, NULL);
|
||||
return NRInterpCoroutine(corPtr, interp, 0, NULL);
|
||||
return TclNRInterpCoroutine(corPtr, interp, 0, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8704,7 +8824,7 @@ NRCoroutineExitCallback(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* NRCoroutineActivateCallback --
|
||||
* TclNRCoroutineActivateCallback --
|
||||
*
|
||||
* This is the workhorse for coroutines: it implements both yield and
|
||||
* resume.
|
||||
@@ -8718,8 +8838,8 @@ NRCoroutineExitCallback(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
NRCoroutineActivateCallback(
|
||||
int
|
||||
TclNRCoroutineActivateCallback(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
@@ -8759,8 +8879,8 @@ NRCoroutineActivateCallback(
|
||||
*/
|
||||
|
||||
if (corPtr->stackLevel != stackLevel) {
|
||||
Tcl_SetResult(interp, "cannot yield: C stack busy",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot yield: C stack busy", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "CANT_YIELD",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -8818,9 +8938,9 @@ NRCoroInjectObjCmd(
|
||||
}
|
||||
|
||||
cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[1]);
|
||||
if ((!cmdPtr) || (cmdPtr->nreProc != NRInterpCoroutine)) {
|
||||
Tcl_AppendResult(interp, "can only inject a command into a coroutine",
|
||||
NULL);
|
||||
if ((!cmdPtr) || (cmdPtr->nreProc != TclNRInterpCoroutine)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"can only inject a command into a coroutine", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COROUTINE",
|
||||
TclGetString(objv[1]), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -8828,8 +8948,8 @@ NRCoroInjectObjCmd(
|
||||
|
||||
corPtr = cmdPtr->objClientData;
|
||||
if (!COR_IS_SUSPENDED(corPtr)) {
|
||||
Tcl_AppendResult(interp,
|
||||
"can only inject a command into a suspended coroutine", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"can only inject a command into a suspended coroutine", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ACTIVE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -8845,9 +8965,9 @@ NRCoroInjectObjCmd(
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
NRInterpCoroutine(
|
||||
TclNRInterpCoroutine(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
@@ -8856,9 +8976,9 @@ NRInterpCoroutine(
|
||||
CoroutineData *corPtr = clientData;
|
||||
|
||||
if (!COR_IS_SUSPENDED(corPtr)) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "coroutine \"", Tcl_GetString(objv[0]),
|
||||
"\" is already running", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"coroutine \"%s\" is already running",
|
||||
Tcl_GetString(objv[0])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "BUSY", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -8894,7 +9014,7 @@ NRInterpCoroutine(
|
||||
break;
|
||||
}
|
||||
|
||||
TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
|
||||
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
|
||||
NULL, NULL, NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -8939,22 +9059,24 @@ TclNRCoroutineObjCmd(
|
||||
&nsPtr, &altNsPtr, &cxtNsPtr, &procName);
|
||||
|
||||
if (nsPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "can't create procedure \"", fullName,
|
||||
"\": unknown namespace", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\": unknown namespace",
|
||||
fullName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (procName == NULL) {
|
||||
Tcl_AppendResult(interp, "can't create procedure \"", fullName,
|
||||
"\": bad procedure name", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\": bad procedure name",
|
||||
fullName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", fullName, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((nsPtr != iPtr->globalNsPtr)
|
||||
&& (procName != NULL) && (procName[0] == ':')) {
|
||||
Tcl_AppendResult(interp, "can't create procedure \"", procName,
|
||||
"\" in non-global namespace with name starting with \":\"",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\" in non-global namespace with"
|
||||
" name starting with \":\"", procName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -8969,12 +9091,12 @@ TclNRCoroutineObjCmd(
|
||||
Tcl_DStringInit(&ds);
|
||||
if (nsPtr != iPtr->globalNsPtr) {
|
||||
Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
|
||||
Tcl_DStringAppend(&ds, "::", 2);
|
||||
TclDStringAppendLiteral(&ds, "::");
|
||||
}
|
||||
Tcl_DStringAppend(&ds, procName, -1);
|
||||
|
||||
cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
|
||||
/*objProc*/ NULL, NRInterpCoroutine, corPtr, DeleteCoroutine);
|
||||
/*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine);
|
||||
Tcl_DStringFree(&ds);
|
||||
|
||||
corPtr->cmdPtr = cmdPtr;
|
||||
@@ -9018,7 +9140,6 @@ TclNRCoroutineObjCmd(
|
||||
corPtr->running.lineLABCPtr = corPtr->lineLABCPtr;
|
||||
corPtr->stackLevel = NULL;
|
||||
corPtr->auxNumLevels = 0;
|
||||
iPtr->numLevels--;
|
||||
|
||||
/*
|
||||
* Create the coro's execEnv, switch to it to push the exit and coro
|
||||
@@ -9037,19 +9158,20 @@ TclNRCoroutineObjCmd(
|
||||
TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
/* insure that the command is looked up in the correct namespace */
|
||||
iPtr->lookupNsPtr = lookupNsPtr;
|
||||
Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
|
||||
iPtr->numLevels--;
|
||||
|
||||
SAVE_CONTEXT(corPtr->running);
|
||||
RESTORE_CONTEXT(corPtr->caller);
|
||||
iPtr->execEnvPtr = corPtr->callerEEPtr;
|
||||
|
||||
/*
|
||||
* Now just resume the coroutine. Take care to insure that the command is
|
||||
* looked up in the correct namespace.
|
||||
* Now just resume the coroutine.
|
||||
*/
|
||||
|
||||
TclNRAddCallback(interp, NRCoroutineActivateCallback, corPtr,
|
||||
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
|
||||
NULL, NULL, NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+117
-71
@@ -127,6 +127,30 @@ static const char B64Digits[65] = {
|
||||
'='
|
||||
};
|
||||
|
||||
/*
|
||||
* How to construct the ensembles.
|
||||
*/
|
||||
|
||||
static const EnsembleImplMap binaryMap[] = {
|
||||
{ "format", BinaryFormatCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
|
||||
{ "scan", BinaryScanCmd, TclCompileBasicMin2ArgCmd, NULL, NULL, 0 },
|
||||
{ "encode", NULL, NULL, NULL, NULL, 0 },
|
||||
{ "decode", NULL, NULL, NULL, NULL, 0 },
|
||||
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
static const EnsembleImplMap encodeMap[] = {
|
||||
{ "hex", BinaryEncodeHex, TclCompileBasic1ArgCmd, NULL, (ClientData)HexDigits, 0 },
|
||||
{ "uuencode", BinaryEncode64, NULL, NULL, (ClientData)UueDigits, 0 },
|
||||
{ "base64", BinaryEncode64, NULL, NULL, (ClientData)B64Digits, 0 },
|
||||
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
static const EnsembleImplMap decodeMap[] = {
|
||||
{ "hex", BinaryDecodeHex, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
|
||||
{ "uuencode", BinaryDecodeUu, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
|
||||
{ "base64", BinaryDecode64, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
|
||||
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
/*
|
||||
* The following object type represents an array of bytes. An array of bytes
|
||||
* is not equivalent to an internationalized string. Conceptually, a string is
|
||||
@@ -303,18 +327,16 @@ Tcl_SetByteArrayObj(
|
||||
TclFreeIntRep(objPtr);
|
||||
Tcl_InvalidateStringRep(objPtr);
|
||||
|
||||
length = (length < 0) ? 0 : length;
|
||||
if (length < 0) {
|
||||
length = 0;
|
||||
}
|
||||
byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
|
||||
byteArrayPtr->used = length;
|
||||
byteArrayPtr->allocated = length;
|
||||
if (length) {
|
||||
if (bytes) {
|
||||
memcpy(byteArrayPtr->bytes, bytes, (size_t) length);
|
||||
} else {
|
||||
memset(byteArrayPtr->bytes, 0, (size_t) length);
|
||||
}
|
||||
}
|
||||
|
||||
if ((bytes != NULL) && (length > 0)) {
|
||||
memcpy(byteArrayPtr->bytes, bytes, (size_t) length);
|
||||
}
|
||||
objPtr->typePtr = &tclByteArrayType;
|
||||
SET_BYTEARRAY(objPtr, byteArrayPtr);
|
||||
}
|
||||
@@ -690,26 +712,6 @@ TclAppendBytesToByteArray(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static const EnsembleImplMap binaryMap[] = {
|
||||
{ "format", BinaryFormatCmd, NULL, NULL, NULL, 0 },
|
||||
{ "scan", BinaryScanCmd, NULL, NULL, NULL, 0 },
|
||||
{ "encode", NULL, NULL, NULL, NULL, 0 },
|
||||
{ "decode", NULL, NULL, NULL, NULL, 0 },
|
||||
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
static const EnsembleImplMap encodeMap[] = {
|
||||
{ "hex", BinaryEncodeHex, NULL, NULL, (ClientData)HexDigits, 0 },
|
||||
{ "uuencode", BinaryEncode64, NULL, NULL, (ClientData)UueDigits, 0 },
|
||||
{ "base64", BinaryEncode64, NULL, NULL, (ClientData)B64Digits, 0 },
|
||||
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
static const EnsembleImplMap decodeMap[] = {
|
||||
{ "hex", BinaryDecodeHex, NULL, NULL, NULL, 0 },
|
||||
{ "uuencode", BinaryDecodeUu, NULL, NULL, NULL, 0 },
|
||||
{ "base64", BinaryDecode64, NULL, NULL, NULL, 0 },
|
||||
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
||||
};
|
||||
|
||||
Tcl_Command
|
||||
TclInitBinaryCmd(
|
||||
Tcl_Interp *interp)
|
||||
@@ -873,9 +875,9 @@ BinaryFormatCmd(
|
||||
if (count == BINARY_ALL) {
|
||||
count = listc;
|
||||
} else if (count > listc) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"number of elements in list does not match count",
|
||||
NULL);
|
||||
-1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -884,9 +886,8 @@ BinaryFormatCmd(
|
||||
|
||||
case 'x':
|
||||
if (count == BINARY_ALL) {
|
||||
Tcl_AppendResult(interp,
|
||||
"cannot use \"*\" in format string with \"x\"",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot use \"*\" in format string with \"x\"", -1));
|
||||
return TCL_ERROR;
|
||||
} else if (count == BINARY_NOCOUNT) {
|
||||
count = 1;
|
||||
@@ -1198,8 +1199,9 @@ BinaryFormatCmd(
|
||||
|
||||
badValue:
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "expected ", errorString,
|
||||
" string but got \"", errorValue, "\" instead", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected %s string but got \"%s\" instead",
|
||||
errorString, errorValue));
|
||||
return TCL_ERROR;
|
||||
|
||||
badCount:
|
||||
@@ -1217,12 +1219,13 @@ BinaryFormatCmd(
|
||||
|
||||
Tcl_UtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
Tcl_AppendResult(interp, "bad field specifier \"", buf, "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad field specifier \"%s\"", buf));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
error:
|
||||
Tcl_AppendResult(interp, errorString, NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1586,12 +1589,13 @@ BinaryScanCmd(
|
||||
|
||||
Tcl_UtfToUniChar(errorString, &ch);
|
||||
buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
|
||||
Tcl_AppendResult(interp, "bad field specifier \"", buf, "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad field specifier \"%s\"", buf));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
error:
|
||||
Tcl_AppendResult(interp, errorString, NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2357,7 +2361,7 @@ BinaryDecodeHex(
|
||||
static const char *const optStrings[] = { "-strict", NULL };
|
||||
|
||||
if (objc < 2 || objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "data");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for (i = 1; i < objc-1; ++i) {
|
||||
@@ -2571,7 +2575,7 @@ BinaryDecodeUu(
|
||||
static const char *const optStrings[] = { "-strict", NULL };
|
||||
|
||||
if (objc < 2 || objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "data");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for (i = 1; i < objc-1; ++i) {
|
||||
@@ -2658,16 +2662,16 @@ BinaryDecode64(
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
Tcl_Obj *resultObj = NULL;
|
||||
unsigned char *data, *datastart, *dataend, c;
|
||||
unsigned char *data, *datastart, *dataend, c = '\0';
|
||||
unsigned char *begin = NULL;
|
||||
unsigned char *cursor = NULL;
|
||||
int strict = 0;
|
||||
int i, index, size, cut = 0, count = 0;
|
||||
enum {OPT_STRICT };
|
||||
enum { OPT_STRICT };
|
||||
static const char *const optStrings[] = { "-strict", NULL };
|
||||
|
||||
if (objc < 2 || objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "data");
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
for (i = 1; i < objc-1; ++i) {
|
||||
@@ -2691,43 +2695,85 @@ BinaryDecode64(
|
||||
while (data < dataend) {
|
||||
unsigned long value = 0;
|
||||
|
||||
for (i=0 ; i<4 ; i++) {
|
||||
/*
|
||||
* Decode the current block. Each base64 block consists of four input
|
||||
* characters A-Z, a-z, 0-9, +, or /. Each character supplies six bits
|
||||
* of output data, so each block's output is 24 bits (three bytes) in
|
||||
* length. The final block can be shorter by one or two bytes, denoted
|
||||
* by the input ending with one or two ='s, respectively.
|
||||
*/
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
/*
|
||||
* Get the next input character. At end of input, pad with at most
|
||||
* two ='s. If more than two ='s would be needed, instead discard
|
||||
* the block read thus far.
|
||||
*/
|
||||
|
||||
if (data < dataend) {
|
||||
c = *data++;
|
||||
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
value = (value << 6) | ((c - 'A') & 0x3f);
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
value = (value << 6) | ((c - 'a' + 26) & 0x3f);
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
value = (value << 6) | ((c - '0' + 52) & 0x3f);
|
||||
} else if (c == '+') {
|
||||
value = (value << 6) | 0x3e;
|
||||
} else if (c == '/') {
|
||||
value = (value << 6) | 0x3f;
|
||||
} else if (c == '=') {
|
||||
value <<= 6;
|
||||
if (cut < 2) {
|
||||
cut++;
|
||||
}
|
||||
} else {
|
||||
if (strict || !isspace(c)) {
|
||||
goto bad64;
|
||||
}
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
} else if (i > 1) {
|
||||
c = '=';
|
||||
} else {
|
||||
cut += 3;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Load the character into the block value. Handle ='s specially
|
||||
* because they're only valid as the last character or two of the
|
||||
* final block of input. Unless strict mode is enabled, skip any
|
||||
* input whitespace characters.
|
||||
*/
|
||||
|
||||
if (cut) {
|
||||
if (c == '=' && i > 1) {
|
||||
value <<= 6;
|
||||
cut++;
|
||||
} else if (!strict && isspace(c)) {
|
||||
i--;
|
||||
} else {
|
||||
goto bad64;
|
||||
}
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
value = (value << 6) | ((c - 'A') & 0x3f);
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
value = (value << 6) | ((c - 'a' + 26) & 0x3f);
|
||||
} else if (c >= '0' && c <= '9') {
|
||||
value = (value << 6) | ((c - '0' + 52) & 0x3f);
|
||||
} else if (c == '+') {
|
||||
value = (value << 6) | 0x3e;
|
||||
} else if (c == '/') {
|
||||
value = (value << 6) | 0x3f;
|
||||
} else if (c == '=') {
|
||||
value <<= 6;
|
||||
cut++;
|
||||
} else if (strict || !isspace(c)) {
|
||||
goto bad64;
|
||||
} else {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
*cursor++ = UCHAR((value >> 16) & 0xff);
|
||||
*cursor++ = UCHAR((value >> 8) & 0xff);
|
||||
*cursor++ = UCHAR(value & 0xff);
|
||||
}
|
||||
if (cut > size) {
|
||||
cut = size;
|
||||
|
||||
/*
|
||||
* Since = is only valid within the final block, if it was encountered
|
||||
* but there are still more input characters, confirm that strict mode
|
||||
* is off and all subsequent characters are whitespace.
|
||||
*/
|
||||
|
||||
if (cut && data < dataend) {
|
||||
if (strict) {
|
||||
goto bad64;
|
||||
}
|
||||
for (; data < dataend; data++) {
|
||||
if (!isspace(*data)) {
|
||||
goto bad64;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Tcl_SetByteArrayLength(resultObj, cursor - begin - cut);
|
||||
Tcl_SetObjResult(interp, resultObj);
|
||||
|
||||
+38
-27
@@ -170,11 +170,15 @@ TclInitDbCkalloc(void)
|
||||
*/
|
||||
|
||||
int
|
||||
TclDumpMemoryInfo(ClientData clientData, int flags)
|
||||
TclDumpMemoryInfo(
|
||||
ClientData clientData,
|
||||
int flags)
|
||||
{
|
||||
char buf[1024];
|
||||
|
||||
if (clientData == NULL) { return 0; }
|
||||
if (clientData == NULL) {
|
||||
return 0;
|
||||
}
|
||||
sprintf(buf,
|
||||
"total mallocs %10d\n"
|
||||
"total frees %10d\n"
|
||||
@@ -815,15 +819,16 @@ MemoryCmd(
|
||||
size_t len;
|
||||
|
||||
if (argc < 2) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" option [args..]\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s option [args..]\"", argv[0]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if ((strcmp(argv[1],"active") == 0) || (strcmp(argv[1],"display") == 0)) {
|
||||
if (strcmp(argv[1], "active") == 0 || strcmp(argv[1], "display") == 0) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" ", argv[1], " file\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s %s file\"",
|
||||
argv[0], argv[1]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
|
||||
@@ -833,7 +838,8 @@ MemoryCmd(
|
||||
result = Tcl_DumpActiveMemory(fileName);
|
||||
Tcl_DStringFree(&buffer);
|
||||
if (result != TCL_OK) {
|
||||
Tcl_AppendResult(interp, "error accessing ", argv[2], NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s",
|
||||
argv[2], Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -857,17 +863,17 @@ MemoryCmd(
|
||||
"maximum bytes allocated", (unsigned long)maximum_bytes_malloced));
|
||||
return TCL_OK;
|
||||
}
|
||||
if (strcmp(argv[1],"init") == 0) {
|
||||
if (strcmp(argv[1], "init") == 0) {
|
||||
if (argc != 3) {
|
||||
goto bad_suboption;
|
||||
}
|
||||
init_malloced_bodies = (strcmp(argv[2],"on") == 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
if (strcmp(argv[1],"objs") == 0) {
|
||||
if (strcmp(argv[1], "objs") == 0) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" objs file\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s objs file\"", argv[0]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
|
||||
@@ -876,7 +882,9 @@ MemoryCmd(
|
||||
}
|
||||
fileP = fopen(fileName, "w");
|
||||
if (fileP == NULL) {
|
||||
Tcl_AppendResult(interp, "cannot open output file", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"cannot open output file: %s",
|
||||
Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TclDbDumpActiveObjects(fileP);
|
||||
@@ -886,8 +894,8 @@ MemoryCmd(
|
||||
}
|
||||
if (strcmp(argv[1],"onexit") == 0) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" onexit file\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s onexit file\"", argv[0]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
|
||||
@@ -901,8 +909,8 @@ MemoryCmd(
|
||||
}
|
||||
if (strcmp(argv[1],"tag") == 0) {
|
||||
if (argc != 3) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" tag string\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s tag string\"", argv[0]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((curTagPtr != NULL) && (curTagPtr->refCount == 0)) {
|
||||
@@ -939,19 +947,20 @@ MemoryCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
Tcl_AppendResult(interp, "bad option \"", argv[1],
|
||||
"\": should be active, break_on_malloc, info, init, objs, onexit, "
|
||||
"tag, trace, trace_on_at_malloc, or validate", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\": should be active, break_on_malloc, info, "
|
||||
"init, objs, onexit, tag, trace, trace_on_at_malloc, or validate",
|
||||
argv[1]));
|
||||
return TCL_ERROR;
|
||||
|
||||
argError:
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" ", argv[1], " count\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s %s count\"", argv[0], argv[1]));
|
||||
return TCL_ERROR;
|
||||
|
||||
bad_suboption:
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" ", argv[1], " on|off\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s %s on|off\"", argv[0], argv[1]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -981,8 +990,8 @@ CheckmemCmd(
|
||||
const char *argv[]) /* String values of arguments. */
|
||||
{
|
||||
if (argc != 2) {
|
||||
Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
|
||||
" fileName\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: should be \"%s fileName\"", argv[0]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
tclMemDumpFileName = dumpFile;
|
||||
@@ -1250,7 +1259,9 @@ Tcl_ValidateAllMemory(
|
||||
}
|
||||
|
||||
int
|
||||
TclDumpMemoryInfo(ClientData clientData, int flags)
|
||||
TclDumpMemoryInfo(
|
||||
ClientData clientData,
|
||||
int flags)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
+6
-6
@@ -878,8 +878,8 @@ ConvertLocalToUTCUsingC(
|
||||
|
||||
if (localErrno != 0
|
||||
|| (fields->seconds == -1 && timeVal.tm_yday == -1)) {
|
||||
Tcl_SetResult(interp, "time value too large/small to represent",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"time value too large/small to represent", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -1018,17 +1018,17 @@ ConvertUTCToLocalUsingC(
|
||||
|
||||
tock = (time_t) fields->seconds;
|
||||
if ((Tcl_WideInt) tock != fields->seconds) {
|
||||
Tcl_AppendResult(interp,
|
||||
"number too large to represent as a Posix time", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"number too large to represent as a Posix time", -1));
|
||||
Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
TzsetIfNecessary();
|
||||
timeVal = ThreadSafeLocalTime(&tock);
|
||||
if (timeVal == NULL) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"localtime failed (clock value may be too "
|
||||
"large/small to represent)", NULL);
|
||||
"large/small to represent)", -1));
|
||||
Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+140
-68
@@ -32,6 +32,9 @@ struct ForeachState {
|
||||
int *argcList; /* Array of value list sizes. */
|
||||
Tcl_Obj ***argvList; /* Array of value lists. */
|
||||
Tcl_Obj **aCopyList; /* Copies of value list arguments. */
|
||||
Tcl_Obj *resultList; /* List of result values from the loop body,
|
||||
* or NULL if we're not collecting them
|
||||
* ([lmap] vs [foreach]). */
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -52,6 +55,8 @@ static int GetStatBuf(Tcl_Interp *interp, Tcl_Obj *pathPtr,
|
||||
static const char * GetTypeFromMode(int mode);
|
||||
static int StoreStatData(Tcl_Interp *interp, Tcl_Obj *varName,
|
||||
Tcl_StatBuf *statPtr);
|
||||
static inline int EachloopCmd(Tcl_Interp *interp, int collect,
|
||||
int objc, Tcl_Obj *const objv[]);
|
||||
static Tcl_NRPostProc CatchObjCmdCallback;
|
||||
static Tcl_NRPostProc ExprCallback;
|
||||
static Tcl_NRPostProc ForSetupCallback;
|
||||
@@ -194,7 +199,8 @@ Tcl_CaseObjCmd(
|
||||
|
||||
if (i == caseObjc-1) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "extra case pattern with no body", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"extra case pattern with no body", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -355,7 +361,8 @@ CatchObjCmdCallback(
|
||||
|
||||
if (NULL == Tcl_ObjSetVar2(interp, optionVarNamePtr, NULL,
|
||||
options, TCL_LEAVE_ERR_MSG)) {
|
||||
Tcl_DecrRefCount(options);
|
||||
/* Do not decrRefCount 'options', it was already done by
|
||||
* Tcl_ObjSetVar2 */
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -409,8 +416,9 @@ Tcl_CdObjCmd(
|
||||
} else {
|
||||
result = Tcl_FSChdir(dir);
|
||||
if (result != TCL_OK) {
|
||||
Tcl_AppendResult(interp, "couldn't change working directory to \"",
|
||||
TclGetString(dir), "\": ", Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't change working directory to \"%s\": %s",
|
||||
TclGetString(dir), Tcl_PosixError(interp)));
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -629,24 +637,27 @@ EncodingDirsObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_Obj *dirListObj;
|
||||
|
||||
if (objc > 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?dirList?");
|
||||
Tcl_WrongNumArgs(interp, 2, objv, "?dirList?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objc -= 1;
|
||||
objv += 1;
|
||||
if (objc == 1) {
|
||||
if (objc == 2) {
|
||||
Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath());
|
||||
return TCL_OK;
|
||||
}
|
||||
if (Tcl_SetEncodingSearchPath(objv[1]) == TCL_ERROR) {
|
||||
Tcl_AppendResult(interp, "expected directory list but got \"",
|
||||
TclGetString(objv[1]), "\"", NULL);
|
||||
|
||||
dirListObj = objv[2];
|
||||
if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected directory list but got \"%s\"",
|
||||
TclGetString(dirListObj)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "ENCODING", "BADPATH",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
Tcl_SetObjResult(interp, dirListObj);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -939,40 +950,40 @@ TclInitFileCmd(
|
||||
*/
|
||||
|
||||
static const EnsembleImplMap initMap[] = {
|
||||
{"atime", FileAttrAccessTimeCmd, NULL, NULL, NULL, 0},
|
||||
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
|
||||
{"channels", TclChannelNamesCmd, NULL, NULL, NULL, 0},
|
||||
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
|
||||
{"delete", TclFileDeleteCmd, NULL, NULL, NULL, 0},
|
||||
{"dirname", PathDirNameCmd, NULL, NULL, NULL, 0},
|
||||
{"executable", FileAttrIsExecutableCmd, NULL, NULL, NULL, 0},
|
||||
{"exists", FileAttrIsExistingCmd, NULL, NULL, NULL, 0},
|
||||
{"extension", PathExtensionCmd, NULL, NULL, NULL, 0},
|
||||
{"isdirectory", FileAttrIsDirectoryCmd, NULL, NULL, NULL, 0},
|
||||
{"isfile", FileAttrIsFileCmd, NULL, NULL, NULL, 0},
|
||||
{"join", PathJoinCmd, NULL, NULL, NULL, 0},
|
||||
{"link", TclFileLinkCmd, NULL, NULL, NULL, 0},
|
||||
{"lstat", FileAttrLinkStatCmd, NULL, NULL, NULL, 0},
|
||||
{"mtime", FileAttrModifyTimeCmd, NULL, NULL, NULL, 0},
|
||||
{"mkdir", TclFileMakeDirsCmd, NULL, NULL, NULL, 0},
|
||||
{"nativename", PathNativeNameCmd, NULL, NULL, NULL, 0},
|
||||
{"normalize", PathNormalizeCmd, NULL, NULL, NULL, 0},
|
||||
{"owned", FileAttrIsOwnedCmd, NULL, NULL, NULL, 0},
|
||||
{"pathtype", PathTypeCmd, NULL, NULL, NULL, 0},
|
||||
{"readable", FileAttrIsReadableCmd, NULL, NULL, NULL, 0},
|
||||
{"readlink", TclFileReadLinkCmd, NULL, NULL, NULL, 0},
|
||||
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
|
||||
{"rootname", PathRootNameCmd, NULL, NULL, NULL, 0},
|
||||
{"separator", FilesystemSeparatorCmd, NULL, NULL, NULL, 0},
|
||||
{"size", FileAttrSizeCmd, NULL, NULL, NULL, 0},
|
||||
{"split", PathSplitCmd, NULL, NULL, NULL, 0},
|
||||
{"stat", FileAttrStatCmd, NULL, NULL, NULL, 0},
|
||||
{"system", PathFilesystemCmd, NULL, NULL, NULL, 0},
|
||||
{"tail", PathTailCmd, NULL, NULL, NULL, 0},
|
||||
{"tempfile", TclFileTemporaryCmd, NULL, NULL, NULL, 0},
|
||||
{"type", FileAttrTypeCmd, NULL, NULL, NULL, 0},
|
||||
{"volumes", FilesystemVolumesCmd, NULL, NULL, NULL, 0},
|
||||
{"writable", FileAttrIsWritableCmd, NULL, NULL, NULL, 0},
|
||||
{"atime", FileAttrAccessTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"attributes", TclFileAttrsCmd, NULL, NULL, NULL, 0},
|
||||
{"channels", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"copy", TclFileCopyCmd, NULL, NULL, NULL, 0},
|
||||
{"delete", TclFileDeleteCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"dirname", PathDirNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"executable", FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"exists", FileAttrIsExistingCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"extension", PathExtensionCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"isdirectory", FileAttrIsDirectoryCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"isfile", FileAttrIsFileCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"join", PathJoinCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
|
||||
{"link", TclFileLinkCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
|
||||
{"lstat", FileAttrLinkStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"mtime", FileAttrModifyTimeCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"mkdir", TclFileMakeDirsCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
|
||||
{"nativename", PathNativeNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"normalize", PathNormalizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"owned", FileAttrIsOwnedCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"pathtype", PathTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readable", FileAttrIsReadableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"readlink", TclFileReadLinkCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"rename", TclFileRenameCmd, NULL, NULL, NULL, 0},
|
||||
{"rootname", PathRootNameCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"separator", FilesystemSeparatorCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"size", FileAttrSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"split", PathSplitCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"stat", FileAttrStatCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"system", PathFilesystemCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"tail", PathTailCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"tempfile", TclFileTemporaryCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
|
||||
{"type", FileAttrTypeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"volumes", FilesystemVolumesCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"writable", FileAttrIsWritableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
return TclMakeEnsemble(interp, "file", initMap);
|
||||
@@ -1043,9 +1054,9 @@ TclMakeFileCommandSafe(
|
||||
Tcl_DString oldBuf, newBuf;
|
||||
|
||||
Tcl_DStringInit(&oldBuf);
|
||||
Tcl_DStringAppend(&oldBuf, "::tcl::file::", -1);
|
||||
TclDStringAppendLiteral(&oldBuf, "::tcl::file::");
|
||||
Tcl_DStringInit(&newBuf);
|
||||
Tcl_DStringAppend(&newBuf, "tcl:file:", -1);
|
||||
TclDStringAppendLiteral(&newBuf, "tcl:file:");
|
||||
for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
|
||||
if (unsafeInfo[i].unsafe) {
|
||||
const char *oldName, *newName;
|
||||
@@ -1163,9 +1174,9 @@ FileAttrAccessTimeCmd(
|
||||
tval.modtime = buf.st_mtime;
|
||||
|
||||
if (Tcl_FSUtime(objv[1], &tval) != 0) {
|
||||
Tcl_AppendResult(interp, "could not set access time for file \"",
|
||||
TclGetString(objv[1]), "\": ", Tcl_PosixError(interp),
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not set access time for file \"%s\": %s",
|
||||
TclGetString(objv[1]), Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1235,9 +1246,9 @@ FileAttrModifyTimeCmd(
|
||||
tval.modtime = newTime;
|
||||
|
||||
if (Tcl_FSUtime(objv[1], &tval) != 0) {
|
||||
Tcl_AppendResult(interp, "could not set modification time for "
|
||||
"file \"", TclGetString(objv[1]), "\": ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not set modification time for file \"%s\": %s",
|
||||
TclGetString(objv[1]), Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1840,7 +1851,7 @@ PathFilesystemCmd(
|
||||
}
|
||||
fsInfo = Tcl_FSFileSystemInfo(objv[1]);
|
||||
if (fsInfo == NULL) {
|
||||
Tcl_SetResult(interp, "unrecognised path", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("unrecognised path", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM",
|
||||
Tcl_GetString(objv[1]), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -1988,8 +1999,9 @@ PathSplitCmd(
|
||||
}
|
||||
res = Tcl_FSSplitPath(objv[1], NULL);
|
||||
if (res == NULL) {
|
||||
Tcl_AppendResult(interp, "could not read \"", TclGetString(objv[1]),
|
||||
"\": no such file or directory", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not read \"%s\": no such file or directory",
|
||||
TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PATHSPLIT", "NONESUCH",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -2090,7 +2102,8 @@ FilesystemSeparatorCmd(
|
||||
Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[1]);
|
||||
|
||||
if (separatorObj == NULL) {
|
||||
Tcl_SetResult(interp, "unrecognised path", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unrecognised path", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM",
|
||||
Tcl_GetString(objv[1]), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -2209,9 +2222,9 @@ GetStatBuf(
|
||||
|
||||
if (status < 0) {
|
||||
if (interp != NULL) {
|
||||
Tcl_AppendResult(interp, "could not read \"",
|
||||
TclGetString(pathPtr), "\": ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not read \"%s\": %s",
|
||||
TclGetString(pathPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2558,7 +2571,7 @@ ForPostNextCallback(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_ForeachObjCmd, TclNRForeachCmd --
|
||||
* Tcl_ForeachObjCmd, TclNRForeachCmd, EachloopCmd --
|
||||
*
|
||||
* This object-based procedure is invoked to process the "foreach" Tcl
|
||||
* command. See the user documentation for details on what it does.
|
||||
@@ -2589,6 +2602,38 @@ TclNRForeachCmd(
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
return EachloopCmd(interp, TCL_EACH_KEEP_NONE, objc, objv);
|
||||
}
|
||||
|
||||
int
|
||||
Tcl_LmapObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
return Tcl_NRCallObjProc(interp, TclNRLmapCmd, dummy, objc, objv);
|
||||
}
|
||||
|
||||
int
|
||||
TclNRLmapCmd(
|
||||
ClientData dummy,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
return EachloopCmd(interp, TCL_EACH_COLLECT, objc, objv);
|
||||
}
|
||||
|
||||
static inline int
|
||||
EachloopCmd(
|
||||
Tcl_Interp *interp, /* Our context for variables and script
|
||||
* evaluation. */
|
||||
int collect, /* Select collecting or accumulating mode
|
||||
* (TCL_EACH_*) */
|
||||
int objc, /* The arguments being passed in... */
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
int numLists = (objc-2) / 2;
|
||||
register struct ForeachState *statePtr;
|
||||
@@ -2633,6 +2678,12 @@ TclNRForeachCmd(
|
||||
statePtr->bodyPtr = objv[objc - 1];
|
||||
statePtr->bodyIdx = objc - 1;
|
||||
|
||||
if (collect == TCL_EACH_COLLECT) {
|
||||
statePtr->resultList = Tcl_NewListObj(0, NULL);
|
||||
} else {
|
||||
statePtr->resultList = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Break up the value lists and variable lists into elements.
|
||||
*/
|
||||
@@ -2646,8 +2697,11 @@ TclNRForeachCmd(
|
||||
TclListObjGetElements(NULL, statePtr->vCopyList[i],
|
||||
&statePtr->varcList[i], &statePtr->varvList[i]);
|
||||
if (statePtr->varcList[i] < 1) {
|
||||
Tcl_AppendResult(interp, "foreach varlist is empty", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FOREACH",
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%s varlist is empty",
|
||||
(statePtr->resultList != NULL ? "lmap" : "foreach")));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION",
|
||||
(statePtr->resultList != NULL ? "LMAP" : "FOREACH"),
|
||||
"NEEDVARS", NULL);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
@@ -2717,14 +2771,21 @@ ForeachLoopStep(
|
||||
switch (result) {
|
||||
case TCL_CONTINUE:
|
||||
result = TCL_OK;
|
||||
break;
|
||||
case TCL_OK:
|
||||
if (statePtr->resultList != NULL) {
|
||||
Tcl_ListObjAppendElement(interp, statePtr->resultList,
|
||||
Tcl_GetObjResult(interp));
|
||||
}
|
||||
break;
|
||||
case TCL_BREAK:
|
||||
result = TCL_OK;
|
||||
goto done;
|
||||
goto finish;
|
||||
case TCL_ERROR:
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (\"foreach\" body line %d)", Tcl_GetErrorLine(interp)));
|
||||
"\n (\"%s\" body line %d)",
|
||||
(statePtr->resultList != NULL ? "lmap" : "foreach"),
|
||||
Tcl_GetErrorLine(interp)));
|
||||
default:
|
||||
goto done;
|
||||
}
|
||||
@@ -2749,7 +2810,14 @@ ForeachLoopStep(
|
||||
* We're done. Tidy up our work space and finish off.
|
||||
*/
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
finish:
|
||||
if (statePtr->resultList == NULL) {
|
||||
Tcl_ResetResult(interp);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, statePtr->resultList);
|
||||
statePtr->resultList = NULL; /* Don't clean it up */
|
||||
}
|
||||
|
||||
done:
|
||||
ForeachCleanup(interp, statePtr);
|
||||
return result;
|
||||
@@ -2782,7 +2850,8 @@ ForeachAssignments(
|
||||
|
||||
if (varValuePtr == NULL) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (setting foreach loop variable \"%s\")",
|
||||
"\n (setting %s loop variable \"%s\")",
|
||||
(statePtr->resultList != NULL ? "lmap" : "foreach"),
|
||||
TclGetString(statePtr->varvList[i][v])));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2811,6 +2880,9 @@ ForeachCleanup(
|
||||
TclDecrRefCount(statePtr->aCopyList[i]);
|
||||
}
|
||||
}
|
||||
if (statePtr->resultList != NULL) {
|
||||
TclDecrRefCount(statePtr->resultList);
|
||||
}
|
||||
TclStackFree(interp, statePtr);
|
||||
}
|
||||
|
||||
|
||||
+186
-148
@@ -27,15 +27,15 @@
|
||||
*/
|
||||
|
||||
typedef struct SortElement {
|
||||
union { /* The value that we sorting by. */
|
||||
union { /* The value that we sorting by. */
|
||||
const char *strValuePtr;
|
||||
long intValue;
|
||||
double doubleValue;
|
||||
Tcl_Obj *objValuePtr;
|
||||
} collationKey;
|
||||
union { /* Object being sorted, or its index. */
|
||||
Tcl_Obj *objPtr;
|
||||
int index;
|
||||
union { /* Object being sorted, or its index. */
|
||||
Tcl_Obj *objPtr;
|
||||
int index;
|
||||
} payload;
|
||||
struct SortElement *nextPtr;/* Next element in the list, or NULL for end
|
||||
* of list. */
|
||||
@@ -161,30 +161,30 @@ static Tcl_Obj * SelectObjFromSublist(Tcl_Obj *firstPtr,
|
||||
*/
|
||||
|
||||
static const EnsembleImplMap defaultInfoMap[] = {
|
||||
{"args", InfoArgsCmd, NULL, NULL, NULL, 0},
|
||||
{"body", InfoBodyCmd, NULL, NULL, NULL, 0},
|
||||
{"cmdcount", InfoCmdCountCmd, NULL, NULL, NULL, 0},
|
||||
{"commands", InfoCommandsCmd, NULL, NULL, NULL, 0},
|
||||
{"complete", InfoCompleteCmd, NULL, NULL, NULL, 0},
|
||||
{"coroutine", TclInfoCoroutineCmd, NULL, NULL, NULL, 0},
|
||||
{"default", InfoDefaultCmd, NULL, NULL, NULL, 0},
|
||||
{"errorstack", InfoErrorStackCmd, NULL, NULL, NULL, 0},
|
||||
{"args", InfoArgsCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"body", InfoBodyCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"cmdcount", InfoCmdCountCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"commands", InfoCommandsCmd, TclCompileInfoCommandsCmd, NULL, NULL, 0},
|
||||
{"complete", InfoCompleteCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"coroutine", TclInfoCoroutineCmd, TclCompileInfoCoroutineCmd, NULL, NULL, 0},
|
||||
{"default", InfoDefaultCmd, TclCompileBasic3ArgCmd, NULL, NULL, 0},
|
||||
{"errorstack", InfoErrorStackCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"exists", TclInfoExistsCmd, TclCompileInfoExistsCmd, NULL, NULL, 0},
|
||||
{"frame", InfoFrameCmd, NULL, NULL, NULL, 0},
|
||||
{"functions", InfoFunctionsCmd, NULL, NULL, NULL, 0},
|
||||
{"globals", TclInfoGlobalsCmd, NULL, NULL, NULL, 0},
|
||||
{"hostname", InfoHostnameCmd, NULL, NULL, NULL, 0},
|
||||
{"level", InfoLevelCmd, NULL, NULL, NULL, 0},
|
||||
{"library", InfoLibraryCmd, NULL, NULL, NULL, 0},
|
||||
{"loaded", InfoLoadedCmd, NULL, NULL, NULL, 0},
|
||||
{"locals", TclInfoLocalsCmd, NULL, NULL, NULL, 0},
|
||||
{"nameofexecutable", InfoNameOfExecutableCmd, NULL, NULL, NULL, 0},
|
||||
{"patchlevel", InfoPatchLevelCmd, NULL, NULL, NULL, 0},
|
||||
{"procs", InfoProcsCmd, NULL, NULL, NULL, 0},
|
||||
{"script", InfoScriptCmd, NULL, NULL, NULL, 0},
|
||||
{"sharedlibextension", InfoSharedlibCmd, NULL, NULL, NULL, 0},
|
||||
{"tclversion", InfoTclVersionCmd, NULL, NULL, NULL, 0},
|
||||
{"vars", TclInfoVarsCmd, NULL, NULL, NULL, 0},
|
||||
{"frame", InfoFrameCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"functions", InfoFunctionsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"globals", TclInfoGlobalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"hostname", InfoHostnameCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"level", InfoLevelCmd, TclCompileInfoLevelCmd, NULL, NULL, 0},
|
||||
{"library", InfoLibraryCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"loaded", InfoLoadedCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"locals", TclInfoLocalsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"nameofexecutable", InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"patchlevel", InfoPatchLevelCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"procs", InfoProcsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"script", InfoScriptCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"sharedlibextension", InfoSharedlibCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"tclversion", InfoTclVersionCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
|
||||
{"vars", TclInfoVarsCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
@@ -229,8 +229,9 @@ TclNRIfObjCmd(
|
||||
Tcl_Obj *boolObj;
|
||||
|
||||
if (objc <= 1) {
|
||||
Tcl_AppendResult(interp, "wrong # args: no expression after \"",
|
||||
TclGetString(objv[0]), "\" argument", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: no expression after \"%s\" argument",
|
||||
TclGetString(objv[0])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -319,8 +320,9 @@ IfConditionCallback(
|
||||
*/
|
||||
|
||||
if (i >= objc) {
|
||||
Tcl_AppendResult(interp, "wrong # args: ",
|
||||
"no expression after \"", clause, "\" argument", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: no expression after \"%s\" argument",
|
||||
clause));
|
||||
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -345,8 +347,9 @@ IfConditionCallback(
|
||||
}
|
||||
}
|
||||
if (i < objc - 1) {
|
||||
Tcl_AppendResult(interp, "wrong # args: ",
|
||||
"extra words after \"else\" clause in \"if\" command", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"wrong # args: extra words after \"else\" clause in \"if\" command",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -361,9 +364,9 @@ IfConditionCallback(
|
||||
return TclNREvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i);
|
||||
|
||||
missingScript:
|
||||
clause = TclGetString(objv[i-1]);
|
||||
Tcl_AppendResult(interp, "wrong # args: no script following \"", clause,
|
||||
"\" argument", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"wrong # args: no script following \"%s\" argument",
|
||||
TclGetString(objv[i-1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -491,7 +494,8 @@ InfoArgsCmd(
|
||||
name = TclGetString(objv[1]);
|
||||
procPtr = TclFindProc(iPtr, name);
|
||||
if (procPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't a procedure", name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -552,7 +556,8 @@ InfoBodyCmd(
|
||||
name = TclGetString(objv[1]);
|
||||
procPtr = TclFindProc(iPtr, name);
|
||||
if (procPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "\"", name, "\" isn't a procedure", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't a procedure", name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -981,7 +986,8 @@ InfoDefaultCmd(
|
||||
|
||||
procPtr = TclFindProc(iPtr, procName);
|
||||
if (procPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "\"", procName, "\" isn't a procedure",NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"\"%s\" isn't a procedure", procName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", procName,
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -1012,8 +1018,9 @@ InfoDefaultCmd(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_AppendResult(interp, "procedure \"", procName,
|
||||
"\" doesn't have an argument \"", argName, "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"procedure \"%s\" doesn't have an argument \"%s\"",
|
||||
procName, argName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARGUMENT", argName, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1055,10 +1062,10 @@ InfoErrorStackCmd(
|
||||
|
||||
target = interp;
|
||||
if (objc == 2) {
|
||||
target = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
|
||||
if (target == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
target = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
|
||||
if (target == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
iPtr = (Interp *) target;
|
||||
@@ -1158,12 +1165,13 @@ InfoFrameCmd(
|
||||
* A coroutine: must fix the level computations AND the cmdFrame chain,
|
||||
* which is interrupted at the base.
|
||||
*/
|
||||
|
||||
CmdFrame *lastPtr = NULL;
|
||||
|
||||
runPtr = iPtr->cmdFramePtr;
|
||||
runPtr = iPtr->cmdFramePtr;
|
||||
|
||||
/* TODO - deal with overflow */
|
||||
topLevel += corPtr->caller.cmdFramePtr->level;
|
||||
topLevel += corPtr->caller.cmdFramePtr->level;
|
||||
while (runPtr) {
|
||||
runPtr->level += corPtr->caller.cmdFramePtr->level;
|
||||
lastPtr = runPtr;
|
||||
@@ -1196,8 +1204,8 @@ InfoFrameCmd(
|
||||
|
||||
if ((level > topLevel) || (level <= - topLevel)) {
|
||||
levelError:
|
||||
Tcl_AppendResult(interp, "bad level \"", TclGetString(objv[1]), "\"",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad level \"%s\"", TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_FRAME",
|
||||
TclGetString(objv[1]), NULL);
|
||||
code = TCL_ERROR;
|
||||
@@ -1401,15 +1409,15 @@ TclInfoFrame(
|
||||
Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr;
|
||||
|
||||
if (namePtr) {
|
||||
Tcl_Obj *procNameObj;
|
||||
Tcl_Obj *procNameObj;
|
||||
|
||||
/*
|
||||
* This is a regular command.
|
||||
*/
|
||||
|
||||
TclNewObj(procNameObj);
|
||||
Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr,
|
||||
procNameObj);
|
||||
TclNewObj(procNameObj);
|
||||
Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr,
|
||||
procNameObj);
|
||||
ADD_PAIR("proc", procNameObj);
|
||||
} else if (procPtr->cmdPtr->clientData) {
|
||||
ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData;
|
||||
@@ -1484,19 +1492,42 @@ InfoFunctionsCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
const char *pattern;
|
||||
Tcl_Obj *script;
|
||||
int code;
|
||||
|
||||
if (objc == 1) {
|
||||
pattern = NULL;
|
||||
} else if (objc == 2) {
|
||||
pattern = TclGetString(objv[1]);
|
||||
} else {
|
||||
if (objc > 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ListMathFuncs(interp, pattern));
|
||||
return TCL_OK;
|
||||
script = Tcl_NewStringObj(
|
||||
" ::apply [::list {{pattern *}} {\n"
|
||||
" ::set cmds {}\n"
|
||||
" ::foreach cmd [::info commands ::tcl::mathfunc::$pattern] {\n"
|
||||
" ::lappend cmds [::namespace tail $cmd]\n"
|
||||
" }\n"
|
||||
" ::foreach cmd [::info commands tcl::mathfunc::$pattern] {\n"
|
||||
" ::set cmd [::namespace tail $cmd]\n"
|
||||
" ::if {$cmd ni $cmds} {\n"
|
||||
" ::lappend cmds $cmd\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" ::return $cmds\n"
|
||||
" } [::namespace current]] ", -1);
|
||||
|
||||
if (objc == 2) {
|
||||
Tcl_Obj *arg = Tcl_NewListObj(1, &(objv[1]));
|
||||
|
||||
Tcl_AppendObjToObj(script, arg);
|
||||
Tcl_DecrRefCount(arg);
|
||||
}
|
||||
|
||||
Tcl_IncrRefCount(script);
|
||||
code = Tcl_EvalObjEx(interp, script, 0);
|
||||
|
||||
Tcl_DecrRefCount(script);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1538,7 +1569,9 @@ InfoHostnameCmd(
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
|
||||
return TCL_OK;
|
||||
}
|
||||
Tcl_SetResult(interp, "unable to determine name of host", TCL_STATIC);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unable to determine name of host", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "HOSTNAME", "UNKNOWN", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1609,8 +1642,8 @@ InfoLevelCmd(
|
||||
return TCL_ERROR;
|
||||
|
||||
levelError:
|
||||
Tcl_AppendResult(interp, "bad level \"", TclGetString(objv[1]), "\"",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad level \"%s\"", TclGetString(objv[1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
|
||||
TclGetString(objv[1]), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -1656,7 +1689,9 @@ InfoLibraryCmd(
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1));
|
||||
return TCL_OK;
|
||||
}
|
||||
Tcl_SetResult(interp, "no library has been specified for Tcl",TCL_STATIC);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"no library has been specified for Tcl", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", "tcl_library",NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2590,9 +2625,10 @@ Tcl_LrepeatObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (elementCount < 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_Format(NULL,
|
||||
"bad count \"%d\": must be integer >= 0", 1, objv+1));
|
||||
Tcl_SetErrorCode(interp, "TCL","OPERATION","LREPEAT","NEGARG", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad count \"%d\": must be integer >= 0", elementCount));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPEAT", "NEGARG",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2608,7 +2644,7 @@ Tcl_LrepeatObjCmd(
|
||||
if (elementCount && objc > LIST_MAX/elementCount) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"max length of a Tcl list (%d elements) exceeded", LIST_MAX));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
totalElems = objc * elementCount;
|
||||
@@ -2723,9 +2759,10 @@ Tcl_LreplaceObjCmd(
|
||||
*/
|
||||
|
||||
if ((first >= listLen) && (listLen > 0)) {
|
||||
Tcl_AppendResult(interp, "list doesn't contain element ",
|
||||
TclGetString(objv[2]), NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL","OPERATION","LREPLACE","BADIDX", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"list doesn't contain element %s", TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (last >= listLen) {
|
||||
@@ -2996,8 +3033,9 @@ Tcl_LsearchObjCmd(
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
if (i > objc-4) {
|
||||
Tcl_AppendResult(interp, "missing starting index", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"missing starting index", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
@@ -3027,10 +3065,10 @@ Tcl_LsearchObjCmd(
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"\"-index\" option must be followed by list index",
|
||||
NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3088,18 +3126,18 @@ Tcl_LsearchObjCmd(
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
Tcl_AppendResult(interp,
|
||||
"-subindices cannot be used without -index option", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
|
||||
"BAD_OPTION_MIX", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"-subindices cannot be used without -index option", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
|
||||
"BAD_OPTION_MIX", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (bisect && (allMatches || negatedMatch)) {
|
||||
Tcl_AppendResult(interp,
|
||||
"-bisect is not compatible with -all or -not", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
|
||||
"BAD_OPTION_MIX", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"-bisect is not compatible with -all or -not", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
|
||||
"BAD_OPTION_MIX", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3531,7 +3569,7 @@ Tcl_LsetObjCmd(
|
||||
|
||||
if (objc < 3) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"listVar ?index? ?index ...? value");
|
||||
"listVar ?index? ?index ...? value");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3664,10 +3702,10 @@ Tcl_LsortObjCmd(
|
||||
break;
|
||||
case LSORT_COMMAND:
|
||||
if (i == objc-2) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"\"-command\" option must be followed "
|
||||
"by comparison command", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
"by comparison command", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
}
|
||||
@@ -3685,29 +3723,30 @@ Tcl_LsortObjCmd(
|
||||
sortInfo.isIncreasing = 1;
|
||||
break;
|
||||
case LSORT_INDEX: {
|
||||
int indexc, dummy;
|
||||
int indexc, dummy;
|
||||
Tcl_Obj **indexv;
|
||||
|
||||
if (i == objc-2) {
|
||||
Tcl_AppendResult(interp, "\"-index\" option must be "
|
||||
"followed by list index", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"\"-index\" option must be followed by list index",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
}
|
||||
if (TclListObjGetElements(interp, objv[i+1], &indexc,
|
||||
&indexv) != TCL_OK) {
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check each of the indices for syntactic correctness. Note that
|
||||
* we do not store the converted values here because we do not
|
||||
* know if this is the only -index option yet and so we can't
|
||||
* allocate any space; that happens after the scan through all the
|
||||
* options is done.
|
||||
*/
|
||||
/*
|
||||
* Check each of the indices for syntactic correctness. Note that
|
||||
* we do not store the converted values here because we do not
|
||||
* know if this is the only -index option yet and so we can't
|
||||
* allocate any space; that happens after the scan through all the
|
||||
* options is done.
|
||||
*/
|
||||
|
||||
for (j=0 ; j<indexc ; j++) {
|
||||
if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
|
||||
@@ -3719,7 +3758,7 @@ Tcl_LsortObjCmd(
|
||||
}
|
||||
}
|
||||
indexPtr = objv[i+1];
|
||||
i++;
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
case LSORT_INTEGER:
|
||||
@@ -3739,9 +3778,10 @@ Tcl_LsortObjCmd(
|
||||
break;
|
||||
case LSORT_STRIDE:
|
||||
if (i == objc-2) {
|
||||
Tcl_AppendResult(interp, "\"-stride\" option must be ",
|
||||
"followed by stride length", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"\"-stride\" option must be "
|
||||
"followed by stride length", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
}
|
||||
@@ -3750,10 +3790,10 @@ Tcl_LsortObjCmd(
|
||||
goto done2;
|
||||
}
|
||||
if (groupSize < 2) {
|
||||
Tcl_AppendResult(interp, "stride length must be at least 2",
|
||||
NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
|
||||
"BADSTRIDE", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"stride length must be at least 2", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
|
||||
"BADSTRIDE", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done2;
|
||||
}
|
||||
@@ -3773,26 +3813,26 @@ Tcl_LsortObjCmd(
|
||||
*/
|
||||
|
||||
if (indexPtr) {
|
||||
Tcl_Obj **indexv;
|
||||
Tcl_Obj **indexv;
|
||||
|
||||
TclListObjGetElements(interp, indexPtr, &sortInfo.indexc, &indexv);
|
||||
switch (sortInfo.indexc) {
|
||||
case 0:
|
||||
sortInfo.indexv = NULL;
|
||||
break;
|
||||
case 1:
|
||||
sortInfo.indexv = &sortInfo.singleIndex;
|
||||
break;
|
||||
default:
|
||||
sortInfo.indexv =
|
||||
TclListObjGetElements(interp, indexPtr, &sortInfo.indexc, &indexv);
|
||||
switch (sortInfo.indexc) {
|
||||
case 0:
|
||||
sortInfo.indexv = NULL;
|
||||
break;
|
||||
case 1:
|
||||
sortInfo.indexv = &sortInfo.singleIndex;
|
||||
break;
|
||||
default:
|
||||
sortInfo.indexv =
|
||||
TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
|
||||
allocatedIndexVector = 1; /* Cannot use indexc field, as it
|
||||
* might be decreased by 1 later. */
|
||||
}
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
|
||||
allocatedIndexVector = 1; /* Cannot use indexc field, as it
|
||||
* might be decreased by 1 later. */
|
||||
}
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
|
||||
&sortInfo.indexv[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listObj = objv[objc-1];
|
||||
@@ -3847,11 +3887,11 @@ Tcl_LsortObjCmd(
|
||||
|
||||
if (group) {
|
||||
if (length % groupSize) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"list size must be a multiple of the stride length",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE",
|
||||
NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE",
|
||||
NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
@@ -3867,11 +3907,11 @@ Tcl_LsortObjCmd(
|
||||
groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1;
|
||||
}
|
||||
if (groupOffset < 0 || groupOffset >= groupSize) {
|
||||
Tcl_AppendResult(interp, "when used with \"-stride\", the "
|
||||
"leading \"-index\" value must be within the group",
|
||||
NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
|
||||
"BADINDEX", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"when used with \"-stride\", the leading \"-index\""
|
||||
" value must be within the group", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
|
||||
"BADINDEX", NULL);
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
@@ -4255,11 +4295,10 @@ SortCompare(
|
||||
|
||||
if (TclGetIntFromObj(infoPtr->interp,
|
||||
Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) {
|
||||
Tcl_ResetResult(infoPtr->interp);
|
||||
Tcl_AppendResult(infoPtr->interp,
|
||||
"-compare command returned non-integer result", NULL);
|
||||
Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
|
||||
"COMPARISONFAILED", NULL);
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_NewStringObj(
|
||||
"-compare command returned non-integer result", -1));
|
||||
Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
|
||||
"COMPARISONFAILED", NULL);
|
||||
infoPtr->resultCode = TCL_ERROR;
|
||||
return 0;
|
||||
}
|
||||
@@ -4470,11 +4509,11 @@ SelectObjFromSublist(
|
||||
return NULL;
|
||||
}
|
||||
if (currentObj == NULL) {
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element %d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
|
||||
"INDEXFAILED", NULL);
|
||||
Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
|
||||
"element %d missing from sublist \"%s\"",
|
||||
index, TclGetString(objPtr)));
|
||||
Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
|
||||
"INDEXFAILED", NULL);
|
||||
infoPtr->resultCode = TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
@@ -4489,6 +4528,5 @@ SelectObjFromSublist(
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 78
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
+93
-62
@@ -34,12 +34,35 @@ static int UniCharIsHexDigit(int character);
|
||||
|
||||
/*
|
||||
* Default set of characters to trim in [string trim] and friends. This is a
|
||||
* UTF-8 literal string containing space, tab, newline, carriage return,
|
||||
* ethiopic wordspace (U+1361), ogham space mark (U+1680), and ideographic
|
||||
* space (U+3000). [TIP #318]
|
||||
* UTF-8 literal string containing all Unicode space characters [TIP #413]
|
||||
*/
|
||||
|
||||
#define DEFAULT_TRIM_SET " \t\n\r\xe1\x8d\xa1\xe1\x9a\x80\xe3\x80\x80"
|
||||
#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) */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -204,8 +227,8 @@ Tcl_RegexpObjCmd(
|
||||
*/
|
||||
|
||||
if (doinline && ((objc - 2) != 0)) {
|
||||
Tcl_AppendResult(interp, "regexp match variables not allowed"
|
||||
" when using -inline", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"regexp match variables not allowed when using -inline", -1));
|
||||
goto optionError;
|
||||
}
|
||||
|
||||
@@ -1839,8 +1862,8 @@ StringMapCmd(
|
||||
strncmp(string, "-nocase", (size_t) length2) == 0) {
|
||||
nocase = 1;
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "bad option \"", string,
|
||||
"\": must be -nocase", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\": must be -nocase", string));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
|
||||
string, NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -2106,8 +2129,8 @@ StringMatchCmd(
|
||||
strncmp(string, "-nocase", (size_t) length) == 0) {
|
||||
nocase = TCL_MATCH_NOCASE;
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "bad option \"", string,
|
||||
"\": must be -nocase", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\": must be -nocase", string));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
|
||||
string, NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -2567,8 +2590,9 @@ StringEqualCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "bad option \"", string2,
|
||||
"\": must be -nocase or -length", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\": must be -nocase or -length",
|
||||
string2));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
|
||||
string2, NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -2716,8 +2740,9 @@ StringCmpCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "bad option \"", string2,
|
||||
"\": must be -nocase or -length", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\": must be -nocase or -length",
|
||||
string2));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
|
||||
string2, NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -3299,28 +3324,28 @@ TclInitStringCmd(
|
||||
Tcl_Interp *interp) /* Current interpreter. */
|
||||
{
|
||||
static const EnsembleImplMap stringImplMap[] = {
|
||||
{"bytelength", StringBytesCmd, NULL, NULL, NULL, 0},
|
||||
{"bytelength", StringBytesCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"compare", StringCmpCmd, TclCompileStringCmpCmd, NULL, NULL, 0},
|
||||
{"equal", StringEqualCmd, TclCompileStringEqualCmd, NULL, NULL, 0},
|
||||
{"first", StringFirstCmd, NULL, NULL, NULL, 0},
|
||||
{"first", StringFirstCmd, TclCompileStringFirstCmd, NULL, NULL, 0},
|
||||
{"index", StringIndexCmd, TclCompileStringIndexCmd, NULL, NULL, 0},
|
||||
{"is", StringIsCmd, NULL, NULL, NULL, 0},
|
||||
{"last", StringLastCmd, NULL, NULL, NULL, 0},
|
||||
{"last", StringLastCmd, TclCompileStringLastCmd, NULL, NULL, 0},
|
||||
{"length", StringLenCmd, TclCompileStringLenCmd, NULL, NULL, 0},
|
||||
{"map", StringMapCmd, NULL, NULL, NULL, 0},
|
||||
{"map", StringMapCmd, TclCompileStringMapCmd, NULL, NULL, 0},
|
||||
{"match", StringMatchCmd, TclCompileStringMatchCmd, NULL, NULL, 0},
|
||||
{"range", StringRangeCmd, NULL, NULL, NULL, 0},
|
||||
{"repeat", StringReptCmd, NULL, NULL, NULL, 0},
|
||||
{"range", StringRangeCmd, TclCompileStringRangeCmd, NULL, NULL, 0},
|
||||
{"repeat", StringReptCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"replace", StringRplcCmd, NULL, NULL, NULL, 0},
|
||||
{"reverse", StringRevCmd, NULL, NULL, NULL, 0},
|
||||
{"tolower", StringLowerCmd, NULL, NULL, NULL, 0},
|
||||
{"toupper", StringUpperCmd, NULL, NULL, NULL, 0},
|
||||
{"totitle", StringTitleCmd, NULL, NULL, NULL, 0},
|
||||
{"trim", StringTrimCmd, NULL, NULL, NULL, 0},
|
||||
{"trimleft", StringTrimLCmd, NULL, NULL, NULL, 0},
|
||||
{"trimright", StringTrimRCmd, NULL, NULL, NULL, 0},
|
||||
{"wordend", StringEndCmd, NULL, NULL, NULL, 0},
|
||||
{"wordstart", StringStartCmd, NULL, NULL, NULL, 0},
|
||||
{"reverse", StringRevCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"tolower", StringLowerCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
|
||||
{"toupper", StringUpperCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
|
||||
{"totitle", StringTitleCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
|
||||
{"trim", StringTrimCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"trimleft", StringTrimLCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"trimright", StringTrimRCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"wordend", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{"wordstart", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
|
||||
@@ -3515,9 +3540,9 @@ TclNRSwitchObjCmd(
|
||||
* Mode already set via -exact, -glob, or -regexp.
|
||||
*/
|
||||
|
||||
Tcl_AppendResult(interp, "bad option \"",
|
||||
TclGetString(objv[i]), "\": ", options[mode],
|
||||
" option already found", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\": %s option already found",
|
||||
TclGetString(objv[i]), options[mode]));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
|
||||
"DOUBLEOPT", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -3534,8 +3559,9 @@ TclNRSwitchObjCmd(
|
||||
case OPT_INDEXV:
|
||||
i++;
|
||||
if (i >= objc-2) {
|
||||
Tcl_AppendResult(interp, "missing variable name argument to ",
|
||||
"-indexvar", " option", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"missing variable name argument to %s option",
|
||||
"-indexvar"));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
|
||||
"NOVAR", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -3546,8 +3572,9 @@ TclNRSwitchObjCmd(
|
||||
case OPT_MATCHV:
|
||||
i++;
|
||||
if (i >= objc-2) {
|
||||
Tcl_AppendResult(interp, "missing variable name argument to ",
|
||||
"-matchvar", " option", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"missing variable name argument to %s option",
|
||||
"-matchvar"));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
|
||||
"NOVAR", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -3565,15 +3592,15 @@ TclNRSwitchObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (indexVarObj != NULL && mode != OPT_REGEXP) {
|
||||
Tcl_AppendResult(interp,
|
||||
"-indexvar option requires -regexp option", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%s option requires -regexp option", "-indexvar"));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
|
||||
"MODERESTRICTION", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (matchVarObj != NULL && mode != OPT_REGEXP) {
|
||||
Tcl_AppendResult(interp,
|
||||
"-matchvar option requires -regexp option", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%s option requires -regexp option", "-matchvar"));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
|
||||
"MODERESTRICTION", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -3622,7 +3649,8 @@ TclNRSwitchObjCmd(
|
||||
|
||||
if (objc % 2) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "extra switch pattern with no body", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"extra switch pattern with no body", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM",
|
||||
NULL);
|
||||
|
||||
@@ -3637,10 +3665,10 @@ TclNRSwitchObjCmd(
|
||||
if (splitObjs) {
|
||||
for (i=0 ; i<objc ; i+=2) {
|
||||
if (TclGetString(objv[i])[0] == '#') {
|
||||
Tcl_AppendResult(interp, ", this may be due to a "
|
||||
"comment incorrectly placed outside of a "
|
||||
"switch body - see the \"switch\" "
|
||||
"documentation", NULL);
|
||||
Tcl_AppendToObj(Tcl_GetObjResult(interp),
|
||||
", this may be due to a comment incorrectly"
|
||||
" placed outside of a switch body - see the"
|
||||
" \"switch\" documentation", -1);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
|
||||
"BADARM", "COMMENT?", NULL);
|
||||
break;
|
||||
@@ -3657,9 +3685,9 @@ TclNRSwitchObjCmd(
|
||||
*/
|
||||
|
||||
if (strcmp(TclGetString(objv[objc-1]), "-") == 0) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "no body specified for pattern \"",
|
||||
TclGetString(objv[objc-2]), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"no body specified for pattern \"%s\"",
|
||||
TclGetString(objv[objc-2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM",
|
||||
"FALLTHROUGH", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -3985,7 +4013,8 @@ Tcl_ThrowObjCmd(
|
||||
if (Tcl_ListObjLength(interp, objv[1], &len) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
} else if (len < 1) {
|
||||
Tcl_AppendResult(interp, "type must be non-empty list", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"type must be non-empty list", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "THROW", "BADEXCEPTION",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -4169,15 +4198,16 @@ TclNRTryObjCmd(
|
||||
switch ((enum Handlers) type) {
|
||||
case TryFinally: /* finally script */
|
||||
if (i < objc-2) {
|
||||
Tcl_AppendResult(interp, "finally clause must be last", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"finally clause must be last", -1));
|
||||
Tcl_DecrRefCount(handlersObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY",
|
||||
"NONTERMINAL", NULL);
|
||||
return TCL_ERROR;
|
||||
} else if (i == objc-1) {
|
||||
Tcl_AppendResult(interp, "wrong # args to finally clause: ",
|
||||
"must be \"", TclGetString(objv[0]),
|
||||
" ... finally script\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"wrong # args to finally clause: must be"
|
||||
" \"... finally script\"", -1));
|
||||
Tcl_DecrRefCount(handlersObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY",
|
||||
"ARGUMENT", NULL);
|
||||
@@ -4188,15 +4218,16 @@ TclNRTryObjCmd(
|
||||
|
||||
case TryOn: /* on code variableList script */
|
||||
if (i > objc-4) {
|
||||
Tcl_AppendResult(interp, "wrong # args to on clause: ",
|
||||
"must be \"", TclGetString(objv[0]),
|
||||
" ... on code variableList script\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"wrong # args to on clause: must be \"... on code"
|
||||
" variableList script\"", -1));
|
||||
Tcl_DecrRefCount(handlersObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "ON",
|
||||
"ARGUMENT", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (TCL_ERROR == TclGetCompletionCodeFromObj(interp, objv[i+1], &code)) {
|
||||
if (TclGetCompletionCodeFromObj(interp, objv[i+1],
|
||||
&code) != TCL_OK) {
|
||||
Tcl_DecrRefCount(handlersObj);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -4205,9 +4236,10 @@ TclNRTryObjCmd(
|
||||
|
||||
case TryTrap: /* trap pattern variableList script */
|
||||
if (i > objc-4) {
|
||||
Tcl_AppendResult(interp, "wrong # args to trap clause: ",
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"wrong # args to trap clause: "
|
||||
"must be \"... trap pattern variableList script\"",
|
||||
NULL);
|
||||
-1));
|
||||
Tcl_DecrRefCount(handlersObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "TRAP",
|
||||
"ARGUMENT", NULL);
|
||||
@@ -4248,9 +4280,8 @@ TclNRTryObjCmd(
|
||||
}
|
||||
}
|
||||
if (bodyShared) {
|
||||
Tcl_AppendResult(interp,
|
||||
"last non-finally clause must not have a body of \"-\"",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"last non-finally clause must not have a body of \"-\"", -1));
|
||||
Tcl_DecrRefCount(handlersObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "BADFALLTHROUGH",
|
||||
NULL);
|
||||
|
||||
+1600
-44
File diff suppressed because it is too large
Load Diff
+414
-160
@@ -133,6 +133,8 @@ const AuxDataType tclJumptableInfoType = {
|
||||
#define OP(name) TclEmitOpcode(INST_##name, envPtr)
|
||||
#define OP1(name,val) TclEmitInstInt1(INST_##name,(val),envPtr)
|
||||
#define OP4(name,val) TclEmitInstInt4(INST_##name,(val),envPtr)
|
||||
#define OP14(name,val1,val2) \
|
||||
TclEmitInstInt1(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
|
||||
#define OP44(name,val1,val2) \
|
||||
TclEmitInstInt4(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
|
||||
#define BODY(token,index) \
|
||||
@@ -249,18 +251,18 @@ TclCompileSetCmd(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileStringCmpCmd --
|
||||
* TclCompileString*Cmd --
|
||||
*
|
||||
* Procedure called to compile the simplest and most common form of the
|
||||
* "string compare" command.
|
||||
* Procedures called to compile various subcommands of the "string"
|
||||
* command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "string compare"
|
||||
* command at runtime.
|
||||
* Instructions are added to envPtr to execute the "string" command at
|
||||
* runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -296,25 +298,6 @@ TclCompileStringCmpCmd(
|
||||
TclEmitOpcode(INST_STR_CMP, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileStringEqualCmd --
|
||||
*
|
||||
* Procedure called to compile the simplest and most common form of the
|
||||
* "string equal" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "string equal" command
|
||||
* at runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileStringEqualCmd(
|
||||
@@ -347,25 +330,70 @@ TclCompileStringEqualCmd(
|
||||
TclEmitOpcode(INST_STR_EQ, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileStringIndexCmd --
|
||||
*
|
||||
* Procedure called to compile the simplest and most common form of the
|
||||
* "string index" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "string index" command
|
||||
* at runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileStringFirstCmd(
|
||||
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. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr;
|
||||
|
||||
/*
|
||||
* We don't support any flags; the bytecode isn't that sophisticated.
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords != 3) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Push the two operands onto the stack and then the test.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP(STR_FIND);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringLastCmd(
|
||||
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. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr;
|
||||
|
||||
/*
|
||||
* We don't support any flags; the bytecode isn't that sophisticated.
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords != 3) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Push the two operands onto the stack and then the test.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
OP(STR_FIND_LAST);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringIndexCmd(
|
||||
@@ -394,25 +422,6 @@ TclCompileStringIndexCmd(
|
||||
TclEmitOpcode(INST_STR_INDEX, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileStringMatchCmd --
|
||||
*
|
||||
* Procedure called to compile the simplest and most common form of the
|
||||
* "string match" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "string match" command
|
||||
* at runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileStringMatchCmd(
|
||||
@@ -494,25 +503,6 @@ TclCompileStringMatchCmd(
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileStringLenCmd --
|
||||
*
|
||||
* Procedure called to compile the simplest and most common form of the
|
||||
* "string length" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "string length"
|
||||
* command at runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileStringLenCmd(
|
||||
@@ -553,6 +543,158 @@ TclCompileStringLenCmd(
|
||||
TclDecrRefCount(objPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringMapCmd(
|
||||
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. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *mapTokenPtr, *stringTokenPtr;
|
||||
Tcl_Obj *mapObj, **objv;
|
||||
char *bytes;
|
||||
int len;
|
||||
|
||||
/*
|
||||
* We only handle the case:
|
||||
*
|
||||
* string map {foo bar} $thing
|
||||
*
|
||||
* That is, a literal two-element list (doesn't need to be brace-quoted,
|
||||
* but does need to be compile-time knowable) and any old argument (the
|
||||
* thing to map).
|
||||
*/
|
||||
|
||||
if (parsePtr->numWords != 3) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
mapTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
stringTokenPtr = TokenAfter(mapTokenPtr);
|
||||
mapObj = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(mapObj);
|
||||
if (!TclWordKnownAtCompileTime(mapTokenPtr, mapObj)) {
|
||||
Tcl_DecrRefCount(mapObj);
|
||||
return TCL_ERROR;
|
||||
} else if (Tcl_ListObjGetElements(NULL, mapObj, &len, &objv) != TCL_OK) {
|
||||
Tcl_DecrRefCount(mapObj);
|
||||
return TCL_ERROR;
|
||||
} else if (len != 2) {
|
||||
Tcl_DecrRefCount(mapObj);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now issue the opcodes. Note that in the case that we know that the
|
||||
* first word is an empty word, we don't issue the map at all. That is the
|
||||
* correct semantics for mapping.
|
||||
*/
|
||||
|
||||
bytes = Tcl_GetStringFromObj(objv[0], &len);
|
||||
if (len == 0) {
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 2);
|
||||
} else {
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
bytes = Tcl_GetStringFromObj(objv[1], &len);
|
||||
PushLiteral(envPtr, bytes, len);
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 2);
|
||||
OP(STR_MAP);
|
||||
}
|
||||
Tcl_DecrRefCount(mapObj);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
int
|
||||
TclCompileStringRangeCmd(
|
||||
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. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr;
|
||||
Tcl_Obj *tmpObj;
|
||||
int idx1, idx2, result;
|
||||
|
||||
if (parsePtr->numWords != 4) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
stringTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
fromTokenPtr = TokenAfter(stringTokenPtr);
|
||||
toTokenPtr = TokenAfter(fromTokenPtr);
|
||||
|
||||
/*
|
||||
* Parse the first index. Will only compile if it is constant and not an
|
||||
* _integer_ less than zero (since we reserve negative indices here for
|
||||
* end-relative indexing).
|
||||
*/
|
||||
|
||||
tmpObj = Tcl_NewObj();
|
||||
result = TCL_ERROR;
|
||||
if (TclWordKnownAtCompileTime(fromTokenPtr, tmpObj)) {
|
||||
if (TclGetIntFromObj(NULL, tmpObj, &idx1) == TCL_OK) {
|
||||
if (idx1 >= 0) {
|
||||
result = TCL_OK;
|
||||
}
|
||||
} else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx1) == TCL_OK) {
|
||||
if (idx1 <= -2) {
|
||||
result = TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
TclDecrRefCount(tmpObj);
|
||||
if (result != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the second index. Will only compile if it is constant and not an
|
||||
* _integer_ less than zero (since we reserve negative indices here for
|
||||
* end-relative indexing).
|
||||
*/
|
||||
|
||||
tmpObj = Tcl_NewObj();
|
||||
result = TCL_ERROR;
|
||||
if (TclWordKnownAtCompileTime(toTokenPtr, tmpObj)) {
|
||||
if (TclGetIntFromObj(NULL, tmpObj, &idx2) == TCL_OK) {
|
||||
if (idx2 >= 0) {
|
||||
result = TCL_OK;
|
||||
}
|
||||
} else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx2) == TCL_OK) {
|
||||
if (idx2 <= -2) {
|
||||
result = TCL_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
TclDecrRefCount(tmpObj);
|
||||
if (result != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
|
||||
/*
|
||||
* Push the operand onto the stack and then the substring operation.
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 1);
|
||||
OP44( STR_RANGE_IMM, idx1, idx2);
|
||||
return TCL_OK;
|
||||
|
||||
/*
|
||||
* Push the operands onto the stack and then the substring operation.
|
||||
*/
|
||||
|
||||
nonConstantIndices:
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 1);
|
||||
CompileWord(envPtr, fromTokenPtr, interp, 2);
|
||||
CompileWord(envPtr, toTokenPtr, interp, 3);
|
||||
OP( STR_RANGE);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -694,14 +836,42 @@ TclSubstCompile(
|
||||
TclEmitPush(literal, envPtr);
|
||||
count++;
|
||||
continue;
|
||||
case TCL_TOKEN_VARIABLE:
|
||||
/*
|
||||
* Check for simple variable access; see if we can only generate
|
||||
* TCL_OK or TCL_ERROR from the substituted variable read; if so,
|
||||
* there is no need to generate elaborate exception-management
|
||||
* code. Note that the first component of TCL_TOKEN_VARIABLE is
|
||||
* always TCL_TOKEN_TEXT...
|
||||
*/
|
||||
|
||||
if (tokenPtr->numComponents > 1) {
|
||||
int i, foundCommand = 0;
|
||||
|
||||
for (i=2 ; i<=tokenPtr->numComponents ; i++) {
|
||||
if (tokenPtr[i].type == TCL_TOKEN_COMMAND) {
|
||||
foundCommand = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (foundCommand) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
envPtr->line = bline;
|
||||
TclCompileVarSubst(interp, tokenPtr, envPtr);
|
||||
bline = envPtr->line;
|
||||
count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
while (count > 255) {
|
||||
TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
|
||||
OP1( CONCAT1, 255);
|
||||
count -= 254;
|
||||
}
|
||||
if (count > 1) {
|
||||
TclEmitInstInt1(INST_CONCAT1, count, envPtr);
|
||||
OP1( CONCAT1, count);
|
||||
count = 1;
|
||||
}
|
||||
|
||||
@@ -722,7 +892,7 @@ TclSubstCompile(
|
||||
|
||||
envPtr->line = bline;
|
||||
catchRange = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
|
||||
TclEmitInstInt4(INST_BEGIN_CATCH4, catchRange, envPtr);
|
||||
OP4( BEGIN_CATCH4, catchRange);
|
||||
ExceptionRangeStarts(envPtr, catchRange);
|
||||
|
||||
switch (tokenPtr->type) {
|
||||
@@ -743,20 +913,20 @@ TclSubstCompile(
|
||||
ExceptionRangeEnds(envPtr, catchRange);
|
||||
|
||||
/* Substitution produced TCL_OK */
|
||||
TclEmitOpcode(INST_END_CATCH, envPtr);
|
||||
OP( END_CATCH);
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &okFixup);
|
||||
|
||||
/* Exceptional return codes processed here */
|
||||
ExceptionRangeTarget(envPtr, catchRange, catchOffset);
|
||||
TclEmitOpcode(INST_PUSH_RETURN_OPTIONS, envPtr);
|
||||
TclEmitOpcode(INST_PUSH_RESULT, envPtr);
|
||||
TclEmitOpcode(INST_PUSH_RETURN_CODE, envPtr);
|
||||
TclEmitOpcode(INST_END_CATCH, envPtr);
|
||||
TclEmitOpcode(INST_RETURN_CODE_BRANCH, envPtr);
|
||||
OP( PUSH_RETURN_OPTIONS);
|
||||
OP( PUSH_RESULT);
|
||||
OP( PUSH_RETURN_CODE);
|
||||
OP( END_CATCH);
|
||||
OP( RETURN_CODE_BRANCH);
|
||||
|
||||
/* ERROR -> reraise it */
|
||||
TclEmitOpcode(INST_RETURN_STK, envPtr);
|
||||
TclEmitOpcode(INST_NOP, envPtr);
|
||||
OP( RETURN_STK);
|
||||
OP( NOP);
|
||||
|
||||
/* RETURN */
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &returnFixup);
|
||||
@@ -775,14 +945,14 @@ TclSubstCompile(
|
||||
Tcl_Panic("TclCompileSubstCmd: bad break jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - breakFixup.codeOffset));
|
||||
}
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
|
||||
breakJump = CurrentOffset(envPtr) - breakOffset;
|
||||
if (breakJump > 127) {
|
||||
TclEmitInstInt4(INST_JUMP4, -breakJump, envPtr);
|
||||
OP4(JUMP4, -breakJump);
|
||||
} else {
|
||||
TclEmitInstInt1(INST_JUMP1, -breakJump, envPtr);
|
||||
OP1(JUMP1, -breakJump);
|
||||
}
|
||||
|
||||
/* CONTINUE destination */
|
||||
@@ -790,8 +960,8 @@ TclSubstCompile(
|
||||
Tcl_Panic("TclCompileSubstCmd: bad continue jump distance %d",
|
||||
(int) (CurrentOffset(envPtr) - continueFixup.codeOffset));
|
||||
}
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
OP( POP);
|
||||
OP( POP);
|
||||
TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &endFixup);
|
||||
|
||||
/* RETURN + other destination */
|
||||
@@ -808,8 +978,8 @@ TclSubstCompile(
|
||||
* Pull the result to top of stack, discard options dict.
|
||||
*/
|
||||
|
||||
TclEmitInstInt4(INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
OP4( REVERSE, 2);
|
||||
OP( POP);
|
||||
|
||||
/*
|
||||
* We've emitted several POP instructions, and the automatic
|
||||
@@ -828,7 +998,7 @@ TclSubstCompile(
|
||||
(int) (CurrentOffset(envPtr) - okFixup.codeOffset));
|
||||
}
|
||||
if (count > 1) {
|
||||
TclEmitInstInt1(INST_CONCAT1, count, envPtr);
|
||||
OP1(CONCAT1, count);
|
||||
count = 1;
|
||||
}
|
||||
|
||||
@@ -840,13 +1010,12 @@ TclSubstCompile(
|
||||
bline = envPtr->line;
|
||||
}
|
||||
|
||||
|
||||
while (count > 255) {
|
||||
TclEmitInstInt1(INST_CONCAT1, 255, envPtr);
|
||||
OP1( CONCAT1, 255);
|
||||
count -= 254;
|
||||
}
|
||||
if (count > 1) {
|
||||
TclEmitInstInt1(INST_CONCAT1, count, envPtr);
|
||||
OP1( CONCAT1, count);
|
||||
}
|
||||
|
||||
Tcl_FreeParse(&parse);
|
||||
@@ -854,6 +1023,7 @@ TclSubstCompile(
|
||||
if (state != NULL) {
|
||||
Tcl_RestoreInterpState(interp, state);
|
||||
TclCompileSyntaxError(interp, envPtr);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
}
|
||||
|
||||
/* Final target of the multi-jump from all BREAKs */
|
||||
@@ -1082,12 +1252,7 @@ TclCompileSwitchCmd(
|
||||
if (TCL_OK != TclFindElement(NULL, bytes, numBytes,
|
||||
&(bodyTokenArray[numWords].start), &bytes,
|
||||
&(bodyTokenArray[numWords].size), &literal) || !literal) {
|
||||
abort:
|
||||
ckfree((char *) bodyToken);
|
||||
ckfree((char *) bodyTokenArray);
|
||||
ckfree((char *) bodyLines);
|
||||
ckfree((char *) bodyContLines);
|
||||
return TCL_ERROR;
|
||||
goto abort;
|
||||
}
|
||||
|
||||
bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
|
||||
@@ -1112,7 +1277,12 @@ TclCompileSwitchCmd(
|
||||
numWords++;
|
||||
}
|
||||
if (numWords % 2) {
|
||||
goto abort;
|
||||
abort:
|
||||
ckfree((char *) bodyToken);
|
||||
ckfree((char *) bodyTokenArray);
|
||||
ckfree((char *) bodyLines);
|
||||
ckfree((char *) bodyContLines);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else if (numWords % 2 || numWords == 0) {
|
||||
/*
|
||||
@@ -1277,14 +1447,14 @@ IssueSwitchChainedTests(
|
||||
|
||||
switch (mode) {
|
||||
case Switch_Exact:
|
||||
TclEmitOpcode(INST_DUP, envPtr);
|
||||
OP( DUP);
|
||||
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
|
||||
TclEmitOpcode(INST_STR_EQ, envPtr);
|
||||
OP( STR_EQ);
|
||||
break;
|
||||
case Switch_Glob:
|
||||
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
|
||||
TclEmitInstInt4(INST_OVER, 1, envPtr);
|
||||
TclEmitInstInt1(INST_STR_MATCH, noCase, envPtr);
|
||||
OP4( OVER, 1);
|
||||
OP1( STR_MATCH, noCase);
|
||||
break;
|
||||
case Switch_Regexp:
|
||||
simple = exact = 0;
|
||||
@@ -1323,7 +1493,7 @@ IssueSwitchChainedTests(
|
||||
TclCompileTokens(interp, bodyToken[i], 1, envPtr);
|
||||
}
|
||||
|
||||
TclEmitInstInt4(INST_OVER, 1, envPtr);
|
||||
OP4( OVER, 1);
|
||||
if (!simple) {
|
||||
/*
|
||||
* Pass correct RE compile flags. We use only Int1
|
||||
@@ -1335,11 +1505,11 @@ IssueSwitchChainedTests(
|
||||
int cflags = TCL_REG_ADVANCED
|
||||
| (noCase ? TCL_REG_NOCASE : 0);
|
||||
|
||||
TclEmitInstInt1(INST_REGEXP, cflags, envPtr);
|
||||
OP1(REGEXP, cflags);
|
||||
} else if (exact && !noCase) {
|
||||
TclEmitOpcode(INST_STR_EQ, envPtr);
|
||||
OP( STR_EQ);
|
||||
} else {
|
||||
TclEmitInstInt1(INST_STR_MATCH, noCase, envPtr);
|
||||
OP1(STR_MATCH, noCase);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1404,7 +1574,7 @@ IssueSwitchChainedTests(
|
||||
* pattern.
|
||||
*/
|
||||
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
OP( POP);
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
envPtr->line = bodyLines[i+1]; /* TIP #280 */
|
||||
envPtr->clNext = bodyContLines[i+1]; /* TIP #280 */
|
||||
@@ -1426,7 +1596,7 @@ IssueSwitchChainedTests(
|
||||
*/
|
||||
|
||||
if (!foundDefault) {
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
OP( POP);
|
||||
PushLiteral(envPtr, "", 0);
|
||||
}
|
||||
|
||||
@@ -1498,6 +1668,7 @@ IssueSwitchJumpTable(
|
||||
int **bodyContLines) /* Array of continuation line info. */
|
||||
{
|
||||
JumptableInfo *jtPtr;
|
||||
int savedStackDepth = envPtr->currStackDepth;
|
||||
int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation;
|
||||
int mustGenerate, foundDefault, jumpToDefault, i;
|
||||
Tcl_DString buffer;
|
||||
@@ -1537,9 +1708,9 @@ IssueSwitchJumpTable(
|
||||
*/
|
||||
|
||||
jumpLocation = CurrentOffset(envPtr);
|
||||
TclEmitInstInt4(INST_JUMP_TABLE, infoIndex, envPtr);
|
||||
OP4( JUMP_TABLE, infoIndex);
|
||||
jumpToDefault = CurrentOffset(envPtr);
|
||||
TclEmitInstInt4(INST_JUMP4, 0, envPtr);
|
||||
OP4( JUMP4, 0);
|
||||
|
||||
for (i=0 ; i<numBodyTokens ; i+=2) {
|
||||
/*
|
||||
@@ -1558,8 +1729,7 @@ IssueSwitchJumpTable(
|
||||
*/
|
||||
|
||||
Tcl_DStringInit(&buffer);
|
||||
Tcl_DStringAppend(&buffer, bodyToken[i]->start,
|
||||
bodyToken[i]->size);
|
||||
TclDStringAppendToken(&buffer, bodyToken[i]);
|
||||
hPtr = Tcl_CreateHashEntry(&jtPtr->hashTable,
|
||||
Tcl_DStringValue(&buffer), &isNew);
|
||||
if (isNew) {
|
||||
@@ -1611,6 +1781,7 @@ IssueSwitchJumpTable(
|
||||
* Compile the body of the arm.
|
||||
*/
|
||||
|
||||
envPtr->currStackDepth = savedStackDepth;
|
||||
envPtr->line = bodyLines[i+1]; /* TIP #280 */
|
||||
envPtr->clNext = bodyContLines[i+1]; /* TIP #280 */
|
||||
TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
|
||||
@@ -1631,7 +1802,7 @@ IssueSwitchJumpTable(
|
||||
* rewriting when we fixed this all up.
|
||||
*/
|
||||
|
||||
TclEmitInstInt4(INST_JUMP4, 0, envPtr);
|
||||
OP4( JUMP4, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1642,6 +1813,7 @@ IssueSwitchJumpTable(
|
||||
*/
|
||||
|
||||
if (!foundDefault) {
|
||||
envPtr->currStackDepth = savedStackDepth;
|
||||
TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
|
||||
envPtr->codeStart+jumpToDefault+1);
|
||||
PushLiteral(envPtr, "", 0);
|
||||
@@ -1662,6 +1834,7 @@ IssueSwitchJumpTable(
|
||||
*/
|
||||
|
||||
TclStackFree(interp, finalFixups);
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1744,6 +1917,52 @@ PrintJumptableInfo(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileTailcallCmd --
|
||||
*
|
||||
* Procedure called to compile the "tailcall" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "tailcall" command at
|
||||
* runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileTailcallCmd(
|
||||
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. */
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *tokenPtr = parsePtr->tokenPtr;
|
||||
int i;
|
||||
|
||||
if (parsePtr->numWords < 2 || parsePtr->numWords > 256
|
||||
|| envPtr->procPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* make room for the nsObjPtr */
|
||||
CompileWord(envPtr, tokenPtr, interp, 0);
|
||||
for (i=1 ; i<parsePtr->numWords ; i++) {
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
}
|
||||
TclEmitInstInt1( INST_TAILCALL, parsePtr->numWords, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1773,6 +1992,7 @@ TclCompileThrowCmd(
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
int numWords = parsePtr->numWords;
|
||||
int savedStackDepth = envPtr->currStackDepth;
|
||||
Tcl_Token *codeToken, *msgToken;
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
@@ -1803,6 +2023,7 @@ TclCompileThrowCmd(
|
||||
CompileWord(envPtr, msgToken, interp, 2);
|
||||
TclCompileSyntaxError(interp, envPtr);
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (len == 0) {
|
||||
@@ -1823,6 +2044,7 @@ TclCompileThrowCmd(
|
||||
PushLiteral(envPtr, string, len);
|
||||
TclDecrRefCount(dictPtr);
|
||||
OP44( RETURN_IMM, 1, 0);
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
} else {
|
||||
/*
|
||||
* When the code token is not known at compilation time, we need to do
|
||||
@@ -1851,6 +2073,7 @@ TclCompileThrowCmd(
|
||||
PUSH( "");
|
||||
OP44( RETURN_IMM, 1, 0);
|
||||
}
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
TclDecrRefCount(objPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -2118,6 +2341,7 @@ IssueTryInstructions(
|
||||
{
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
int range, resultVar, optionsVar;
|
||||
int savedStackDepth = envPtr->currStackDepth;
|
||||
int i, j, len, forwardsNeedFixing = 0;
|
||||
int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource;
|
||||
char buf[TCL_INTEGER_SPACE];
|
||||
@@ -2179,6 +2403,7 @@ IssueTryInstructions(
|
||||
LOAD( optionsVar);
|
||||
PUSH( "-errorcode");
|
||||
OP4( DICT_GET, 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
OP44( LIST_RANGE_IMM, 0, len-1);
|
||||
PUSH( TclGetString(matchClauses[i]));
|
||||
OP( STR_EQ);
|
||||
@@ -2219,6 +2444,7 @@ IssueTryInstructions(
|
||||
forwardsToFix[j] = -1;
|
||||
}
|
||||
}
|
||||
envPtr->currStackDepth = savedStackDepth;
|
||||
BODY( handlerTokens[i], 5+i*4);
|
||||
}
|
||||
|
||||
@@ -2250,6 +2476,7 @@ IssueTryInstructions(
|
||||
}
|
||||
TclStackFree(interp, forwardsToFix);
|
||||
TclStackFree(interp, addrsToFix);
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2286,6 +2513,7 @@ IssueTryFinallyInstructions(
|
||||
range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE);
|
||||
OP4( BEGIN_CATCH4, range);
|
||||
ExceptionRangeStarts(envPtr, range);
|
||||
envPtr->currStackDepth = savedStackDepth;
|
||||
BODY( bodyToken, 1);
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
PUSH( "0");
|
||||
@@ -2330,6 +2558,7 @@ IssueTryFinallyInstructions(
|
||||
LOAD( optionsVar);
|
||||
PUSH( "-errorcode");
|
||||
OP4( DICT_GET, 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
OP44( LIST_RANGE_IMM, 0, len-1);
|
||||
PUSH( TclGetString(matchClauses[i]));
|
||||
OP( STR_EQ);
|
||||
@@ -2402,6 +2631,7 @@ IssueTryFinallyInstructions(
|
||||
}
|
||||
OP4( BEGIN_CATCH4, range);
|
||||
}
|
||||
envPtr->currStackDepth = savedStackDepth;
|
||||
BODY( handlerTokens[i], 5+i*4);
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
OP( PUSH_RETURN_OPTIONS);
|
||||
@@ -2453,7 +2683,6 @@ IssueTryFinallyInstructions(
|
||||
*/
|
||||
|
||||
OP( POP);
|
||||
envPtr->currStackDepth = savedStackDepth;
|
||||
|
||||
/*
|
||||
* Process the finally clause (at last!) Note that we do not wrap this in
|
||||
@@ -2463,11 +2692,13 @@ IssueTryFinallyInstructions(
|
||||
* next command (or some inter-command manipulation).
|
||||
*/
|
||||
|
||||
envPtr->currStackDepth = savedStackDepth;
|
||||
BODY( finallyToken, 3 + 4*numHandlers);
|
||||
OP( POP);
|
||||
LOAD( optionsVar);
|
||||
LOAD( resultVar);
|
||||
OP( RETURN_STK);
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -2508,7 +2739,7 @@ TclCompileUnsetCmd(
|
||||
flags = 1;
|
||||
varTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
leadingWord = Tcl_NewObj();
|
||||
if (TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) {
|
||||
if (numWords > 0 && TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) {
|
||||
int len;
|
||||
const char *bytes = Tcl_GetStringFromObj(leadingWord, &len);
|
||||
|
||||
@@ -2548,20 +2779,18 @@ TclCompileUnsetCmd(
|
||||
*/
|
||||
|
||||
if (!simpleVarName) {
|
||||
TclEmitInstInt1( INST_UNSET_STK, flags, envPtr);
|
||||
OP1( UNSET_STK, flags);
|
||||
} else if (isScalar) {
|
||||
if (localIndex < 0) {
|
||||
TclEmitInstInt1(INST_UNSET_STK, flags, envPtr);
|
||||
OP1( UNSET_STK, flags);
|
||||
} else {
|
||||
TclEmitInstInt1(INST_UNSET_SCALAR, flags, envPtr);
|
||||
TclEmitInt4( localIndex, envPtr);
|
||||
OP14( UNSET_SCALAR, flags, localIndex);
|
||||
}
|
||||
} else {
|
||||
if (localIndex < 0) {
|
||||
TclEmitInstInt1(INST_UNSET_ARRAY_STK, flags, envPtr);
|
||||
OP1( UNSET_ARRAY_STK, flags);
|
||||
} else {
|
||||
TclEmitInstInt1(INST_UNSET_ARRAY, flags, envPtr);
|
||||
TclEmitInt4( localIndex, envPtr);
|
||||
OP14( UNSET_ARRAY, flags, localIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2698,7 +2927,7 @@ TclCompileWhileCmd(
|
||||
CompileBody(envPtr, bodyTokenPtr, interp);
|
||||
ExceptionRangeEnds(envPtr, range);
|
||||
envPtr->currStackDepth = savedStackDepth + 1;
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
OP( POP);
|
||||
|
||||
/*
|
||||
* Compile the test expression then emit the conditional jump that
|
||||
@@ -2750,6 +2979,49 @@ TclCompileWhileCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclCompileYieldCmd --
|
||||
*
|
||||
* Procedure called to compile the "yield" command.
|
||||
*
|
||||
* Results:
|
||||
* Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
|
||||
* evaluation to runtime.
|
||||
*
|
||||
* Side effects:
|
||||
* Instructions are added to envPtr to execute the "yield" command at
|
||||
* runtime.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclCompileYieldCmd(
|
||||
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. */
|
||||
{
|
||||
if (parsePtr->numWords < 1 || parsePtr->numWords > 2) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (parsePtr->numWords == 1) {
|
||||
PushLiteral(envPtr, "", 0);
|
||||
} else {
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Token *valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
CompileWord(envPtr, valueTokenPtr, interp, 1);
|
||||
}
|
||||
OP( YIELD);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -3075,7 +3347,7 @@ CompileAssociativeBinaryOpCmd(
|
||||
* calcuations, including roundoff errors.
|
||||
*/
|
||||
|
||||
TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
|
||||
OP4( REVERSE, words-1);
|
||||
}
|
||||
while (--words > 1) {
|
||||
TclEmitOpcode(instruction, envPtr);
|
||||
@@ -3166,31 +3438,19 @@ CompileComparisonOpCmd(
|
||||
CompileWord(envPtr, tokenPtr, interp, 1);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, 2);
|
||||
if (tmpIndex <= 255) {
|
||||
TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
|
||||
}
|
||||
STORE(tmpIndex);
|
||||
TclEmitOpcode(instruction, envPtr);
|
||||
for (words=3 ; words<parsePtr->numWords ;) {
|
||||
if (tmpIndex <= 255) {
|
||||
TclEmitInstInt1(INST_LOAD_SCALAR1, tmpIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4(INST_LOAD_SCALAR4, tmpIndex, envPtr);
|
||||
}
|
||||
LOAD(tmpIndex);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
CompileWord(envPtr, tokenPtr, interp, words);
|
||||
if (++words < parsePtr->numWords) {
|
||||
if (tmpIndex <= 255) {
|
||||
TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
|
||||
}
|
||||
STORE(tmpIndex);
|
||||
}
|
||||
TclEmitOpcode(instruction, envPtr);
|
||||
}
|
||||
for (; words>3 ; words--) {
|
||||
TclEmitOpcode(INST_BITAND, envPtr);
|
||||
OP( BITAND);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3198,13 +3458,7 @@ CompileComparisonOpCmd(
|
||||
* might be expensive elsewhere.
|
||||
*/
|
||||
|
||||
PushLiteral(envPtr, "", 0);
|
||||
if (tmpIndex <= 255) {
|
||||
TclEmitInstInt1(INST_STORE_SCALAR1, tmpIndex, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4(INST_STORE_SCALAR4, tmpIndex, envPtr);
|
||||
}
|
||||
TclEmitOpcode(INST_POP, envPtr);
|
||||
OP14( UNSET_SCALAR, 0, tmpIndex);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2296,7 +2296,7 @@ CompileExprTree(
|
||||
int length;
|
||||
|
||||
Tcl_DStringInit(&cmdName);
|
||||
Tcl_DStringAppend(&cmdName, "tcl::mathfunc::", -1);
|
||||
TclDStringAppendLiteral(&cmdName, "tcl::mathfunc::");
|
||||
p = TclGetStringFromObj(*funcObjv, &length);
|
||||
funcObjv++;
|
||||
Tcl_DStringAppend(&cmdName, p, length);
|
||||
|
||||
+133
-20
@@ -37,7 +37,7 @@ TCL_DECLARE_MUTEX(tableMutex)
|
||||
int tclTraceCompile = 0;
|
||||
static int traceInitialized = 0;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* A table describing the Tcl bytecode instructions. Entries in this table
|
||||
* must correspond to the instruction opcode definitions in tclCompile.h. The
|
||||
@@ -372,13 +372,13 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
* Stack: ... value => ...
|
||||
* Note that the jump table contains offsets relative to the PC when
|
||||
* it points to this instruction; the code is relocatable. */
|
||||
{"upvar", 5, 0, 1, {OPERAND_LVT4}},
|
||||
{"upvar", 5, -1, 1, {OPERAND_LVT4}},
|
||||
/* finds level and otherName in stack, links to local variable at
|
||||
* index op1. Leaves the level on stack. */
|
||||
{"nsupvar", 5, 0, 1, {OPERAND_LVT4}},
|
||||
{"nsupvar", 5, -1, 1, {OPERAND_LVT4}},
|
||||
/* finds namespace and otherName in stack, links to local variable at
|
||||
* index op1. Leaves the namespace on stack. */
|
||||
{"variable", 5, 0, 1, {OPERAND_LVT4}},
|
||||
{"variable", 5, -1, 1, {OPERAND_LVT4}},
|
||||
/* finds namespace and otherName in stack, links to local variable at
|
||||
* index op1. Leaves the namespace on stack. */
|
||||
{"syntax", 9, -1, 2, {OPERAND_INT4, OPERAND_UINT4}},
|
||||
@@ -434,6 +434,105 @@ InstructionDesc const tclInstructionTable[] = {
|
||||
/* Map variable contents back into a dictionary in the local variable
|
||||
* indicated by the LVT index. Part of [dict with].
|
||||
* Stack: ... path keyList => ... */
|
||||
{"dictExists", 5, INT_MIN, 1, {OPERAND_UINT4}},
|
||||
/* The top op4 words (min 1) are a key path into the dictionary just
|
||||
* below the keys on the stack, and all those values are replaced by a
|
||||
* boolean indicating whether it is possible to read out a value from
|
||||
* that key-path (like [dict exists]).
|
||||
* Stack: ... dict key1 ... keyN => ... boolean */
|
||||
{"verifyDict", 1, -1, 0, {OPERAND_NONE}},
|
||||
/* Verifies that the word on the top of the stack is a dictionary,
|
||||
* popping it if it is and throwing an error if it is not.
|
||||
* Stack: ... value => ... */
|
||||
|
||||
{"strmap", 1, -2, 0, {OPERAND_NONE}},
|
||||
/* Simplified version of [string map] that only applies one change
|
||||
* string, and only case-sensitively.
|
||||
* Stack: ... from to string => ... changedString */
|
||||
{"strfind", 1, -1, 0, {OPERAND_NONE}},
|
||||
/* Find the first index of a needle string in a haystack string,
|
||||
* producing the index (integer) or -1 if nothing found.
|
||||
* Stack: ... needle haystack => ... index */
|
||||
{"strrfind", 1, -1, 0, {OPERAND_NONE}},
|
||||
/* Find the last index of a needle string in a haystack string,
|
||||
* producing the index (integer) or -1 if nothing found.
|
||||
* Stack: ... needle haystack => ... index */
|
||||
{"strrangeImm", 9, 0, 2, {OPERAND_IDX4, OPERAND_IDX4}},
|
||||
/* String Range: push (string range stktop op4 op4) */
|
||||
{"strrange", 1, -2, 0, {OPERAND_NONE}},
|
||||
/* String Range with non-constant arguments.
|
||||
* Stack: ... string idxA idxB => ... substring */
|
||||
|
||||
{"yield", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Makes the current coroutine yield the value at the top of the
|
||||
* stack, and places the response back on top of the stack when it
|
||||
* resumes.
|
||||
* Stack: ... valueToYield => ... resumeValue */
|
||||
{"coroName", 1, +1, 0, {OPERAND_NONE}},
|
||||
/* Push the name of the interpreter's current coroutine as an object
|
||||
* on the stack. */
|
||||
{"tailcall", 2, INT_MIN, 1, {OPERAND_UINT1}},
|
||||
/* Do a tailcall with the opnd items on the stack as the thing to
|
||||
* tailcall to; opnd must be greater than 0 for the semantics to work
|
||||
* right. */
|
||||
|
||||
{"currentNamespace", 1, +1, 0, {OPERAND_NONE}},
|
||||
/* Push the name of the interpreter's current namespace as an object
|
||||
* on the stack. */
|
||||
{"infoLevelNumber", 1, +1, 0, {OPERAND_NONE}},
|
||||
/* Push the stack depth (i.e., [info level]) of the interpreter as an
|
||||
* object on the stack. */
|
||||
{"infoLevelArgs", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Push the argument words to a stack depth (i.e., [info level <n>])
|
||||
* of the interpreter as an object on the stack.
|
||||
* Stack: ... depth => ... argList */
|
||||
{"resolveCmd", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Resolves the command named on the top of the stack to its fully
|
||||
* qualified version, or produces the empty string if no such command
|
||||
* exists. Never generates errors.
|
||||
* Stack: ... cmdName => ... fullCmdName */
|
||||
{"tclooSelf", 1, +1, 0, {OPERAND_NONE}},
|
||||
/* Push the identity of the current TclOO object (i.e., the name of
|
||||
* its current public access command) on the stack. */
|
||||
{"tclooClass", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Push the class of the TclOO object named at the top of the stack
|
||||
* onto the stack.
|
||||
* Stack: ... object => ... class */
|
||||
{"tclooNamespace", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Push the namespace of the TclOO object named at the top of the
|
||||
* stack onto the stack.
|
||||
* Stack: ... object => ... namespace */
|
||||
{"tclooIsObject", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Push whether the value named at the top of the stack is a TclOO
|
||||
* object (i.e., a boolean). Can corrupt the interpreter result
|
||||
* despite not throwing, so not safe for use in a post-exception
|
||||
* context.
|
||||
* Stack: ... value => ... boolean */
|
||||
|
||||
{"arrayExistsStk", 1, 0, 0, {OPERAND_NONE}},
|
||||
/* Looks up the element on the top of the stack and tests whether it
|
||||
* is an array. Pushes a boolean describing whether this is the
|
||||
* case. Also runs the whole-array trace on the named variable, so can
|
||||
* throw anything.
|
||||
* Stack: ... varName => ... boolean */
|
||||
{"arrayExistsImm", 5, +1, 1, {OPERAND_UINT4}},
|
||||
/* Looks up the variable indexed by opnd and tests whether it is an
|
||||
* array. Pushes a boolean describing whether this is the case. Also
|
||||
* runs the whole-array trace on the named variable, so can throw
|
||||
* anything.
|
||||
* Stack: ... => ... boolean */
|
||||
{"arrayMakeStk", 1, -1, 0, {OPERAND_NONE}},
|
||||
/* Forces the element on the top of the stack to be the name of an
|
||||
* array.
|
||||
* Stack: ... varName => ... */
|
||||
{"arrayMakeImm", 5, 0, 1, {OPERAND_UINT4}},
|
||||
/* Forces the variable indexed by opnd to be an array. Does not touch
|
||||
* the stack. */
|
||||
|
||||
{"invokeReplace", 6, INT_MIN, 2, {OPERAND_UINT4,OPERAND_UINT1}},
|
||||
/* Invoke command named objv[0], replacing the first two words with
|
||||
* the word at the top of the stack;
|
||||
* <objc,objv> = <op4,top op4 after popping 1> */
|
||||
|
||||
{NULL, 0, 0, 0, {OPERAND_NONE}}
|
||||
};
|
||||
@@ -1661,8 +1760,8 @@ TclCompileScript(
|
||||
* have side effects that rely on the unmodified string.
|
||||
*/
|
||||
|
||||
Tcl_DStringSetLength(&ds, 0);
|
||||
Tcl_DStringAppend(&ds, tokenPtr[1].start,tokenPtr[1].size);
|
||||
TclDStringClear(&ds);
|
||||
TclDStringAppendToken(&ds, &tokenPtr[1]);
|
||||
|
||||
cmdPtr = (Command *) Tcl_FindCommand(interp,
|
||||
Tcl_DStringValue(&ds),
|
||||
@@ -1673,10 +1772,13 @@ TclCompileScript(
|
||||
&& !(cmdPtr->nsPtr->flags&NS_SUPPRESS_COMPILATION)
|
||||
&& !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)
|
||||
&& !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
|
||||
int savedNumCmds = envPtr->numCommands;
|
||||
int code, savedNumCmds = envPtr->numCommands;
|
||||
unsigned savedCodeNext =
|
||||
envPtr->codeNext - envPtr->codeStart;
|
||||
int update = 0, code;
|
||||
int update = 0;
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
int startStackDepth = envPtr->currStackDepth;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mark the start of the command; the proper bytecode
|
||||
@@ -1720,6 +1822,25 @@ TclCompileScript(
|
||||
envPtr);
|
||||
|
||||
if (code == TCL_OK) {
|
||||
/*
|
||||
* Confirm that the command compiler generated a
|
||||
* single value on the stack as its result. This
|
||||
* is only done in debugging mode, as it *should*
|
||||
* be correct and normal users have no reasonable
|
||||
* way to fix it anyway.
|
||||
*/
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
int diff = envPtr->currStackDepth-startStackDepth;
|
||||
|
||||
if (diff != 1 && (diff != 0 ||
|
||||
*(envPtr->codeNext-1) != INST_DONE)) {
|
||||
Tcl_Panic("bad stack adjustment when compiling"
|
||||
" %.*s (was %d instead of 1)",
|
||||
parsePtr->tokenPtr->size,
|
||||
parsePtr->tokenPtr->start, diff);
|
||||
}
|
||||
#endif
|
||||
if (update) {
|
||||
/*
|
||||
* Fix the bytecode length.
|
||||
@@ -2044,7 +2165,7 @@ TclCompileTokens(
|
||||
for ( ; count > 0; count--, tokenPtr++) {
|
||||
switch (tokenPtr->type) {
|
||||
case TCL_TOKEN_TEXT:
|
||||
Tcl_DStringAppend(&textBuffer, tokenPtr->start, tokenPtr->size);
|
||||
TclDStringAppendToken(&textBuffer, tokenPtr);
|
||||
TclAdvanceLines(&envPtr->line, tokenPtr->start,
|
||||
tokenPtr->start + tokenPtr->size);
|
||||
break;
|
||||
@@ -2091,9 +2212,7 @@ TclCompileTokens(
|
||||
*/
|
||||
|
||||
if (Tcl_DStringLength(&textBuffer) > 0) {
|
||||
int literal = TclRegisterNewLiteral(envPtr,
|
||||
Tcl_DStringValue(&textBuffer),
|
||||
Tcl_DStringLength(&textBuffer));
|
||||
int literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
|
||||
|
||||
TclEmitPush(literal, envPtr);
|
||||
numObjsToConcat++;
|
||||
@@ -2120,9 +2239,7 @@ TclCompileTokens(
|
||||
if (Tcl_DStringLength(&textBuffer) > 0) {
|
||||
int literal;
|
||||
|
||||
literal = TclRegisterNewLiteral(envPtr,
|
||||
Tcl_DStringValue(&textBuffer),
|
||||
Tcl_DStringLength(&textBuffer));
|
||||
literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
|
||||
TclEmitPush(literal, envPtr);
|
||||
numObjsToConcat++;
|
||||
Tcl_DStringFree(&textBuffer);
|
||||
@@ -2145,13 +2262,10 @@ TclCompileTokens(
|
||||
*/
|
||||
|
||||
if (Tcl_DStringLength(&textBuffer) > 0) {
|
||||
int literal;
|
||||
int literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
|
||||
|
||||
literal = TclRegisterNewLiteral(envPtr, Tcl_DStringValue(&textBuffer),
|
||||
Tcl_DStringLength(&textBuffer));
|
||||
TclEmitPush(literal, envPtr);
|
||||
numObjsToConcat++;
|
||||
|
||||
if (numCL) {
|
||||
TclContinuationsEnter(envPtr->literalArrayPtr[literal].objPtr,
|
||||
numCL, clPosition);
|
||||
@@ -4627,6 +4741,5 @@ RecordByteCodeStats(
|
||||
* c-basic-offset: 4
|
||||
* fill-column: 78
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*/
|
||||
|
||||
+45
-4
@@ -676,13 +676,45 @@ typedef struct ByteCode {
|
||||
#define INST_UNSET_ARRAY_STK 136
|
||||
#define INST_UNSET_STK 137
|
||||
|
||||
/* For [dict with] compilation */
|
||||
/* For [dict with], [dict exists], [dict create] and [dict merge] */
|
||||
#define INST_DICT_EXPAND 138
|
||||
#define INST_DICT_RECOMBINE_STK 139
|
||||
#define INST_DICT_RECOMBINE_IMM 140
|
||||
#define INST_DICT_EXISTS 141
|
||||
#define INST_DICT_VERIFY 142
|
||||
|
||||
/* For [string map] and [regsub] compilation */
|
||||
#define INST_STR_MAP 143
|
||||
#define INST_STR_FIND 144
|
||||
#define INST_STR_FIND_LAST 145
|
||||
#define INST_STR_RANGE_IMM 146
|
||||
#define INST_STR_RANGE 147
|
||||
|
||||
/* For operations to do with coroutines and other NRE-manipulators */
|
||||
#define INST_YIELD 148
|
||||
#define INST_COROUTINE_NAME 149
|
||||
#define INST_TAILCALL 150
|
||||
|
||||
/* For compilation of basic information operations */
|
||||
#define INST_NS_CURRENT 151
|
||||
#define INST_INFO_LEVEL_NUM 152
|
||||
#define INST_INFO_LEVEL_ARGS 153
|
||||
#define INST_RESOLVE_COMMAND 154
|
||||
#define INST_TCLOO_SELF 155
|
||||
#define INST_TCLOO_CLASS 156
|
||||
#define INST_TCLOO_NS 157
|
||||
#define INST_TCLOO_IS_OBJECT 158
|
||||
|
||||
/* For compilation of [array] subcommands */
|
||||
#define INST_ARRAY_EXISTS_STK 159
|
||||
#define INST_ARRAY_EXISTS_IMM 160
|
||||
#define INST_ARRAY_MAKE_STK 161
|
||||
#define INST_ARRAY_MAKE_IMM 162
|
||||
|
||||
#define INST_INVOKE_REPLACE 163
|
||||
|
||||
/* The last opcode */
|
||||
#define LAST_INST_OPCODE 140
|
||||
#define LAST_INST_OPCODE 163
|
||||
|
||||
/*
|
||||
* Table describing the Tcl bytecode instructions: their name (for displaying
|
||||
@@ -866,8 +898,7 @@ typedef struct {
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
MODULE_SCOPE Tcl_NRPostProc NRCommand;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc NRInterpCoroutine;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRInterpCoroutine;
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
@@ -1364,6 +1395,16 @@ MODULE_SCOPE Tcl_Obj *TclNewInstNameObj(unsigned char inst);
|
||||
#define EnvHasLVT(envPtr) \
|
||||
(envPtr->procPtr || envPtr->iPtr->varFramePtr->localCachePtr)
|
||||
|
||||
/*
|
||||
* Macros for making it easier to deal with tokens and DStrings.
|
||||
*/
|
||||
|
||||
#define TclDStringAppendToken(dsPtr, tokenPtr) \
|
||||
Tcl_DStringAppend((dsPtr), (tokenPtr)->start, (tokenPtr)->size)
|
||||
#define TclRegisterDStringLiteral(envPtr, dsPtr) \
|
||||
TclRegisterLiteral(envPtr, Tcl_DStringValue(dsPtr), \
|
||||
Tcl_DStringLength(dsPtr), /*flags*/ 0)
|
||||
|
||||
/*
|
||||
* DTrace probe macros (NOPs if DTrace support is not enabled).
|
||||
*/
|
||||
|
||||
+6
-6
@@ -155,7 +155,7 @@ Tcl_RegisterConfig(
|
||||
*/
|
||||
|
||||
Tcl_DStringInit(&cmdName);
|
||||
Tcl_DStringAppend(&cmdName, "::", -1);
|
||||
TclDStringAppendLiteral(&cmdName, "::");
|
||||
Tcl_DStringAppend(&cmdName, pkgName, -1);
|
||||
|
||||
/*
|
||||
@@ -173,7 +173,7 @@ Tcl_RegisterConfig(
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_DStringAppend(&cmdName, "::pkgconfig", -1);
|
||||
TclDStringAppendLiteral(&cmdName, "::pkgconfig");
|
||||
|
||||
if (Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdName),
|
||||
QueryConfigObjCmd, cdPtr, QueryConfigDelete) == NULL) {
|
||||
@@ -236,7 +236,7 @@ QueryConfigObjCmd(
|
||||
* present.
|
||||
*/
|
||||
|
||||
Tcl_SetResult(interp, "package not known", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("package not known", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "FATAL", "PKGCFG_BASE",
|
||||
Tcl_GetString(pkgName), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -251,7 +251,7 @@ QueryConfigObjCmd(
|
||||
|
||||
if (Tcl_DictObjGet(interp, pkgDict, objv[2], &val) != TCL_OK
|
||||
|| val == NULL) {
|
||||
Tcl_SetResult(interp, "key not known", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("key not known", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CONFIG",
|
||||
Tcl_GetString(objv[2]), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -270,8 +270,8 @@ QueryConfigObjCmd(
|
||||
listPtr = Tcl_NewListObj(n, NULL);
|
||||
|
||||
if (!listPtr) {
|
||||
Tcl_SetResult(interp, "insufficient memory to create list",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"insufficient memory to create list", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+9
-2
@@ -1807,8 +1807,12 @@ EXTERN void * Tcl_FindSymbol(Tcl_Interp *interp,
|
||||
/* 629 */
|
||||
EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp,
|
||||
Tcl_LoadHandle handlePtr);
|
||||
/* 630 */
|
||||
EXTERN void Tcl_ZlibStreamSetCompressionDictionary(
|
||||
Tcl_ZlibStream zhandle,
|
||||
Tcl_Obj *compressionDictionaryObj);
|
||||
|
||||
typedef struct TclStubHooks {
|
||||
typedef struct {
|
||||
const struct TclPlatStubs *tclPlatStubs;
|
||||
const struct TclIntStubs *tclIntStubs;
|
||||
const struct TclIntPlatStubs *tclIntPlatStubs;
|
||||
@@ -1816,7 +1820,7 @@ typedef struct TclStubHooks {
|
||||
|
||||
typedef struct TclStubs {
|
||||
int magic;
|
||||
const struct TclStubHooks *hooks;
|
||||
const TclStubHooks *hooks;
|
||||
|
||||
int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */
|
||||
CONST84_RETURN char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */
|
||||
@@ -2472,6 +2476,7 @@ typedef struct TclStubs {
|
||||
int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */
|
||||
void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */
|
||||
int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */
|
||||
void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */
|
||||
} TclStubs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -3764,6 +3769,8 @@ extern const TclStubs *tclStubsPtr;
|
||||
(tclStubsPtr->tcl_FindSymbol) /* 628 */
|
||||
#define Tcl_FSUnloadFile \
|
||||
(tclStubsPtr->tcl_FSUnloadFile) /* 629 */
|
||||
#define Tcl_ZlibStreamSetCompressionDictionary \
|
||||
(tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */
|
||||
|
||||
#endif /* defined(USE_TCL_STUBS) */
|
||||
|
||||
|
||||
+273
-31
@@ -76,9 +76,12 @@ static int FinalizeDictWith(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
static int DictForNRCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static int DictMapNRCmd(ClientData dummy, Tcl_Interp *interp,
|
||||
int objc, Tcl_Obj *const *objv);
|
||||
static int DictForLoopCallback(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
|
||||
static int DictMapLoopCallback(ClientData data[],
|
||||
Tcl_Interp *interp, int result);
|
||||
|
||||
/*
|
||||
* Table of dict subcommand names and implementations.
|
||||
@@ -86,23 +89,24 @@ static int DictForLoopCallback(ClientData data[],
|
||||
|
||||
static const EnsembleImplMap implementationMap[] = {
|
||||
{"append", DictAppendCmd, TclCompileDictAppendCmd, NULL, NULL, 0 },
|
||||
{"create", DictCreateCmd, NULL, NULL, NULL, 0 },
|
||||
{"exists", DictExistsCmd, NULL, NULL, NULL, 0 },
|
||||
{"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
|
||||
{"create", DictCreateCmd, TclCompileDictCreateCmd, NULL, NULL, 0 },
|
||||
{"exists", DictExistsCmd, TclCompileDictExistsCmd, NULL, NULL, 0 },
|
||||
{"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
|
||||
{"for", NULL, TclCompileDictForCmd, DictForNRCmd, NULL, 0 },
|
||||
{"get", DictGetCmd, TclCompileDictGetCmd, NULL, NULL, 0 },
|
||||
{"incr", DictIncrCmd, TclCompileDictIncrCmd, NULL, NULL, 0 },
|
||||
{"info", DictInfoCmd, NULL, NULL, NULL, 0 },
|
||||
{"keys", DictKeysCmd, NULL, NULL, NULL, 0 },
|
||||
{"info", DictInfoCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
|
||||
{"keys", DictKeysCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
|
||||
{"lappend", DictLappendCmd, TclCompileDictLappendCmd, NULL, NULL, 0 },
|
||||
{"merge", DictMergeCmd, NULL, NULL, NULL, 0 },
|
||||
{"remove", DictRemoveCmd, NULL, NULL, NULL, 0 },
|
||||
{"map", NULL, TclCompileDictMapCmd, DictMapNRCmd, NULL, 0 },
|
||||
{"merge", DictMergeCmd, TclCompileDictMergeCmd, NULL, NULL, 0 },
|
||||
{"remove", DictRemoveCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
|
||||
{"replace", DictReplaceCmd, NULL, NULL, NULL, 0 },
|
||||
{"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 },
|
||||
{"size", DictSizeCmd, NULL, NULL, NULL, 0 },
|
||||
{"unset", DictUnsetCmd, NULL, NULL, NULL, 0 },
|
||||
{"size", DictSizeCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
|
||||
{"unset", DictUnsetCmd, TclCompileDictUnsetCmd, NULL, NULL, 0 },
|
||||
{"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 },
|
||||
{"values", DictValuesCmd, NULL, NULL, NULL, 0 },
|
||||
{"values", DictValuesCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
|
||||
{"with", DictWithCmd, TclCompileDictWithCmd, NULL, NULL, 0 },
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
@@ -181,6 +185,23 @@ static const Tcl_HashKeyType chainHashType = {
|
||||
AllocChainEntry,
|
||||
TclFreeObjEntry
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure used in implementation of 'dict map' to hold the state that gets
|
||||
* passed between parts of the implementation.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Tcl_Obj *keyVarObj; /* The name of the variable that will have
|
||||
* keys assigned to it. */
|
||||
Tcl_Obj *valueVarObj; /* The name of the variable that will have
|
||||
* values assigned to it. */
|
||||
Tcl_DictSearch search; /* The dictionary search structure. */
|
||||
Tcl_Obj *scriptObj; /* The script to evaluate each time through
|
||||
* the loop. */
|
||||
Tcl_Obj *accumulatorObj; /* The dictionary used to accumulate the
|
||||
* results. */
|
||||
} DictMapStorage;
|
||||
|
||||
/***** START OF FUNCTIONS IMPLEMENTING DICT CORE API *****/
|
||||
|
||||
@@ -700,7 +721,8 @@ SetDictFromAny(
|
||||
|
||||
missingValue:
|
||||
if (interp != NULL) {
|
||||
Tcl_SetResult(interp, "missing value to go with key", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"missing value to go with key", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL);
|
||||
}
|
||||
result = TCL_ERROR;
|
||||
@@ -779,9 +801,9 @@ TclTraceDictPath(
|
||||
}
|
||||
if ((flags & DICT_PATH_CREATE) != DICT_PATH_CREATE) {
|
||||
if (interp != NULL) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "key \"", TclGetString(keyv[i]),
|
||||
"\" not known in dictionary", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"key \"%s\" not known in dictionary",
|
||||
TclGetString(keyv[i])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
|
||||
TclGetString(keyv[i]), NULL);
|
||||
}
|
||||
@@ -953,6 +975,7 @@ Tcl_DictObjGet(
|
||||
if (dictPtr->typePtr != &tclDictType) {
|
||||
int result = SetDictFromAny(interp, dictPtr);
|
||||
if (result != TCL_OK) {
|
||||
*valuePtrPtr = NULL;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1571,9 +1594,9 @@ DictGetCmd(
|
||||
return result;
|
||||
}
|
||||
if (valuePtr == NULL) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "key \"", TclGetString(objv[objc-1]),
|
||||
"\" not known in dictionary", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"key \"%s\" not known in dictionary",
|
||||
TclGetString(objv[objc-1])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
|
||||
TclGetString(objv[objc-1]), NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -2027,6 +2050,7 @@ DictInfoCmd(
|
||||
{
|
||||
Tcl_Obj *dictPtr;
|
||||
Dict *dict;
|
||||
char *statsStr;
|
||||
|
||||
if (objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "dictionary");
|
||||
@@ -2042,7 +2066,9 @@ DictInfoCmd(
|
||||
}
|
||||
dict = dictPtr->internalRep.otherValuePtr;
|
||||
|
||||
Tcl_SetResult(interp, Tcl_HashStats(&dict->table), TCL_DYNAMIC);
|
||||
statsStr = Tcl_HashStats(&dict->table);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1));
|
||||
ckfree(statsStr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2331,7 +2357,7 @@ DictAppendCmd(
|
||||
*
|
||||
* DictForNRCmd --
|
||||
*
|
||||
* This function implements the "dict for" Tcl command. See the user
|
||||
* These functions implement the "dict for" Tcl command. See the user
|
||||
* documentation for details on what it does, and TIP#111 for the formal
|
||||
* specification.
|
||||
*
|
||||
@@ -2371,8 +2397,8 @@ DictForNRCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (varc != 2) {
|
||||
Tcl_SetResult(interp, "must have exactly two variable names",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"must have exactly two variable names", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
searchPtr = TclStackAlloc(interp, sizeof(Tcl_DictSearch));
|
||||
@@ -2484,13 +2510,15 @@ DictForLoopCallback(
|
||||
*/
|
||||
|
||||
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);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
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) {
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
@@ -2516,6 +2544,217 @@ DictForLoopCallback(
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* DictMapNRCmd --
|
||||
*
|
||||
* These functions implement the "dict map" Tcl command. See the user
|
||||
* documentation for details on what it does, and TIP#405 for the formal
|
||||
* specification.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
DictMapNRCmd(
|
||||
ClientData dummy,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const *objv)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Tcl_Obj **varv, *keyObj, *valueObj;
|
||||
DictMapStorage *storagePtr;
|
||||
int varc, done;
|
||||
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv,
|
||||
"{keyVar valueVar} dictionary script");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse arguments.
|
||||
*/
|
||||
|
||||
if (TclListObjGetElements(interp, objv[1], &varc, &varv) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (varc != 2) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"must have exactly two variable names", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
storagePtr = TclStackAlloc(interp, sizeof(DictMapStorage));
|
||||
if (Tcl_DictObjFirst(interp, objv[2], &storagePtr->search, &keyObj,
|
||||
&valueObj, &done) != TCL_OK) {
|
||||
TclStackFree(interp, storagePtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (done) {
|
||||
/*
|
||||
* Note that this exit leaves an empty value in the result (due to
|
||||
* command calling conventions) but that is OK since an empty value is
|
||||
* an empty dictionary.
|
||||
*/
|
||||
|
||||
TclStackFree(interp, storagePtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
TclNewObj(storagePtr->accumulatorObj);
|
||||
TclListObjGetElements(NULL, objv[1], &varc, &varv);
|
||||
storagePtr->keyVarObj = varv[0];
|
||||
storagePtr->valueVarObj = varv[1];
|
||||
storagePtr->scriptObj = objv[3];
|
||||
|
||||
/*
|
||||
* Make sure that these objects (which we need throughout the body of the
|
||||
* loop) don't vanish. Note that the dictionary internal rep is locked
|
||||
* internally so that updates, shimmering, etc are not a problem.
|
||||
*/
|
||||
|
||||
Tcl_IncrRefCount(storagePtr->accumulatorObj);
|
||||
Tcl_IncrRefCount(storagePtr->keyVarObj);
|
||||
Tcl_IncrRefCount(storagePtr->valueVarObj);
|
||||
Tcl_IncrRefCount(storagePtr->scriptObj);
|
||||
|
||||
/*
|
||||
* Stop the value from getting hit in any way by any traces on the key
|
||||
* variable.
|
||||
*/
|
||||
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
if (Tcl_ObjSetVar2(interp, storagePtr->keyVarObj, NULL, keyObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
TclDecrRefCount(valueObj);
|
||||
goto error;
|
||||
}
|
||||
if (Tcl_ObjSetVar2(interp, storagePtr->valueVarObj, NULL, valueObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
TclDecrRefCount(valueObj);
|
||||
goto error;
|
||||
}
|
||||
TclDecrRefCount(valueObj);
|
||||
|
||||
/*
|
||||
* Run the script.
|
||||
*/
|
||||
|
||||
TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL);
|
||||
return TclNREvalObjEx(interp, storagePtr->scriptObj, 0,
|
||||
iPtr->cmdFramePtr, 3);
|
||||
|
||||
/*
|
||||
* For unwinding everything on error.
|
||||
*/
|
||||
|
||||
error:
|
||||
TclDecrRefCount(storagePtr->keyVarObj);
|
||||
TclDecrRefCount(storagePtr->valueVarObj);
|
||||
TclDecrRefCount(storagePtr->scriptObj);
|
||||
TclDecrRefCount(storagePtr->accumulatorObj);
|
||||
Tcl_DictObjDone(&storagePtr->search);
|
||||
TclStackFree(interp, storagePtr);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
DictMapLoopCallback(
|
||||
ClientData data[],
|
||||
Tcl_Interp *interp,
|
||||
int result)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
DictMapStorage *storagePtr = data[0];
|
||||
Tcl_Obj *keyObj, *valueObj;
|
||||
int done;
|
||||
|
||||
/*
|
||||
* Process the result from the previous execution of the script body.
|
||||
*/
|
||||
|
||||
if (result == TCL_CONTINUE) {
|
||||
result = TCL_OK;
|
||||
} else if (result != TCL_OK) {
|
||||
if (result == TCL_BREAK) {
|
||||
Tcl_ResetResult(interp);
|
||||
result = TCL_OK;
|
||||
} else if (result == TCL_ERROR) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (\"dict map\" body line %d)",
|
||||
Tcl_GetErrorLine(interp)));
|
||||
}
|
||||
goto done;
|
||||
} else {
|
||||
keyObj = Tcl_ObjGetVar2(interp, storagePtr->keyVarObj, NULL,
|
||||
TCL_LEAVE_ERR_MSG);
|
||||
if (keyObj == NULL) {
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
Tcl_DictObjPut(NULL, storagePtr->accumulatorObj, keyObj,
|
||||
Tcl_GetObjResult(interp));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next mapping from the dictionary.
|
||||
*/
|
||||
|
||||
Tcl_DictObjNext(&storagePtr->search, &keyObj, &valueObj, &done);
|
||||
if (done) {
|
||||
Tcl_SetObjResult(interp, storagePtr->accumulatorObj);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stop the value from getting hit in any way by any traces on the key
|
||||
* variable.
|
||||
*/
|
||||
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
if (Tcl_ObjSetVar2(interp, storagePtr->keyVarObj, NULL, keyObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
TclDecrRefCount(valueObj);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (Tcl_ObjSetVar2(interp, storagePtr->valueVarObj, NULL, valueObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
TclDecrRefCount(valueObj);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
TclDecrRefCount(valueObj);
|
||||
|
||||
/*
|
||||
* Run the script.
|
||||
*/
|
||||
|
||||
TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL);
|
||||
return TclNREvalObjEx(interp, storagePtr->scriptObj, 0,
|
||||
iPtr->cmdFramePtr, 3);
|
||||
|
||||
/*
|
||||
* For unwinding everything once the iterating is done.
|
||||
*/
|
||||
|
||||
done:
|
||||
TclDecrRefCount(storagePtr->keyVarObj);
|
||||
TclDecrRefCount(storagePtr->valueVarObj);
|
||||
TclDecrRefCount(storagePtr->scriptObj);
|
||||
TclDecrRefCount(storagePtr->accumulatorObj);
|
||||
Tcl_DictObjDone(&storagePtr->search);
|
||||
TclStackFree(interp, storagePtr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -2787,8 +3026,8 @@ DictFilterCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (varc != 2) {
|
||||
Tcl_SetResult(interp, "must have exactly two variable names",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"must have exactly two variable names", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
keyVarObj = varv[0];
|
||||
@@ -2828,16 +3067,19 @@ DictFilterCmd(
|
||||
if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "couldn't set key variable: \"",
|
||||
TclGetString(keyVarObj), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't set key variable: \"%s\"",
|
||||
TclGetString(keyVarObj)));
|
||||
result = TCL_ERROR;
|
||||
goto abnormalResult;
|
||||
}
|
||||
if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
|
||||
TCL_LEAVE_ERR_MSG) == NULL) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "couldn't set value variable: \"",
|
||||
TclGetString(valueVarObj), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't set value variable: \"%s\"",
|
||||
TclGetString(valueVarObj)));
|
||||
result = TCL_ERROR;
|
||||
goto abnormalResult;
|
||||
}
|
||||
|
||||
@@ -3438,7 +3680,7 @@ TclInitDictCmd(
|
||||
{
|
||||
return TclMakeEnsemble(interp, "dict", implementationMap);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Local Variables:
|
||||
* mode: c
|
||||
|
||||
@@ -1542,7 +1542,8 @@ OpenEncodingFileChannel(
|
||||
}
|
||||
|
||||
if ((NULL == chan) && (interp != NULL)) {
|
||||
Tcl_AppendResult(interp, "unknown encoding \"", name, "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"unknown encoding \"%s\"", name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
|
||||
}
|
||||
Tcl_DecrRefCount(fileNameObj);
|
||||
@@ -1616,7 +1617,8 @@ LoadEncodingFile(
|
||||
break;
|
||||
}
|
||||
if ((encoding == NULL) && (interp != NULL)) {
|
||||
Tcl_AppendResult(interp, "invalid encoding file \"", name, "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"invalid encoding file \"%s\"", name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
|
||||
}
|
||||
Tcl_Close(NULL, chan);
|
||||
@@ -1872,9 +1874,9 @@ LoadTableEncoding(
|
||||
* Read lines from the encoding until EOF.
|
||||
*/
|
||||
|
||||
for (Tcl_DStringSetLength(&lineString, 0);
|
||||
for (TclDStringClear(&lineString);
|
||||
(len = Tcl_Gets(chan, &lineString)) >= 0;
|
||||
Tcl_DStringSetLength(&lineString, 0)) {
|
||||
TclDStringClear(&lineString)) {
|
||||
const unsigned char *p;
|
||||
int to, from;
|
||||
|
||||
|
||||
+695
-131
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -772,9 +772,9 @@ TclCygwinPutenv(
|
||||
} else {
|
||||
int size;
|
||||
|
||||
size = cygwin_posix_to_win32_path_list_buf_size(value);
|
||||
size = cygwin_conv_path_list(0, value, NULL, 0);
|
||||
buf = alloca(size + 1);
|
||||
cygwin_posix_to_win32_path_list(value, buf);
|
||||
cygwin_conv_path_list(0, value, buf, size);
|
||||
}
|
||||
|
||||
SetEnvironmentVariableA(name, buf);
|
||||
|
||||
+5
-4
@@ -1416,7 +1416,7 @@ Tcl_VwaitObjCmd(
|
||||
}
|
||||
if (Tcl_LimitExceeded(interp)) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "limit exceeded", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("limit exceeded", -1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1426,8 +1426,9 @@ Tcl_VwaitObjCmd(
|
||||
|
||||
if (!foundEvent) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "can't wait for variable \"", nameString,
|
||||
"\": would wait forever", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't wait for variable \"%s\": would wait forever",
|
||||
nameString));
|
||||
Tcl_SetErrorCode(interp, "TCL", "EVENT", "NO_SOURCES", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1519,7 +1520,7 @@ Tcl_UpdateObjCmd(
|
||||
}
|
||||
if (Tcl_LimitExceeded(interp)) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "limit exceeded", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("limit exceeded", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
+648
-39
@@ -17,6 +17,7 @@
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclCompile.h"
|
||||
#include "tclOOInt.h"
|
||||
#include "tommath.h"
|
||||
#include <math.h>
|
||||
|
||||
@@ -250,13 +251,24 @@ VarHashCreateVar(
|
||||
* otherwise, push objResultPtr. If (result < 0), objResultPtr already
|
||||
* has the correct reference count.
|
||||
*
|
||||
* We use the new compile-time assertions to cheack that nCleanup is constant
|
||||
* We use the new compile-time assertions to check that nCleanup is constant
|
||||
* and within range.
|
||||
*/
|
||||
|
||||
#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
|
||||
/* Verify the stack depth, only when no expansion is in progress */
|
||||
|
||||
#if TCL_COMPILE_DEBUG
|
||||
#define CHECK_STACK() \
|
||||
ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, \
|
||||
/*checkStack*/ auxObjList == NULL)
|
||||
#else
|
||||
#define CHECK_STACK()
|
||||
#endif
|
||||
|
||||
#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling) \
|
||||
do { \
|
||||
TCL_CT_ASSERT((nCleanup >= 0) && (nCleanup <= 2)); \
|
||||
CHECK_STACK(); \
|
||||
if (nCleanup == 0) { \
|
||||
if (resultHandling != 0) { \
|
||||
if ((resultHandling) > 0) { \
|
||||
@@ -285,7 +297,8 @@ VarHashCreateVar(
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \
|
||||
#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling) \
|
||||
CHECK_STACK(); \
|
||||
do { \
|
||||
pc += (pcAdjustment); \
|
||||
cleanup = (nCleanup); \
|
||||
@@ -684,7 +697,7 @@ static void PrintByteCodeInfo(ByteCode *codePtr);
|
||||
static const char * StringForResultCode(int result);
|
||||
static void ValidatePcAndStackTop(ByteCode *codePtr,
|
||||
const unsigned char *pc, int stackTop,
|
||||
int stackLowerBound, int checkStack);
|
||||
int checkStack);
|
||||
#endif /* TCL_COMPILE_DEBUG */
|
||||
static ByteCode * CompileExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr);
|
||||
static void DeleteExecStack(ExecStack *esPtr);
|
||||
@@ -858,6 +871,7 @@ TclCreateExecEnv(
|
||||
TclNewBooleanObj(eePtr->constants[1], 1);
|
||||
Tcl_IncrRefCount(eePtr->constants[1]);
|
||||
eePtr->interp = interp;
|
||||
eePtr->NRStack = NULL;
|
||||
eePtr->callbackPtr = NULL;
|
||||
eePtr->corPtr = NULL;
|
||||
eePtr->rewind = 0;
|
||||
@@ -876,6 +890,11 @@ TclCreateExecEnv(
|
||||
}
|
||||
Tcl_MutexUnlock(&execMutex);
|
||||
|
||||
/* Initialize the NRE stack */
|
||||
|
||||
((Interp *) interp)->execEnvPtr = eePtr;
|
||||
eePtr->callbackPtr = TclNewCallback(interp);
|
||||
eePtr->callbackPtr--;
|
||||
return eePtr;
|
||||
}
|
||||
|
||||
@@ -919,7 +938,7 @@ TclDeleteExecEnv(
|
||||
{
|
||||
ExecStack *esPtr = eePtr->execStackPtr, *tmpPtr;
|
||||
|
||||
cachedInExit = TclInExit();
|
||||
cachedInExit = TclInExit();
|
||||
|
||||
/*
|
||||
* Delete all stacks in this exec env.
|
||||
@@ -1047,6 +1066,7 @@ GrowEvaluationStack(
|
||||
return MEMSTART(markerPtr);
|
||||
}
|
||||
} else {
|
||||
#ifndef PURIFY
|
||||
Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
|
||||
int offset = OFFSET(tmpMarkerPtr);
|
||||
|
||||
@@ -1063,6 +1083,7 @@ GrowEvaluationStack(
|
||||
*esPtr->markerPtr = (Tcl_Obj *) markerPtr;
|
||||
return memStart;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1074,8 +1095,9 @@ GrowEvaluationStack(
|
||||
if (move) {
|
||||
moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1;
|
||||
}
|
||||
needed = growth + moveWords + WALLOCALIGN;
|
||||
needed = growth + moveWords + WALLOCALIGN - 1;
|
||||
|
||||
|
||||
/*
|
||||
* Check if there is enough room in the next stack (if there is one, it
|
||||
* should be both empty and the last one!)
|
||||
@@ -1105,10 +1127,15 @@ GrowEvaluationStack(
|
||||
* including the elements to be copied over and the new marker.
|
||||
*/
|
||||
|
||||
#ifndef PURIFY
|
||||
newElems = 2*currElems;
|
||||
while (needed > newElems) {
|
||||
newElems *= 2;
|
||||
}
|
||||
#else
|
||||
newElems = needed;
|
||||
#endif
|
||||
|
||||
newBytes = sizeof(ExecStack) + (newElems-1) * sizeof(Tcl_Obj *);
|
||||
|
||||
oldPtr = esPtr;
|
||||
@@ -1211,7 +1238,7 @@ TclStackFree(
|
||||
Tcl_Obj **markerPtr, *marker;
|
||||
|
||||
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
|
||||
Tcl_Free((char *) freePtr);
|
||||
ckfree((char *) freePtr);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1257,6 +1284,10 @@ TclStackFree(
|
||||
}
|
||||
if (esPtr->prevPtr) {
|
||||
eePtr->execStackPtr = esPtr->prevPtr;
|
||||
#ifdef PURIFY
|
||||
eePtr->execStackPtr->nextPtr = NULL;
|
||||
DeleteExecStack(esPtr);
|
||||
#endif
|
||||
} else {
|
||||
eePtr->execStackPtr = esPtr;
|
||||
}
|
||||
@@ -1271,7 +1302,7 @@ TclStackAlloc(
|
||||
int numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *);
|
||||
|
||||
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
|
||||
return (void *) Tcl_Alloc(numBytes);
|
||||
return (void *) ckalloc(numBytes);
|
||||
}
|
||||
|
||||
return (void *) StackAllocWords(interp, numWords);
|
||||
@@ -1290,7 +1321,7 @@ TclStackRealloc(
|
||||
int numWords;
|
||||
|
||||
if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
|
||||
return (void *) Tcl_Realloc((char *) ptr, numBytes);
|
||||
return (void *) ckrealloc((char *) ptr, numBytes);
|
||||
}
|
||||
|
||||
eePtr = iPtr->execEnvPtr;
|
||||
@@ -2230,8 +2261,7 @@ TEBCresume(
|
||||
* Skip the stack depth check if an expansion is in progress.
|
||||
*/
|
||||
|
||||
ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH, 0,
|
||||
/*checkStack*/ auxObjList == NULL);
|
||||
CHECK_STACK();
|
||||
if (traceInstructions) {
|
||||
fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH);
|
||||
TclPrintInstruction(codePtr, pc);
|
||||
@@ -2331,6 +2361,91 @@ TEBCresume(
|
||||
cleanup = 1;
|
||||
goto processExceptionReturn;
|
||||
|
||||
case INST_YIELD: {
|
||||
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
|
||||
|
||||
TRACE(("%.30s => ", O2S(OBJ_AT_TOS)));
|
||||
if (!corPtr) {
|
||||
TRACE_APPEND(("ERROR: yield outside coroutine\n"));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"yield can only be called in a coroutine", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD",
|
||||
NULL);
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
TRACE_WITH_OBJ(("yield, result="), iPtr->objResultPtr);
|
||||
if (traceInstructions) {
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
#endif
|
||||
/* TIP #280: Record the last piece of info needed by
|
||||
* 'TclGetSrcInfoForPc', and push the frame.
|
||||
*/
|
||||
|
||||
bcFramePtr->data.tebc.pc = (char *) pc;
|
||||
iPtr->cmdFramePtr = bcFramePtr;
|
||||
|
||||
if (iPtr->flags & INTERP_DEBUG_FRAME) {
|
||||
TclArgumentBCEnter((Tcl_Interp *) iPtr, objv, objc,
|
||||
codePtr, bcFramePtr, pc - codePtr->codeStart);
|
||||
}
|
||||
|
||||
pc++;
|
||||
cleanup = 1;
|
||||
TEBC_YIELD();
|
||||
|
||||
Tcl_SetObjResult(interp, OBJ_AT_TOS);
|
||||
TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
|
||||
INT2PTR(0), NULL, NULL);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
case INST_TAILCALL: {
|
||||
Tcl_Obj *listPtr, *nsObjPtr;
|
||||
|
||||
opnd = TclGetUInt1AtPtr(pc+1);
|
||||
|
||||
if (!(iPtr->varFramePtr->isProcCallFrame & 1)) {
|
||||
TRACE(("%d => ERROR: tailcall in non-proc context\n", opnd));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"tailcall can only be called from a proc or lambda", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
{
|
||||
register int i;
|
||||
|
||||
TRACE(("%d [", opnd));
|
||||
for (i=opnd-1 ; i>=0 ; i--) {
|
||||
TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_DEPTH(i))));
|
||||
if (i > 0) {
|
||||
TRACE_APPEND((" "));
|
||||
}
|
||||
}
|
||||
TRACE_APPEND(("] => RETURN..."));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Push the evaluation of the called command into the NR callback
|
||||
* stack.
|
||||
*/
|
||||
|
||||
listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1));
|
||||
nsObjPtr = Tcl_NewStringObj(iPtr->varFramePtr->nsPtr->fullName, -1);
|
||||
TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
|
||||
iPtr->varFramePtr->tailcallPtr = listPtr;
|
||||
|
||||
result = TCL_RETURN;
|
||||
cleanup = opnd;
|
||||
goto processExceptionReturn;
|
||||
}
|
||||
|
||||
case INST_DONE:
|
||||
if (tosPtr > initTosPtr) {
|
||||
/*
|
||||
@@ -2876,6 +2991,69 @@ TEBCresume(
|
||||
Tcl_Panic("TclNRExecuteByteCode: obsolete INST_CALL_FUNC1 found");
|
||||
#endif
|
||||
|
||||
case INST_INVOKE_REPLACE:
|
||||
objc = TclGetUInt4AtPtr(pc+1);
|
||||
opnd = TclGetUInt1AtPtr(pc+5);
|
||||
objPtr = POP_OBJECT();
|
||||
objv = &OBJ_AT_DEPTH(objc-1);
|
||||
cleanup = objc;
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
if (tclTraceExec >= 2) {
|
||||
int i;
|
||||
|
||||
if (traceInstructions) {
|
||||
strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
|
||||
TRACE(("%u => call (implementation %s) ", objc, O2S(objPtr)));
|
||||
} else {
|
||||
fprintf(stdout,
|
||||
"%d: (%u) invoking (using implementation %s) ",
|
||||
iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
|
||||
O2S(objPtr));
|
||||
}
|
||||
for (i = 0; i < objc; i++) {
|
||||
if (i < opnd) {
|
||||
fprintf(stdout, "<");
|
||||
TclPrintObject(stdout, objv[i], 15);
|
||||
fprintf(stdout, ">");
|
||||
} else {
|
||||
TclPrintObject(stdout, objv[i], 15);
|
||||
}
|
||||
fprintf(stdout, " ");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
fflush(stdout);
|
||||
}
|
||||
#endif /*TCL_COMPILE_DEBUG*/
|
||||
{
|
||||
Tcl_Obj *copyPtr = Tcl_NewListObj(objc - opnd + 1, NULL);
|
||||
register List *listRepPtr = copyPtr->internalRep.twoPtrValue.ptr1;
|
||||
Tcl_Obj **copyObjv = &listRepPtr->elements;
|
||||
int i;
|
||||
|
||||
listRepPtr->elemCount = objc - opnd + 1;
|
||||
copyObjv[0] = objPtr;
|
||||
memcpy(copyObjv+1, objv+opnd, sizeof(Tcl_Obj *) * (objc - opnd));
|
||||
for (i=1 ; i<objc-opnd+1 ; i++) {
|
||||
Tcl_IncrRefCount(copyObjv[i]);
|
||||
}
|
||||
objPtr = copyPtr;
|
||||
}
|
||||
bcFramePtr->data.tebc.pc = (char *) pc;
|
||||
iPtr->cmdFramePtr = bcFramePtr;
|
||||
if (iPtr->flags & INTERP_DEBUG_FRAME) {
|
||||
TclArgumentBCEnter((Tcl_Interp *) iPtr, objv, objc,
|
||||
codePtr, bcFramePtr, pc - codePtr->codeStart);
|
||||
}
|
||||
iPtr->ensembleRewrite.sourceObjs = objv;
|
||||
iPtr->ensembleRewrite.numRemovedObjs = opnd;
|
||||
iPtr->ensembleRewrite.numInsertedObjs = 1;
|
||||
DECACHE_STACK_INFO();
|
||||
pc += 6;
|
||||
TEBC_YIELD();
|
||||
TclNRAddCallback(interp, TclClearRootEnsemble, NULL,NULL,NULL,NULL);
|
||||
return TclNREvalObjEx(interp, objPtr, (TCL_EVAL_INVOKE|TCL_EVAL_REDIRECT),
|
||||
NULL, INT_MIN);
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------
|
||||
* Start of INST_LOAD instructions.
|
||||
@@ -3785,6 +3963,104 @@ TEBCresume(
|
||||
/*
|
||||
* End of INST_UNSET instructions.
|
||||
* -----------------------------------------------------------------
|
||||
* Start of INST_ARRAY instructions.
|
||||
*/
|
||||
|
||||
case INST_ARRAY_EXISTS_IMM:
|
||||
opnd = TclGetUInt4AtPtr(pc+1);
|
||||
pcAdjustment = 5;
|
||||
cleanup = 0;
|
||||
part1Ptr = NULL;
|
||||
arrayPtr = NULL;
|
||||
TRACE(("%u => ", opnd));
|
||||
varPtr = LOCAL(opnd);
|
||||
while (TclIsVarLink(varPtr)) {
|
||||
varPtr = varPtr->value.linkPtr;
|
||||
}
|
||||
goto doArrayExists;
|
||||
case INST_ARRAY_EXISTS_STK:
|
||||
opnd = -1;
|
||||
pcAdjustment = 1;
|
||||
cleanup = 1;
|
||||
part1Ptr = OBJ_AT_TOS;
|
||||
TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
|
||||
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
|
||||
/*createPart1*/0, /*createPart2*/0, &arrayPtr);
|
||||
doArrayExists:
|
||||
if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
|
||||
&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
|
||||
DECACHE_STACK_INFO();
|
||||
result = TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,
|
||||
NULL, (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|
|
||||
TCL_GLOBAL_ONLY|TCL_TRACE_ARRAY), 1, opnd);
|
||||
CACHE_STACK_INFO();
|
||||
if (result == TCL_ERROR) {
|
||||
TRACE_APPEND(("ERROR: %.30s\n",
|
||||
O2S(Tcl_GetObjResult(interp))));
|
||||
goto gotError;
|
||||
}
|
||||
}
|
||||
if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
|
||||
objResultPtr = TCONST(1);
|
||||
} else {
|
||||
objResultPtr = TCONST(0);
|
||||
}
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(pcAdjustment, cleanup, 1);
|
||||
|
||||
case INST_ARRAY_MAKE_IMM:
|
||||
opnd = TclGetUInt4AtPtr(pc+1);
|
||||
pcAdjustment = 5;
|
||||
cleanup = 0;
|
||||
part1Ptr = NULL;
|
||||
arrayPtr = NULL;
|
||||
TRACE(("%u => ", opnd));
|
||||
varPtr = LOCAL(opnd);
|
||||
while (TclIsVarLink(varPtr)) {
|
||||
varPtr = varPtr->value.linkPtr;
|
||||
}
|
||||
goto doArrayMake;
|
||||
case INST_ARRAY_MAKE_STK:
|
||||
opnd = -1;
|
||||
pcAdjustment = 1;
|
||||
cleanup = 1;
|
||||
part1Ptr = OBJ_AT_TOS;
|
||||
TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
|
||||
varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
|
||||
"set", /*createPart1*/1, /*createPart2*/0, &arrayPtr);
|
||||
if (varPtr == NULL) {
|
||||
TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
|
||||
goto gotError;
|
||||
}
|
||||
doArrayMake:
|
||||
if (varPtr && !TclIsVarArray(varPtr)) {
|
||||
if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
|
||||
/*
|
||||
* Either an array element, or a scalar: lose!
|
||||
*/
|
||||
|
||||
TclObjVarErrMsg(interp, part1Ptr, NULL, "array set",
|
||||
"variable isn't array", opnd);
|
||||
Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
|
||||
TRACE_APPEND(("ERROR: bad array ref: %.30s\n",
|
||||
O2S(Tcl_GetObjResult(interp))));
|
||||
goto gotError;
|
||||
}
|
||||
TclSetVarArray(varPtr);
|
||||
varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable));
|
||||
TclInitVarHashTable(varPtr->value.tablePtr,
|
||||
TclGetVarNsPtr(varPtr));
|
||||
#ifdef TCL_COMPILE_DEBUG
|
||||
TRACE_APPEND(("done\n"));
|
||||
} else {
|
||||
TRACE_APPEND(("nothing to do\n"));
|
||||
#endif
|
||||
}
|
||||
NEXT_INST_V(pcAdjustment, cleanup, 0);
|
||||
|
||||
/*
|
||||
* End of INST_ARRAY instructions.
|
||||
* -----------------------------------------------------------------
|
||||
* Start of variable linking instructions.
|
||||
*/
|
||||
|
||||
@@ -4043,6 +4319,136 @@ TEBCresume(
|
||||
NEXT_INST_F(1, 2, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------
|
||||
* Start of general introspector instructions.
|
||||
*/
|
||||
|
||||
case INST_NS_CURRENT: {
|
||||
Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
|
||||
|
||||
if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) {
|
||||
TclNewLiteralStringObj(objResultPtr, "::");
|
||||
} else {
|
||||
TclNewStringObj(objResultPtr, currNsPtr->fullName,
|
||||
strlen(currNsPtr->fullName));
|
||||
}
|
||||
TRACE_WITH_OBJ(("=> "), objResultPtr);
|
||||
NEXT_INST_F(1, 0, 1);
|
||||
}
|
||||
case INST_COROUTINE_NAME: {
|
||||
CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
|
||||
|
||||
TclNewObj(objResultPtr);
|
||||
if (corPtr && !(corPtr->cmdPtr->flags & CMD_IS_DELETED)) {
|
||||
Tcl_GetCommandFullName(interp, (Tcl_Command) corPtr->cmdPtr,
|
||||
objResultPtr);
|
||||
}
|
||||
TRACE_WITH_OBJ(("=> "), objResultPtr);
|
||||
NEXT_INST_F(1, 0, 1);
|
||||
}
|
||||
case INST_INFO_LEVEL_NUM:
|
||||
TclNewIntObj(objResultPtr, iPtr->varFramePtr->level);
|
||||
TRACE_WITH_OBJ(("=> "), objResultPtr);
|
||||
NEXT_INST_F(1, 0, 1);
|
||||
case INST_INFO_LEVEL_ARGS: {
|
||||
int level;
|
||||
register CallFrame *framePtr = iPtr->varFramePtr;
|
||||
register CallFrame *rootFramePtr = iPtr->rootFramePtr;
|
||||
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
if (TclGetIntFromObj(interp, valuePtr, &level) != TCL_OK) {
|
||||
TRACE_WITH_OBJ(("%.30s => ERROR: ", O2S(valuePtr)),
|
||||
Tcl_GetObjResult(interp));
|
||||
goto gotError;
|
||||
}
|
||||
TRACE(("%d => ", level));
|
||||
if (level <= 0) {
|
||||
level += framePtr->level;
|
||||
}
|
||||
for (; (framePtr->level!=level) && (framePtr!=rootFramePtr) ;
|
||||
framePtr = framePtr->callerVarPtr) {
|
||||
/* Empty loop body */
|
||||
}
|
||||
if (framePtr == rootFramePtr) {
|
||||
Tcl_AppendResult(interp, "bad level \"", TclGetString(valuePtr),
|
||||
"\"", NULL);
|
||||
TRACE_APPEND(("ERROR: bad level\n"));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
|
||||
TclGetString(valuePtr), NULL);
|
||||
goto gotError;
|
||||
}
|
||||
objResultPtr = Tcl_NewListObj(framePtr->objc, framePtr->objv);
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
}
|
||||
case INST_RESOLVE_COMMAND: {
|
||||
Tcl_Command cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS);
|
||||
|
||||
TclNewObj(objResultPtr);
|
||||
if (cmd != NULL) {
|
||||
Tcl_GetCommandFullName(interp, cmd, objResultPtr);
|
||||
}
|
||||
TRACE_WITH_OBJ(("\"%.20s\" => ", O2S(OBJ_AT_TOS)), objResultPtr);
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
}
|
||||
case INST_TCLOO_SELF: {
|
||||
CallFrame *framePtr = iPtr->varFramePtr;
|
||||
CallContext *contextPtr;
|
||||
|
||||
if (framePtr == NULL ||
|
||||
!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
|
||||
TRACE(("=> ERROR: no TclOO call context\n"));
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"self may only be called from inside a method",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
|
||||
goto gotError;
|
||||
}
|
||||
contextPtr = framePtr->clientData;
|
||||
|
||||
/*
|
||||
* Call out to get the name; it's expensive to compute but cached.
|
||||
*/
|
||||
|
||||
objResultPtr = TclOOObjectName(interp, contextPtr->oPtr);
|
||||
TRACE_WITH_OBJ(("=> "), objResultPtr);
|
||||
NEXT_INST_F(1, 0, 1);
|
||||
}
|
||||
{
|
||||
Object *oPtr;
|
||||
|
||||
case INST_TCLOO_IS_OBJECT:
|
||||
oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
|
||||
objResultPtr = TCONST(oPtr != NULL ? 1 : 0);
|
||||
TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
case INST_TCLOO_CLASS:
|
||||
oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
|
||||
if (oPtr == NULL) {
|
||||
TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
|
||||
goto gotError;
|
||||
}
|
||||
objResultPtr = TclOOObjectName(interp, oPtr->selfCls->thisPtr);
|
||||
TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
case INST_TCLOO_NS:
|
||||
oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
|
||||
if (oPtr == NULL) {
|
||||
TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
/*
|
||||
* TclOO objects *never* have the global namespace as their NS.
|
||||
*/
|
||||
|
||||
TclNewStringObj(objResultPtr, oPtr->namespacePtr->fullName,
|
||||
strlen(oPtr->namespacePtr->fullName));
|
||||
TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
|
||||
NEXT_INST_F(1, 1, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* -----------------------------------------------------------------
|
||||
* Start of INST_LIST and related instructions.
|
||||
@@ -4592,6 +4998,176 @@ TEBCresume(
|
||||
O2S(objResultPtr)));
|
||||
NEXT_INST_F(1, 2, 1);
|
||||
|
||||
case INST_STR_RANGE:
|
||||
TRACE(("\"%.20s\" %s %s =>",
|
||||
O2S(OBJ_AT_DEPTH(2)), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
|
||||
length = Tcl_GetCharLength(OBJ_AT_DEPTH(2)) - 1;
|
||||
if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length,
|
||||
&fromIdx) != TCL_OK
|
||||
|| TclGetIntForIndexM(interp, OBJ_AT_TOS, length,
|
||||
&toIdx) != TCL_OK) {
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
if (fromIdx < 0) {
|
||||
fromIdx = 0;
|
||||
}
|
||||
if (toIdx >= length) {
|
||||
toIdx = length;
|
||||
}
|
||||
if (toIdx >= fromIdx) {
|
||||
objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx);
|
||||
} else {
|
||||
TclNewObj(objResultPtr);
|
||||
}
|
||||
TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
|
||||
case INST_STR_RANGE_IMM:
|
||||
valuePtr = OBJ_AT_TOS;
|
||||
fromIdx = TclGetInt4AtPtr(pc+1);
|
||||
toIdx = TclGetInt4AtPtr(pc+5);
|
||||
length = Tcl_GetCharLength(valuePtr);
|
||||
TRACE(("\"%.20s\" %d %d => ", O2S(valuePtr), fromIdx, toIdx));
|
||||
|
||||
/*
|
||||
* Adjust indices for end-based indexing.
|
||||
*/
|
||||
|
||||
if (fromIdx < -1) {
|
||||
fromIdx += 1 + length;
|
||||
if (fromIdx < 0) {
|
||||
fromIdx = 0;
|
||||
}
|
||||
} else if (fromIdx >= length) {
|
||||
fromIdx = length;
|
||||
}
|
||||
if (toIdx < -1) {
|
||||
toIdx += 1 + length;
|
||||
} else if (toIdx >= length) {
|
||||
toIdx = length - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we can do a sane substring.
|
||||
*/
|
||||
|
||||
if (fromIdx <= toIdx) {
|
||||
objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx);
|
||||
} else {
|
||||
TclNewObj(objResultPtr);
|
||||
}
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_F(9, 1, 1);
|
||||
|
||||
{
|
||||
Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p;
|
||||
int length3;
|
||||
Tcl_Obj *value3Ptr;
|
||||
|
||||
case INST_STR_MAP:
|
||||
valuePtr = OBJ_AT_TOS; /* "Main" string. */
|
||||
value3Ptr = OBJ_UNDER_TOS; /* "Target" string. */
|
||||
value2Ptr = OBJ_AT_DEPTH(2); /* "Source" string. */
|
||||
if (value3Ptr == value2Ptr) {
|
||||
objResultPtr = valuePtr;
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
} else if (valuePtr == value2Ptr) {
|
||||
objResultPtr = value3Ptr;
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
}
|
||||
ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
|
||||
if (length == 0) {
|
||||
objResultPtr = valuePtr;
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
}
|
||||
ustring2 = Tcl_GetUnicodeFromObj(value2Ptr, &length2);
|
||||
if (length2 > length || length2 == 0) {
|
||||
objResultPtr = valuePtr;
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
} else if (length2 == length) {
|
||||
if (memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length)) {
|
||||
objResultPtr = valuePtr;
|
||||
} else {
|
||||
objResultPtr = value3Ptr;
|
||||
}
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
}
|
||||
ustring3 = Tcl_GetUnicodeFromObj(value3Ptr, &length3);
|
||||
|
||||
objResultPtr = Tcl_NewUnicodeObj(ustring1, 0);
|
||||
p = ustring1;
|
||||
end = ustring1 + length;
|
||||
for (; ustring1 < end; ustring1++) {
|
||||
if ((*ustring1 == *ustring2) && (length2==1 ||
|
||||
memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length2)
|
||||
== 0)) {
|
||||
if (p != ustring1) {
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1-p);
|
||||
p = ustring1 + length2;
|
||||
} else {
|
||||
p += length2;
|
||||
}
|
||||
ustring1 = p - 1;
|
||||
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, ustring3, length3);
|
||||
}
|
||||
}
|
||||
if (p != ustring1) {
|
||||
/*
|
||||
* Put the rest of the unmapped chars onto result.
|
||||
*/
|
||||
|
||||
Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1 - p);
|
||||
}
|
||||
TRACE_WITH_OBJ(("%.20s %.20s %.20s => ",
|
||||
O2S(value2Ptr), O2S(value3Ptr), O2S(valuePtr)), objResultPtr);
|
||||
NEXT_INST_V(1, 3, 1);
|
||||
|
||||
case INST_STR_FIND:
|
||||
ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length); /* Haystack */
|
||||
ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
|
||||
|
||||
match = -1;
|
||||
if (length2 > 0 && length2 <= length) {
|
||||
end = ustring1 + length - length2 + 1;
|
||||
for (p=ustring1 ; p<end ; p++) {
|
||||
if ((*p == *ustring2) &&
|
||||
memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
|
||||
match = p - ustring1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE(("%.20s %.20s => %d\n",
|
||||
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
|
||||
|
||||
TclNewIntObj(objResultPtr, match);
|
||||
NEXT_INST_F(1, 2, 1);
|
||||
|
||||
case INST_STR_FIND_LAST:
|
||||
ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length); /* Haystack */
|
||||
ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
|
||||
|
||||
match = -1;
|
||||
if (length2 > 0 && length2 <= length) {
|
||||
for (p=ustring1+length-length2 ; p>=ustring1 ; p--) {
|
||||
if ((*p == *ustring2) &&
|
||||
memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
|
||||
match = p - ustring1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TRACE(("%.20s %.20s => %d\n",
|
||||
O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
|
||||
|
||||
TclNewIntObj(objResultPtr, match);
|
||||
NEXT_INST_F(1, 2, 1);
|
||||
}
|
||||
|
||||
case INST_STR_MATCH:
|
||||
nocase = TclGetInt1AtPtr(pc+1);
|
||||
valuePtr = OBJ_AT_TOS; /* String */
|
||||
@@ -4896,8 +5472,8 @@ TEBCresume(
|
||||
|
||||
case INST_RSHIFT:
|
||||
if (l2 < 0) {
|
||||
Tcl_SetResult(interp, "negative shift argument",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"negative shift argument", -1));
|
||||
#if 0
|
||||
DECACHE_STACK_INFO();
|
||||
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
|
||||
@@ -4944,8 +5520,8 @@ TEBCresume(
|
||||
|
||||
case INST_LSHIFT:
|
||||
if (l2 < 0) {
|
||||
Tcl_SetResult(interp, "negative shift argument",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"negative shift argument", -1));
|
||||
#if 0
|
||||
DECACHE_STACK_INFO();
|
||||
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
|
||||
@@ -4967,9 +5543,8 @@ TEBCresume(
|
||||
* good place to draw the line.
|
||||
*/
|
||||
|
||||
Tcl_SetResult(interp,
|
||||
"integer value too large to represent",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"integer value too large to represent", -1));
|
||||
#if 0
|
||||
DECACHE_STACK_INFO();
|
||||
Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
|
||||
@@ -5649,41 +6224,73 @@ TEBCresume(
|
||||
Tcl_DictSearch *searchPtr;
|
||||
DictUpdateInfo *duiPtr;
|
||||
|
||||
case INST_DICT_VERIFY:
|
||||
dictPtr = OBJ_AT_TOS;
|
||||
TRACE(("=> "));
|
||||
if (Tcl_DictObjSize(interp, dictPtr, &done) != TCL_OK) {
|
||||
TRACE_APPEND(("ERROR verifying dictionary nature of \"%s\": %s\n",
|
||||
O2S(OBJ_AT_DEPTH(opnd)), O2S(Tcl_GetObjResult(interp))));
|
||||
goto gotError;
|
||||
}
|
||||
TRACE_APPEND(("OK\n"));
|
||||
NEXT_INST_F(1, 1, 0);
|
||||
|
||||
case INST_DICT_GET:
|
||||
case INST_DICT_EXISTS: {
|
||||
register Tcl_Interp *interp2 = interp;
|
||||
|
||||
opnd = TclGetUInt4AtPtr(pc+1);
|
||||
TRACE(("%u => ", opnd));
|
||||
dictPtr = OBJ_AT_DEPTH(opnd);
|
||||
if (*pc == INST_DICT_EXISTS) {
|
||||
interp2 = NULL;
|
||||
}
|
||||
if (opnd > 1) {
|
||||
dictPtr = TclTraceDictPath(interp, dictPtr, opnd-1,
|
||||
dictPtr = TclTraceDictPath(interp2, dictPtr, opnd-1,
|
||||
&OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ);
|
||||
if (dictPtr == NULL) {
|
||||
if (*pc == INST_DICT_EXISTS) {
|
||||
goto dictNotExists;
|
||||
}
|
||||
TRACE_WITH_OBJ((
|
||||
"%u => ERROR tracing dictionary path into \"%s\": ",
|
||||
opnd, O2S(OBJ_AT_DEPTH(opnd))),
|
||||
"ERROR tracing dictionary path into \"%s\": ",
|
||||
O2S(OBJ_AT_DEPTH(opnd))),
|
||||
Tcl_GetObjResult(interp));
|
||||
goto gotError;
|
||||
}
|
||||
}
|
||||
if (Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS,
|
||||
if (Tcl_DictObjGet(interp2, dictPtr, OBJ_AT_TOS,
|
||||
&objResultPtr) == TCL_OK) {
|
||||
if (*pc == INST_DICT_EXISTS) {
|
||||
objResultPtr = TCONST(objResultPtr ? 1 : 0);
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(5, opnd+1, 1);
|
||||
}
|
||||
if (objResultPtr) {
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(5, opnd+1, 1);
|
||||
}
|
||||
DECACHE_STACK_INFO();
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "key \"", TclGetString(OBJ_AT_TOS),
|
||||
"\" not known in dictionary", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"key \"%s\" not known in dictionary",
|
||||
TclGetString(OBJ_AT_TOS)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
|
||||
TclGetString(OBJ_AT_TOS), NULL);
|
||||
CACHE_STACK_INFO();
|
||||
TRACE_WITH_OBJ(("%u => ERROR ", opnd), Tcl_GetObjResult(interp));
|
||||
} else {
|
||||
if (*pc == INST_DICT_EXISTS) {
|
||||
dictNotExists:
|
||||
objResultPtr = TCONST(0);
|
||||
TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
|
||||
NEXT_INST_V(5, opnd+1, 1);
|
||||
}
|
||||
TRACE_WITH_OBJ((
|
||||
"%u => ERROR reading leaf dictionary key \"%s\": ",
|
||||
opnd, O2S(dictPtr)), Tcl_GetObjResult(interp));
|
||||
}
|
||||
goto gotError;
|
||||
}
|
||||
|
||||
case INST_DICT_SET:
|
||||
case INST_DICT_UNSET:
|
||||
@@ -6304,7 +6911,7 @@ TEBCresume(
|
||||
|
||||
divideByZero:
|
||||
DECACHE_STACK_INFO();
|
||||
Tcl_SetResult(interp, "divide by zero", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by zero", -1));
|
||||
Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", NULL);
|
||||
CACHE_STACK_INFO();
|
||||
goto gotError;
|
||||
@@ -6316,8 +6923,8 @@ TEBCresume(
|
||||
|
||||
exponOfZero:
|
||||
DECACHE_STACK_INFO();
|
||||
Tcl_SetResult(interp, "exponentiation of zero by negative power",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"exponentiation of zero by negative power", -1));
|
||||
Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
|
||||
"exponentiation of zero by negative power", NULL);
|
||||
CACHE_STACK_INFO();
|
||||
@@ -6693,7 +7300,8 @@ ExecuteExtendedBinaryMathOp(
|
||||
invalid = 0;
|
||||
}
|
||||
if (invalid) {
|
||||
Tcl_SetResult(interp, "negative shift argument", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"negative shift argument", -1));
|
||||
return GENERAL_ARITHMETIC_ERROR;
|
||||
}
|
||||
|
||||
@@ -6723,8 +7331,8 @@ ExecuteExtendedBinaryMathOp(
|
||||
* place to draw the line.
|
||||
*/
|
||||
|
||||
Tcl_SetResult(interp, "integer value too large to represent",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"integer value too large to represent", -1));
|
||||
return GENERAL_ARITHMETIC_ERROR;
|
||||
}
|
||||
shift = (int)(*((const long *)ptr2));
|
||||
@@ -7125,7 +7733,8 @@ ExecuteExtendedBinaryMathOp(
|
||||
*/
|
||||
|
||||
if (type2 != TCL_NUMBER_LONG) {
|
||||
Tcl_SetResult(interp, "exponent too large", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"exponent too large", -1));
|
||||
return GENERAL_ARITHMETIC_ERROR;
|
||||
}
|
||||
|
||||
@@ -7363,7 +7972,8 @@ ExecuteExtendedBinaryMathOp(
|
||||
Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
|
||||
if (big2.used > 1) {
|
||||
mp_clear(&big2);
|
||||
Tcl_SetResult(interp, "exponent too large", TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"exponent too large", -1));
|
||||
return GENERAL_ARITHMETIC_ERROR;
|
||||
}
|
||||
Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
|
||||
@@ -7957,11 +8567,10 @@ ValidatePcAndStackTop(
|
||||
int stackTop, /* Current stack top. Must be between
|
||||
* stackLowerBound and stackUpperBound
|
||||
* (inclusive). */
|
||||
int stackLowerBound, /* Smallest legal value for stackTop. */
|
||||
int checkStack) /* 0 if the stack depth check should be
|
||||
* skipped. */
|
||||
{
|
||||
int stackUpperBound = stackLowerBound + codePtr->maxStackDepth;
|
||||
int stackUpperBound = codePtr->maxStackDepth;
|
||||
/* Greatest legal value for stackTop. */
|
||||
unsigned relativePc = (unsigned) (pc - codePtr->codeStart);
|
||||
unsigned long codeStart = (unsigned long) codePtr->codeStart;
|
||||
@@ -7979,13 +8588,13 @@ ValidatePcAndStackTop(
|
||||
(unsigned) opCode, relativePc);
|
||||
Tcl_Panic("TclNRExecuteByteCode execution failure: bad opcode");
|
||||
}
|
||||
if (checkStack &&
|
||||
((stackTop < stackLowerBound) || (stackTop > stackUpperBound))) {
|
||||
if (checkStack &&
|
||||
((stackTop < 0) || (stackTop > stackUpperBound))) {
|
||||
int numChars;
|
||||
const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL);
|
||||
|
||||
fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min %i, max %i)",
|
||||
stackTop, relativePc, stackLowerBound, stackUpperBound);
|
||||
fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min 0, max %i)",
|
||||
stackTop, relativePc, stackUpperBound);
|
||||
if (cmd != NULL) {
|
||||
Tcl_Obj *message;
|
||||
|
||||
|
||||
+74
-70
@@ -10,11 +10,6 @@
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#ifndef _WIN64
|
||||
/* See [Bug 2935503]: file mtime sets wrong time */
|
||||
# define _USE_32BIT_TIME_T
|
||||
#endif
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tclFileSystem.h"
|
||||
|
||||
@@ -152,9 +147,9 @@ FileCopyRename(
|
||||
if ((objc - i) > 2) {
|
||||
errno = ENOTDIR;
|
||||
Tcl_PosixError(interp);
|
||||
Tcl_AppendResult(interp, "error ",
|
||||
(copyFlag ? "copying" : "renaming"), ": target \"",
|
||||
TclGetString(target), "\" is not a directory", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error %s: target \"%s\" is not a directory",
|
||||
(copyFlag?"copying":"renaming"), TclGetString(target)));
|
||||
result = TCL_ERROR;
|
||||
} else {
|
||||
/*
|
||||
@@ -304,8 +299,9 @@ TclFileMakeDirsCmd(
|
||||
|
||||
done:
|
||||
if (errfile != NULL) {
|
||||
Tcl_AppendResult(interp, "can't create directory \"",
|
||||
TclGetString(errfile), "\": ", Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create directory \"%s\": %s",
|
||||
TclGetString(errfile), Tcl_PosixError(interp)));
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if (split != NULL) {
|
||||
@@ -384,9 +380,9 @@ TclFileDeleteCmd(
|
||||
result = Tcl_FSRemoveDirectory(objv[i], force, &errorBuffer);
|
||||
if (result != TCL_OK) {
|
||||
if ((force == 0) && (errno == EEXIST)) {
|
||||
Tcl_AppendResult(interp, "error deleting \"",
|
||||
TclGetString(objv[i]), "\": directory not empty",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error deleting \"%s\": directory not empty",
|
||||
TclGetString(objv[i])));
|
||||
Tcl_PosixError(interp);
|
||||
goto done;
|
||||
}
|
||||
@@ -426,12 +422,13 @@ TclFileDeleteCmd(
|
||||
* We try to accomodate poor error results from our Tcl_FS calls.
|
||||
*/
|
||||
|
||||
Tcl_AppendResult(interp, "error deleting unknown file: ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error deleting unknown file: %s",
|
||||
Tcl_PosixError(interp)));
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "error deleting \"",
|
||||
TclGetString(errfile), "\": ", Tcl_PosixError(interp),
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error deleting \"%s\": %s",
|
||||
TclGetString(errfile), Tcl_PosixError(interp)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -540,17 +537,17 @@ CopyRenameOneFile(
|
||||
if (S_ISDIR(sourceStatBuf.st_mode)
|
||||
&& !S_ISDIR(targetStatBuf.st_mode)) {
|
||||
errno = EISDIR;
|
||||
Tcl_AppendResult(interp, "can't overwrite file \"",
|
||||
TclGetString(target), "\" with directory \"",
|
||||
TclGetString(source), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't overwrite file \"%s\" with directory \"%s\"",
|
||||
TclGetString(target), TclGetString(source)));
|
||||
goto done;
|
||||
}
|
||||
if (!S_ISDIR(sourceStatBuf.st_mode)
|
||||
&& S_ISDIR(targetStatBuf.st_mode)) {
|
||||
errno = EISDIR;
|
||||
Tcl_AppendResult(interp, "can't overwrite directory \"",
|
||||
TclGetString(target), "\" with file \"",
|
||||
TclGetString(source), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't overwrite directory \"%s\" with file \"%s\"",
|
||||
TclGetString(target), TclGetString(source)));
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -581,10 +578,10 @@ CopyRenameOneFile(
|
||||
}
|
||||
|
||||
if (errno == EINVAL) {
|
||||
Tcl_AppendResult(interp, "error renaming \"",
|
||||
TclGetString(source), "\" to \"", TclGetString(target),
|
||||
"\": trying to rename a volume or "
|
||||
"move a directory into itself", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error renaming \"%s\" to \"%s\": trying to rename a"
|
||||
" volume or move a directory into itself",
|
||||
TclGetString(source), TclGetString(target)));
|
||||
goto done;
|
||||
} else if (errno != EXDEV) {
|
||||
errfile = target;
|
||||
@@ -628,8 +625,9 @@ CopyRenameOneFile(
|
||||
* Actual file doesn't exist.
|
||||
*/
|
||||
|
||||
Tcl_AppendResult(interp, "error copying \"", TclGetString(source),
|
||||
"\": the target of this link doesn't exist", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error copying \"%s\": the target of this link doesn't"
|
||||
" exist", TclGetString(source)));
|
||||
goto done;
|
||||
} else {
|
||||
int counter = 0;
|
||||
@@ -764,23 +762,27 @@ CopyRenameOneFile(
|
||||
}
|
||||
}
|
||||
if (result != TCL_OK) {
|
||||
Tcl_AppendResult(interp, "can't unlink \"", TclGetString(errfile),
|
||||
"\": ", Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't unlink \"%s\": %s",
|
||||
TclGetString(errfile), Tcl_PosixError(interp)));
|
||||
errfile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (errfile != NULL) {
|
||||
Tcl_AppendResult(interp, "error ", (copyFlag ? "copying" : "renaming"),
|
||||
" \"", TclGetString(source), NULL);
|
||||
Tcl_Obj *errorMsg = Tcl_ObjPrintf("error %s \"%s\"",
|
||||
(copyFlag ? "copying" : "renaming"), TclGetString(source));
|
||||
|
||||
if (errfile != source) {
|
||||
Tcl_AppendResult(interp, "\" to \"", TclGetString(target), NULL);
|
||||
Tcl_AppendPrintfToObj(errorMsg, " to \"%s\"",
|
||||
TclGetString(target));
|
||||
if (errfile != target) {
|
||||
Tcl_AppendResult(interp, "\": \"", TclGetString(errfile),NULL);
|
||||
Tcl_AppendPrintfToObj(errorMsg, ": \"%s\"",
|
||||
TclGetString(errfile));
|
||||
}
|
||||
}
|
||||
Tcl_AppendResult(interp, "\": ", Tcl_PosixError(interp), NULL);
|
||||
Tcl_AppendPrintfToObj(errorMsg, ": %s", Tcl_PosixError(interp));
|
||||
Tcl_SetObjResult(interp, errorMsg);
|
||||
}
|
||||
if (errorBuffer != NULL) {
|
||||
Tcl_DecrRefCount(errorBuffer);
|
||||
@@ -983,9 +985,10 @@ TclFileAttrsCmd(
|
||||
* There was an error, probably that the filePtr is not
|
||||
* accepted by any filesystem
|
||||
*/
|
||||
Tcl_AppendResult(interp, "could not read \"",
|
||||
TclGetString(filePtr), "\": ", Tcl_PosixError(interp),
|
||||
NULL);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not read \"%s\": %s",
|
||||
TclGetString(filePtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1071,9 +1074,9 @@ TclFileAttrsCmd(
|
||||
Tcl_Obj *objPtr = NULL;
|
||||
|
||||
if (numObjStrings == 0) {
|
||||
Tcl_AppendResult(interp, "bad option \"", TclGetString(objv[0]),
|
||||
"\", there are no file attributes in this filesystem.",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\", there are no file attributes in this"
|
||||
" filesystem", TclGetString(objv[0])));
|
||||
Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL);
|
||||
goto end;
|
||||
}
|
||||
@@ -1098,9 +1101,9 @@ TclFileAttrsCmd(
|
||||
int i, index;
|
||||
|
||||
if (numObjStrings == 0) {
|
||||
Tcl_AppendResult(interp, "bad option \"", TclGetString(objv[0]),
|
||||
"\", there are no file attributes in this filesystem.",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad option \"%s\", there are no file attributes in this"
|
||||
" filesystem", TclGetString(objv[0])));
|
||||
Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL);
|
||||
goto end;
|
||||
}
|
||||
@@ -1114,8 +1117,8 @@ TclFileAttrsCmd(
|
||||
TclFreeIntRep(objv[i]);
|
||||
}
|
||||
if (i + 1 == objc) {
|
||||
Tcl_AppendResult(interp, "value for \"",
|
||||
TclGetString(objv[i]), "\" missing", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"value for \"%s\" missing", TclGetString(objv[i])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FATTR",
|
||||
"NOVALUE", NULL);
|
||||
goto end;
|
||||
@@ -1224,9 +1227,9 @@ TclFileLinkCmd(
|
||||
*/
|
||||
|
||||
if (errno == EEXIST) {
|
||||
Tcl_AppendResult(interp, "could not create new link \"",
|
||||
TclGetString(objv[index]),
|
||||
"\": that path already exists", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not create new link \"%s\": that path already"
|
||||
" exists", TclGetString(objv[index])));
|
||||
Tcl_PosixError(interp);
|
||||
} else if (errno == ENOENT) {
|
||||
/*
|
||||
@@ -1244,23 +1247,23 @@ TclFileLinkCmd(
|
||||
access = Tcl_FSAccess(dirPtr, F_OK);
|
||||
Tcl_DecrRefCount(dirPtr);
|
||||
if (access != 0) {
|
||||
Tcl_AppendResult(interp, "could not create new link \"",
|
||||
TclGetString(objv[index]),
|
||||
"\": no such file or directory", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not create new link \"%s\": no such file"
|
||||
" or directory", TclGetString(objv[index])));
|
||||
Tcl_PosixError(interp);
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "could not create new link \"",
|
||||
TclGetString(objv[index]), "\": target \"",
|
||||
TclGetString(objv[index+1]), "\" doesn't exist",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not create new link \"%s\": target \"%s\" "
|
||||
"doesn't exist", TclGetString(objv[index]),
|
||||
TclGetString(objv[index+1])));
|
||||
errno = ENOENT;
|
||||
Tcl_PosixError(interp);
|
||||
}
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "could not create new link \"",
|
||||
TclGetString(objv[index]), "\" pointing to \"",
|
||||
TclGetString(objv[index+1]), "\": ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not create new link \"%s\" pointing to \"%s\": %s",
|
||||
TclGetString(objv[index]),
|
||||
TclGetString(objv[index+1]), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1275,9 +1278,9 @@ TclFileLinkCmd(
|
||||
|
||||
contents = Tcl_FSLink(objv[index], NULL, 0);
|
||||
if (contents == NULL) {
|
||||
Tcl_AppendResult(interp, "could not read link \"",
|
||||
TclGetString(objv[index]), "\": ", Tcl_PosixError(interp),
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not read link \"%s\": %s",
|
||||
TclGetString(objv[index]), Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
@@ -1332,8 +1335,9 @@ TclFileReadLinkCmd(
|
||||
contents = Tcl_FSLink(objv[1], NULL, 0);
|
||||
|
||||
if (contents == NULL) {
|
||||
Tcl_AppendResult(interp, "could not readlink \"",
|
||||
TclGetString(objv[1]), "\": ", Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not read link \"%s\": %s",
|
||||
TclGetString(objv[1]), Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, contents);
|
||||
@@ -1487,8 +1491,8 @@ TclFileTemporaryCmd(
|
||||
if (nameVarObj) {
|
||||
TclDecrRefCount(nameObj);
|
||||
}
|
||||
Tcl_AppendResult(interp, "can't create temporary file: ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create temporary file: %s", Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_RegisterChannel(interp, chan);
|
||||
@@ -1499,7 +1503,7 @@ TclFileTemporaryCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_AppendResult(interp, Tcl_GetChannelName(chan), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
+100
-86
@@ -72,9 +72,9 @@ SetResultLength(
|
||||
{
|
||||
Tcl_DStringSetLength(resultPtr, offset);
|
||||
if (extended == 2) {
|
||||
Tcl_DStringAppend(resultPtr, "//?/UNC/", 8);
|
||||
TclDStringAppendLiteral(resultPtr, "//?/UNC/");
|
||||
} else if (extended == 1) {
|
||||
Tcl_DStringAppend(resultPtr, "//?/", 4);
|
||||
TclDStringAppendLiteral(resultPtr, "//?/");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ ExtractWinRoot(
|
||||
if (path[1] != '/' && path[1] != '\\') {
|
||||
SetResultLength(resultPtr, offset, extended);
|
||||
*typePtr = TCL_PATH_VOLUME_RELATIVE;
|
||||
Tcl_DStringAppend(resultPtr, "/", 1);
|
||||
TclDStringAppendLiteral(resultPtr, "/");
|
||||
return &path[1];
|
||||
}
|
||||
host = &path[2];
|
||||
@@ -161,7 +161,7 @@ ExtractWinRoot(
|
||||
*/
|
||||
|
||||
*typePtr = TCL_PATH_VOLUME_RELATIVE;
|
||||
Tcl_DStringAppend(resultPtr, "/", 1);
|
||||
TclDStringAppendLiteral(resultPtr, "/");
|
||||
return &path[2];
|
||||
}
|
||||
SetResultLength(resultPtr, offset, extended);
|
||||
@@ -180,9 +180,9 @@ ExtractWinRoot(
|
||||
break;
|
||||
}
|
||||
}
|
||||
Tcl_DStringAppend(resultPtr, "//", 2);
|
||||
TclDStringAppendLiteral(resultPtr, "//");
|
||||
Tcl_DStringAppend(resultPtr, host, hlen);
|
||||
Tcl_DStringAppend(resultPtr, "/", 1);
|
||||
TclDStringAppendLiteral(resultPtr, "/");
|
||||
Tcl_DStringAppend(resultPtr, share, slen);
|
||||
|
||||
tail = &share[slen];
|
||||
@@ -221,7 +221,7 @@ ExtractWinRoot(
|
||||
|
||||
*typePtr = TCL_PATH_ABSOLUTE;
|
||||
Tcl_DStringAppend(resultPtr, path, 2);
|
||||
Tcl_DStringAppend(resultPtr, "/", 1);
|
||||
TclDStringAppendLiteral(resultPtr, "/");
|
||||
|
||||
return tail;
|
||||
}
|
||||
@@ -411,25 +411,36 @@ TclpGetNativePathType(
|
||||
* Paths that begin with / are absolute.
|
||||
*/
|
||||
|
||||
#ifdef __QNX__
|
||||
/*
|
||||
* Check for QNX //<node id> prefix
|
||||
*/
|
||||
if (*path && (pathLen > 3) && (path[0] == '/')
|
||||
&& (path[1] == '/') && isdigit(UCHAR(path[2]))) {
|
||||
path += 3;
|
||||
while (isdigit(UCHAR(*path))) {
|
||||
path++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (path[0] == '/') {
|
||||
++path;
|
||||
#if defined(__CYGWIN__) || defined(__QNX__)
|
||||
/*
|
||||
* Check for "//" network path prefix
|
||||
*/
|
||||
if ((*path == '/') && path[1] && (path[1] != '/')) {
|
||||
path += 2;
|
||||
while (*path && *path != '/') {
|
||||
++path;
|
||||
}
|
||||
#if defined(__CYGWIN__)
|
||||
/* UNC paths need to be followed by a share name */
|
||||
if (*path++ && (*path && *path != '/')) {
|
||||
++path;
|
||||
while (*path && *path != '/') {
|
||||
++path;
|
||||
}
|
||||
} else {
|
||||
path = origPath + 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
if (driveNameLengthPtr != NULL) {
|
||||
/*
|
||||
* We need this addition in case the QNX code was used.
|
||||
* We need this addition in case the QNX or Cygwin code was used.
|
||||
*/
|
||||
|
||||
*driveNameLengthPtr = (1 + path - origPath);
|
||||
*driveNameLengthPtr = (path - origPath);
|
||||
}
|
||||
} else {
|
||||
type = TCL_PATH_RELATIVE;
|
||||
@@ -632,32 +643,43 @@ SplitUnixPath(
|
||||
const char *path) /* Pointer to string containing a path. */
|
||||
{
|
||||
int length;
|
||||
const char *p, *elementStart;
|
||||
const char *origPath = path, *elementStart;
|
||||
Tcl_Obj *result = Tcl_NewObj();
|
||||
|
||||
/*
|
||||
* Deal with the root directory as a special case.
|
||||
*/
|
||||
|
||||
#ifdef __QNX__
|
||||
/*
|
||||
* Check for QNX //<node id> prefix
|
||||
*/
|
||||
|
||||
if ((path[0] == '/') && (path[1] == '/')
|
||||
&& isdigit(UCHAR(path[2]))) { /* INTL: digit */
|
||||
path += 3;
|
||||
while (isdigit(UCHAR(*path))) { /* INTL: digit */
|
||||
path++;
|
||||
}
|
||||
}
|
||||
if (*path == '/') {
|
||||
Tcl_Obj *rootElt;
|
||||
++path;
|
||||
#if defined(__CYGWIN__) || defined(__QNX__)
|
||||
/*
|
||||
* Check for "//" network path prefix
|
||||
*/
|
||||
if ((*path == '/') && path[1] && (path[1] != '/')) {
|
||||
path += 2;
|
||||
while (*path && *path != '/') {
|
||||
++path;
|
||||
}
|
||||
#if defined(__CYGWIN__)
|
||||
/* UNC paths need to be followed by a share name */
|
||||
if (*path++ && (*path && *path != '/')) {
|
||||
++path;
|
||||
while (*path && *path != '/') {
|
||||
++path;
|
||||
}
|
||||
} else {
|
||||
path = origPath + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (path[0] == '/') {
|
||||
Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("/",1));
|
||||
p = path+1;
|
||||
} else {
|
||||
p = path;
|
||||
}
|
||||
#endif
|
||||
rootElt = Tcl_NewStringObj(origPath, path - origPath);
|
||||
Tcl_ListObjAppendElement(NULL, result, rootElt);
|
||||
while (*path == '/') {
|
||||
++path;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -666,14 +688,14 @@ SplitUnixPath(
|
||||
*/
|
||||
|
||||
for (;;) {
|
||||
elementStart = p;
|
||||
while ((*p != '\0') && (*p != '/')) {
|
||||
p++;
|
||||
elementStart = path;
|
||||
while ((*path != '\0') && (*path != '/')) {
|
||||
path++;
|
||||
}
|
||||
length = p - elementStart;
|
||||
length = path - elementStart;
|
||||
if (length > 0) {
|
||||
Tcl_Obj *nextElt;
|
||||
if ((elementStart[0] == '~') && (elementStart != path)) {
|
||||
if ((elementStart[0] == '~') && (elementStart != origPath)) {
|
||||
TclNewLiteralStringObj(nextElt, "./");
|
||||
Tcl_AppendToObj(nextElt, elementStart, length);
|
||||
} else {
|
||||
@@ -681,7 +703,7 @@ SplitUnixPath(
|
||||
}
|
||||
Tcl_ListObjAppendElement(NULL, result, nextElt);
|
||||
}
|
||||
if (*p++ == '\0') {
|
||||
if (*path++ == '\0') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1040,7 +1062,7 @@ Tcl_TranslateFileName(
|
||||
}
|
||||
|
||||
Tcl_DStringInit(bufferPtr);
|
||||
Tcl_DStringAppend(bufferPtr, Tcl_GetString(transPtr), -1);
|
||||
TclDStringAppendObj(bufferPtr, transPtr);
|
||||
Tcl_DecrRefCount(path);
|
||||
Tcl_DecrRefCount(transPtr);
|
||||
|
||||
@@ -1157,9 +1179,10 @@ DoTildeSubst(
|
||||
dir = TclGetEnv("HOME", &dirString);
|
||||
if (dir == NULL) {
|
||||
if (interp) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "couldn't find HOME environment "
|
||||
"variable to expand path", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"couldn't find HOME environment "
|
||||
"variable to expand path", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "FILENAME", "NO_HOME", NULL);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1168,8 +1191,9 @@ DoTildeSubst(
|
||||
} else if (TclpGetUserHome(user, resultPtr) == NULL) {
|
||||
if (interp) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "user \"", user, "\" doesn't exist",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"user \"%s\" doesn't exist", user));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "USER", user, NULL);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1312,9 +1336,9 @@ Tcl_GlobObjCmd(
|
||||
|
||||
endOfForLoop:
|
||||
if ((globFlags & TCL_GLOBMODE_TAILS) && (pathOrDir == NULL)) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"\"-tails\" must be used with either "
|
||||
"\"-directory\" or \"-path\"", NULL);
|
||||
"\"-directory\" or \"-path\"", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB",
|
||||
"BADOPTIONCOMBINATION", NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -1396,7 +1420,7 @@ Tcl_GlobObjCmd(
|
||||
search = Tcl_DStringValue(&pref);
|
||||
while ((find = (strpbrk(search, "\\[]*?{}"))) != NULL) {
|
||||
Tcl_DStringAppend(&prefix, search, find-search);
|
||||
Tcl_DStringAppend(&prefix, "\\", 1);
|
||||
TclDStringAppendLiteral(&prefix, "\\");
|
||||
Tcl_DStringAppend(&prefix, find, 1);
|
||||
search = find+1;
|
||||
if (*search == '\0') {
|
||||
@@ -1558,8 +1582,7 @@ Tcl_GlobObjCmd(
|
||||
Tcl_DStringInit(&prefix);
|
||||
}
|
||||
for (i = 0; i < objc; i++) {
|
||||
string = Tcl_GetStringFromObj(objv[i], &length);
|
||||
Tcl_DStringAppend(&prefix, string, length);
|
||||
TclDStringAppendObj(&prefix, objv[i]);
|
||||
if (i != objc -1) {
|
||||
Tcl_DStringAppend(&prefix, separators, 1);
|
||||
}
|
||||
@@ -1575,11 +1598,9 @@ Tcl_GlobObjCmd(
|
||||
for (i = 0; i < objc; i++) {
|
||||
Tcl_DStringInit(&str);
|
||||
if (dir == PATH_GENERAL) {
|
||||
Tcl_DStringAppend(&str, Tcl_DStringValue(&prefix),
|
||||
Tcl_DStringLength(&prefix));
|
||||
TclDStringAppendDString(&str, &prefix);
|
||||
}
|
||||
string = Tcl_GetStringFromObj(objv[i], &length);
|
||||
Tcl_DStringAppend(&str, string, length);
|
||||
TclDStringAppendObj(&str, objv[i]);
|
||||
if (TclGlob(interp, Tcl_DStringValue(&str), pathOrDir, globFlags,
|
||||
globTypes) != TCL_OK) {
|
||||
result = TCL_ERROR;
|
||||
@@ -1611,20 +1632,23 @@ Tcl_GlobObjCmd(
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
Tcl_AppendResult(interp, "no files matched glob pattern",
|
||||
(join || (objc == 1)) ? " \"" : "s \"", NULL);
|
||||
Tcl_Obj *errorMsg =
|
||||
Tcl_ObjPrintf("no files matched glob pattern%s \"",
|
||||
(join || (objc == 1)) ? "" : "s");
|
||||
|
||||
if (join) {
|
||||
Tcl_AppendResult(interp, Tcl_DStringValue(&prefix), NULL);
|
||||
Tcl_AppendToObj(errorMsg, Tcl_DStringValue(&prefix), -1);
|
||||
} else {
|
||||
const char *sep = "";
|
||||
|
||||
for (i = 0; i < objc; i++) {
|
||||
string = Tcl_GetString(objv[i]);
|
||||
Tcl_AppendResult(interp, sep, string, NULL);
|
||||
Tcl_AppendPrintfToObj(errorMsg, "%s%s",
|
||||
sep, Tcl_GetString(objv[i]));
|
||||
sep = " ";
|
||||
}
|
||||
}
|
||||
Tcl_AppendResult(interp, "\"", NULL);
|
||||
Tcl_AppendToObj(errorMsg, "\"", -1);
|
||||
Tcl_SetObjResult(interp, errorMsg);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "NOMATCH",
|
||||
NULL);
|
||||
result = TCL_ERROR;
|
||||
@@ -1755,6 +1779,7 @@ TclGlob(
|
||||
if (c != '\0') {
|
||||
tail++;
|
||||
}
|
||||
Tcl_DStringFree(&buffer);
|
||||
} else {
|
||||
tail = pattern;
|
||||
}
|
||||
@@ -2192,15 +2217,15 @@ DoGlob(
|
||||
closeBrace = p;
|
||||
break;
|
||||
}
|
||||
Tcl_SetResult(interp, "unmatched open-brace in file name",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unmatched open-brace in file name", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
|
||||
} else if (*p == '}') {
|
||||
Tcl_SetResult(interp, "unmatched close-brace in file name",
|
||||
TCL_STATIC);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unmatched close-brace in file name", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE",
|
||||
NULL);
|
||||
return TCL_ERROR;
|
||||
@@ -2384,9 +2409,9 @@ DoGlob(
|
||||
if (length == 0 && (Tcl_DStringLength(&append) == 0)) {
|
||||
if (((*name == '\\') && (name[1] == '/' ||
|
||||
name[1] == '\\')) || (*name == '/')) {
|
||||
Tcl_DStringAppend(&append, "/", 1);
|
||||
TclDStringAppendLiteral(&append, "/");
|
||||
} else {
|
||||
Tcl_DStringAppend(&append, ".", 1);
|
||||
TclDStringAppendLiteral(&append, ".");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2395,22 +2420,11 @@ DoGlob(
|
||||
case TCL_PLATFORM_UNIX:
|
||||
if (length == 0 && (Tcl_DStringLength(&append) == 0)) {
|
||||
if ((*name == '\\' && name[1] == '/') || (*name == '/')) {
|
||||
Tcl_DStringAppend(&append, "/", 1);
|
||||
TclDStringAppendLiteral(&append, "/");
|
||||
} else {
|
||||
Tcl_DStringAppend(&append, ".", 1);
|
||||
TclDStringAppendLiteral(&append, ".");
|
||||
}
|
||||
}
|
||||
#if defined(__CYGWIN__) && !defined(__WIN32__)
|
||||
{
|
||||
DLLIMPORT extern int cygwin_conv_to_posix_path(const char *,
|
||||
char *);
|
||||
char winbuf[MAXPATHLEN+1];
|
||||
|
||||
cygwin_conv_to_posix_path(Tcl_DStringValue(&append), winbuf);
|
||||
Tcl_DStringFree(&append);
|
||||
Tcl_DStringAppend(&append, winbuf, -1);
|
||||
}
|
||||
#endif /* __CYGWIN__ && __WIN32__ */
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+4
-51
@@ -15,45 +15,6 @@
|
||||
|
||||
#include "tcl.h"
|
||||
|
||||
/*
|
||||
* struct FilesystemRecord --
|
||||
*
|
||||
* A filesystem record is used to keep track of each filesystem currently
|
||||
* registered with the core, in a linked list. Pointers to these structures
|
||||
* are also kept by each "path" Tcl_Obj, and we must retain a refCount on the
|
||||
* number of such references.
|
||||
*/
|
||||
|
||||
typedef struct FilesystemRecord {
|
||||
ClientData clientData; /* Client specific data for the new filesystem
|
||||
* (can be NULL) */
|
||||
const Tcl_Filesystem *fsPtr; /* Pointer to filesystem dispatch table. */
|
||||
int fileRefCount; /* How many Tcl_Obj's use this filesystem. */
|
||||
struct FilesystemRecord *nextPtr;
|
||||
/* The next filesystem registered to Tcl, or
|
||||
* NULL if no more. */
|
||||
struct FilesystemRecord *prevPtr;
|
||||
/* The previous filesystem registered to Tcl,
|
||||
* or NULL if no more. */
|
||||
} FilesystemRecord;
|
||||
|
||||
/*
|
||||
* This structure holds per-thread private copy of the current directory
|
||||
* maintained by the global cwdPathPtr. This structure holds per-thread
|
||||
* private copies of some global data. This way we avoid most of the
|
||||
* synchronization calls which boosts performance, at cost of having to update
|
||||
* this information each time the corresponding epoch counter changes.
|
||||
*/
|
||||
|
||||
typedef struct ThreadSpecificData {
|
||||
int initialized;
|
||||
int cwdPathEpoch;
|
||||
int filesystemEpoch;
|
||||
Tcl_Obj *cwdPathPtr;
|
||||
ClientData cwdClientData;
|
||||
FilesystemRecord *filesystemList;
|
||||
} ThreadSpecificData;
|
||||
|
||||
/*
|
||||
* The internal TclFS API provides routines for handling and manipulating
|
||||
* paths efficiently, taking direct advantage of the "path" Tcl_Obj type.
|
||||
@@ -62,31 +23,23 @@ typedef struct ThreadSpecificData {
|
||||
*/
|
||||
|
||||
MODULE_SCOPE int TclFSCwdPointerEquals(Tcl_Obj **pathPtrPtr);
|
||||
MODULE_SCOPE int TclFSMakePathFromNormalized(Tcl_Interp *interp,
|
||||
Tcl_Obj *pathPtr, ClientData clientData);
|
||||
MODULE_SCOPE int TclFSNormalizeToUniquePath(Tcl_Interp *interp,
|
||||
Tcl_Obj *pathPtr, int startAt,
|
||||
ClientData *clientDataPtr);
|
||||
Tcl_Obj *pathPtr, int startAt);
|
||||
MODULE_SCOPE Tcl_Obj * TclFSMakePathRelative(Tcl_Interp *interp,
|
||||
Tcl_Obj *pathPtr, Tcl_Obj *cwdPtr);
|
||||
MODULE_SCOPE Tcl_Obj * TclFSInternalToNormalized(
|
||||
const Tcl_Filesystem *fromFilesystem,
|
||||
ClientData clientData,
|
||||
FilesystemRecord **fsRecPtrPtr);
|
||||
MODULE_SCOPE int TclFSEnsureEpochOk(Tcl_Obj *pathPtr,
|
||||
const Tcl_Filesystem **fsPtrPtr);
|
||||
MODULE_SCOPE void TclFSSetPathDetails(Tcl_Obj *pathPtr,
|
||||
FilesystemRecord *fsRecPtr,
|
||||
ClientData clientData);
|
||||
const Tcl_Filesystem *fsPtr, ClientData clientData);
|
||||
MODULE_SCOPE Tcl_Obj * TclFSNormalizeAbsolutePath(Tcl_Interp *interp,
|
||||
Tcl_Obj *pathPtr, ClientData *clientDataPtr);
|
||||
Tcl_Obj *pathPtr);
|
||||
MODULE_SCOPE int TclFSEpoch(void);
|
||||
|
||||
/*
|
||||
* Private shared variables for use by tclIOUtil.c and tclPathObj.c
|
||||
*/
|
||||
|
||||
MODULE_SCOPE const Tcl_Filesystem tclNativeFilesystem;
|
||||
MODULE_SCOPE Tcl_ThreadDataKey tclFsDataKey;
|
||||
|
||||
/*
|
||||
* Private shared functions for use by tclIOUtil.c, tclPathObj.c and
|
||||
|
||||
+86
-68
@@ -427,7 +427,10 @@ TclFinalizeIOSubsystem(void)
|
||||
statePtr != NULL;
|
||||
statePtr = statePtr->nextCSPtr) {
|
||||
chanPtr = statePtr->topChanPtr;
|
||||
if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED | CHANNEL_DEAD)
|
||||
if (GotFlag(statePtr, CHANNEL_DEAD)) {
|
||||
continue;
|
||||
}
|
||||
if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED )
|
||||
|| GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
|
||||
ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
|
||||
active = 1;
|
||||
@@ -876,19 +879,25 @@ CheckForStdChannelsBeingClosed(
|
||||
ChannelState *statePtr = ((Channel *) chan)->state;
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
if ((chan == tsdPtr->stdinChannel) && tsdPtr->stdinInitialized) {
|
||||
if (tsdPtr->stdinInitialized
|
||||
&& tsdPtr->stdinChannel != NULL
|
||||
&& statePtr == ((Channel *)tsdPtr->stdinChannel)->state) {
|
||||
if (statePtr->refCount < 2) {
|
||||
statePtr->refCount = 0;
|
||||
tsdPtr->stdinChannel = NULL;
|
||||
return;
|
||||
}
|
||||
} else if ((chan == tsdPtr->stdoutChannel) && tsdPtr->stdoutInitialized) {
|
||||
} else if (tsdPtr->stdoutInitialized
|
||||
&& tsdPtr->stdoutChannel != NULL
|
||||
&& statePtr == ((Channel *)tsdPtr->stdoutChannel)->state) {
|
||||
if (statePtr->refCount < 2) {
|
||||
statePtr->refCount = 0;
|
||||
tsdPtr->stdoutChannel = NULL;
|
||||
return;
|
||||
}
|
||||
} else if ((chan == tsdPtr->stderrChannel) && tsdPtr->stderrInitialized) {
|
||||
} else if (tsdPtr->stderrInitialized
|
||||
&& tsdPtr->stderrChannel != NULL
|
||||
&& statePtr == ((Channel *)tsdPtr->stderrChannel)->state) {
|
||||
if (statePtr->refCount < 2) {
|
||||
statePtr->refCount = 0;
|
||||
tsdPtr->stderrChannel = NULL;
|
||||
@@ -1024,8 +1033,9 @@ Tcl_UnregisterChannel(
|
||||
|
||||
if (GotFlag(statePtr, CHANNEL_INCLOSE)) {
|
||||
if (interp != NULL) {
|
||||
Tcl_AppendResult(interp, "Illegal recursive call to close "
|
||||
"through close-handler of channel", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"illegal recursive call to close through close-handler"
|
||||
" of channel", -1));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1260,8 +1270,8 @@ Tcl_GetChannel(
|
||||
hTblPtr = GetChannelTable(interp);
|
||||
hPtr = Tcl_FindHashEntry(hTblPtr, name);
|
||||
if (hPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "can not find channel named \"", chanName,
|
||||
"\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can not find channel named \"%s\"", chanName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanName, NULL);
|
||||
return NULL;
|
||||
}
|
||||
@@ -1581,8 +1591,9 @@ Tcl_StackChannel(
|
||||
|
||||
if (statePtr == NULL) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "couldn't find state for channel \"",
|
||||
Tcl_GetChannelName(prevChan), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"couldn't find state for channel \"%s\"",
|
||||
Tcl_GetChannelName(prevChan)));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1602,9 +1613,9 @@ Tcl_StackChannel(
|
||||
|
||||
if ((mask & (statePtr->flags & (TCL_READABLE | TCL_WRITABLE))) == 0) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp,
|
||||
"reading and writing both disallowed for channel \"",
|
||||
Tcl_GetChannelName(prevChan), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"reading and writing both disallowed for channel \"%s\"",
|
||||
Tcl_GetChannelName(prevChan)));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1627,8 +1638,9 @@ Tcl_StackChannel(
|
||||
statePtr->csPtrR = csPtrR;
|
||||
statePtr->csPtrW = csPtrW;
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "could not flush channel \"",
|
||||
Tcl_GetChannelName(prevChan), "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not flush channel \"%s\"",
|
||||
Tcl_GetChannelName(prevChan)));
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -1781,9 +1793,9 @@ Tcl_UnstackChannel(
|
||||
*/
|
||||
|
||||
if (!TclChanCaughtErrorBypass(interp, chan) && interp) {
|
||||
Tcl_AppendResult(interp, "could not flush channel \"",
|
||||
Tcl_GetChannelName((Tcl_Channel) chanPtr), "\"",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not flush channel \"%s\"",
|
||||
Tcl_GetChannelName((Tcl_Channel) chanPtr)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2315,8 +2327,8 @@ CheckForDeadChannel(
|
||||
|
||||
Tcl_SetErrno(EINVAL);
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "unable to access channel: invalid channel",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unable to access channel: invalid channel", -1));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -2460,7 +2472,7 @@ FlushChannel(
|
||||
* it's a tty channel (dup'ed underneath)
|
||||
*/
|
||||
|
||||
if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
|
||||
if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED) && !TclInExit()) {
|
||||
SetFlag(statePtr, BG_FLUSH_SCHEDULED);
|
||||
UpdateInterest(chanPtr);
|
||||
}
|
||||
@@ -3048,8 +3060,9 @@ Tcl_Close(
|
||||
|
||||
if (GotFlag(statePtr, CHANNEL_INCLOSE)) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "Illegal recursive call to close "
|
||||
"through close-handler of channel", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"illegal recursive call to close through close-handler"
|
||||
" of channel", -1));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -3207,8 +3220,9 @@ Tcl_CloseEx(
|
||||
*/
|
||||
|
||||
if (!chanPtr->typePtr->close2Proc) {
|
||||
Tcl_AppendResult(interp, "Half-close of channels not supported by ",
|
||||
chanPtr->typePtr->typeName, "s", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"half-close of channels not supported by %ss",
|
||||
chanPtr->typePtr->typeName));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3217,9 +3231,8 @@ Tcl_CloseEx(
|
||||
*/
|
||||
|
||||
if (chanPtr != statePtr->topChanPtr) {
|
||||
Tcl_AppendResult(interp,
|
||||
"Half-close not applicable to stack of transformations",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"half-close not applicable to stack of transformations", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3237,9 +3250,9 @@ Tcl_CloseEx(
|
||||
} else {
|
||||
msg = "write";
|
||||
}
|
||||
Tcl_AppendResult(interp, "Half-close of ", msg,
|
||||
"-side not possible, side not opened or already closed",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"Half-close of %s-side not possible, side not opened or"
|
||||
" already closed", msg));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -3250,8 +3263,9 @@ Tcl_CloseEx(
|
||||
|
||||
if (statePtr->flags & CHANNEL_INCLOSE) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "Illegal recursive call to close "
|
||||
"through close-handler of channel", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"illegal recursive call to close through close-handler"
|
||||
" of channel", -1));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -4431,14 +4445,12 @@ Tcl_Gets(
|
||||
* for managing the storage. */
|
||||
{
|
||||
Tcl_Obj *objPtr;
|
||||
int charsStored, length;
|
||||
const char *string;
|
||||
int charsStored;
|
||||
|
||||
TclNewObj(objPtr);
|
||||
charsStored = Tcl_GetsObj(chan, objPtr);
|
||||
if (charsStored > 0) {
|
||||
string = TclGetStringFromObj(objPtr, &length);
|
||||
Tcl_DStringAppend(lineRead, string, length);
|
||||
TclDStringAppendObj(lineRead, objPtr);
|
||||
}
|
||||
TclDecrRefCount(objPtr);
|
||||
return charsStored;
|
||||
@@ -7546,11 +7558,12 @@ Tcl_BadChannelOption(
|
||||
const char **argv;
|
||||
int argc, i;
|
||||
Tcl_DString ds;
|
||||
Tcl_Obj *errObj;
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
Tcl_DStringAppend(&ds, genericopt, -1);
|
||||
if (optionList && (*optionList)) {
|
||||
Tcl_DStringAppend(&ds, " ", 1);
|
||||
TclDStringAppendLiteral(&ds, " ");
|
||||
Tcl_DStringAppend(&ds, optionList, -1);
|
||||
}
|
||||
if (Tcl_SplitList(interp, Tcl_DStringValue(&ds),
|
||||
@@ -7558,13 +7571,14 @@ Tcl_BadChannelOption(
|
||||
Tcl_Panic("malformed option list in channel driver");
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "bad option \"", optionName,
|
||||
"\": should be one of ", NULL);
|
||||
errObj = Tcl_ObjPrintf("bad option \"%s\": should be one of ",
|
||||
optionName);
|
||||
argc--;
|
||||
for (i = 0; i < argc; i++) {
|
||||
Tcl_AppendResult(interp, "-", argv[i], ", ", NULL);
|
||||
Tcl_AppendPrintfToObj(errObj, "-%s, ", argv[i]);
|
||||
}
|
||||
Tcl_AppendResult(interp, "or -", argv[i], NULL);
|
||||
Tcl_AppendPrintfToObj(errObj, "or -%s", argv[i]);
|
||||
Tcl_SetObjResult(interp, errObj);
|
||||
Tcl_DStringFree(&ds);
|
||||
ckfree(argv);
|
||||
}
|
||||
@@ -7842,8 +7856,9 @@ Tcl_SetChannelOption(
|
||||
|
||||
if (statePtr->csPtrR || statePtr->csPtrW) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "unable to set channel options: "
|
||||
"background copy in progress", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unable to set channel options: background copy in"
|
||||
" progress", -1));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -7892,8 +7907,9 @@ Tcl_SetChannelOption(
|
||||
ResetFlag(statePtr, CHANNEL_LINEBUFFERED);
|
||||
SetFlag(statePtr, CHANNEL_UNBUFFERED);
|
||||
} else if (interp) {
|
||||
Tcl_AppendResult(interp, "bad value for -buffering: "
|
||||
"must be one of full, line, or none", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"bad value for -buffering: must be one of"
|
||||
" full, line, or none", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
return TCL_OK;
|
||||
@@ -7948,8 +7964,9 @@ Tcl_SetChannelOption(
|
||||
|
||||
if (inValue & 0x80 || outValue & 0x80) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "bad value for -eofchar: ",
|
||||
"must be non-NUL ASCII character", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"bad value for -eofchar: must be non-NUL ASCII"
|
||||
" character", -1));
|
||||
}
|
||||
ckfree(argv);
|
||||
return TCL_ERROR;
|
||||
@@ -7962,9 +7979,9 @@ Tcl_SetChannelOption(
|
||||
}
|
||||
} else {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"bad value for -eofchar: should be a list of zero,"
|
||||
" one, or two elements", NULL);
|
||||
" one, or two elements", -1));
|
||||
}
|
||||
ckfree(argv);
|
||||
return TCL_ERROR;
|
||||
@@ -7996,9 +8013,9 @@ Tcl_SetChannelOption(
|
||||
writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[1] : NULL;
|
||||
} else {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp,
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"bad value for -translation: must be a one or two"
|
||||
" element list", NULL);
|
||||
" element list", -1));
|
||||
}
|
||||
ckfree(argv);
|
||||
return TCL_ERROR;
|
||||
@@ -8026,10 +8043,9 @@ Tcl_SetChannelOption(
|
||||
translation = TCL_PLATFORM_TRANSLATION;
|
||||
} else {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp,
|
||||
"bad value for -translation: "
|
||||
"must be one of auto, binary, cr, lf, crlf,"
|
||||
" or platform", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"bad value for -translation: must be one of "
|
||||
"auto, binary, cr, lf, crlf, or platform", -1));
|
||||
}
|
||||
ckfree(argv);
|
||||
return TCL_ERROR;
|
||||
@@ -8077,10 +8093,9 @@ Tcl_SetChannelOption(
|
||||
statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
|
||||
} else {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp,
|
||||
"bad value for -translation: "
|
||||
"must be one of auto, binary, cr, lf, crlf,"
|
||||
" or platform", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"bad value for -translation: must be one of "
|
||||
"auto, binary, cr, lf, crlf, or platform", -1));
|
||||
}
|
||||
ckfree(argv);
|
||||
return TCL_ERROR;
|
||||
@@ -8824,6 +8839,7 @@ TclChannelEventScriptInvoker(
|
||||
*/
|
||||
|
||||
Tcl_Preserve(interp);
|
||||
Tcl_Preserve(chanPtr);
|
||||
result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL);
|
||||
|
||||
/*
|
||||
@@ -8840,6 +8856,7 @@ TclChannelEventScriptInvoker(
|
||||
}
|
||||
Tcl_BackgroundException(interp, result);
|
||||
}
|
||||
Tcl_Release(chanPtr);
|
||||
Tcl_Release(interp);
|
||||
}
|
||||
|
||||
@@ -8898,8 +8915,8 @@ Tcl_FileEventObjCmd(
|
||||
chanPtr = (Channel *) chan;
|
||||
statePtr = chanPtr->state;
|
||||
if ((statePtr->flags & mask) == 0) {
|
||||
Tcl_AppendResult(interp, "channel is not ",
|
||||
(mask == TCL_READABLE) ? "readable" : "writable", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf("channel is not %s",
|
||||
(mask == TCL_READABLE) ? "readable" : "writable"));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -9020,15 +9037,15 @@ TclCopyChannel(
|
||||
|
||||
if (BUSY_STATE(inStatePtr, TCL_READABLE)) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "channel \"",
|
||||
Tcl_GetChannelName(inChan), "\" is busy", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" is busy", Tcl_GetChannelName(inChan)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (BUSY_STATE(outStatePtr, TCL_WRITABLE)) {
|
||||
if (interp) {
|
||||
Tcl_AppendResult(interp, "channel \"",
|
||||
Tcl_GetChannelName(outChan), "\" is busy", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" is busy", Tcl_GetChannelName(outChan)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -10154,8 +10171,9 @@ SetBlockMode(
|
||||
*/
|
||||
|
||||
if (!TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) {
|
||||
Tcl_AppendResult(interp, "error setting blocking mode: ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error setting blocking mode: %s",
|
||||
Tcl_PosixError(interp)));
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
|
||||
+97
-93
@@ -174,9 +174,10 @@ Tcl_PutsObjCmd(
|
||||
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((mode & TCL_WRITABLE) == 0) {
|
||||
Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
|
||||
"\" wasn't opened for writing", NULL);
|
||||
if (!(mode & TCL_WRITABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" wasn't opened for writing",
|
||||
TclGetString(chanObjPtr)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -201,8 +202,8 @@ Tcl_PutsObjCmd(
|
||||
|
||||
error:
|
||||
if (!TclChanCaughtErrorBypass(interp, chan)) {
|
||||
Tcl_AppendResult(interp, "error writing \"", TclGetString(chanObjPtr),
|
||||
"\": ", Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -244,9 +245,10 @@ Tcl_FlushObjCmd(
|
||||
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((mode & TCL_WRITABLE) == 0) {
|
||||
Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
|
||||
"\" wasn't opened for writing", NULL);
|
||||
if (!(mode & TCL_WRITABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" wasn't opened for writing",
|
||||
TclGetString(chanObjPtr)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -259,9 +261,9 @@ Tcl_FlushObjCmd(
|
||||
*/
|
||||
|
||||
if (!TclChanCaughtErrorBypass(interp, chan)) {
|
||||
Tcl_AppendResult(interp, "error flushing \"",
|
||||
TclGetString(chanObjPtr), "\": ", Tcl_PosixError(interp),
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error flushing \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -306,9 +308,10 @@ Tcl_GetsObjCmd(
|
||||
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((mode & TCL_READABLE) == 0) {
|
||||
Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
|
||||
"\" wasn't opened for reading", NULL);
|
||||
if (!(mode & TCL_READABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" wasn't opened for reading",
|
||||
TclGetString(chanObjPtr)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -326,10 +329,9 @@ Tcl_GetsObjCmd(
|
||||
*/
|
||||
|
||||
if (!TclChanCaughtErrorBypass(interp, chan)) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "error reading \"",
|
||||
TclGetString(chanObjPtr), "\": ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error reading \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -411,9 +413,10 @@ Tcl_ReadObjCmd(
|
||||
if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((mode & TCL_READABLE) == 0) {
|
||||
Tcl_AppendResult(interp, "channel \"", TclGetString(chanObjPtr),
|
||||
"\" wasn't opened for reading", NULL);
|
||||
if (!(mode & TCL_READABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" wasn't opened for reading",
|
||||
TclGetString(chanObjPtr)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
i++; /* Consumed channel name. */
|
||||
@@ -436,11 +439,11 @@ Tcl_ReadObjCmd(
|
||||
|
||||
if (strcmp(TclGetString(objv[i]), "nonewline") != 0) {
|
||||
#endif
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "expected non-negative integer but got \"",
|
||||
TclGetString(objv[i]), "\"", NULL);
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
|
||||
return TCL_ERROR;
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"expected non-negative integer but got \"%s\"",
|
||||
TclGetString(objv[i])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
|
||||
return TCL_ERROR;
|
||||
#if TCL_MAJOR_VERSION < 9
|
||||
}
|
||||
newline = 1;
|
||||
@@ -460,10 +463,9 @@ Tcl_ReadObjCmd(
|
||||
*/
|
||||
|
||||
if (!TclChanCaughtErrorBypass(interp, chan)) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "error reading \"",
|
||||
TclGetString(chanObjPtr), "\": ", Tcl_PosixError(interp),
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error reading \"%s\": %s",
|
||||
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
|
||||
}
|
||||
Tcl_DecrRefCount(resultPtr);
|
||||
return TCL_ERROR;
|
||||
@@ -552,9 +554,9 @@ Tcl_SeekObjCmd(
|
||||
*/
|
||||
|
||||
if (!TclChanCaughtErrorBypass(interp, chan)) {
|
||||
Tcl_AppendResult(interp, "error during seek on \"",
|
||||
TclGetString(objv[1]), "\": ", Tcl_PosixError(interp),
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error during seek on \"%s\": %s",
|
||||
TclGetString(objv[1]), Tcl_PosixError(interp)));
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -679,9 +681,9 @@ Tcl_CloseObjCmd(
|
||||
*/
|
||||
|
||||
if (!(dir & Tcl_GetChannelMode(chan))) {
|
||||
Tcl_AppendResult(interp, "Half-close of ", dirOptions[index],
|
||||
"-side not possible, side not opened or already closed",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"Half-close of %s-side not possible, side not opened"
|
||||
" or already closed", dirOptions[index]));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -977,9 +979,9 @@ Tcl_ExecObjCmd(
|
||||
*/
|
||||
|
||||
if (!TclChanCaughtErrorBypass(interp, chan)) {
|
||||
Tcl_ResetResult(interp);
|
||||
Tcl_AppendResult(interp, "error reading output from command: ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error reading output from command: %s",
|
||||
Tcl_PosixError(interp)));
|
||||
Tcl_DecrRefCount(resultPtr);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
@@ -1048,9 +1050,10 @@ Tcl_FblockedObjCmd(
|
||||
if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((mode & TCL_READABLE) == 0) {
|
||||
Tcl_AppendResult(interp, "channel \"", TclGetString(objv[1]),
|
||||
"\" wasn't opened for reading", NULL);
|
||||
if (!(mode & TCL_READABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" wasn't opened for reading",
|
||||
TclGetString(objv[1])));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1174,7 +1177,7 @@ Tcl_OpenObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_RegisterChannel(interp, chan);
|
||||
Tcl_AppendResult(interp, Tcl_GetChannelName(chan), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1479,8 +1482,8 @@ Tcl_SocketObjCmd(
|
||||
switch ((enum socketOptions) optionIndex) {
|
||||
case SKT_ASYNC:
|
||||
if (server == 1) {
|
||||
Tcl_AppendResult(interp,
|
||||
"cannot set -async option for server sockets", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot set -async option for server sockets", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
async = 1;
|
||||
@@ -1488,8 +1491,8 @@ Tcl_SocketObjCmd(
|
||||
case SKT_MYADDR:
|
||||
a++;
|
||||
if (a >= objc) {
|
||||
Tcl_AppendResult(interp,
|
||||
"no argument given for -myaddr option", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"no argument given for -myaddr option", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
myaddr = TclGetString(objv[a]);
|
||||
@@ -1499,8 +1502,8 @@ Tcl_SocketObjCmd(
|
||||
|
||||
a++;
|
||||
if (a >= objc) {
|
||||
Tcl_AppendResult(interp,
|
||||
"no argument given for -myport option", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"no argument given for -myport option", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
myPortName = TclGetString(objv[a]);
|
||||
@@ -1511,15 +1514,15 @@ Tcl_SocketObjCmd(
|
||||
}
|
||||
case SKT_SERVER:
|
||||
if (async == 1) {
|
||||
Tcl_AppendResult(interp,
|
||||
"cannot set -async option for server sockets", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot set -async option for server sockets", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
server = 1;
|
||||
a++;
|
||||
if (a >= objc) {
|
||||
Tcl_AppendResult(interp,
|
||||
"no argument given for -server option", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"no argument given for -server option", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
script = TclGetString(objv[a]);
|
||||
@@ -1531,8 +1534,8 @@ Tcl_SocketObjCmd(
|
||||
if (server) {
|
||||
host = myaddr; /* NULL implies INADDR_ANY */
|
||||
if (myport != 0) {
|
||||
Tcl_AppendResult(interp, "option -myport is not valid for servers",
|
||||
NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"option -myport is not valid for servers", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else if (a < objc) {
|
||||
@@ -1599,9 +1602,9 @@ Tcl_SocketObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_RegisterChannel(interp, chan);
|
||||
Tcl_AppendResult(interp, Tcl_GetChannelName(chan), NULL);
|
||||
|
||||
Tcl_RegisterChannel(interp, chan);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1651,17 +1654,19 @@ Tcl_FcopyObjCmd(
|
||||
if (TclGetChannelFromObj(interp, objv[1], &inChan, &mode, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((mode & TCL_READABLE) == 0) {
|
||||
Tcl_AppendResult(interp, "channel \"", TclGetString(objv[1]),
|
||||
"\" wasn't opened for reading", NULL);
|
||||
if (!(mode & TCL_READABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" wasn't opened for reading",
|
||||
TclGetString(objv[1])));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (TclGetChannelFromObj(interp, objv[2], &outChan, &mode, 0) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((mode & TCL_WRITABLE) == 0) {
|
||||
Tcl_AppendResult(interp, "channel \"", TclGetString(objv[2]),
|
||||
"\" wasn't opened for writing", NULL);
|
||||
if (!(mode & TCL_WRITABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"channel \"%s\" wasn't opened for writing",
|
||||
TclGetString(objv[2])));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1745,14 +1750,14 @@ ChanPendingObjCmd(
|
||||
|
||||
switch ((enum options) index) {
|
||||
case PENDING_INPUT:
|
||||
if ((mode & TCL_READABLE) == 0) {
|
||||
if (!(mode & TCL_READABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_InputBuffered(chan)));
|
||||
}
|
||||
break;
|
||||
case PENDING_OUTPUT:
|
||||
if ((mode & TCL_WRITABLE) == 0) {
|
||||
if (!(mode & TCL_WRITABLE)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_OutputBuffered(chan)));
|
||||
@@ -1806,8 +1811,8 @@ ChanTruncateObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (length < 0) {
|
||||
Tcl_AppendResult(interp,
|
||||
"cannot truncate to negative length of file", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"cannot truncate to negative length of file", -1));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
@@ -1817,18 +1822,17 @@ ChanTruncateObjCmd(
|
||||
|
||||
length = Tcl_Tell(chan);
|
||||
if (length == Tcl_WideAsLong(-1)) {
|
||||
Tcl_AppendResult(interp,
|
||||
"could not determine current location in \"",
|
||||
TclGetString(objv[1]), "\": ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"could not determine current location in \"%s\": %s",
|
||||
TclGetString(objv[1]), Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (Tcl_TruncateChannel(chan, length) != TCL_OK) {
|
||||
Tcl_AppendResult(interp, "error during truncate on \"",
|
||||
TclGetString(objv[1]), "\": ",
|
||||
Tcl_PosixError(interp), NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error during truncate on \"%s\": %s",
|
||||
TclGetString(objv[1]), Tcl_PosixError(interp)));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -1948,25 +1952,25 @@ TclInitChanCmd(
|
||||
* function at the moment.
|
||||
*/
|
||||
static const EnsembleImplMap initMap[] = {
|
||||
{"blocked", Tcl_FblockedObjCmd, NULL, NULL, NULL, 0},
|
||||
{"close", Tcl_CloseObjCmd, NULL, NULL, NULL, 0},
|
||||
{"copy", Tcl_FcopyObjCmd, NULL, NULL, NULL, 0},
|
||||
{"create", TclChanCreateObjCmd, NULL, NULL, NULL, 0}, /* TIP #219 */
|
||||
{"eof", Tcl_EofObjCmd, NULL, NULL, NULL, 0},
|
||||
{"event", Tcl_FileEventObjCmd, NULL, NULL, NULL, 0},
|
||||
{"flush", Tcl_FlushObjCmd, NULL, NULL, NULL, 0},
|
||||
{"gets", Tcl_GetsObjCmd, NULL, NULL, NULL, 0},
|
||||
{"names", TclChannelNamesCmd, NULL, NULL, NULL, 0},
|
||||
{"pending", ChanPendingObjCmd, NULL, NULL, NULL, 0}, /* TIP #287 */
|
||||
{"pop", TclChanPopObjCmd, NULL, NULL, NULL, 0}, /* TIP #230 */
|
||||
{"postevent", TclChanPostEventObjCmd, NULL, NULL, NULL, 0}, /* TIP #219 */
|
||||
{"push", TclChanPushObjCmd, NULL, NULL, NULL, 0}, /* TIP #230 */
|
||||
{"puts", Tcl_PutsObjCmd, NULL, NULL, NULL, 0},
|
||||
{"read", Tcl_ReadObjCmd, NULL, NULL, NULL, 0},
|
||||
{"seek", Tcl_SeekObjCmd, NULL, NULL, NULL, 0},
|
||||
{"pipe", ChanPipeObjCmd, NULL, NULL, NULL, 0}, /* TIP #304 */
|
||||
{"tell", Tcl_TellObjCmd, NULL, NULL, NULL, 0},
|
||||
{"truncate", ChanTruncateObjCmd, NULL, NULL, NULL, 0}, /* TIP #208 */
|
||||
{"blocked", Tcl_FblockedObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"close", Tcl_CloseObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"copy", Tcl_FcopyObjCmd, NULL, NULL, NULL, 0},
|
||||
{"create", TclChanCreateObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #219 */
|
||||
{"eof", Tcl_EofObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"event", Tcl_FileEventObjCmd, TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
|
||||
{"flush", Tcl_FlushObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"gets", Tcl_GetsObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
|
||||
{"names", TclChannelNamesCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
|
||||
{"pending", ChanPendingObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #287 */
|
||||
{"pipe", ChanPipeObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0}, /* TIP #304 */
|
||||
{"pop", TclChanPopObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, /* TIP #230 */
|
||||
{"postevent", TclChanPostEventObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #219 */
|
||||
{"push", TclChanPushObjCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, /* TIP #230 */
|
||||
{"puts", Tcl_PutsObjCmd, NULL, NULL, NULL, 0},
|
||||
{"read", Tcl_ReadObjCmd, NULL, NULL, NULL, 0},
|
||||
{"seek", Tcl_SeekObjCmd, TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
|
||||
{"tell", Tcl_TellObjCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
|
||||
{"truncate", ChanTruncateObjCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, /* TIP #208 */
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
static const char *const extras[] = {
|
||||
|
||||
+2
-2
@@ -284,8 +284,8 @@ TclChannelTransform(
|
||||
dataPtr->self = Tcl_StackChannel(interp, &transformChannelType, dataPtr,
|
||||
mode, chan);
|
||||
if (dataPtr->self == NULL) {
|
||||
Tcl_AppendResult(interp, "\nfailed to stack channel \"",
|
||||
Tcl_GetChannelName(chan), "\"", NULL);
|
||||
Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp),
|
||||
"\nfailed to stack channel \"%s\"", Tcl_GetChannelName(chan));
|
||||
Tcl_DecrRefCount(dataPtr->command);
|
||||
ResultClear(&dataPtr->result);
|
||||
ckfree(dataPtr);
|
||||
|
||||
+81
-66
@@ -404,25 +404,25 @@ static int ForwardProc(Tcl_Event *evPtr, int mask);
|
||||
static void SrcExitProc(ClientData clientData);
|
||||
|
||||
#define FreeReceivedError(p) \
|
||||
if ((p)->base.mustFree) { \
|
||||
ckfree((p)->base.msgStr); \
|
||||
if ((p)->base.mustFree) { \
|
||||
ckfree((p)->base.msgStr); \
|
||||
}
|
||||
#define PassReceivedErrorInterp(i,p) \
|
||||
if ((i) != NULL) { \
|
||||
Tcl_SetChannelErrorInterp((i), \
|
||||
Tcl_NewStringObj((p)->base.msgStr, -1)); \
|
||||
} \
|
||||
if ((i) != NULL) { \
|
||||
Tcl_SetChannelErrorInterp((i), \
|
||||
Tcl_NewStringObj((p)->base.msgStr, -1)); \
|
||||
} \
|
||||
FreeReceivedError(p)
|
||||
#define PassReceivedError(c,p) \
|
||||
Tcl_SetChannelError((c), Tcl_NewStringObj((p)->base.msgStr, -1)); \
|
||||
FreeReceivedError(p)
|
||||
#define ForwardSetStaticError(p,emsg) \
|
||||
(p)->base.code = TCL_ERROR; \
|
||||
(p)->base.mustFree = 0; \
|
||||
(p)->base.code = TCL_ERROR; \
|
||||
(p)->base.mustFree = 0; \
|
||||
(p)->base.msgStr = (char *) (emsg)
|
||||
#define ForwardSetDynamicError(p,emsg) \
|
||||
(p)->base.code = TCL_ERROR; \
|
||||
(p)->base.mustFree = 1; \
|
||||
(p)->base.code = TCL_ERROR; \
|
||||
(p)->base.mustFree = 1; \
|
||||
(p)->base.msgStr = (char *) (emsg)
|
||||
|
||||
static void ForwardSetObjError(ForwardParam *p, Tcl_Obj *objPtr);
|
||||
@@ -739,7 +739,8 @@ TclChanCreateObjCmd(
|
||||
* Return handle as result of command.
|
||||
*/
|
||||
|
||||
Tcl_SetResult(interp, (char *)chanPtr->state->channelName, TCL_VOLATILE);
|
||||
Tcl_SetObjResult(interp,
|
||||
Tcl_NewStringObj(chanPtr->state->channelName, -1));
|
||||
return TCL_OK;
|
||||
|
||||
error:
|
||||
@@ -774,13 +775,15 @@ TclChanCreateObjCmd(
|
||||
*/
|
||||
|
||||
typedef struct ReflectEvent {
|
||||
Tcl_Event header;
|
||||
ReflectedChannel* rcPtr;
|
||||
int events;
|
||||
Tcl_Event header;
|
||||
ReflectedChannel *rcPtr;
|
||||
int events;
|
||||
} ReflectEvent;
|
||||
|
||||
static int
|
||||
ReflectEventRun (Tcl_Event* ev, int flags)
|
||||
ReflectEventRun(
|
||||
Tcl_Event *ev,
|
||||
int flags)
|
||||
{
|
||||
/* OWNER thread
|
||||
*
|
||||
@@ -789,14 +792,16 @@ ReflectEventRun (Tcl_Event* ev, int flags)
|
||||
* accomplishing that.
|
||||
*/
|
||||
|
||||
ReflectEvent* e = (ReflectEvent*) ev;
|
||||
ReflectEvent *e = (ReflectEvent *) ev;
|
||||
|
||||
Tcl_NotifyChannel (e->rcPtr->chan, e->events);
|
||||
Tcl_NotifyChannel(e->rcPtr->chan, e->events);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
ReflectEventDelete (Tcl_Event* ev, ClientData cd)
|
||||
ReflectEventDelete(
|
||||
Tcl_Event *ev,
|
||||
ClientData cd)
|
||||
{
|
||||
/* OWNER thread
|
||||
*
|
||||
@@ -805,11 +810,9 @@ ReflectEventDelete (Tcl_Event* ev, ClientData cd)
|
||||
* invalid channel.
|
||||
*/
|
||||
|
||||
ReflectEvent* e = (ReflectEvent*) ev;
|
||||
ReflectEvent *e = (ReflectEvent *) ev;
|
||||
|
||||
if ((ev->proc != ReflectEventRun) ||
|
||||
((cd != NULL) &&
|
||||
(cd != e->rcPtr))) {
|
||||
if ((ev->proc != ReflectEventRun) || ((cd != NULL) && (cd != e->rcPtr))) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -867,8 +870,8 @@ TclChanPostEventObjCmd(
|
||||
hPtr = Tcl_FindHashEntry(&rcmPtr->map, chanId);
|
||||
|
||||
if (hPtr == NULL) {
|
||||
Tcl_AppendResult(interp, "can not find reflected channel named \"",
|
||||
chanId, "\"", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can not find reflected channel named \"%s\"", chanId));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanId, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -925,8 +928,9 @@ TclChanPostEventObjCmd(
|
||||
*/
|
||||
|
||||
if (events & ~rcPtr->interest) {
|
||||
Tcl_AppendResult(interp, "tried to post events channel \"", chanId,
|
||||
"\" is not interested in", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"tried to post events channel \"%s\" is not interested in",
|
||||
chanId));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -937,10 +941,11 @@ TclChanPostEventObjCmd(
|
||||
#ifdef TCL_THREADS
|
||||
if (rcPtr->owner == rcPtr->thread) {
|
||||
#endif
|
||||
Tcl_NotifyChannel (chan, events);
|
||||
Tcl_NotifyChannel(chan, events);
|
||||
#ifdef TCL_THREADS
|
||||
} else {
|
||||
ReflectEvent* ev = ckalloc (sizeof (ReflectEvent));
|
||||
ReflectEvent *ev = ckalloc(sizeof(ReflectEvent));
|
||||
|
||||
ev->header.proc = ReflectEventRun;
|
||||
ev->events = events;
|
||||
ev->rcPtr = rcPtr;
|
||||
@@ -957,7 +962,8 @@ TclChanPostEventObjCmd(
|
||||
* The teardown of unprocessed events is currently coupled to the
|
||||
* thread reflected channel map
|
||||
*/
|
||||
(void) GetThreadReflectedChannelMap ();
|
||||
|
||||
(void) GetThreadReflectedChannelMap();
|
||||
|
||||
/* XXX Race condition !!
|
||||
* XXX The destination thread may not exist anymore already.
|
||||
@@ -965,8 +971,9 @@ TclChanPostEventObjCmd(
|
||||
* XXX Can we detect this ? (check the validity of the owner threadid ?)
|
||||
* XXX Actually, in that case the channel should be dead also !
|
||||
*/
|
||||
Tcl_ThreadQueueEvent (rcPtr->owner, (Tcl_Event*) ev, TCL_QUEUE_TAIL);
|
||||
Tcl_ThreadAlert (rcPtr->owner);
|
||||
|
||||
Tcl_ThreadQueueEvent(rcPtr->owner, (Tcl_Event *) ev, TCL_QUEUE_TAIL);
|
||||
Tcl_ThreadAlert(rcPtr->owner);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1156,8 +1163,11 @@ ReflectClose(
|
||||
ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p);
|
||||
result = p.base.code;
|
||||
|
||||
/* Now squash the pending reflection events for this channel. */
|
||||
Tcl_DeleteEvents (ReflectEventDelete, rcPtr);
|
||||
/*
|
||||
* Now squash the pending reflection events for this channel.
|
||||
*/
|
||||
|
||||
Tcl_DeleteEvents(ReflectEventDelete, rcPtr);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
FreeReceivedError(&p);
|
||||
@@ -1165,7 +1175,7 @@ ReflectClose(
|
||||
}
|
||||
#endif
|
||||
|
||||
Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
@@ -1177,7 +1187,7 @@ ReflectClose(
|
||||
*/
|
||||
|
||||
if (rcPtr->methods == 0) {
|
||||
Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
return EOK;
|
||||
}
|
||||
|
||||
@@ -1192,10 +1202,13 @@ ReflectClose(
|
||||
ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p);
|
||||
result = p.base.code;
|
||||
|
||||
/* Now squash the pending reflection events for this channel. */
|
||||
Tcl_DeleteEvents (ReflectEventDelete, rcPtr);
|
||||
/*
|
||||
* Now squash the pending reflection events for this channel.
|
||||
*/
|
||||
|
||||
Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
Tcl_DeleteEvents(ReflectEventDelete, rcPtr);
|
||||
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
PassReceivedErrorInterp(interp, &p);
|
||||
@@ -1240,7 +1253,7 @@ ReflectClose(
|
||||
}
|
||||
#endif
|
||||
|
||||
Tcl_EventuallyFree (rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
|
||||
#ifdef TCL_THREADS
|
||||
}
|
||||
#endif
|
||||
@@ -1348,7 +1361,7 @@ ReflectInput(
|
||||
*errorCodePtr = EOK;
|
||||
|
||||
if (bytec > 0) {
|
||||
memcpy(buf, bytev, (size_t)bytec);
|
||||
memcpy(buf, bytev, (size_t) bytec);
|
||||
}
|
||||
|
||||
stop:
|
||||
@@ -1549,12 +1562,13 @@ ReflectSeekWide(
|
||||
Tcl_Preserve(rcPtr);
|
||||
|
||||
offObj = Tcl_NewWideIntObj(offset);
|
||||
baseObj = Tcl_NewStringObj((seekMode == SEEK_SET) ? "start" :
|
||||
((seekMode == SEEK_CUR) ? "current" : "end"), -1);
|
||||
baseObj = Tcl_NewStringObj(
|
||||
(seekMode == SEEK_SET) ? "start" :
|
||||
(seekMode == SEEK_CUR) ? "current" : "end", -1);
|
||||
Tcl_IncrRefCount(offObj);
|
||||
Tcl_IncrRefCount(baseObj);
|
||||
|
||||
if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj)!=TCL_OK) {
|
||||
if (InvokeTclMethod(rcPtr, "seek", offObj, baseObj, &resObj) != TCL_OK) {
|
||||
Tcl_SetChannelError(rcPtr->chan, resObj);
|
||||
goto invalid;
|
||||
}
|
||||
@@ -1760,7 +1774,9 @@ ReflectBlock(
|
||||
*/
|
||||
|
||||
static void
|
||||
ReflectThread(ClientData clientData, int action)
|
||||
ReflectThread(
|
||||
ClientData clientData,
|
||||
int action)
|
||||
{
|
||||
ReflectedChannel *rcPtr = clientData;
|
||||
|
||||
@@ -1772,7 +1788,7 @@ ReflectThread(ClientData clientData, int action)
|
||||
rcPtr->owner = NULL;
|
||||
break;
|
||||
default:
|
||||
Tcl_Panic ("Unknown thread action code.");
|
||||
Tcl_Panic("Unknown thread action code.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1947,7 +1963,7 @@ ReflectGetOption(
|
||||
*/
|
||||
|
||||
if (optionObj != NULL) {
|
||||
Tcl_DStringAppend(dsPtr, TclGetString(resObj), -1);
|
||||
TclDStringAppendObj(dsPtr, resObj);
|
||||
goto ok;
|
||||
}
|
||||
|
||||
@@ -1982,7 +1998,7 @@ ReflectGetOption(
|
||||
const char *str = Tcl_GetStringFromObj(resObj, &len);
|
||||
|
||||
if (len) {
|
||||
Tcl_DStringAppend(dsPtr, " ", 1);
|
||||
TclDStringAppendLiteral(dsPtr, " ");
|
||||
Tcl_DStringAppend(dsPtr, str, len);
|
||||
}
|
||||
goto ok;
|
||||
@@ -2046,7 +2062,8 @@ EncodeEventMask(
|
||||
}
|
||||
|
||||
if (listc < 1) {
|
||||
Tcl_AppendResult(interp, "bad ", objName, " list: is empty", NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad %s list: is empty", objName));
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -2807,7 +2824,7 @@ DeleteThreadReflectedChannelMap(
|
||||
* actually.
|
||||
*/
|
||||
|
||||
Tcl_DeleteEvents (ReflectEventDelete, NULL);
|
||||
Tcl_DeleteEvents(ReflectEventDelete, NULL);
|
||||
|
||||
/*
|
||||
* Get the map of all channels handled by the current thread. This is a
|
||||
@@ -2978,9 +2995,8 @@ ForwardProc(
|
||||
Tcl_Interp *interp = rcPtr->interp;
|
||||
ForwardParam *paramPtr = evPtr->param;
|
||||
Tcl_Obj *resObj = NULL; /* Interp result of InvokeTclMethod */
|
||||
ReflectedChannelMap *rcmPtr;
|
||||
/* Map of reflected channels with handlers in
|
||||
* this interp. */
|
||||
ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
|
||||
* this interp. */
|
||||
Tcl_HashEntry *hPtr; /* Entry in the above map */
|
||||
|
||||
/*
|
||||
@@ -3023,12 +3039,12 @@ ForwardProc(
|
||||
|
||||
rcmPtr = GetReflectedChannelMap(interp);
|
||||
hPtr = Tcl_FindHashEntry(&rcmPtr->map,
|
||||
Tcl_GetChannelName(rcPtr->chan));
|
||||
Tcl_GetChannelName(rcPtr->chan));
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
|
||||
rcmPtr = GetThreadReflectedChannelMap();
|
||||
hPtr = Tcl_FindHashEntry(&rcmPtr->map,
|
||||
Tcl_GetChannelName(rcPtr->chan));
|
||||
Tcl_GetChannelName(rcPtr->chan));
|
||||
Tcl_DeleteHashEntry(hPtr);
|
||||
|
||||
FreeReflectedChannelArgs(rcPtr);
|
||||
@@ -3063,7 +3079,7 @@ ForwardProc(
|
||||
paramPtr->input.toRead = -1;
|
||||
} else {
|
||||
if (bytec > 0) {
|
||||
memcpy(paramPtr->input.buf, bytev, (size_t)bytec);
|
||||
memcpy(paramPtr->input.buf, bytev, (size_t) bytec);
|
||||
}
|
||||
paramPtr->input.toRead = bytec;
|
||||
}
|
||||
@@ -3075,7 +3091,7 @@ ForwardProc(
|
||||
|
||||
case ForwardedOutput: {
|
||||
Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *)
|
||||
paramPtr->output.buf, paramPtr->output.toWrite);
|
||||
paramPtr->output.buf, paramPtr->output.toWrite);
|
||||
Tcl_IncrRefCount(bufObj);
|
||||
|
||||
Tcl_Preserve(rcPtr);
|
||||
@@ -3115,8 +3131,8 @@ ForwardProc(
|
||||
case ForwardedSeek: {
|
||||
Tcl_Obj *offObj = Tcl_NewWideIntObj(paramPtr->seek.offset);
|
||||
Tcl_Obj *baseObj = Tcl_NewStringObj(
|
||||
(paramPtr->seek.seekMode==SEEK_SET) ? "start" :
|
||||
(paramPtr->seek.seekMode==SEEK_CUR) ? "current" : "end", -1);
|
||||
(paramPtr->seek.seekMode==SEEK_SET) ? "start" :
|
||||
(paramPtr->seek.seekMode==SEEK_CUR) ? "current" : "end", -1);
|
||||
|
||||
Tcl_IncrRefCount(offObj);
|
||||
Tcl_IncrRefCount(baseObj);
|
||||
@@ -3166,11 +3182,11 @@ ForwardProc(
|
||||
|
||||
case ForwardedBlock: {
|
||||
Tcl_Obj *blockObj = Tcl_NewBooleanObj(!paramPtr->block.nonblocking);
|
||||
Tcl_IncrRefCount(blockObj);
|
||||
|
||||
Tcl_IncrRefCount(blockObj);
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "blocking", blockObj, NULL,
|
||||
&resObj) != TCL_OK) {
|
||||
&resObj) != TCL_OK) {
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
}
|
||||
Tcl_Release(rcPtr);
|
||||
@@ -3186,7 +3202,7 @@ ForwardProc(
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "configure", optionObj, valueObj,
|
||||
&resObj) != TCL_OK) {
|
||||
&resObj) != TCL_OK) {
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
}
|
||||
Tcl_Release(rcPtr);
|
||||
@@ -3201,14 +3217,13 @@ ForwardProc(
|
||||
*/
|
||||
|
||||
Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->getOpt.name, -1);
|
||||
Tcl_IncrRefCount(optionObj);
|
||||
|
||||
Tcl_IncrRefCount(optionObj);
|
||||
Tcl_Preserve(rcPtr);
|
||||
if (InvokeTclMethod(rcPtr, "cget", optionObj, NULL, &resObj)!=TCL_OK){
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
} else {
|
||||
Tcl_DStringAppend(paramPtr->getOpt.value,
|
||||
TclGetString(resObj), -1);
|
||||
TclDStringAppendObj(paramPtr->getOpt.value, resObj);
|
||||
}
|
||||
Tcl_Release(rcPtr);
|
||||
Tcl_DecrRefCount(optionObj);
|
||||
@@ -3233,7 +3248,7 @@ ForwardProc(
|
||||
Tcl_Obj **listv;
|
||||
|
||||
if (Tcl_ListObjGetElements(interp, resObj, &listc,
|
||||
&listv) != TCL_OK) {
|
||||
&listv) != TCL_OK) {
|
||||
Tcl_DecrRefCount(resObj);
|
||||
resObj = MarshallError(interp);
|
||||
ForwardSetObjError(paramPtr, resObj);
|
||||
@@ -3253,7 +3268,7 @@ ForwardProc(
|
||||
const char *str = Tcl_GetStringFromObj(resObj, &len);
|
||||
|
||||
if (len) {
|
||||
Tcl_DStringAppend(paramPtr->getOpt.value, " ", 1);
|
||||
TclDStringAppendLiteral(paramPtr->getOpt.value, " ");
|
||||
Tcl_DStringAppend(paramPtr->getOpt.value, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user