Compare commits
524
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
410bda416e | ||
|
|
861217dbe3 | ||
|
|
45f5143205 | ||
|
|
de9c1aff4a | ||
|
|
e7a5b8aaa5 | ||
|
|
cd39f34fa5 | ||
|
|
e7be4a19a0 | ||
|
|
a0374a6e61 | ||
|
|
3f3c89a947 | ||
|
|
6b5d0e5d8d | ||
|
|
d9dbcf5afb | ||
|
|
4dc5255a8e | ||
|
|
e7a86d967c | ||
|
|
6fce39545c | ||
|
|
87fd09e44a | ||
|
|
cd4e0ec5de | ||
|
|
954522812e | ||
|
|
db9b0eccf3 | ||
|
|
06c3fd0c5b | ||
|
|
c13e34da37 | ||
|
|
a9d546dfbc | ||
|
|
6798b2404f | ||
|
|
5fd318bc35 | ||
|
|
88812125b1 | ||
|
|
947fb98db5 | ||
|
|
ed53b715ac | ||
|
|
b8b87e5280 | ||
|
|
0c5bd7480e | ||
|
|
64038c5656 | ||
|
|
101ac8bca7 | ||
|
|
30e7e05895 | ||
|
|
b4d6691add | ||
|
|
ce6aa3ea08 | ||
|
|
3492c92f3d | ||
|
|
d7f41b448c | ||
|
|
405b9175e6 | ||
|
|
2c44354d13 | ||
|
|
612199cbe9 | ||
|
|
f337281f75 | ||
|
|
7fe003f8d2 | ||
|
|
f003df5624 | ||
|
|
9fb9471807 | ||
|
|
0254080ca0 | ||
|
|
8c2cbf3211 | ||
|
|
c68d043691 | ||
|
|
720c8de452 | ||
|
|
596e89b17d | ||
|
|
847a048c18 | ||
|
|
da8fbb89c4 | ||
|
|
0d33258649 | ||
|
|
f406561f40 | ||
|
|
465d28aa75 | ||
|
|
6c0170972f | ||
|
|
4d47b7f97f | ||
|
|
0e5d21e88f | ||
|
|
0c568099ee | ||
|
|
5753c7a42b | ||
|
|
914d6e1546 | ||
|
|
683dada217 | ||
|
|
2cd8bf554e | ||
|
|
e9c0312caf | ||
|
|
9a809e614a | ||
|
|
0bceead396 | ||
|
|
6faf2feff2 | ||
|
|
9090aca429 | ||
|
|
fe83175465 | ||
|
|
468041eef8 | ||
|
|
85233a4693 | ||
|
|
4ad7747c62 | ||
|
|
812174d578 | ||
|
|
471d356605 | ||
|
|
455b61dce3 | ||
|
|
2d54b68224 | ||
|
|
cce4368ace | ||
|
|
7a1cc7e3b3 | ||
|
|
0b90c0b92e | ||
|
|
dda81853f3 | ||
|
|
0af226b20a | ||
|
|
919808c6a5 | ||
|
|
beff988e79 | ||
|
|
e8f10bd44e | ||
|
|
fa3a1e4638 | ||
|
|
74c5043b5a | ||
|
|
dafcde1702 | ||
|
|
e16817b409 | ||
|
|
03a4436237 | ||
|
|
e52e074e4f | ||
|
|
0b5a1c79b7 | ||
|
|
0c44c5003d | ||
|
|
2b9b50b436 | ||
|
|
80fc86a116 | ||
|
|
1da12398f2 | ||
|
|
4322dab97e | ||
|
|
3243dfedd1 | ||
|
|
fa5058cbca | ||
|
|
e62743b6ee | ||
|
|
ade95255b9 | ||
|
|
0b96f3fb32 | ||
|
|
3971514c1b | ||
|
|
e6dd74e90e | ||
|
|
cf4de002dc | ||
|
|
c64afc94f1 | ||
|
|
55898c44b9 | ||
|
|
b9b319fad2 | ||
|
|
5d5bd4cd55 | ||
|
|
1e854210b7 | ||
|
|
7d25e385a2 | ||
|
|
c329006b1a | ||
|
|
40e9ab2e65 | ||
|
|
dc74da2f56 | ||
|
|
c6eb0cc51d | ||
|
|
a7c17bc224 | ||
|
|
2606a3a7db | ||
|
|
ea6e8c9dcd | ||
|
|
01a9d5c7cc | ||
|
|
4a6163c6a6 | ||
|
|
396c1a637c | ||
|
|
1553090bc3 | ||
|
|
f4babdb0ac | ||
|
|
4c79bcbe64 | ||
|
|
568724e468 | ||
|
|
ad022e6d3b | ||
|
|
5765c1e392 | ||
|
|
0031252bf1 | ||
|
|
4d73b33b87 | ||
|
|
e2877119cd | ||
|
|
451c384456 | ||
|
|
4f65558ad0 | ||
|
|
185cdc39c6 | ||
|
|
365ee5bb13 | ||
|
|
f674720166 | ||
|
|
a37e29cf85 | ||
|
|
fde3c52d29 | ||
|
|
99ca63a80a | ||
|
|
25fcbf685d | ||
|
|
2567185fd2 | ||
|
|
ca5e7c5b63 | ||
|
|
836fa11775 | ||
|
|
3be49723fc | ||
|
|
da7f77f96f | ||
|
|
98887219c2 | ||
|
|
93310b9171 | ||
|
|
b618278c9f | ||
|
|
73eb8eb8d1 | ||
|
|
adf9cf5543 | ||
|
|
77821adfe8 | ||
|
|
4f918b61b0 | ||
|
|
1a98844412 | ||
|
|
876f2d5b63 | ||
|
|
fa7659336c | ||
|
|
175fe8c23f | ||
|
|
a0c6bf8d92 | ||
|
|
2eba1ce11e | ||
|
|
6cd01fd0f8 | ||
|
|
46e8af13b6 | ||
|
|
b0fce7a700 | ||
|
|
d20d1e603b | ||
|
|
19c0142741 | ||
|
|
189d0a83d2 | ||
|
|
aa4c401952 | ||
|
|
f08ea44564 | ||
|
|
83df36ac41 | ||
|
|
eb9e2858c1 | ||
|
|
68214211b7 | ||
|
|
92aca935b3 | ||
|
|
e403ff8f45 | ||
|
|
8a7371192a | ||
|
|
0abda82b1e | ||
|
|
92c0d0a011 | ||
|
|
fb10dc69ee | ||
|
|
03a71b0706 | ||
|
|
a4953f93f4 | ||
|
|
1c35ed873a | ||
|
|
ac67b57981 | ||
|
|
7ea11c7f98 | ||
|
|
e755aba59f | ||
|
|
5fea88381c | ||
|
|
9a892a33b7 | ||
|
|
8e6fe27ecc | ||
|
|
f0b9b9fbb6 | ||
|
|
244885a03e | ||
|
|
45e646472d | ||
|
|
48d6a20861 | ||
|
|
498f069f0e | ||
|
|
48456596ff | ||
|
|
6d9902632c | ||
|
|
fafc11d6e0 | ||
|
|
4a5058fc1b | ||
|
|
7e4261e22c | ||
|
|
eb1212a3c1 | ||
|
|
063db11523 | ||
|
|
26b5bf3eca | ||
|
|
6c799d891d | ||
|
|
32f3dce79d | ||
|
|
fc03549d34 | ||
|
|
54590627ee | ||
|
|
daa36e9a1b | ||
|
|
b0898beca6 | ||
|
|
a922e9fd15 | ||
|
|
6631e46bd3 | ||
|
|
4a038240c4 | ||
|
|
ad43c617e3 | ||
|
|
a27cc004d2 | ||
|
|
301f6bcb83 | ||
|
|
9a7ce78e96 | ||
|
|
ca634be831 | ||
|
|
b0e6ac7da9 | ||
|
|
9a9b619c9f | ||
|
|
0b3bf9e30d | ||
|
|
82cd662f00 | ||
|
|
cae732bd8d | ||
|
|
f2f7b85f88 | ||
|
|
444ba0a874 | ||
|
|
71df313773 | ||
|
|
189c6453b4 | ||
|
|
5a190dd003 | ||
|
|
5bcb4bc9a0 | ||
|
|
28361a2bfe | ||
|
|
c1f84789ba | ||
|
|
5e11793221 | ||
|
|
dc40e6f797 | ||
|
|
b6f5c15189 | ||
|
|
1725b74695 | ||
|
|
e10cd2e0a5 | ||
|
|
34c238c152 | ||
|
|
07c71d17a2 | ||
|
|
f4cc39572c | ||
|
|
051a7ec3ae | ||
|
|
ee66488c36 | ||
|
|
f64bba0499 | ||
|
|
dbe18af9ea | ||
|
|
9acbab2c0e | ||
|
|
52dc6e55e5 | ||
|
|
0fb81cb5dd | ||
|
|
03e581e857 | ||
|
|
e0360a8c34 | ||
|
|
aecff8b1e7 | ||
|
|
67f6f5cdb1 | ||
|
|
4fb66d5d55 | ||
|
|
50bb6253da | ||
|
|
556dc3036e | ||
|
|
3ddcb1cfb5 | ||
|
|
191ea171cb | ||
|
|
48549d55b0 | ||
|
|
137a89f1e2 | ||
|
|
8c866ee6be | ||
|
|
0239e7e77f | ||
|
|
dddf400b7e | ||
|
|
c220b0dcfa | ||
|
|
2555e0d7e6 | ||
|
|
dfeacc8edb | ||
|
|
9ef7f0a940 | ||
|
|
5cddfdcda6 | ||
|
|
54ae4feac8 | ||
|
|
a2c5ea2c08 | ||
|
|
a3daf1a6d1 | ||
|
|
6c313a5846 | ||
|
|
bbaba520ab | ||
|
|
a0a62d119d | ||
|
|
7573551ccb | ||
|
|
5d11ad1e8a | ||
|
|
cd525c7bb1 | ||
|
|
4644a04ee3 | ||
|
|
0af956fe7e | ||
|
|
9ba4b4f901 | ||
|
|
cf3348e41c | ||
|
|
7b04f399b0 | ||
|
|
3aab0c568b | ||
|
|
21877b851c | ||
|
|
d7ed325913 | ||
|
|
07aa7381a9 | ||
|
|
bb1c5fe833 | ||
|
|
3f1dfde45f | ||
|
|
c15cc5c510 | ||
|
|
99e890b52c | ||
|
|
72f0f0b346 | ||
|
|
f3af86c67e | ||
|
|
3eef9fcea1 | ||
|
|
906cf353b2 | ||
|
|
8a44c35e8c | ||
|
|
3e34d38b2d | ||
|
|
92f8ce13df | ||
|
|
f0d821a83c | ||
|
|
b8fbe8c1d3 | ||
|
|
1a237e67df | ||
|
|
db726dc570 | ||
|
|
4bbfdee3db | ||
|
|
88233497ab | ||
|
|
b96b6a46ba | ||
|
|
0efada5548 | ||
|
|
99798b2202 | ||
|
|
f327b7e9dc | ||
|
|
d7d31d6041 | ||
|
|
72998869a3 | ||
|
|
c47ba70f45 | ||
|
|
e68b491806 | ||
|
|
4190501ec7 | ||
|
|
e87d0bcdf4 | ||
|
|
c032f5043e | ||
|
|
79b5a0a716 | ||
|
|
4fc9a4c991 | ||
|
|
8396e878da | ||
|
|
fe65a79d19 | ||
|
|
a8a602d3ff | ||
|
|
2930169517 | ||
|
|
d95ab0247a | ||
|
|
20dedcd841 | ||
|
|
14c8dabffe | ||
|
|
811ec68434 | ||
|
|
c2e98a86d4 | ||
|
|
48fb6e2c88 | ||
|
|
9b1ecce298 | ||
|
|
ca83d59e10 | ||
|
|
160a58238a | ||
|
|
dd0e9cf6b1 | ||
|
|
3c23d21835 | ||
|
|
fac696b394 | ||
|
|
9215c2610c | ||
|
|
119652bd95 | ||
|
|
011dd7b0f6 | ||
|
|
52b098ca11 | ||
|
|
82877a8aa3 | ||
|
|
a1bc5b8a2b | ||
|
|
c19490026d | ||
|
|
bc3e198cba | ||
|
|
b946ce971f | ||
|
|
c2eeda3f09 | ||
|
|
75924256c1 | ||
|
|
42c80667fd | ||
|
|
3c942c50d9 | ||
|
|
335305de9c | ||
|
|
48047bb120 | ||
|
|
b44ffcf5e2 | ||
|
|
ff436137df | ||
|
|
42236b435f | ||
|
|
a27501598a | ||
|
|
28017c14e3 | ||
|
|
ac3259b669 | ||
|
|
5560b9198b | ||
|
|
51319d2cae | ||
|
|
5ff5853a6e | ||
|
|
24d7fa6401 | ||
|
|
65007a4d02 | ||
|
|
4eed307023 | ||
|
|
0dd94666f5 | ||
|
|
c4d4363abd | ||
|
|
0197a30845 | ||
|
|
346cce5745 | ||
|
|
e3439b6af2 | ||
|
|
59ebc49f0f | ||
|
|
ca86fd3219 | ||
|
|
1ed5a135ed | ||
|
|
f6a35fe784 | ||
|
|
9f65735813 | ||
|
|
2ea108ae28 | ||
|
|
d7b5cde35f | ||
|
|
ba9e81068e | ||
|
|
a7b6d60948 | ||
|
|
eb2a9484b8 | ||
|
|
a92e1c508f | ||
|
|
0fc6533fcb | ||
|
|
01fd6594cf | ||
|
|
752cfbe04c | ||
|
|
1ffeaf24ef | ||
|
|
b7e5592df1 | ||
|
|
944a3d95ff | ||
|
|
29dda71bad | ||
|
|
0faadee83c | ||
|
|
78374f18a4 | ||
|
|
729fcd5f09 | ||
|
|
c59b3f3bc1 | ||
|
|
a037934e21 | ||
|
|
56e7df256a | ||
|
|
429acda3ee | ||
|
|
cf4d5a8cfe | ||
|
|
ed20823380 | ||
|
|
12d3a7d307 | ||
|
|
e82d7fb753 | ||
|
|
5188d1d927 | ||
|
|
b8bf04f5ec | ||
|
|
f31af075d0 | ||
|
|
3b989eefe0 | ||
|
|
a2d6ec1119 | ||
|
|
2ba5fab30e | ||
|
|
f74bde3e62 | ||
|
|
98c6b22c10 | ||
|
|
be0c5786a0 | ||
|
|
a982dd11fa | ||
|
|
fd61a8e89e | ||
|
|
2c1224dce7 | ||
|
|
c7530621ad | ||
|
|
a7ba08158b | ||
|
|
42764c99be | ||
|
|
2ad54a6f6e | ||
|
|
f941597e43 | ||
|
|
c1e89d73fd | ||
|
|
d0665d7a12 | ||
|
|
ac4fb39a73 | ||
|
|
45808db8dc | ||
|
|
47b333303e | ||
|
|
27e8f4db3d | ||
|
|
c06751fdf8 | ||
|
|
9b30058284 | ||
|
|
22719c6596 | ||
|
|
6fff25ecbc | ||
|
|
cf516b0eb8 | ||
|
|
8c4d8a4f14 | ||
|
|
ded2a79966 | ||
|
|
d52223f024 | ||
|
|
4030616bbf | ||
|
|
88451d16ba | ||
|
|
3691ae66b6 | ||
|
|
203cbf2ea0 | ||
|
|
b6c2770a30 | ||
|
|
1a0c2e24eb | ||
|
|
735d38cd7c | ||
|
|
9e2ed8b729 | ||
|
|
adc216698f | ||
|
|
1cbd95eeee | ||
|
|
db930a501f | ||
|
|
2f2459e120 | ||
|
|
8fd76cb873 | ||
|
|
c8fbbd8f3e | ||
|
|
b0a9f6c55b | ||
|
|
b8b341fea6 | ||
|
|
9a322ef016 | ||
|
|
312263821f | ||
|
|
9e80ee005e | ||
|
|
3aa68b1a0b | ||
|
|
ca470c3d4e | ||
|
|
6642181b9d | ||
|
|
a67fec7324 | ||
|
|
aad24c7ffc | ||
|
|
fe508fa3b5 | ||
|
|
2318b70929 | ||
|
|
fcc5b3486f | ||
|
|
c324bb3eff | ||
|
|
ff1c348970 | ||
|
|
16976013d1 | ||
|
|
172896b15a | ||
|
|
fe8915122a | ||
|
|
7db056b75a | ||
|
|
6f23316c4a | ||
|
|
fa7141288f | ||
|
|
63a9fcf2e7 | ||
|
|
b6f90aaf1f | ||
|
|
4ef03a8950 | ||
|
|
ef82c5073a | ||
|
|
237b4d22a2 | ||
|
|
823edbf0ab | ||
|
|
a72fed191e | ||
|
|
5015dd8a1f | ||
|
|
5abbd5b2da | ||
|
|
0c646bc3d1 | ||
|
|
f4e4349cad | ||
|
|
9845cc7c9c | ||
|
|
fdc29e53d3 | ||
|
|
a0f84e1b73 | ||
|
|
21379b0cf5 | ||
|
|
65895760ea | ||
|
|
20730e0afb | ||
|
|
c0295836a8 | ||
|
|
8c50df7bbf | ||
|
|
ec0fc7f816 | ||
|
|
f5c6b07246 | ||
|
|
35256f809e | ||
|
|
01201582b7 | ||
|
|
24b65fbe41 | ||
|
|
457587f033 | ||
|
|
78cf383197 | ||
|
|
71c784c8bc | ||
|
|
e4269a7140 | ||
|
|
3734937878 | ||
|
|
07c1c221cb | ||
|
|
246e599142 | ||
|
|
f1aa04858d | ||
|
|
301208c889 | ||
|
|
b5e3779cf2 | ||
|
|
56e2bd0be4 | ||
|
|
34cb030c7b | ||
|
|
a91099b33b | ||
|
|
ad9a3b8b45 | ||
|
|
c7e43807bf | ||
|
|
d8e7cf09b1 | ||
|
|
4f406d752d | ||
|
|
6d85564696 | ||
|
|
071f38c482 | ||
|
|
b81c66b4c7 | ||
|
|
0e5d15e072 | ||
|
|
78a20a11b2 | ||
|
|
54431f3360 | ||
|
|
943b46881e | ||
|
|
757012c289 | ||
|
|
0a8718312d | ||
|
|
68b53cfb25 | ||
|
|
935e991786 | ||
|
|
43c89a019c | ||
|
|
57aa77515a | ||
|
|
8dd2373a08 | ||
|
|
03470df2ff | ||
|
|
5aaef06572 | ||
|
|
0b8e964f45 | ||
|
|
c86a23de04 | ||
|
|
ca0b2a012e | ||
|
|
4401a58b2a | ||
|
|
ccabb2af0c | ||
|
|
875f1b248d | ||
|
|
b1c5e807ca | ||
|
|
cf30ba443c | ||
|
|
8c62a9c228 | ||
|
|
3bde30215b | ||
|
|
46db6e4a00 | ||
|
|
cddb5b612f | ||
|
|
d56986e037 | ||
|
|
e9b2f70238 | ||
|
|
de59a00a30 | ||
|
|
7eea851880 | ||
|
|
0515becf7a | ||
|
|
6b2a58ffcd | ||
|
|
30cebba4d6 | ||
|
|
afc0ba5cdc | ||
|
|
cf3f133df1 | ||
|
|
eb03584c16 | ||
|
|
f0aac87b35 |
@@ -12,6 +12,8 @@ win/buildall.vc.bat
|
||||
win/coffbase.txt
|
||||
win/makefile.vc
|
||||
win/rules.vc
|
||||
win/rules-ext.vc
|
||||
win/targets.vc
|
||||
win/tcl.dsp
|
||||
win/tcl.dsw
|
||||
win/tcl.hpj.in
|
||||
@@ -12,6 +12,8 @@ win/buildall.vc.bat
|
||||
win/coffbase.txt
|
||||
win/makefile.vc
|
||||
win/rules.vc
|
||||
win/rules-ext.vc
|
||||
win/targets.vc
|
||||
win/tcl.dsp
|
||||
win/tcl.dsw
|
||||
win/tcl.hpj.in
|
||||
@@ -44,5 +44,6 @@ unix/pkgs/*
|
||||
win/Debug*
|
||||
win/Release*
|
||||
win/pkgs/*
|
||||
win/coffbase.txt
|
||||
win/tcl.hpj
|
||||
win/nmhlp-out.txt
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>tcl8.7</name>
|
||||
<name>tcl8</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
|
||||
@@ -8234,7 +8234,7 @@ Dropped support for OS X versions less than 10.4 (Tiger) (fellows)
|
||||
|
||||
2013-05-16 (platform support) mingw-4.0 (nijtmans)
|
||||
|
||||
2013-05-19 (platform support) FreeBSD updates (gahr)
|
||||
2013-05-19 (platform support) FreeBSD updates (cerutti)
|
||||
|
||||
2013-05-20 (bug fix)[3613567] access error temp file creation (keene)
|
||||
|
||||
@@ -8657,7 +8657,7 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
|
||||
|
||||
2016-05-21 (bug)[f7d4e] [namespace delete] performance (fellows)
|
||||
|
||||
2016-06-02 (TIP 447) execution time verbosity option (gahr)
|
||||
2016-06-02 (TIP 447) execution time verbosity option (cerutti)
|
||||
=> tcltest 2.4.0
|
||||
|
||||
2016-06-16 (bug)[16828b] crash due to [vwait] trace undo fail (dah,porter)
|
||||
@@ -8796,6 +8796,45 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
|
||||
|
||||
--- Released 8.6.7, August 9, 2017 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
2017-08-10 [array names -regexp] supports backrefs (goth)
|
||||
|
||||
2017-08-10 Fix gcc build failures due to #pragma placement (cassoff,fellows)
|
||||
|
||||
2017-08-29 (bug)[b50fb2] exec redir append stdout and stderr to file (coulter)
|
||||
|
||||
2017-08-31 (bug)[2a9465] http state 100 continue handling broken (oehlmann)
|
||||
=> http 2.8.12
|
||||
|
||||
2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter)
|
||||
|
||||
2017-10-19 (bug)[1a5655] [info * methods] includes mixins (fellows)
|
||||
|
||||
2017-10-23 tzdata updated to Olson's tzdata2017c (jima)
|
||||
|
||||
2017-10-24 (bug)[fc1409] segfault in method cloning, oo-15.15 (coulter,fellows)
|
||||
|
||||
2017-11-03 (bug)[6f2f83] More robust [load] for ReactOS (werner)
|
||||
|
||||
2017-11-08 (bug)[3298012] Stop crash when hash tables overflow 32 bits (porter)
|
||||
|
||||
2017-11-14 (bug)[5d6de6] Close failing case of [package prefer stable] (kupries)
|
||||
|
||||
2017-11-17 (bug)[fab924] Fix misleading [load] message on Windows (oehlmann)
|
||||
|
||||
2017-12-05 (bug)[4f6a1e] Crash when ensemble map and list are same (sebres)
|
||||
|
||||
2017-12-06 (bug)[ce3a21] file normalize failure when tail is empty (porter)
|
||||
|
||||
2017-12-08 (new)[TIP 477] nmake build system reform (nadkarni)
|
||||
|
||||
2017-12-19 (bug)[586e71] EvalObjv exception handling at level #0 (sebres,porter)
|
||||
|
||||
--- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tcl/ for details
|
||||
|
||||
Changes to 8.7a1 include all changes to the 8.6 line through 8.6.7,
|
||||
plus the following, which focuses on the high-level feature changes
|
||||
in this changeset (new minor version) rather than bug fixes:
|
||||
|
||||
2016-03-17 (bug)[0b8c38] socket accept callbacks always in global ns (porter)
|
||||
*** POTENTIAL INCOMPATIBILITY ***
|
||||
|
||||
@@ -8836,7 +8875,6 @@ improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
|
||||
2017-06-23 (TIP 472) Support 0d as prefix of decimal numbers (iyer,griffin)
|
||||
|
||||
2017-08-31 (bug)[2a9465] http state 100 continue handling broken (oehlmann)
|
||||
=> http 2.8.12
|
||||
|
||||
2017-09-02 (bug)[0e4d88] replace command, delete trace kills namespace (porter)
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* float.h --
|
||||
*
|
||||
* This is a dummy header file to #include in Tcl when there
|
||||
* is no float.h in /usr/include. Right now this file is empty:
|
||||
* Tcl contains #ifdefs to deal with the lack of definitions;
|
||||
* all it needs is for the #include statement to work.
|
||||
*
|
||||
* Copyright (c) 1993 The Regents of the University of California.
|
||||
* Copyright (c) 1994 Sun Microsystems, Inc.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution
|
||||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
@@ -260,10 +260,6 @@ Windows-only convenience
|
||||
functions for converting between UTF-8 and Windows strings
|
||||
based on the TCHAR type which is by convention
|
||||
a Unicode character on Windows NT.
|
||||
These functions are essentially wrappers around
|
||||
\fBTcl_UtfToExternalDString\fR and
|
||||
\fBTcl_ExternalToUtfDString\fR that convert to and from the
|
||||
Unicode encoding.
|
||||
.PP
|
||||
\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
|
||||
Given an \fIencoding\fR, the return value is the \fIname\fR argument that
|
||||
|
||||
+4
-4
@@ -176,10 +176,10 @@ it is faster to execute the script directly.
|
||||
.TP 23
|
||||
\fBTCL_EVAL_GLOBAL\fR
|
||||
.
|
||||
If this flag is set, the script is processed at global level. This
|
||||
means that it is evaluated in the global namespace and its variable
|
||||
context consists of global variables only (it ignores any Tcl
|
||||
procedures that are active).
|
||||
If this flag is set, the script is evaluated in the global namespace instead of
|
||||
the current namespace and its variable context consists of global variables
|
||||
only (it ignores any Tcl procedures that are active).
|
||||
.\" TODO: document TCL_EVAL_INVOKE and TCL_EVAL_NOERR.
|
||||
|
||||
.SH "MISCELLANEOUS DETAILS"
|
||||
.PP
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ are provided by the C language standard. The \fBTcl_WideInt\fR type is a
|
||||
typedef defined to be whatever signed integral type covers at least the
|
||||
64-bit integer range (-9223372036854775808 to 9223372036854775807). Depending
|
||||
on the platform and the C compiler, the actual type might be
|
||||
\fBlong int\fR, \fBlong long int\fR, \fB__int64\fR, or something else.
|
||||
\fBlong long int\fR, \fB__int64\fR, or something else.
|
||||
The \fBmp_int\fR type is a multiple-precision integer type defined
|
||||
by the LibTomMath multiple-precision integer library.
|
||||
.PP
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ the command. The \fIfreeProc\fR field will be initialized to zero,
|
||||
and \fIinterp->result\fR will point to an empty string. Commands that
|
||||
do not return any value can simply leave the fields alone.
|
||||
Furthermore, the empty string pointed to by \fIresult\fR is actually
|
||||
part of an array of \fBTCL_RESULT_SIZE\fR characters (approximately 200).
|
||||
part of an array of approximately 200 characters.
|
||||
If a command wishes to return a short string, it can simply copy
|
||||
it to the area pointed to by \fIinterp->result\fR. Or, it can use
|
||||
the sprintf procedure to generate a short result string at the location
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2008 by Kevin B. Kenny.
|
||||
.\" Copyright (c) 2018 by Nathan Coulter.
|
||||
.\"
|
||||
'\" See the file "license.terms" for information on usage and redistribution
|
||||
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
@@ -38,43 +39,39 @@ void
|
||||
.SH ARGUMENTS
|
||||
.AS Tcl_CmdDeleteProc *interp in
|
||||
.AP Tcl_Interp *interp in
|
||||
Interpreter in which to create or evaluate a command.
|
||||
The relevant Interpreter.
|
||||
.AP char *cmdName in
|
||||
Name of a new command to create.
|
||||
Name of the command to create.
|
||||
.AP Tcl_ObjCmdProc *proc in
|
||||
Implementation of a command that will be called whenever \fIcmdName\fR
|
||||
is invoked as a command in the unoptimized way.
|
||||
Called in order to evaluate a command. Is often just a small wrapper that uses
|
||||
\fBTcl_NRCallObjProc\fR to call \fInreProc\fR using a new trampoline. Behaves
|
||||
in the same way as the \fIproc\fR argument to \fBTcl_CreateObjCommand\fR(3)
|
||||
(\fIq.v.\fR).
|
||||
.AP Tcl_ObjCmdProc *nreProc in
|
||||
Implementation of a command that will be called whenever \fIcmdName\fR
|
||||
is invoked and requested to conserve the C stack.
|
||||
Called instead of \fIproc\fR when a trampoline is already in use.
|
||||
.AP ClientData clientData in
|
||||
Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
|
||||
\fIdeleteProc\fR and \fIobjProc\fR.
|
||||
Arbitrary one-word value passed to \fIproc\fR, \fInreProc\fR, \fIdeleteProc\fR
|
||||
and \fIobjProc\fR.
|
||||
.AP Tcl_CmdDeleteProc *deleteProc in/out
|
||||
Procedure to call before \fIcmdName\fR is deleted from the interpreter.
|
||||
This procedure allows for command-specific cleanup. If \fIdeleteProc\fR
|
||||
is \fBNULL\fR, then no procedure is called before the command is deleted.
|
||||
Called before \fIcmdName\fR is deleted from the interpreter, allowing for
|
||||
command-specific cleanup. May be NULL.
|
||||
.AP int objc in
|
||||
Count of parameters provided to the implementation of a command.
|
||||
Number of items in \fIobjv\fR.
|
||||
.AP Tcl_Obj **objv in
|
||||
Pointer to an array of Tcl values. Each value holds the value of a
|
||||
single word in the command to execute.
|
||||
Words in the command.
|
||||
.AP Tcl_Obj *objPtr in
|
||||
Pointer to a Tcl_Obj whose value is a script or expression to execute.
|
||||
A script or expression to evaluate.
|
||||
.AP int flags in
|
||||
ORed combination of flag bits that specify additional options.
|
||||
\fBTCL_EVAL_GLOBAL\fR is the only flag that is currently supported.
|
||||
.\" TODO: This is a lie. But kbk didn't grasp TCL_EVAL_INVOKE and
|
||||
.\" TCL_EVAL_NOERR well enough to document them.
|
||||
As described for \fITcl_EvalObjv\fR.
|
||||
.PP
|
||||
.AP Tcl_Command cmd in
|
||||
Token for a command that is to be used instead of the currently
|
||||
executing command.
|
||||
Token to use instead of one derived from the first word of \fIobjv\fR in order
|
||||
to evaluate a command.
|
||||
.AP Tcl_Obj *resultPtr out
|
||||
Pointer to an unshared Tcl_Obj where the result of expression
|
||||
evaluation is written.
|
||||
Pointer to an unshared Tcl_Obj where the result of the evaluation is stored if
|
||||
the return code is TCL_OK.
|
||||
.AP Tcl_NRPostProc *postProcPtr in
|
||||
Pointer to a function that will be invoked when the command currently
|
||||
executing in the interpreter designated by \fIinterp\fR completes.
|
||||
A function to push.
|
||||
.AP ClientData data0 in
|
||||
.AP ClientData data1 in
|
||||
.AP ClientData data2 in
|
||||
@@ -84,98 +81,51 @@ to the function designated by \fIpostProcPtr\fR when it is invoked.
|
||||
.BE
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
This series of C functions provides an interface whereby commands that
|
||||
are implemented in C can be evaluated, and invoke Tcl commands scripts
|
||||
and scripts, without consuming space on the C stack. The non-recursive
|
||||
evaluation is done by installing a \fItrampoline\fR, a small piece of
|
||||
code that invokes a command or script, and then executes a series of
|
||||
callbacks when the command or script returns.
|
||||
These functions provide an interface to the function stack that an interpreter
|
||||
iterates through to evaluate commands. The routine behind a command is
|
||||
implemented by an initial function and any additional functions that the
|
||||
routine pushes onto the stack as it progresses. The interpreter itself pushes
|
||||
functions onto the stack to react to the end of a routine and to exercise other
|
||||
forms of control such as switching between in-progress stacks and the
|
||||
evaluation of other scripts at additional levels without adding frames to the C
|
||||
stack. To execute a routine, the initial function for the routine is called
|
||||
and then a small bit of code called a \fItrampoline\fR iteratively takes
|
||||
functions off the stack and calls them, using the value of the last call as the
|
||||
value of the routine.
|
||||
.PP
|
||||
The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
|
||||
interpreter designated by \fIinterp\fR that is prepared to handle
|
||||
nonrecursive evaluation with a trampoline. The \fIcmdName\fR argument
|
||||
gives the name of the new command. If \fIcmdName\fR contains any
|
||||
namespace qualifiers, then the new command is added to the specified
|
||||
namespace; otherwise, it is added to the global namespace. \fIproc\fR
|
||||
gives the procedure that will be called when the interpreter wishes to
|
||||
evaluate the command in an unoptimized manner, and \fInreProc\fR is
|
||||
the procedure that will be called when the interpreter wishes to
|
||||
evaluate the command using a trampoline. \fIdeleteProc\fR is a
|
||||
function that will be called before the command is deleted from the
|
||||
interpreter. When any of the three functions is invoked, it is passed
|
||||
the \fIclientData\fR parameter.
|
||||
\fBTcl_NRCallObjProc\fR calls \fInreProc\fR using a new trampoline.
|
||||
.PP
|
||||
\fBTcl_NRCreateCommand\fR deletes any existing command
|
||||
\fIname\fR already associated with the interpreter
|
||||
(however see below for an exception where the existing command
|
||||
is not deleted).
|
||||
It returns a token that may be used to refer
|
||||
to the command in subsequent calls to \fBTcl_GetCommandName\fR.
|
||||
If \fBTcl_NRCreateCommand\fR is called for an interpreter that is in
|
||||
the process of being deleted, then it does not create a new command,
|
||||
does not delete any existing command of the same name, and returns NULL.
|
||||
\fBTcl_NRCreateCommand\fR, an alternative to \fBTcl_CreateObjCommand\fR,
|
||||
resolves \fIcmdName\fR, which may contain namespace qualifiers, relative to the
|
||||
current namespace, creates a command by that name, and returns a token for the
|
||||
command which may be used in subsequent calls to \fBTcl_GetCommandName\fR.
|
||||
Except for a few cases noted below any existing command by the same name is
|
||||
first deleted. If \fIinterp\fR is in the process of being deleted
|
||||
\fBTcl_NRCreateCommand\fR does not create any command, does not delete any
|
||||
command, and returns NULL.
|
||||
.PP
|
||||
The \fIproc\fR and \fInreProc\fR function are expected to conform to
|
||||
all the rules set forth for the \fIproc\fR argument to
|
||||
\fBTcl_CreateObjCommand\fR(3) (\fIq.v.\fR).
|
||||
\fBTcl_NREvalObj\fR pushes a function that is like \fBTcl_EvalObjEx\fR but
|
||||
consumes no space on the C stack.
|
||||
.PP
|
||||
When a command that is written to cope with evaluation via trampoline
|
||||
is invoked without a trampoline on the stack, it will usually respond
|
||||
to the invocation by creating a trampoline and calling the
|
||||
trampoline-enabled implementation of the same command. This call is done by
|
||||
means of \fBTcl_NRCallObjProc\fR. In the call to
|
||||
\fBTcl_NRCallObjProc\fR, the \fIinterp\fR, \fIclientData\fR,
|
||||
\fIobjc\fR and \fIobjv\fR parameters should be the same ones that were
|
||||
passed to \fIproc\fR. The \fInreProc\fR parameter should designate the
|
||||
trampoline-enabled implementation of the command.
|
||||
\fBTcl_NREvalObjv\fR pushes a function that is like \fBTcl_EvalObjv\fR but
|
||||
consumes no space on the C stack.
|
||||
.PP
|
||||
\fBTcl_NREvalObj\fR arranges for the script contained in \fIobjPtr\fR
|
||||
to be evaluated in the interpreter designated by \fIinterp\fR after
|
||||
the current command (which must be trampoline-enabled) returns. It is
|
||||
the method by which a command may invoke a script without consuming
|
||||
space on the C stack. Similarly, \fBTcl_NREvalObjv\fR arranges to
|
||||
invoke a single Tcl command whose words have already been separated
|
||||
and substituted. The \fIobjc\fR and \fIobjv\fR parameters give the
|
||||
words of the command to be evaluated when execution reaches the
|
||||
trampoline.
|
||||
\fBTcl_NRCmdSwap\fR is like \fBTcl_NREvalObjv\fR, but uses \fIcmd\fR, a token
|
||||
previously returned by \fBTcl_CreateObjCommand\fR or
|
||||
\fBTcl_GetCommandFromObj\fR, instead of resolving the first word of \fIobjv\fR.
|
||||
. The name of this command must be the same as \fIobjv[0]\fR.
|
||||
.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 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_NREvalObjv\fR.
|
||||
\fBTcl_NRExprObj\fR pushes a function that evaluates \fIobjPtr\fR as an
|
||||
expression in the same manner as \fBTcl_ExprObj\fR but without consuming space
|
||||
on the C stack.
|
||||
.PP
|
||||
\fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
|
||||
all accept a \fIflags\fR parameter, which is an OR-ed-together set of
|
||||
bits to control evaluation. At the present time, the only supported flag
|
||||
available to callers is \fBTCL_EVAL_GLOBAL\fR.
|
||||
.\" TODO: Again, this is a lie. Do we want to explain TCL_EVAL_INVOKE
|
||||
.\" and TCL_EVAL_NOERR?
|
||||
If the \fBTCL_EVAL_GLOBAL\fR flag is set, the script or command is
|
||||
evaluated in the global namespace. If it is not set, it is evaluated
|
||||
in the current namespace.
|
||||
All of the functions return \fBTCL_OK\fR if the evaluation of the script,
|
||||
command, or expression has been scheduled successfully. Otherwise (for example
|
||||
if the command name cannot be resolved), they return \fBTCL_ERROR\fR and store
|
||||
a message as the interpreter's result.
|
||||
.PP
|
||||
\fBTcl_NRExprObj\fR arranges for the expression contained in \fIobjPtr\fR
|
||||
to be evaluated in the interpreter designated by \fIinterp\fR after
|
||||
the current command (which must be trampoline-enabled) returns. It is
|
||||
the method by which a command may evaluate a Tcl expression without consuming
|
||||
space on the C stack. The argument \fIresultPtr\fR is a pointer to an
|
||||
unshared Tcl_Obj where the result of expression evaluation is to be written.
|
||||
If expression evaluation returns any code other than TCL_OK, the
|
||||
\fIresultPtr\fR value is left untouched.
|
||||
.PP
|
||||
All of the routines return \fBTCL_OK\fR if command or expression invocation
|
||||
has been scheduled successfully. If for any reason the scheduling cannot
|
||||
be completed (for example, if the interpreter is unable to find
|
||||
the requested command), they return \fBTCL_ERROR\fR with an
|
||||
appropriate message left in the interpreter's result.
|
||||
.PP
|
||||
\fBTcl_NRAddCallback\fR arranges to have a C function called when the
|
||||
current trampoline-enabled command in the Tcl interpreter designated
|
||||
by \fIinterp\fR returns. The \fIpostProcPtr\fR argument is a pointer
|
||||
to the callback function, which must have arguments and return value
|
||||
consistent with the \fBTcl_NRPostProc\fR data type:
|
||||
\fBTcl_NRAddCallback\fR pushes \fIpostProcPtr\fR. The signature for
|
||||
\fBTcl_NRPostProc\fR is:
|
||||
.PP
|
||||
.CS
|
||||
typedef int
|
||||
@@ -185,25 +135,13 @@ typedef int
|
||||
int \fIresult\fR);
|
||||
.CE
|
||||
.PP
|
||||
When the trampoline invokes the callback function, the \fIdata\fR
|
||||
parameter will point to an array containing the four one-word
|
||||
quantities that were passed to \fBTcl_NRAddCallback\fR in the
|
||||
\fIdata0\fR through \fIdata3\fR parameters. The Tcl interpreter will
|
||||
be designated by the \fIinterp\fR parameter, and the \fIresult\fR
|
||||
parameter will contain the result (\fBTCL_OK\fR, \fBTCL_ERROR\fR,
|
||||
\fBTCL_RETURN\fR, \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR) that was
|
||||
returned by the command evaluation. The callback function is expected,
|
||||
in turn, either to return a \fIresult\fR to control further evaluation.
|
||||
.PP
|
||||
Multiple \fBTcl_NRAddCallback\fR invocations may request multiple
|
||||
callbacks, which may be to the same or different callback
|
||||
functions. If multiple callbacks are requested, they are executed in
|
||||
last-in, first-out order, that is, the most recently requested
|
||||
callback is executed first.
|
||||
\fIdata\fR is a pointer to an array containing \fIdata0\fR through \fIdata3\fR.
|
||||
\fIresult\fR is the value returned by the previous function implementing part
|
||||
the routine.
|
||||
.SH EXAMPLE
|
||||
.PP
|
||||
The usual pattern for Tcl commands that invoke other Tcl commands
|
||||
is something like:
|
||||
The following command uses \fBTcl_EvalObjEx\fR, which consumes space on the C
|
||||
stack, to evalute a script:
|
||||
.PP
|
||||
.CS
|
||||
int
|
||||
@@ -228,28 +166,17 @@ int
|
||||
\fITheCmdOldObjProc\fR, clientData, TheCmdDeleteProc);
|
||||
.CE
|
||||
.PP
|
||||
To enable a command like this one for trampoline-based evaluation,
|
||||
it must be split into three pieces:
|
||||
.IP \(bu
|
||||
A non-trampoline implementation, \fITheCmdNewObjProc\fR,
|
||||
which will simply create a trampoline
|
||||
and invoke the trampoline-based implementation.
|
||||
.IP \(bu
|
||||
A trampoline-enabled implementation, \fITheCmdNRObjProc\fR. This
|
||||
function will perform the initialization, request that the trampoline
|
||||
call the postprocessing routine after command evaluation, and finally,
|
||||
request that the trampoline call the inner command.
|
||||
.IP \(bu
|
||||
A postprocessing routine, \fITheCmdPostProc\fR. This function will
|
||||
perform the postprocessing formerly done after the return from the
|
||||
inner command in \fITheCmdObjProc\fR.
|
||||
.PP
|
||||
The non-trampoline implementation is simple and stylized, containing
|
||||
a single statement:
|
||||
To avoid consuming space on the C stack, \fITheCmdOldObjProc\fR is renamed to
|
||||
\fITheCmdNRObjProc\fR and the postprocessing step is split into a separate
|
||||
function, \fITheCmdPostProc\fR, which is pushed onto the function stack.
|
||||
\fITcl_EvalObjEx\fR is replaced with \fITcl_NREvalObj\fR, which uses a
|
||||
trampoline instead of consuming space on the C stack. A new version of
|
||||
\fITheCmdOldObjProc\fR is just a a wrapper that uses \fBTcl_NRCallObjProc\fR to
|
||||
call \fITheCmdNRObjProc\fR:
|
||||
.PP
|
||||
.CS
|
||||
int
|
||||
\fITheCmdNewObjProc\fR(
|
||||
\fITheCmdOldObjProc\fR(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
@@ -260,9 +187,6 @@ int
|
||||
}
|
||||
.CE
|
||||
.PP
|
||||
The trampoline-enabled implementation requests postprocessing,
|
||||
and returns to the trampoline requesting command evaluation.
|
||||
.PP
|
||||
.CS
|
||||
int
|
||||
\fITheCmdNRObjProc\fR
|
||||
@@ -284,9 +208,6 @@ int
|
||||
}
|
||||
.CE
|
||||
.PP
|
||||
The postprocessing procedure does whatever the original command did
|
||||
upon return from the inner evaluation.
|
||||
.PP
|
||||
.CS
|
||||
int
|
||||
\fITheCmdNRPostProc\fR(
|
||||
@@ -303,26 +224,13 @@ int
|
||||
}
|
||||
.CE
|
||||
.PP
|
||||
If \fItheCommand\fR is a command that results in multiple commands or
|
||||
scripts being evaluated, its postprocessing routine may schedule
|
||||
additional postprocessing and then request another command evaluation
|
||||
by means of \fBTcl_NREvalObj\fR or one of the other evaluation
|
||||
routines. Looping and sequencing constructs may be implemented in this way.
|
||||
Any function comprising a routine can push other functions, making it possible
|
||||
implement looping and sequencing constructs using the function stack.
|
||||
.PP
|
||||
Finally, to install a trampoline-enabled command in the interpreter,
|
||||
\fBTcl_NRCreateCommand\fR is used in place of
|
||||
\fBTcl_CreateObjCommand\fR. It accepts two command procedures instead
|
||||
of one. The first is for use when no trampoline is yet on the stack,
|
||||
and the second is for use when there is already a trampoline in place.
|
||||
.PP
|
||||
.CS
|
||||
\fBTcl_NRCreateCommand\fR(interp, "theCommand",
|
||||
\fITheCmdNewObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
|
||||
TheCmdDeleteProc);
|
||||
.CE
|
||||
.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, value, result, script
|
||||
.SH COPYRIGHT
|
||||
Copyright (c) 2008 by Kevin B. Kenny
|
||||
Copyright (c) 2008 by Kevin B. Kenny.
|
||||
Copyright (c) 2018 by Nathan Coulter.
|
||||
|
||||
+1
-1
@@ -257,7 +257,7 @@ The \fBincr\fR command first gets an integer from \fIx\fR's value
|
||||
by calling \fBTcl_GetIntFromObj\fR.
|
||||
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
|
||||
by setting the value's internal representation
|
||||
to the integer \fB123\fR
|
||||
and setting the value's \fItypePtr\fR
|
||||
to point to the integer Tcl_ObjType structure.
|
||||
|
||||
+2
-2
@@ -54,9 +54,9 @@ is called, Tcl will take care of memory management.
|
||||
.PP
|
||||
The second triplet stores the snapshot of only the interpreter
|
||||
result (not its complete state) in memory allocated by the caller.
|
||||
These routines are passed a pointer to a \fBTcl_SavedResult\fR structure
|
||||
These routines are passed a pointer to \fBTcl_SavedResult\fR
|
||||
that is used to store enough information to restore the interpreter result.
|
||||
This structure can be allocated on the stack of the calling
|
||||
\fBTcl_SavedResult\fR can be allocated on the stack of the calling
|
||||
procedure. These routines do not save the state of any error
|
||||
information in the interpreter (e.g. the \fB\-errorcode\fR or
|
||||
\fB\-errorinfo\fR return options, when an error is in progress).
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS char *str in/out
|
||||
.AP int ch in
|
||||
The Tcl_UniChar to be converted.
|
||||
The Unicode character to be converted.
|
||||
.AP char *str in/out
|
||||
Pointer to UTF-8 string to be converted in place.
|
||||
.BE
|
||||
|
||||
@@ -48,19 +48,16 @@ int
|
||||
.SH ARGUMENTS
|
||||
.AS int ch
|
||||
.AP int ch in
|
||||
The Tcl_UniChar to be examined.
|
||||
The Unicode character to be examined.
|
||||
.BE
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
All of the routines described examine Tcl_UniChars and return a
|
||||
All of the routines described examine Unicode characters and return a
|
||||
boolean value. A non-zero return value means that the character does
|
||||
belong to the character class associated with the called routine. The
|
||||
rest of this document just describes the character classes associated
|
||||
with the various routines.
|
||||
.PP
|
||||
Note: A Tcl_UniChar is a Unicode character represented as an unsigned,
|
||||
fixed-size quantity.
|
||||
|
||||
.SH "CHARACTER CLASSES"
|
||||
.PP
|
||||
|
||||
@@ -77,7 +77,7 @@ int
|
||||
Buffer in which the UTF-8 representation of the Tcl_UniChar is stored. At most
|
||||
\fBTCL_UTF_MAX\fR bytes are stored in the buffer.
|
||||
.AP int ch in
|
||||
The Tcl_UniChar to be converted or examined.
|
||||
The Unicode character to be converted or examined.
|
||||
.AP Tcl_UniChar *chPtr out
|
||||
Filled with the Tcl_UniChar represented by the head of the UTF-8 string.
|
||||
.AP "const char" *src in
|
||||
|
||||
+23
-10
@@ -83,14 +83,15 @@ Specifies that the number should be padded on the left with
|
||||
zeroes instead of spaces.
|
||||
.TP 10
|
||||
\fB#\fR
|
||||
Requests an alternate output form. For \fBo\fR and \fBO\fR
|
||||
conversions it guarantees that the first digit is always \fB0\fR.
|
||||
For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively)
|
||||
Requests an alternate output form. For \fBo\fR conversions,
|
||||
\fB0o\fR will be added to the beginning of the result unless
|
||||
it is zero. For \fBx\fR or \fBX\fR conversions, \fB0x\fR
|
||||
will be added to the beginning of the result unless it is zero.
|
||||
For \fBb\fR conversions, \fB0b\fR
|
||||
will be added to the beginning of the result unless it is zero.
|
||||
For \fBd\fR conversions, \fB0d\fR will be added to the beginning
|
||||
of the result unless it is zero.
|
||||
For \fBd\fR conversions, \fB0d\fR there is no effect unless
|
||||
the \fB0\fR specifier is used as well: In that case, \fB0d\fR
|
||||
will be added to the beginning.
|
||||
For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
|
||||
\fBg\fR, and \fBG\fR) it guarantees that the result always
|
||||
has a decimal point.
|
||||
@@ -132,7 +133,7 @@ it must be a numeric string.
|
||||
.SS "OPTIONAL SIZE MODIFIER"
|
||||
.PP
|
||||
The fifth part of a conversion specifier is a size modifier,
|
||||
which must be \fBll\fR, \fBh\fR, or \fBl\fR.
|
||||
which must be \fBll\fR, \fBh\fR, \fBl\fR, or \fBL\fR.
|
||||
If it is \fBll\fR it specifies that an integer value is taken
|
||||
without truncation for conversion to a formatted substring.
|
||||
If it is \fBh\fR it specifies that an integer value is
|
||||
@@ -140,7 +141,9 @@ truncated to a 16-bit range before converting. This option is rarely useful.
|
||||
If it is \fBl\fR it specifies that the integer value is
|
||||
truncated to the same range as that produced by the \fBwide()\fR
|
||||
function of the \fBexpr\fR command (at least a 64-bit range).
|
||||
If neither \fBh\fR nor \fBl\fR are present, the integer value is
|
||||
If it is \fBL\fR it specifies that an integer or double value is taken
|
||||
without truncation for conversion to a formatted substring.
|
||||
If neither \fBh\fR nor \fBl\fR nor \fBL\fR are present, the integer value is
|
||||
truncated to the same range as that produced by the \fBint()\fR
|
||||
function of the \fBexpr\fR command (at least a 32-bit range, but
|
||||
determined by the value of the \fBwordSize\fR element of the
|
||||
@@ -171,7 +174,7 @@ for \fBx\fR and
|
||||
for \fBX\fR).
|
||||
.TP 10
|
||||
\fBb\fR
|
||||
Convert integer to binary string, using digits 0 and 1.
|
||||
Convert integer to unsigned binary string, using digits 0 and 1.
|
||||
.TP 10
|
||||
\fBc\fR
|
||||
Convert integer to the Unicode character it represents.
|
||||
@@ -200,8 +203,19 @@ precision, then convert number as for \fB%e\fR or
|
||||
Otherwise convert as for \fB%f\fR.
|
||||
Trailing zeroes and a trailing decimal point are omitted.
|
||||
.TP 10
|
||||
\fBa\fR or \fBA\fR
|
||||
Convert double to hexadecimal notation in the form
|
||||
\fI0x1.yyy\fBp\(+-\fIzz\fR, where the number of \fIy\fR's is
|
||||
determined by the precision (default: 13).
|
||||
If the \fBA\fR form is used then the hex characters
|
||||
are printed in uppercase.
|
||||
.TP 10
|
||||
\fB%\fR
|
||||
No conversion: just insert \fB%\fR.
|
||||
.TP 10
|
||||
\fBp\fR
|
||||
Shorthand form for \fB0x%zx\fR, so it outputs the integer in
|
||||
hexadecimal form with \fB0x\fR prefix.
|
||||
.SH "DIFFERENCES FROM ANSI SPRINTF"
|
||||
.PP
|
||||
The behavior of the format command is the same as the
|
||||
@@ -210,13 +224,12 @@ differences:
|
||||
.IP [1]
|
||||
Tcl guarantees that it will be working with UNICODE characters.
|
||||
.IP [2]
|
||||
\fB%p\fR and \fB%n\fR specifiers are not supported.
|
||||
\fB%n\fR specifier is not supported.
|
||||
.IP [3]
|
||||
For \fB%c\fR conversions the argument must be an integer value,
|
||||
which will then be converted to the corresponding character value.
|
||||
.IP [4]
|
||||
The size modifiers are ignored when formatting floating-point values.
|
||||
The \fBll\fR modifier has no \fBsprintf\fR counterpart.
|
||||
The \fBb\fR specifier has no \fBsprintf\fR counterpart.
|
||||
.SH EXAMPLES
|
||||
.PP
|
||||
|
||||
@@ -148,6 +148,19 @@ or \fB\-not\fR.
|
||||
These options are used to search lists of lists. They may be used
|
||||
with any other options.
|
||||
.TP
|
||||
\fB\-stride\0\fIstrideLength\fR
|
||||
.
|
||||
If this option is specified, the list is treated as consisting of
|
||||
groups of \fIstrideLength\fR elements and the groups are searched by
|
||||
either their first element or, if the \fB\-index\fR option is used,
|
||||
by the element within each group given by the first index passed to
|
||||
\fB\-index\fR (which is then ignored by \fB\-index\fR). The resulting
|
||||
index always points to the first element in a group.
|
||||
.PP
|
||||
The list length must be an integer multiple of \fIstrideLength\fR, which
|
||||
in turn must be at least 1. A \fIstrideLength\fR of 1 is the default and
|
||||
indicates no grouping.
|
||||
.TP
|
||||
\fB\-index\fR\0\fIindexList\fR
|
||||
.
|
||||
This option is designed for use when searching within nested lists.
|
||||
@@ -208,6 +221,13 @@ It is also possible to search inside elements:
|
||||
\fBlsearch\fR -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*
|
||||
\fI\(-> {a abc} {b bcd}\fR
|
||||
.CE
|
||||
.PP
|
||||
The same thing for a flattened list:
|
||||
.PP
|
||||
.CS
|
||||
\fBlsearch\fR -stride 2 -index 1 -all -inline {a abc b bcd c cde} *bc*
|
||||
\fI\(-> {a abc b bcd}\fR
|
||||
.CE
|
||||
.SH "SEE ALSO"
|
||||
foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n),
|
||||
lset(n), lsort(n), lrange(n), lreplace(n),
|
||||
|
||||
+55
-58
@@ -32,7 +32,7 @@ declare 0 {
|
||||
const char *version, const void *clientData)
|
||||
}
|
||||
declare 1 {
|
||||
CONST84_RETURN char *Tcl_PkgRequireEx(Tcl_Interp *interp,
|
||||
const char *Tcl_PkgRequireEx(Tcl_Interp *interp,
|
||||
const char *name, const char *version, int exact,
|
||||
void *clientDataPtr)
|
||||
}
|
||||
@@ -154,7 +154,7 @@ declare 35 {
|
||||
}
|
||||
declare 36 {
|
||||
int Tcl_GetIndexFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
CONST84 char *const *tablePtr, const char *msg, int flags, int *indexPtr)
|
||||
const char *const *tablePtr, const char *msg, int flags, int *indexPtr)
|
||||
}
|
||||
declare 37 {
|
||||
int Tcl_GetInt(Tcl_Interp *interp, const char *src, int *intPtr)
|
||||
@@ -285,7 +285,7 @@ declare 75 {
|
||||
declare 76 {
|
||||
void Tcl_BackgroundError(Tcl_Interp *interp)
|
||||
}
|
||||
declare 77 {
|
||||
declare 77 {deprecated {Use Tcl_UtfBackslash}} {
|
||||
char Tcl_Backslash(const char *src, int *readPtr)
|
||||
}
|
||||
declare 78 {
|
||||
@@ -306,7 +306,7 @@ declare 82 {
|
||||
int Tcl_CommandComplete(const char *cmd)
|
||||
}
|
||||
declare 83 {
|
||||
char *Tcl_Concat(int argc, CONST84 char *const *argv)
|
||||
char *Tcl_Concat(int argc, const char *const *argv)
|
||||
}
|
||||
declare 84 {
|
||||
int Tcl_ConvertElement(const char *src, char *dst, int flags)
|
||||
@@ -318,7 +318,7 @@ declare 85 {
|
||||
declare 86 {
|
||||
int Tcl_CreateAlias(Tcl_Interp *slave, const char *slaveCmd,
|
||||
Tcl_Interp *target, const char *targetCmd, int argc,
|
||||
CONST84 char *const *argv)
|
||||
const char *const *argv)
|
||||
}
|
||||
declare 87 {
|
||||
int Tcl_CreateAliasObj(Tcl_Interp *slave, const char *slaveCmd,
|
||||
@@ -352,7 +352,7 @@ declare 93 {
|
||||
declare 94 {
|
||||
Tcl_Interp *Tcl_CreateInterp(void)
|
||||
}
|
||||
declare 95 {
|
||||
declare 95 {deprecated {}} {
|
||||
void Tcl_CreateMathFunc(Tcl_Interp *interp, const char *name,
|
||||
int numArgs, Tcl_ValueType *argTypes,
|
||||
Tcl_MathProc *proc, ClientData clientData)
|
||||
@@ -461,15 +461,14 @@ declare 126 {
|
||||
int Tcl_Eof(Tcl_Channel chan)
|
||||
}
|
||||
declare 127 {
|
||||
CONST84_RETURN char *Tcl_ErrnoId(void)
|
||||
const char *Tcl_ErrnoId(void)
|
||||
}
|
||||
declare 128 {
|
||||
CONST84_RETURN char *Tcl_ErrnoMsg(int err)
|
||||
const char *Tcl_ErrnoMsg(int err)
|
||||
}
|
||||
declare 129 {
|
||||
int Tcl_Eval(Tcl_Interp *interp, const char *script)
|
||||
}
|
||||
# This is obsolete, use Tcl_FSEvalFile
|
||||
declare 130 {
|
||||
int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName)
|
||||
}
|
||||
@@ -529,12 +528,12 @@ declare 147 {
|
||||
}
|
||||
declare 148 {
|
||||
int Tcl_GetAlias(Tcl_Interp *interp, const char *slaveCmd,
|
||||
Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr,
|
||||
int *argcPtr, CONST84 char ***argvPtr)
|
||||
Tcl_Interp **targetInterpPtr, const char **targetCmdPtr,
|
||||
int *argcPtr, const char ***argvPtr)
|
||||
}
|
||||
declare 149 {
|
||||
int Tcl_GetAliasObj(Tcl_Interp *interp, const char *slaveCmd,
|
||||
Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr,
|
||||
Tcl_Interp **targetInterpPtr, const char **targetCmdPtr,
|
||||
int *objcPtr, Tcl_Obj ***objv)
|
||||
}
|
||||
declare 150 {
|
||||
@@ -559,7 +558,7 @@ declare 155 {
|
||||
int Tcl_GetChannelMode(Tcl_Channel chan)
|
||||
}
|
||||
declare 156 {
|
||||
CONST84_RETURN char *Tcl_GetChannelName(Tcl_Channel chan)
|
||||
const char *Tcl_GetChannelName(Tcl_Channel chan)
|
||||
}
|
||||
declare 157 {
|
||||
int Tcl_GetChannelOption(Tcl_Interp *interp, Tcl_Channel chan,
|
||||
@@ -573,14 +572,14 @@ declare 159 {
|
||||
Tcl_CmdInfo *infoPtr)
|
||||
}
|
||||
declare 160 {
|
||||
CONST84_RETURN char *Tcl_GetCommandName(Tcl_Interp *interp,
|
||||
const char *Tcl_GetCommandName(Tcl_Interp *interp,
|
||||
Tcl_Command command)
|
||||
}
|
||||
declare 161 {
|
||||
int Tcl_GetErrno(void)
|
||||
}
|
||||
declare 162 {
|
||||
CONST84_RETURN char *Tcl_GetHostName(void)
|
||||
const char *Tcl_GetHostName(void)
|
||||
}
|
||||
declare 163 {
|
||||
int Tcl_GetInterpPath(Tcl_Interp *askInterp, Tcl_Interp *slaveInterp)
|
||||
@@ -623,14 +622,14 @@ declare 173 {
|
||||
Tcl_Channel Tcl_GetStdChannel(int type)
|
||||
}
|
||||
declare 174 {
|
||||
CONST84_RETURN char *Tcl_GetStringResult(Tcl_Interp *interp)
|
||||
const char *Tcl_GetStringResult(Tcl_Interp *interp)
|
||||
}
|
||||
declare 175 {
|
||||
CONST84_RETURN char *Tcl_GetVar(Tcl_Interp *interp, const char *varName,
|
||||
const char *Tcl_GetVar(Tcl_Interp *interp, const char *varName,
|
||||
int flags)
|
||||
}
|
||||
declare 176 {
|
||||
CONST84_RETURN char *Tcl_GetVar2(Tcl_Interp *interp, const char *part1,
|
||||
const char *Tcl_GetVar2(Tcl_Interp *interp, const char *part1,
|
||||
const char *part2, int flags)
|
||||
}
|
||||
declare 177 {
|
||||
@@ -663,7 +662,7 @@ declare 185 {
|
||||
}
|
||||
# Obsolete, use Tcl_FSJoinPath
|
||||
declare 186 {
|
||||
char *Tcl_JoinPath(int argc, CONST84 char *const *argv,
|
||||
char *Tcl_JoinPath(int argc, const char *const *argv,
|
||||
Tcl_DString *resultPtr)
|
||||
}
|
||||
declare 187 {
|
||||
@@ -686,7 +685,7 @@ declare 191 {
|
||||
Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket)
|
||||
}
|
||||
declare 192 {
|
||||
char *Tcl_Merge(int argc, CONST84 char *const *argv)
|
||||
char *Tcl_Merge(int argc, const char *const *argv)
|
||||
}
|
||||
declare 193 {
|
||||
Tcl_HashEntry *Tcl_NextHashEntry(Tcl_HashSearch *searchPtr)
|
||||
@@ -704,7 +703,7 @@ declare 196 {
|
||||
}
|
||||
declare 197 {
|
||||
Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, int argc,
|
||||
CONST84 char **argv, int flags)
|
||||
const char **argv, int flags)
|
||||
}
|
||||
# This is obsolete, use Tcl_FSOpenFileChannel
|
||||
declare 198 {
|
||||
@@ -730,7 +729,7 @@ declare 203 {
|
||||
int Tcl_PutEnv(const char *assignment)
|
||||
}
|
||||
declare 204 {
|
||||
CONST84_RETURN char *Tcl_PosixError(Tcl_Interp *interp)
|
||||
const char *Tcl_PosixError(Tcl_Interp *interp)
|
||||
}
|
||||
declare 205 {
|
||||
void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position)
|
||||
@@ -766,7 +765,7 @@ declare 214 {
|
||||
}
|
||||
declare 215 {
|
||||
void Tcl_RegExpRange(Tcl_RegExp regexp, int index,
|
||||
CONST84 char **startPtr, CONST84 char **endPtr)
|
||||
const char **startPtr, const char **endPtr)
|
||||
}
|
||||
declare 216 {
|
||||
void Tcl_Release(ClientData clientData)
|
||||
@@ -780,8 +779,7 @@ declare 218 {
|
||||
declare 219 {
|
||||
int Tcl_ScanCountedElement(const char *src, int length, int *flagPtr)
|
||||
}
|
||||
# Obsolete
|
||||
declare 220 {
|
||||
declare 220 {deprecated {}} {
|
||||
int Tcl_SeekOld(Tcl_Channel chan, int offset, int mode)
|
||||
}
|
||||
declare 221 {
|
||||
@@ -837,29 +835,29 @@ declare 236 {
|
||||
void Tcl_SetStdChannel(Tcl_Channel channel, int type)
|
||||
}
|
||||
declare 237 {
|
||||
CONST84_RETURN char *Tcl_SetVar(Tcl_Interp *interp, const char *varName,
|
||||
const char *Tcl_SetVar(Tcl_Interp *interp, const char *varName,
|
||||
const char *newValue, int flags)
|
||||
}
|
||||
declare 238 {
|
||||
CONST84_RETURN char *Tcl_SetVar2(Tcl_Interp *interp, const char *part1,
|
||||
const char *Tcl_SetVar2(Tcl_Interp *interp, const char *part1,
|
||||
const char *part2, const char *newValue, int flags)
|
||||
}
|
||||
declare 239 {
|
||||
CONST84_RETURN char *Tcl_SignalId(int sig)
|
||||
const char *Tcl_SignalId(int sig)
|
||||
}
|
||||
declare 240 {
|
||||
CONST84_RETURN char *Tcl_SignalMsg(int sig)
|
||||
const char *Tcl_SignalMsg(int sig)
|
||||
}
|
||||
declare 241 {
|
||||
void Tcl_SourceRCFile(Tcl_Interp *interp)
|
||||
}
|
||||
declare 242 {
|
||||
int Tcl_SplitList(Tcl_Interp *interp, const char *listStr, int *argcPtr,
|
||||
CONST84 char ***argvPtr)
|
||||
const char ***argvPtr)
|
||||
}
|
||||
# Obsolete, use Tcl_FSSplitPath
|
||||
declare 243 {
|
||||
void Tcl_SplitPath(const char *path, int *argcPtr, CONST84 char ***argvPtr)
|
||||
void Tcl_SplitPath(const char *path, int *argcPtr, const char ***argvPtr)
|
||||
}
|
||||
declare 244 {
|
||||
void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName,
|
||||
@@ -868,8 +866,7 @@ declare 244 {
|
||||
declare 245 {
|
||||
int Tcl_StringMatch(const char *str, const char *pattern)
|
||||
}
|
||||
# Obsolete
|
||||
declare 246 {
|
||||
declare 246 {deprecated {}} {
|
||||
int Tcl_TellOld(Tcl_Channel chan)
|
||||
}
|
||||
declare 247 {
|
||||
@@ -945,25 +942,25 @@ declare 265 {
|
||||
declare 266 {
|
||||
void Tcl_ValidateAllMemory(const char *file, int line)
|
||||
}
|
||||
declare 267 {
|
||||
declare 267 {deprecated {see TIP #422}} {
|
||||
void Tcl_AppendResultVA(Tcl_Interp *interp, va_list argList)
|
||||
}
|
||||
declare 268 {
|
||||
declare 268 {deprecated {see TIP #422}} {
|
||||
void Tcl_AppendStringsToObjVA(Tcl_Obj *objPtr, va_list argList)
|
||||
}
|
||||
declare 269 {
|
||||
char *Tcl_HashStats(Tcl_HashTable *tablePtr)
|
||||
}
|
||||
declare 270 {
|
||||
CONST84_RETURN char *Tcl_ParseVar(Tcl_Interp *interp, const char *start,
|
||||
CONST84 char **termPtr)
|
||||
const char *Tcl_ParseVar(Tcl_Interp *interp, const char *start,
|
||||
const char **termPtr)
|
||||
}
|
||||
declare 271 {
|
||||
CONST84_RETURN char *Tcl_PkgPresent(Tcl_Interp *interp, const char *name,
|
||||
const char *Tcl_PkgPresent(Tcl_Interp *interp, const char *name,
|
||||
const char *version, int exact)
|
||||
}
|
||||
declare 272 {
|
||||
CONST84_RETURN char *Tcl_PkgPresentEx(Tcl_Interp *interp,
|
||||
const char *Tcl_PkgPresentEx(Tcl_Interp *interp,
|
||||
const char *name, const char *version, int exact,
|
||||
void *clientDataPtr)
|
||||
}
|
||||
@@ -973,19 +970,19 @@ declare 273 {
|
||||
}
|
||||
# TIP #268: The internally used new Require function is in slot 573.
|
||||
declare 274 {
|
||||
CONST84_RETURN char *Tcl_PkgRequire(Tcl_Interp *interp, const char *name,
|
||||
const char *Tcl_PkgRequire(Tcl_Interp *interp, const char *name,
|
||||
const char *version, int exact)
|
||||
}
|
||||
declare 275 {
|
||||
declare 275 {deprecated {see TIP #422}} {
|
||||
void Tcl_SetErrorCodeVA(Tcl_Interp *interp, va_list argList)
|
||||
}
|
||||
declare 276 {
|
||||
declare 276 {deprecated {see TIP #422}} {
|
||||
int Tcl_VarEvalVA(Tcl_Interp *interp, va_list argList)
|
||||
}
|
||||
declare 277 {
|
||||
Tcl_Pid Tcl_WaitPid(Tcl_Pid pid, int *statPtr, int options)
|
||||
}
|
||||
declare 278 {
|
||||
declare 278 {deprecated {see TIP #422}} {
|
||||
TCL_NORETURN void Tcl_PanicVA(const char *format, va_list argList)
|
||||
}
|
||||
declare 279 {
|
||||
@@ -1087,7 +1084,7 @@ declare 301 {
|
||||
Tcl_Encoding Tcl_GetEncoding(Tcl_Interp *interp, const char *name)
|
||||
}
|
||||
declare 302 {
|
||||
CONST84_RETURN char *Tcl_GetEncodingName(Tcl_Encoding encoding)
|
||||
const char *Tcl_GetEncodingName(Tcl_Encoding encoding)
|
||||
}
|
||||
declare 303 {
|
||||
void Tcl_GetEncodingNames(Tcl_Interp *interp)
|
||||
@@ -1163,7 +1160,7 @@ declare 324 {
|
||||
int Tcl_UniCharToUtf(int ch, char *buf)
|
||||
}
|
||||
declare 325 {
|
||||
CONST84_RETURN char *Tcl_UtfAtIndex(const char *src, int index)
|
||||
const char *Tcl_UtfAtIndex(const char *src, int index)
|
||||
}
|
||||
declare 326 {
|
||||
int Tcl_UtfCharComplete(const char *src, int length)
|
||||
@@ -1172,16 +1169,16 @@ declare 327 {
|
||||
int Tcl_UtfBackslash(const char *src, int *readPtr, char *dst)
|
||||
}
|
||||
declare 328 {
|
||||
CONST84_RETURN char *Tcl_UtfFindFirst(const char *src, int ch)
|
||||
const char *Tcl_UtfFindFirst(const char *src, int ch)
|
||||
}
|
||||
declare 329 {
|
||||
CONST84_RETURN char *Tcl_UtfFindLast(const char *src, int ch)
|
||||
const char *Tcl_UtfFindLast(const char *src, int ch)
|
||||
}
|
||||
declare 330 {
|
||||
CONST84_RETURN char *Tcl_UtfNext(const char *src)
|
||||
const char *Tcl_UtfNext(const char *src)
|
||||
}
|
||||
declare 331 {
|
||||
CONST84_RETURN char *Tcl_UtfPrev(const char *src, const char *start)
|
||||
const char *Tcl_UtfPrev(const char *src, const char *start)
|
||||
}
|
||||
declare 332 {
|
||||
int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding,
|
||||
@@ -1214,10 +1211,10 @@ declare 339 {
|
||||
declare 340 {
|
||||
char *Tcl_GetString(Tcl_Obj *objPtr)
|
||||
}
|
||||
declare 341 {
|
||||
CONST84_RETURN char *Tcl_GetDefaultEncodingDir(void)
|
||||
declare 341 {deprecated {Use Tcl_GetEncodingSearchPath}} {
|
||||
const char *Tcl_GetDefaultEncodingDir(void)
|
||||
}
|
||||
declare 342 {
|
||||
declare 342 {deprecated {Use Tcl_SetEncodingSearchPath}} {
|
||||
void Tcl_SetDefaultEncodingDir(const char *path)
|
||||
}
|
||||
declare 343 {
|
||||
@@ -1266,7 +1263,7 @@ declare 356 {
|
||||
Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp, Tcl_Obj *patObj,
|
||||
int flags)
|
||||
}
|
||||
declare 357 {
|
||||
declare 357 {deprecated {Use Tcl_EvalTokensStandard}} {
|
||||
Tcl_Obj *Tcl_EvalTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr,
|
||||
int count)
|
||||
}
|
||||
@@ -1279,7 +1276,7 @@ declare 359 {
|
||||
}
|
||||
declare 360 {
|
||||
int Tcl_ParseBraces(Tcl_Interp *interp, const char *start, int numBytes,
|
||||
Tcl_Parse *parsePtr, int append, CONST84 char **termPtr)
|
||||
Tcl_Parse *parsePtr, int append, const char **termPtr)
|
||||
}
|
||||
declare 361 {
|
||||
int Tcl_ParseCommand(Tcl_Interp *interp, const char *start, int numBytes,
|
||||
@@ -1292,7 +1289,7 @@ declare 362 {
|
||||
declare 363 {
|
||||
int Tcl_ParseQuotedString(Tcl_Interp *interp, const char *start,
|
||||
int numBytes, Tcl_Parse *parsePtr, int append,
|
||||
CONST84 char **termPtr)
|
||||
const char **termPtr)
|
||||
}
|
||||
declare 364 {
|
||||
int Tcl_ParseVarName(Tcl_Interp *interp, const char *start, int numBytes,
|
||||
@@ -1408,7 +1405,7 @@ declare 397 {
|
||||
int Tcl_ChannelBuffered(Tcl_Channel chan)
|
||||
}
|
||||
declare 398 {
|
||||
CONST84_RETURN char *Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr)
|
||||
const char *Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr)
|
||||
}
|
||||
declare 399 {
|
||||
Tcl_ChannelTypeVersion Tcl_ChannelVersion(
|
||||
@@ -1548,12 +1545,12 @@ declare 434 {
|
||||
}
|
||||
|
||||
# TIP#15 (math function introspection) dkf
|
||||
declare 435 {
|
||||
declare 435 {deprecated {}} {
|
||||
int Tcl_GetMathFuncInfo(Tcl_Interp *interp, const char *name,
|
||||
int *numArgsPtr, Tcl_ValueType **argTypesPtr,
|
||||
Tcl_MathProc **procPtr, ClientData *clientDataPtr)
|
||||
}
|
||||
declare 436 {
|
||||
declare 436 {deprecated {}} {
|
||||
Tcl_Obj *Tcl_ListMathFuncs(Tcl_Interp *interp, const char *pattern)
|
||||
}
|
||||
|
||||
|
||||
+68
-105
@@ -137,7 +137,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
# define TCL_VARARGS(type, name) (type name, ...)
|
||||
# define TCL_VARARGS_DEF(type, name) (type name, ...)
|
||||
# define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
|
||||
@@ -254,10 +254,9 @@ extern "C" {
|
||||
* New code should use prototypes.
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
# undef _ANSI_ARGS_
|
||||
# define _ANSI_ARGS_(x) x
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
* Definitions that allow this header file to be used either with or without
|
||||
@@ -267,34 +266,16 @@ extern "C" {
|
||||
#ifndef INLINE
|
||||
# define INLINE
|
||||
#endif
|
||||
|
||||
#ifdef NO_CONST
|
||||
# ifndef const
|
||||
# define const
|
||||
# endif
|
||||
#endif
|
||||
#ifndef CONST
|
||||
# define CONST const
|
||||
#endif
|
||||
#define CONST84 const
|
||||
#define CONST84_RETURN const
|
||||
|
||||
#ifdef USE_NON_CONST
|
||||
# ifdef USE_COMPAT_CONST
|
||||
# error define at most one of USE_NON_CONST and USE_COMPAT_CONST
|
||||
# endif
|
||||
# define CONST84
|
||||
# define CONST84_RETURN
|
||||
#else
|
||||
# ifdef USE_COMPAT_CONST
|
||||
# define CONST84
|
||||
# define CONST84_RETURN const
|
||||
# else
|
||||
# define CONST84 const
|
||||
# define CONST84_RETURN const
|
||||
# endif
|
||||
#endif
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
#ifndef CONST86
|
||||
# define CONST86 CONST84
|
||||
# define CONST86 const
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -318,6 +299,7 @@ extern "C" {
|
||||
* VOID. This block is skipped under Cygwin and Mingw.
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
#if defined(_WIN32) && !defined(HAVE_WINNT_IGNORE_VOID)
|
||||
#ifndef VOID
|
||||
#define VOID void
|
||||
@@ -333,23 +315,16 @@ typedef long LONG;
|
||||
*/
|
||||
|
||||
#ifndef __VXWORKS__
|
||||
# ifndef NO_VOID
|
||||
# define VOID void
|
||||
# else
|
||||
# define VOID char
|
||||
# endif
|
||||
# define VOID void
|
||||
#endif
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 */
|
||||
|
||||
/*
|
||||
* Miscellaneous declarations.
|
||||
*/
|
||||
|
||||
#ifndef _CLIENTDATA
|
||||
# ifndef NO_VOID
|
||||
typedef void *ClientData;
|
||||
# else
|
||||
typedef int *ClientData;
|
||||
# endif
|
||||
typedef void *ClientData;
|
||||
# define _CLIENTDATA
|
||||
#endif
|
||||
|
||||
@@ -396,44 +371,40 @@ typedef long LONG;
|
||||
# if defined(_WIN32)
|
||||
# define TCL_WIDE_INT_TYPE __int64
|
||||
# define TCL_LL_MODIFIER "I64"
|
||||
# if defined(_WIN64)
|
||||
# define TCL_Z_MODIFIER "I"
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
# define TCL_WIDE_INT_TYPE long long
|
||||
# define TCL_LL_MODIFIER "ll"
|
||||
# define TCL_Z_MODIFIER "z"
|
||||
# else /* ! _WIN32 && ! __GNUC__ */
|
||||
/*
|
||||
* Don't know what platform it is and configure hasn't discovered what is
|
||||
* going on for us. Try to guess...
|
||||
*/
|
||||
# include <limits.h>
|
||||
# if (INT_MAX < LONG_MAX)
|
||||
# if defined(LLONG_MAX) && (LLONG_MAX == LONG_MAX)
|
||||
# define TCL_WIDE_INT_IS_LONG 1
|
||||
# else
|
||||
# define TCL_WIDE_INT_TYPE long long
|
||||
# endif
|
||||
# endif /* _WIN32 */
|
||||
#endif /* !TCL_WIDE_INT_TYPE & !TCL_WIDE_INT_IS_LONG */
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
# undef TCL_WIDE_INT_TYPE
|
||||
# define TCL_WIDE_INT_TYPE long
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
#ifndef TCL_WIDE_INT_TYPE
|
||||
# define TCL_WIDE_INT_TYPE long long
|
||||
#endif /* !TCL_WIDE_INT_TYPE */
|
||||
|
||||
typedef TCL_WIDE_INT_TYPE Tcl_WideInt;
|
||||
typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
|
||||
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
# ifndef TCL_LL_MODIFIER
|
||||
# define TCL_LL_MODIFIER "l"
|
||||
# endif /* !TCL_LL_MODIFIER */
|
||||
#else /* TCL_WIDE_INT_IS_LONG */
|
||||
/*
|
||||
* The next short section of defines are only done when not running on Windows
|
||||
* or some other strange platform.
|
||||
*/
|
||||
# ifndef TCL_LL_MODIFIER
|
||||
# define TCL_LL_MODIFIER "ll"
|
||||
# endif /* !TCL_LL_MODIFIER */
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
#ifndef TCL_LL_MODIFIER
|
||||
# define TCL_LL_MODIFIER "ll"
|
||||
#endif /* !TCL_LL_MODIFIER */
|
||||
#ifndef TCL_Z_MODIFIER
|
||||
# if defined(__GNUC__) && !defined(_WIN32)
|
||||
# define TCL_Z_MODIFIER "z"
|
||||
# else
|
||||
# define TCL_Z_MODIFIER ""
|
||||
# endif
|
||||
#endif /* !TCL_Z_MODIFIER */
|
||||
#define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
|
||||
#define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val)))
|
||||
#define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val)))
|
||||
@@ -493,35 +464,13 @@ typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
|
||||
*/
|
||||
|
||||
typedef struct Tcl_Interp
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
{
|
||||
/* TIP #330: Strongly discourage extensions from using the string
|
||||
* result. */
|
||||
#ifdef USE_INTERP_RESULT
|
||||
char *result TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
|
||||
/* If the last command returned a string
|
||||
* result, this points to it. */
|
||||
void (*freeProc) (char *blockPtr)
|
||||
TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
|
||||
/* Zero means the string result is statically
|
||||
* allocated. TCL_DYNAMIC means it was
|
||||
* allocated with ckalloc and should be freed
|
||||
* with ckfree. Other values give the address
|
||||
* of function to invoke to free the result.
|
||||
* Tcl_Eval must free it before executing next
|
||||
* command. */
|
||||
#else
|
||||
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");
|
||||
/* When TCL_ERROR is returned, this gives the
|
||||
* line number within the command where the
|
||||
* error occurred (1 if first line). */
|
||||
#else
|
||||
int errorLineDontUse; /* Don't use in extensions! */
|
||||
#endif
|
||||
}
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
Tcl_Interp;
|
||||
@@ -673,7 +622,9 @@ typedef struct stat *Tcl_OldStat_;
|
||||
#define TCL_BREAK 3
|
||||
#define TCL_CONTINUE 4
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
#define TCL_RESULT_SIZE 200
|
||||
#endif
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------------
|
||||
@@ -689,6 +640,7 @@ typedef struct stat *Tcl_OldStat_;
|
||||
* Argument descriptors for math function callbacks in expressions:
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
typedef enum {
|
||||
TCL_INT, TCL_DOUBLE, TCL_EITHER, TCL_WIDE_INT
|
||||
} Tcl_ValueType;
|
||||
@@ -700,6 +652,10 @@ typedef struct Tcl_Value {
|
||||
double doubleValue; /* Double-precision floating value. */
|
||||
Tcl_WideInt wideValue; /* Wide (min. 64-bit) integer value. */
|
||||
} Tcl_Value;
|
||||
#else
|
||||
#define Tcl_ValueType void /* Just enough to prevent compilation error in Tcl */
|
||||
#define Tcl_Value void /* Just enough to prevent compilation error in Tcl */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Forward declaration of Tcl_Obj to prevent an error when the forward
|
||||
@@ -720,10 +676,10 @@ typedef void (Tcl_ChannelProc) (ClientData clientData, int mask);
|
||||
typedef void (Tcl_CloseProc) (ClientData data);
|
||||
typedef void (Tcl_CmdDeleteProc) (ClientData clientData);
|
||||
typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
|
||||
int argc, CONST84 char *argv[]);
|
||||
int argc, const char *argv[]);
|
||||
typedef void (Tcl_CmdTraceProc) (ClientData clientData, Tcl_Interp *interp,
|
||||
int level, char *command, Tcl_CmdProc *proc,
|
||||
ClientData cmdClientData, int argc, CONST84 char *argv[]);
|
||||
ClientData cmdClientData, int argc, const char *argv[]);
|
||||
typedef int (Tcl_CmdObjTraceProc) (ClientData clientData, Tcl_Interp *interp,
|
||||
int level, const char *command, Tcl_Command commandInfo, int objc,
|
||||
struct Tcl_Obj *const *objv);
|
||||
@@ -760,7 +716,7 @@ typedef void (Tcl_TimerProc) (ClientData clientData);
|
||||
typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *interp, struct Tcl_Obj *objPtr);
|
||||
typedef void (Tcl_UpdateStringProc) (struct Tcl_Obj *objPtr);
|
||||
typedef char * (Tcl_VarTraceProc) (ClientData clientData, Tcl_Interp *interp,
|
||||
CONST84 char *part1, CONST84 char *part2, int flags);
|
||||
const char *part1, const char *part2, int flags);
|
||||
typedef void (Tcl_CommandTraceProc) (ClientData clientData, Tcl_Interp *interp,
|
||||
const char *oldName, const char *newName, int flags);
|
||||
typedef void (Tcl_CreateFileHandlerProc) (int fd, int mask, Tcl_FileProc *proc,
|
||||
@@ -871,7 +827,7 @@ typedef struct Tcl_SavedResult {
|
||||
char *appendResult;
|
||||
int appendAvl;
|
||||
int appendUsed;
|
||||
char resultSpace[TCL_RESULT_SIZE+1];
|
||||
char resultSpace[200+1];
|
||||
} Tcl_SavedResult;
|
||||
|
||||
/*
|
||||
@@ -997,7 +953,7 @@ typedef struct Tcl_DString {
|
||||
|
||||
#define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
|
||||
#define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
# define Tcl_DStringTrunc Tcl_DStringSetLength
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
@@ -1125,7 +1081,7 @@ typedef struct Tcl_DString {
|
||||
* give the flag)
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
# define TCL_PARSE_PART1 0x400
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
@@ -1344,8 +1300,8 @@ typedef struct Tcl_HashSearch {
|
||||
typedef struct {
|
||||
void *next; /* Search position for underlying hash
|
||||
* table. */
|
||||
int epoch; /* Epoch marker for dictionary being searched,
|
||||
* or -1 if search has terminated. */
|
||||
unsigned int epoch; /* Epoch marker for dictionary being searched,
|
||||
* or 0 if search has terminated. */
|
||||
Tcl_Dict dictionaryPtr; /* Reference to dictionary being searched. */
|
||||
} Tcl_DictSearch;
|
||||
|
||||
@@ -1478,14 +1434,14 @@ typedef int (Tcl_DriverClose2Proc) (ClientData instanceData,
|
||||
typedef int (Tcl_DriverInputProc) (ClientData instanceData, char *buf,
|
||||
int toRead, int *errorCodePtr);
|
||||
typedef int (Tcl_DriverOutputProc) (ClientData instanceData,
|
||||
CONST84 char *buf, int toWrite, int *errorCodePtr);
|
||||
const char *buf, int toWrite, int *errorCodePtr);
|
||||
typedef int (Tcl_DriverSeekProc) (ClientData instanceData, long offset,
|
||||
int mode, int *errorCodePtr);
|
||||
typedef int (Tcl_DriverSetOptionProc) (ClientData instanceData,
|
||||
Tcl_Interp *interp, const char *optionName,
|
||||
const char *value);
|
||||
typedef int (Tcl_DriverGetOptionProc) (ClientData instanceData,
|
||||
Tcl_Interp *interp, CONST84 char *optionName,
|
||||
Tcl_Interp *interp, const char *optionName,
|
||||
Tcl_DString *dsPtr);
|
||||
typedef void (Tcl_DriverWatchProc) (ClientData instanceData, int mask);
|
||||
typedef int (Tcl_DriverGetHandleProc) (ClientData instanceData,
|
||||
@@ -1978,7 +1934,7 @@ typedef struct Tcl_Token {
|
||||
* TCL_TOKEN_OPERATOR - The token describes one expression operator.
|
||||
* An operator might be the name of a math
|
||||
* function such as "abs". A TCL_TOKEN_OPERATOR
|
||||
* token is always preceeded by one
|
||||
* token is always preceded by one
|
||||
* TCL_TOKEN_SUB_EXPR token for the operator's
|
||||
* subexpression, and is followed by zero or more
|
||||
* TCL_TOKEN_SUB_EXPR tokens for the operator's
|
||||
@@ -2409,14 +2365,27 @@ const char * TclTomMathInitializeStubs(Tcl_Interp *interp,
|
||||
const char *version, int epoch, int revision);
|
||||
|
||||
#ifdef USE_TCL_STUBS
|
||||
#define Tcl_InitStubs(interp, version, exact) \
|
||||
(Tcl_InitStubs)(interp, version, \
|
||||
#if TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE
|
||||
# define Tcl_InitStubs(interp, version, exact) \
|
||||
(Tcl_InitStubs)(interp, version, \
|
||||
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
|
||||
TCL_STUB_MAGIC)
|
||||
#else
|
||||
#define Tcl_InitStubs(interp, version, exact) \
|
||||
Tcl_PkgInitStubsCheck(interp, version, \
|
||||
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
|
||||
# define Tcl_InitStubs(interp, version, exact) \
|
||||
(Tcl_InitStubs)(interp, TCL_PATCH_LEVEL, \
|
||||
1|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
|
||||
TCL_STUB_MAGIC)
|
||||
#endif
|
||||
#else
|
||||
#if TCL_RELEASE_LEVEL == TCL_FINAL_RELEASE
|
||||
# define Tcl_InitStubs(interp, version, exact) \
|
||||
Tcl_PkgInitStubsCheck(interp, version, \
|
||||
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
|
||||
#else
|
||||
# define Tcl_InitStubs(interp, version, exact) \
|
||||
Tcl_PkgInitStubsCheck(interp, TCL_PATCH_LEVEL, \
|
||||
1|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -2544,15 +2513,9 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
# undef Tcl_NewDoubleObj
|
||||
# define Tcl_NewDoubleObj(val) \
|
||||
Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
|
||||
# undef Tcl_NewIntObj
|
||||
# define Tcl_NewIntObj(val) \
|
||||
Tcl_DbNewLongObj(val, __FILE__, __LINE__)
|
||||
# undef Tcl_NewListObj
|
||||
# define Tcl_NewListObj(objc, objv) \
|
||||
Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
|
||||
# undef Tcl_NewLongObj
|
||||
# define Tcl_NewLongObj(val) \
|
||||
Tcl_DbNewLongObj(val, __FILE__, __LINE__)
|
||||
# undef Tcl_NewObj
|
||||
# define Tcl_NewObj() \
|
||||
Tcl_DbNewObj(__FILE__, __LINE__)
|
||||
@@ -2615,10 +2578,10 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
|
||||
* Deprecated Tcl functions:
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
/*
|
||||
* These function have been renamed. The old names are deprecated, but we
|
||||
* define these macros for backwards compatibilty.
|
||||
* define these macros for backwards compatibility.
|
||||
*/
|
||||
|
||||
# define Tcl_Ckalloc Tcl_Alloc
|
||||
|
||||
+5
-5
@@ -661,14 +661,14 @@ mstats(
|
||||
|
||||
fprintf(stderr, "\nused:\t");
|
||||
for (i = 0; i < NBUCKETS; i++) {
|
||||
fprintf(stderr, " %" TCL_LL_MODIFIER "d", (Tcl_WideInt)numMallocs[i]);
|
||||
fprintf(stderr, " %" TCL_Z_MODIFIER "u", numMallocs[i]);
|
||||
totalUsed += numMallocs[i] * (1 << (i + 3));
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n\tTotal small in use: %" TCL_LL_MODIFIER "d, total free: %" TCL_LL_MODIFIER "d\n",
|
||||
(Tcl_WideInt)totalUsed, (Tcl_WideInt)totalFree);
|
||||
fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %" TCL_LL_MODIFIER "d\n",
|
||||
MAXMALLOC, (Tcl_WideInt)numMallocs[NBUCKETS]);
|
||||
fprintf(stderr, "\n\tTotal small in use: %" TCL_Z_MODIFIER "u, total free: %" TCL_Z_MODIFIER "u\n",
|
||||
totalUsed, totalFree);
|
||||
fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %" TCL_Z_MODIFIER "u\n",
|
||||
MAXMALLOC, numMallocs[NBUCKETS]);
|
||||
|
||||
Tcl_MutexUnlock(allocMutexPtr);
|
||||
}
|
||||
|
||||
+13
-12
@@ -2246,23 +2246,24 @@ GetListIndexOperand(
|
||||
Tcl_Token* tokenPtr = *tokenPtrPtr;
|
||||
/* INOUT: Pointer to the next token in the
|
||||
* source code */
|
||||
Tcl_Obj* intObj; /* Integer from the source code */
|
||||
int status; /* Tcl status return */
|
||||
Tcl_Obj *value;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Extract the next token as a string.
|
||||
*/
|
||||
|
||||
if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) {
|
||||
/* General operand validity check */
|
||||
if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &value) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/* Convert to an integer, advance to the next token and return. */
|
||||
/*
|
||||
* Convert to an integer, advance to the next token and return.
|
||||
* NOTE: Indexing a list with an index before it yields the
|
||||
* same result as indexing after it, and might be more easily portable
|
||||
* when list size limits grow.
|
||||
*/
|
||||
status = TclIndexEncode(interp, value,
|
||||
TCL_INDEX_BEFORE,TCL_INDEX_BEFORE, result);
|
||||
|
||||
status = TclGetIntForIndex(interp, intObj, -2, result);
|
||||
Tcl_DecrRefCount(intObj);
|
||||
Tcl_DecrRefCount(value);
|
||||
*tokenPtrPtr = TokenAfter(tokenPtr);
|
||||
return status;
|
||||
}
|
||||
@@ -4266,7 +4267,7 @@ AddBasicBlockRangeToErrorInfo(
|
||||
Tcl_AppendObjToErrorInfo(interp, lineNo);
|
||||
Tcl_AddErrorInfo(interp, " and ");
|
||||
if (bbPtr->successor1 != NULL) {
|
||||
TclSetLongObj(lineNo, bbPtr->successor1->startLine);
|
||||
TclSetIntObj(lineNo, bbPtr->successor1->startLine);
|
||||
Tcl_AppendObjToErrorInfo(interp, lineNo);
|
||||
} else {
|
||||
Tcl_AddErrorInfo(interp, "end of assembly code");
|
||||
|
||||
+197
-107
@@ -118,6 +118,8 @@ static Tcl_ObjCmdProc ExprEntierFunc;
|
||||
static Tcl_ObjCmdProc ExprFloorFunc;
|
||||
static Tcl_ObjCmdProc ExprIntFunc;
|
||||
static Tcl_ObjCmdProc ExprIsqrtFunc;
|
||||
static Tcl_ObjCmdProc ExprMaxFunc;
|
||||
static Tcl_ObjCmdProc ExprMinFunc;
|
||||
static Tcl_ObjCmdProc ExprRandFunc;
|
||||
static Tcl_ObjCmdProc ExprRoundFunc;
|
||||
static Tcl_ObjCmdProc ExprSqrtFunc;
|
||||
@@ -130,8 +132,10 @@ static Tcl_NRPostProc NRCoroutineCallerCallback;
|
||||
static Tcl_NRPostProc NRCoroutineExitCallback;
|
||||
static Tcl_NRPostProc NRCommand;
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED)
|
||||
static Tcl_ObjCmdProc OldMathFuncProc;
|
||||
static void OldMathFuncDeleteProc(ClientData clientData);
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) */
|
||||
static void ProcessUnexpectedResult(Tcl_Interp *interp,
|
||||
int returnCode);
|
||||
static int RewindCoroutine(CoroutineData *corPtr, int result);
|
||||
@@ -203,7 +207,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"append", Tcl_AppendObjCmd, TclCompileAppendCmd, NULL, CMD_IS_SAFE},
|
||||
{"apply", Tcl_ApplyObjCmd, NULL, TclNRApplyObjCmd, CMD_IS_SAFE},
|
||||
{"break", Tcl_BreakObjCmd, TclCompileBreakCmd, NULL, CMD_IS_SAFE},
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
{"case", Tcl_CaseObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
#endif
|
||||
{"catch", Tcl_CatchObjCmd, TclCompileCatchCmd, TclNRCatchObjCmd, CMD_IS_SAFE},
|
||||
@@ -234,7 +238,7 @@ static const CmdInfo builtInCmds[] = {
|
||||
{"lsearch", Tcl_LsearchObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"lset", Tcl_LsetObjCmd, TclCompileLsetCmd, NULL, CMD_IS_SAFE},
|
||||
{"lsort", Tcl_LsortObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"package", Tcl_PackageObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"package", Tcl_PackageObjCmd, NULL, TclNRPackageObjCmd, CMD_IS_SAFE},
|
||||
{"proc", Tcl_ProcObjCmd, NULL, NULL, CMD_IS_SAFE},
|
||||
{"regexp", Tcl_RegexpObjCmd, TclCompileRegexpCmd, NULL, CMD_IS_SAFE},
|
||||
{"regsub", Tcl_RegsubObjCmd, TclCompileRegsubCmd, NULL, CMD_IS_SAFE},
|
||||
@@ -321,6 +325,8 @@ static const BuiltinFuncDef BuiltinFuncTable[] = {
|
||||
{ "isqrt", ExprIsqrtFunc, NULL },
|
||||
{ "log", ExprUnaryFunc, (ClientData) log },
|
||||
{ "log10", ExprUnaryFunc, (ClientData) log10 },
|
||||
{ "max", ExprMaxFunc, NULL },
|
||||
{ "min", ExprMinFunc, NULL },
|
||||
{ "pow", ExprBinaryFunc, (ClientData) pow },
|
||||
{ "rand", ExprRandFunc, NULL },
|
||||
{ "round", ExprRoundFunc, NULL },
|
||||
@@ -813,6 +819,7 @@ Tcl_CreateInterp(void)
|
||||
TclInitNamespaceCmd(interp);
|
||||
TclInitStringCmd(interp);
|
||||
TclInitPrefixCmd(interp);
|
||||
TclInitProcessCmd(interp);
|
||||
|
||||
/*
|
||||
* Register "clock" subcommands. These *do* go through
|
||||
@@ -950,9 +957,11 @@ Tcl_CreateInterp(void)
|
||||
|
||||
Tcl_SetVar2(interp, "tcl_patchLevel", NULL, TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
|
||||
Tcl_SetVar2(interp, "tcl_version", NULL, TCL_VERSION, TCL_GLOBAL_ONLY);
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
Tcl_TraceVar2(interp, "tcl_precision", NULL,
|
||||
TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
|
||||
TclPrecTraceProc, NULL);
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
TclpSetVariables(interp);
|
||||
|
||||
#ifdef TCL_THREADS
|
||||
@@ -2098,13 +2107,13 @@ Tcl_CreateCommand(
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
|
||||
if (isNew || deleted) {
|
||||
if (isNew || deleted) {
|
||||
/*
|
||||
* isNew - No conflict with existing command.
|
||||
* deleted - We've already deleted a conflicting command
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* An existing command conflicts. Try to delete it.. */
|
||||
cmdPtr = Tcl_GetHashValue(hPtr);
|
||||
@@ -2245,64 +2254,82 @@ Tcl_CreateObjCommand(
|
||||
* name. */
|
||||
ClientData clientData, /* Arbitrary value to pass to object
|
||||
* function. */
|
||||
Tcl_CmdDeleteProc *deleteProc)
|
||||
Tcl_CmdDeleteProc *deleteProc
|
||||
/* If not NULL, gives a function to call when
|
||||
* this command is deleted. */
|
||||
)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
ImportRef *oldRefPtr = NULL;
|
||||
Namespace *nsPtr;
|
||||
Command *cmdPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
const char *tail;
|
||||
int isNew = 0, deleted = 0;
|
||||
ImportedCmdData *dataPtr;
|
||||
|
||||
if (iPtr->flags & DELETED) {
|
||||
/*
|
||||
* The interpreter is being deleted. Don't create any new commands;
|
||||
* it's not safe to muck with the interpreter anymore.
|
||||
*/
|
||||
|
||||
return (Tcl_Command) NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine where the command should reside. If its name contains
|
||||
* namespace qualifiers, we put it in the specified namespace;
|
||||
* otherwise, we always put it in the global namespace.
|
||||
*/
|
||||
|
||||
if (strstr(cmdName, "::") != NULL) {
|
||||
Namespace *dummy1, *dummy2;
|
||||
|
||||
TclGetNamespaceForQualName(interp, cmdName, NULL,
|
||||
TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
|
||||
if ((nsPtr == NULL) || (tail == NULL)) {
|
||||
return (Tcl_Command) NULL;
|
||||
}
|
||||
} else {
|
||||
nsPtr = iPtr->globalNsPtr;
|
||||
tail = cmdName;
|
||||
}
|
||||
|
||||
return TclCreateObjCommandInNs(interp, tail, (Tcl_Namespace *) nsPtr,
|
||||
proc, clientData, deleteProc);
|
||||
}
|
||||
|
||||
Tcl_Command
|
||||
TclCreateObjCommandInNs (
|
||||
Tcl_Interp *interp,
|
||||
const char *cmdName, /* Name of command, without any namespace components */
|
||||
Tcl_Namespace *namespace, /* The namespace to create the command in */
|
||||
Tcl_ObjCmdProc *proc, /* Object-based function to associate with
|
||||
* name. */
|
||||
ClientData clientData, /* Arbitrary value to pass to object
|
||||
* function. */
|
||||
Tcl_CmdDeleteProc *deleteProc
|
||||
/* If not NULL, gives a function to call when
|
||||
* this command is deleted. */
|
||||
) {
|
||||
int deleted = 0, isNew = 0;
|
||||
Command *cmdPtr;
|
||||
ImportRef *oldRefPtr = NULL;
|
||||
ImportedCmdData *dataPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Namespace *nsPtr = (Namespace *) namespace;
|
||||
/*
|
||||
* If the command name we seek to create already exists, we need to
|
||||
* delete that first. That can be tricky in the presence of traces.
|
||||
* Loop until we no longer find an existing command in the way, or
|
||||
* until we've deleted one command and that didn't finish the job.
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
/*
|
||||
* Determine where the command should reside. If its name contains
|
||||
* namespace qualifiers, we put it in the specified namespace;
|
||||
* otherwise, we always put it in the global namespace.
|
||||
*/
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
|
||||
|
||||
if (strstr(cmdName, "::") != NULL) {
|
||||
Namespace *dummy1, *dummy2;
|
||||
|
||||
TclGetNamespaceForQualName(interp, cmdName, NULL,
|
||||
TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
|
||||
if ((nsPtr == NULL) || (tail == NULL)) {
|
||||
return (Tcl_Command) NULL;
|
||||
}
|
||||
} else {
|
||||
nsPtr = iPtr->globalNsPtr;
|
||||
tail = cmdName;
|
||||
}
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
|
||||
|
||||
if (isNew || deleted) {
|
||||
if (isNew || deleted) {
|
||||
/*
|
||||
* isNew - No conflict with existing command.
|
||||
* deleted - We've already deleted a conflicting command
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* An existing command conflicts. Try to delete it.. */
|
||||
cmdPtr = Tcl_GetHashValue(hPtr);
|
||||
@@ -2336,7 +2363,13 @@ Tcl_CreateObjCommand(
|
||||
cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
|
||||
}
|
||||
|
||||
/* Make sure namespace doesn't get deallocated. */
|
||||
cmdPtr->nsPtr->refCount++;
|
||||
|
||||
Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
|
||||
nsPtr = (Namespace *) TclEnsureNamespace(interp,
|
||||
(Tcl_Namespace *)cmdPtr->nsPtr);
|
||||
TclNsDecrRefCount(cmdPtr->nsPtr);
|
||||
|
||||
if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
|
||||
oldRefPtr = cmdPtr->importRefPtr;
|
||||
@@ -2345,7 +2378,6 @@ Tcl_CreateObjCommand(
|
||||
TclCleanupCommandMacro(cmdPtr);
|
||||
deleted = 1;
|
||||
}
|
||||
|
||||
if (!isNew) {
|
||||
/*
|
||||
* If the deletion callback recreated the command, just throw away
|
||||
@@ -2367,7 +2399,7 @@ Tcl_CreateObjCommand(
|
||||
* commands.
|
||||
*/
|
||||
|
||||
TclInvalidateCmdLiteral(interp, tail, nsPtr);
|
||||
TclInvalidateCmdLiteral(interp, cmdName, nsPtr);
|
||||
|
||||
/*
|
||||
* The list of command exported from the namespace might have changed.
|
||||
@@ -2597,10 +2629,6 @@ TclRenameCommand(
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
cmdNsPtr = cmdPtr->nsPtr;
|
||||
oldFullName = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(oldFullName);
|
||||
Tcl_GetCommandFullName(interp, cmd, oldFullName);
|
||||
|
||||
/*
|
||||
* If the new command name is NULL or empty, delete the command. Do this
|
||||
@@ -2609,10 +2637,14 @@ TclRenameCommand(
|
||||
|
||||
if ((newName == NULL) || (*newName == '\0')) {
|
||||
Tcl_DeleteCommandFromToken(interp, cmd);
|
||||
result = TCL_OK;
|
||||
goto done;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
cmdNsPtr = cmdPtr->nsPtr;
|
||||
oldFullName = Tcl_NewObj();
|
||||
Tcl_IncrRefCount(oldFullName);
|
||||
Tcl_GetCommandFullName(interp, cmd, oldFullName);
|
||||
|
||||
/*
|
||||
* Make sure that the destination command does not already exist. The
|
||||
* rename operation is like creating a command, so we should automatically
|
||||
@@ -3124,6 +3156,8 @@ Tcl_DeleteCommandFromToken(
|
||||
* traces.
|
||||
*/
|
||||
|
||||
cmdPtr->nsPtr->refCount++;
|
||||
|
||||
if (cmdPtr->tracePtr != NULL) {
|
||||
CommandTrace *tracePtr;
|
||||
CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE);
|
||||
@@ -3151,6 +3185,7 @@ Tcl_DeleteCommandFromToken(
|
||||
*/
|
||||
|
||||
TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
|
||||
TclNsDecrRefCount(cmdPtr->nsPtr);
|
||||
|
||||
/*
|
||||
* If the command being deleted has a compile function, increment the
|
||||
@@ -3488,6 +3523,7 @@ TclCleanupCommand(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED)
|
||||
void
|
||||
Tcl_CreateMathFunc(
|
||||
Tcl_Interp *interp, /* Interpreter in which function is to be
|
||||
@@ -3538,7 +3574,7 @@ Tcl_CreateMathFunc(
|
||||
|
||||
static int
|
||||
OldMathFuncProc(
|
||||
ClientData clientData, /* Ponter to OldMathFuncData describing the
|
||||
ClientData clientData, /* Pointer to OldMathFuncData describing the
|
||||
* function being called */
|
||||
Tcl_Interp *interp, /* Tcl interpreter */
|
||||
int objc, /* Actual parameter count */
|
||||
@@ -3651,7 +3687,7 @@ OldMathFuncProc(
|
||||
*/
|
||||
|
||||
if (funcResult.type == TCL_INT) {
|
||||
TclNewLongObj(valuePtr, funcResult.intValue);
|
||||
TclNewIntObj(valuePtr, funcResult.intValue);
|
||||
} else if (funcResult.type == TCL_WIDE_INT) {
|
||||
valuePtr = Tcl_NewWideIntObj(funcResult.wideValue);
|
||||
} else {
|
||||
@@ -3819,6 +3855,7 @@ Tcl_ListMathFuncs(
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -4426,7 +4463,9 @@ TclNRRunCallbacks(
|
||||
/* All callbacks down to rootPtr not inclusive
|
||||
* are to be run. */
|
||||
{
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) */
|
||||
NRE_callback *callbackPtr;
|
||||
Tcl_NRPostProc *procPtr;
|
||||
|
||||
@@ -4440,9 +4479,13 @@ TclNRRunCallbacks(
|
||||
* are for NR function calls, and those are Tcl_Obj based.
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
if (*(iPtr->result) != 0) {
|
||||
(void) Tcl_GetObjResult(interp);
|
||||
}
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) */
|
||||
|
||||
/* This is the trampoline. */
|
||||
|
||||
while (TOP_CB(interp) != rootPtr) {
|
||||
callbackPtr = TOP_CB(interp);
|
||||
@@ -4577,7 +4620,7 @@ TEOV_Exception(
|
||||
if (result == TCL_RETURN) {
|
||||
result = TclUpdateReturnInfo(iPtr);
|
||||
}
|
||||
if ((result != TCL_ERROR) && !allowExceptions) {
|
||||
if ((result != TCL_OK) && (result != TCL_ERROR) && !allowExceptions) {
|
||||
ProcessUnexpectedResult(interp, result);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
@@ -4758,7 +4801,7 @@ TEOV_RunEnterTraces(
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Command *cmdPtr = *cmdPtrPtr;
|
||||
size_t newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
|
||||
unsigned int newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
|
||||
int length, traceCode = TCL_OK;
|
||||
const char *command = TclGetStringFromObj(commandPtr, &length);
|
||||
|
||||
@@ -4901,6 +4944,7 @@ Tcl_EvalTokensStandard(
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -4948,6 +4992,7 @@ Tcl_EvalTokens(
|
||||
Tcl_ResetResult(interp);
|
||||
return resPtr;
|
||||
}
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -6466,7 +6511,6 @@ Tcl_ExprLongObj(
|
||||
resultPtr = Tcl_NewBignumObj(&big);
|
||||
/* FALLTHROUGH */
|
||||
}
|
||||
case TCL_NUMBER_LONG:
|
||||
case TCL_NUMBER_WIDE:
|
||||
case TCL_NUMBER_BIG:
|
||||
result = TclGetLongFromObj(interp, resultPtr, ptr);
|
||||
@@ -6834,7 +6878,8 @@ Tcl_AddObjErrorInfo(
|
||||
|
||||
iPtr->flags |= ERR_LEGACY_COPY;
|
||||
if (iPtr->errorInfo == NULL) {
|
||||
if (iPtr->result[0] != 0) {
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
if (*(iPtr->result) != 0) {
|
||||
/*
|
||||
* The interp's string result is set, apparently by some extension
|
||||
* making a deprecated direct write to it. That extension may
|
||||
@@ -6844,9 +6889,9 @@ Tcl_AddObjErrorInfo(
|
||||
*/
|
||||
|
||||
iPtr->errorInfo = Tcl_NewStringObj(iPtr->result, -1);
|
||||
} else {
|
||||
} else
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) */
|
||||
iPtr->errorInfo = iPtr->objResultPtr;
|
||||
}
|
||||
Tcl_IncrRefCount(iPtr->errorInfo);
|
||||
if (!iPtr->errorCode) {
|
||||
Tcl_SetErrorCode(interp, "NONE", NULL);
|
||||
@@ -7442,12 +7487,12 @@ ExprAbsFunc(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (type == TCL_NUMBER_LONG) {
|
||||
long l = *((const long *) ptr);
|
||||
if (type == TCL_NUMBER_WIDE) {
|
||||
Tcl_WideInt l = *((const Tcl_WideInt *) ptr);
|
||||
|
||||
if (l > (long)0) {
|
||||
if (l > (Tcl_WideInt)0) {
|
||||
goto unChanged;
|
||||
} else if (l == (long)0) {
|
||||
} else if (l == (Tcl_WideInt)0) {
|
||||
const char *string = objv[1]->bytes;
|
||||
if (string) {
|
||||
while (*string != '0') {
|
||||
@@ -7459,11 +7504,11 @@ ExprAbsFunc(
|
||||
}
|
||||
}
|
||||
goto unChanged;
|
||||
} else if (l == LONG_MIN) {
|
||||
TclInitBignumFromLong(&big, l);
|
||||
} else if (l == LLONG_MIN) {
|
||||
TclInitBignumFromWideInt(&big, l);
|
||||
goto tooLarge;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewLongObj(-l));
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-l));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -7487,24 +7532,8 @@ ExprAbsFunc(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (type == TCL_NUMBER_WIDE) {
|
||||
Tcl_WideInt w = *((const Tcl_WideInt *) ptr);
|
||||
|
||||
if (w >= (Tcl_WideInt)0) {
|
||||
goto unChanged;
|
||||
}
|
||||
if (w == LLONG_MIN) {
|
||||
TclInitBignumFromWideInt(&big, w);
|
||||
goto tooLarge;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-w));
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (type == TCL_NUMBER_BIG) {
|
||||
if (mp_cmp_d((const mp_int *) ptr, 0) == MP_LT) {
|
||||
if (mp_isneg((const mp_int *) ptr)) {
|
||||
Tcl_GetBignumFromObj(NULL, objv[1], &big);
|
||||
tooLarge:
|
||||
mp_neg(&big, &big);
|
||||
@@ -7699,6 +7728,71 @@ ExprWideFunc(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common implmentation of max() and min().
|
||||
*/
|
||||
static int
|
||||
ExprMaxMinFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
Tcl_Interp *interp, /* The interpreter in which to execute the
|
||||
* function. */
|
||||
int objc, /* Actual parameter count. */
|
||||
Tcl_Obj *const *objv, /* Actual parameter vector. */
|
||||
int op) /* Comparison direction */
|
||||
{
|
||||
Tcl_Obj *res;
|
||||
double d;
|
||||
int type, i;
|
||||
ClientData ptr;
|
||||
|
||||
if (objc < 2) {
|
||||
MathFuncWrongNumArgs(interp, 2, objc, objv);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
res = objv[1];
|
||||
for (i = 1; i < objc; i++) {
|
||||
if (TclGetNumberFromObj(interp, objv[i], &ptr, &type) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (type == TCL_NUMBER_NAN) {
|
||||
/*
|
||||
* Get the error message for NaN.
|
||||
*/
|
||||
|
||||
Tcl_GetDoubleFromObj(interp, objv[i], &d);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (TclCompareTwoNumbers(objv[i], res) == op) {
|
||||
res = objv[i];
|
||||
}
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, res);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
ExprMaxFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
Tcl_Interp *interp, /* The interpreter in which to execute the
|
||||
* function. */
|
||||
int objc, /* Actual parameter count. */
|
||||
Tcl_Obj *const *objv) /* Actual parameter vector. */
|
||||
{
|
||||
return ExprMaxMinFunc(clientData, interp, objc, objv, MP_GT);
|
||||
}
|
||||
|
||||
static int
|
||||
ExprMinFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
Tcl_Interp *interp, /* The interpreter in which to execute the
|
||||
* function. */
|
||||
int objc, /* Actual parameter count. */
|
||||
Tcl_Obj *const *objv) /* Actual parameter vector. */
|
||||
{
|
||||
return ExprMaxMinFunc(clientData, interp, objc, objv, MP_LT);
|
||||
}
|
||||
|
||||
static int
|
||||
ExprRandFunc(
|
||||
ClientData clientData, /* Ignored. */
|
||||
@@ -7722,7 +7816,7 @@ ExprRandFunc(
|
||||
iPtr->flags |= RAND_SEED_INITIALIZED;
|
||||
|
||||
/*
|
||||
* To ensure different seeds in different threads (bug #416643),
|
||||
* To ensure different seeds in different threads (bug #416643),
|
||||
* take into consideration the thread this interp is running in.
|
||||
*/
|
||||
|
||||
@@ -8187,6 +8281,22 @@ Tcl_NRCreateCommand(
|
||||
cmdPtr->nreProc = nreProc;
|
||||
return (Tcl_Command) cmdPtr;
|
||||
}
|
||||
|
||||
Tcl_Command
|
||||
TclNRCreateCommandInNs (
|
||||
Tcl_Interp *interp,
|
||||
const char *cmdName,
|
||||
Tcl_Namespace *nsPtr,
|
||||
Tcl_ObjCmdProc *proc,
|
||||
Tcl_ObjCmdProc *nreProc,
|
||||
ClientData clientData,
|
||||
Tcl_CmdDeleteProc *deleteProc) {
|
||||
Command *cmdPtr = (Command *)
|
||||
TclCreateObjCommandInNs(interp,cmdName,nsPtr,proc,clientData,deleteProc);
|
||||
|
||||
cmdPtr->nreProc = nreProc;
|
||||
return (Tcl_Command) cmdPtr;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Stuff for the public api
|
||||
@@ -8972,9 +9082,9 @@ TclNRCoroutineObjCmd(
|
||||
{
|
||||
Command *cmdPtr;
|
||||
CoroutineData *corPtr;
|
||||
const char *fullName, *procName;
|
||||
Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
|
||||
Tcl_DString ds;
|
||||
const char *procName, *simpleName;
|
||||
Namespace *nsPtr, *altNsPtr, *cxtNsPtr,
|
||||
*inNsPtr = (Namespace *)TclGetCurrentNamespace(interp);
|
||||
Namespace *lookupNsPtr = iPtr->varFramePtr->nsPtr;
|
||||
|
||||
if (objc < 3) {
|
||||
@@ -8982,34 +9092,21 @@ TclNRCoroutineObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: this is copy/pasted from Tcl_ProcObjCommand. Should have
|
||||
* something in tclUtil.c to find the FQ name.
|
||||
*/
|
||||
|
||||
fullName = TclGetString(objv[1]);
|
||||
TclGetNamespaceForQualName(interp, fullName, NULL, 0,
|
||||
&nsPtr, &altNsPtr, &cxtNsPtr, &procName);
|
||||
procName = TclGetString(objv[1]);
|
||||
TclGetNamespaceForQualName(interp, procName, inNsPtr, 0,
|
||||
&nsPtr, &altNsPtr, &cxtNsPtr, &simpleName);
|
||||
|
||||
if (nsPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\": unknown namespace",
|
||||
fullName));
|
||||
procName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (procName == NULL) {
|
||||
if (simpleName == 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_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\" in non-global namespace with"
|
||||
" name starting with \":\"", procName));
|
||||
procName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -9021,16 +9118,9 @@ TclNRCoroutineObjCmd(
|
||||
|
||||
corPtr = ckalloc(sizeof(CoroutineData));
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
if (nsPtr != iPtr->globalNsPtr) {
|
||||
Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
|
||||
TclDStringAppendLiteral(&ds, "::");
|
||||
}
|
||||
Tcl_DStringAppend(&ds, procName, -1);
|
||||
|
||||
cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
|
||||
/*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine);
|
||||
Tcl_DStringFree(&ds);
|
||||
cmdPtr = (Command *) TclNRCreateCommandInNs(interp, simpleName,
|
||||
(Tcl_Namespace *)nsPtr, /*objProc*/ NULL, TclNRInterpCoroutine,
|
||||
corPtr, DeleteCoroutine);
|
||||
|
||||
corPtr->cmdPtr = cmdPtr;
|
||||
cmdPtr->refCount++;
|
||||
|
||||
+14
-14
@@ -187,15 +187,15 @@ TclDumpMemoryInfo(
|
||||
"total mallocs %10u\n"
|
||||
"total frees %10u\n"
|
||||
"current packets allocated %10u\n"
|
||||
"current bytes allocated %10" TCL_LL_MODIFIER "u\n"
|
||||
"current bytes allocated %10" TCL_Z_MODIFIER "u\n"
|
||||
"maximum packets allocated %10u\n"
|
||||
"maximum bytes allocated %10" TCL_LL_MODIFIER "u\n",
|
||||
"maximum bytes allocated %10" TCL_Z_MODIFIER "u\n",
|
||||
total_mallocs,
|
||||
total_frees,
|
||||
current_malloc_packets,
|
||||
(Tcl_WideInt)current_bytes_malloced,
|
||||
current_bytes_malloced,
|
||||
maximum_malloc_packets,
|
||||
(Tcl_WideInt)maximum_bytes_malloced);
|
||||
maximum_bytes_malloced);
|
||||
if (flags == 0) {
|
||||
fprintf((FILE *)clientData, "%s", buf);
|
||||
} else {
|
||||
@@ -254,7 +254,7 @@ ValidateMemory(
|
||||
fprintf(stderr, "low guard failed at %p, %s %d\n",
|
||||
memHeaderP->body, file, line);
|
||||
fflush(stderr); /* In case name pointer is bad. */
|
||||
fprintf(stderr, "%" TCL_LL_MODIFIER "d bytes allocated at (%s %d)\n", (Tcl_WideInt) memHeaderP->length,
|
||||
fprintf(stderr, "%" TCL_Z_MODIFIER "u bytes allocated at (%s %d)\n", memHeaderP->length,
|
||||
memHeaderP->file, memHeaderP->line);
|
||||
Tcl_Panic("Memory validation failure");
|
||||
}
|
||||
@@ -276,8 +276,8 @@ ValidateMemory(
|
||||
fprintf(stderr, "high guard failed at %p, %s %d\n",
|
||||
memHeaderP->body, file, line);
|
||||
fflush(stderr); /* In case name pointer is bad. */
|
||||
fprintf(stderr, "%" TCL_LL_MODIFIER "d bytes allocated at (%s %d)\n",
|
||||
(Tcl_WideInt)memHeaderP->length, memHeaderP->file,
|
||||
fprintf(stderr, "%" TCL_Z_MODIFIER "u bytes allocated at (%s %d)\n",
|
||||
memHeaderP->length, memHeaderP->file,
|
||||
memHeaderP->line);
|
||||
Tcl_Panic("Memory validation failure");
|
||||
}
|
||||
@@ -359,9 +359,9 @@ Tcl_DumpActiveMemory(
|
||||
Tcl_MutexLock(ckallocMutexPtr);
|
||||
for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
|
||||
address = &memScanP->body[0];
|
||||
fprintf(fileP, "%p - %p %" TCL_LL_MODIFIER "d @ %s %d %s",
|
||||
fprintf(fileP, "%p - %p %" TCL_Z_MODIFIER "u @ %s %d %s",
|
||||
address, address + memScanP->length - 1,
|
||||
(Tcl_WideInt)memScanP->length, memScanP->file, memScanP->line,
|
||||
memScanP->length, memScanP->file, memScanP->line,
|
||||
(memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
|
||||
(void) fputc('\n', fileP);
|
||||
}
|
||||
@@ -611,8 +611,8 @@ Tcl_DbCkfree(
|
||||
memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
|
||||
|
||||
if (alloc_tracing) {
|
||||
fprintf(stderr, "ckfree %p %" TCL_LL_MODIFIER "d %s %d\n",
|
||||
memp->body, (Tcl_WideInt) memp->length, file, line);
|
||||
fprintf(stderr, "ckfree %p %" TCL_Z_MODIFIER "u %s %d\n",
|
||||
memp->body, memp->length, file, line);
|
||||
}
|
||||
|
||||
if (validate_memory) {
|
||||
@@ -859,12 +859,12 @@ MemoryCmd(
|
||||
}
|
||||
if (strcmp(argv[1],"info") == 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER"d\n%-25s %10u\n%-25s %10" TCL_LL_MODIFIER "d\n",
|
||||
"%-25s %10u\n%-25s %10u\n%-25s %10u\n%-25s %10" TCL_Z_MODIFIER"u\n%-25s %10u\n%-25s %10" TCL_Z_MODIFIER "u\n",
|
||||
"total mallocs", total_mallocs, "total frees", total_frees,
|
||||
"current packets allocated", current_malloc_packets,
|
||||
"current bytes allocated", (Tcl_WideInt)current_bytes_malloced,
|
||||
"current bytes allocated", current_bytes_malloced,
|
||||
"maximum packets allocated", maximum_malloc_packets,
|
||||
"maximum bytes allocated", (Tcl_WideInt)maximum_bytes_malloced));
|
||||
"maximum bytes allocated", maximum_bytes_malloced));
|
||||
return TCL_OK;
|
||||
}
|
||||
if (strcmp(argv[1], "init") == 0) {
|
||||
|
||||
+1
-1
@@ -164,7 +164,7 @@ Tcl_BreakObjCmd(
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
/* ARGSUSED */
|
||||
int
|
||||
Tcl_CaseObjCmd(
|
||||
|
||||
+187
-92
@@ -64,8 +64,9 @@ typedef struct SortInfo {
|
||||
* SORTMODE_COMMAND. Pre-initialized to hold
|
||||
* base of command. */
|
||||
int *indexv; /* If the -index option was specified, this
|
||||
* holds the indexes contained in the list
|
||||
* supplied as an argument to that option.
|
||||
* holds an encoding of the indexes contained
|
||||
* in the list supplied as an argument to
|
||||
* that option.
|
||||
* NULL if no indexes supplied, and points to
|
||||
* singleIndex field when only one
|
||||
* supplied. */
|
||||
@@ -92,14 +93,6 @@ typedef struct SortInfo {
|
||||
#define SORTMODE_DICTIONARY 4
|
||||
#define SORTMODE_ASCII_NC 8
|
||||
|
||||
/*
|
||||
* Magic values for the index field of the SortInfo structure. Note that the
|
||||
* index "end-1" will be translated to SORTIDX_END-1, etc.
|
||||
*/
|
||||
|
||||
#define SORTIDX_NONE -1 /* Not indexed; use whole value. */
|
||||
#define SORTIDX_END -2 /* Indexed from end. */
|
||||
|
||||
/*
|
||||
* Forward declarations for procedures defined in this file:
|
||||
*/
|
||||
@@ -2160,7 +2153,7 @@ Tcl_JoinObjCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* The argument objects. */
|
||||
{
|
||||
int listLen;
|
||||
int length, listLen;
|
||||
Tcl_Obj *resObjPtr = NULL, *joinObjPtr, **elemPtrs;
|
||||
|
||||
if ((objc < 2) || (objc > 3)) {
|
||||
@@ -2191,9 +2184,9 @@ Tcl_JoinObjCmd(
|
||||
joinObjPtr = (objc == 2) ? Tcl_NewStringObj(" ", 1) : objv[2];
|
||||
Tcl_IncrRefCount(joinObjPtr);
|
||||
|
||||
if (Tcl_GetCharLength(joinObjPtr) == 0) {
|
||||
TclStringCatObjv(interp, /* inPlace */ 0, listLen, elemPtrs,
|
||||
&resObjPtr);
|
||||
(void) Tcl_GetStringFromObj(joinObjPtr, &length);
|
||||
if (length == 0) {
|
||||
resObjPtr = TclStringCat(interp, listLen, elemPtrs, 0);
|
||||
} else {
|
||||
int i;
|
||||
|
||||
@@ -2787,7 +2780,7 @@ Tcl_LreplaceObjCmd(
|
||||
* (to allow for replacing the last elem).
|
||||
*/
|
||||
|
||||
if ((first > listLen) && (listLen > 0)) {
|
||||
if ((first >= listLen) && (listLen > 0)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"list doesn't contain element %s", TclGetString(objv[2])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX",
|
||||
@@ -2938,20 +2931,21 @@ Tcl_LsearchObjCmd(
|
||||
Tcl_Obj *const objv[]) /* Argument values. */
|
||||
{
|
||||
const char *bytes, *patternBytes;
|
||||
int i, match, index, result, listc, length, elemLen, bisect;
|
||||
int dataType, isIncreasing, lower, upper, offset;
|
||||
int i, match, index, result=TCL_OK, listc, length, elemLen, bisect;
|
||||
int allocatedIndexVector = 0;
|
||||
int dataType, isIncreasing, lower, upper, start, groupSize, groupOffset;
|
||||
Tcl_WideInt patWide, objWide;
|
||||
int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
|
||||
double patDouble, objDouble;
|
||||
SortInfo sortInfo;
|
||||
Tcl_Obj *patObj, **listv, *listPtr, *startPtr, *itemPtr;
|
||||
SortStrCmpFn_t strCmpFn = strcmp;
|
||||
SortStrCmpFn_t strCmpFn = TclUtfCmp;
|
||||
Tcl_RegExp regexp = NULL;
|
||||
static const char *const options[] = {
|
||||
"-all", "-ascii", "-bisect", "-decreasing", "-dictionary",
|
||||
"-exact", "-glob", "-increasing", "-index",
|
||||
"-inline", "-integer", "-nocase", "-not",
|
||||
"-real", "-regexp", "-sorted", "-start",
|
||||
"-real", "-regexp", "-sorted", "-start", "-stride",
|
||||
"-subindices", NULL
|
||||
};
|
||||
enum options {
|
||||
@@ -2959,7 +2953,7 @@ Tcl_LsearchObjCmd(
|
||||
LSEARCH_DICTIONARY, LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING,
|
||||
LSEARCH_INDEX, LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE,
|
||||
LSEARCH_NOT, LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED,
|
||||
LSEARCH_START, LSEARCH_SUBINDICES
|
||||
LSEARCH_START, LSEARCH_STRIDE, LSEARCH_SUBINDICES
|
||||
};
|
||||
enum datatypes {
|
||||
ASCII, DICTIONARY, INTEGER, REAL
|
||||
@@ -2979,7 +2973,9 @@ Tcl_LsearchObjCmd(
|
||||
bisect = 0;
|
||||
listPtr = NULL;
|
||||
startPtr = NULL;
|
||||
offset = 0;
|
||||
groupSize = 1;
|
||||
groupOffset = 0;
|
||||
start = 0;
|
||||
noCase = 0;
|
||||
sortInfo.compareCmdPtr = NULL;
|
||||
sortInfo.isIncreasing = 1;
|
||||
@@ -2997,9 +2993,6 @@ Tcl_LsearchObjCmd(
|
||||
for (i = 1; i < objc-2; i++) {
|
||||
if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
|
||||
!= TCL_OK) {
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
@@ -3064,6 +3057,7 @@ Tcl_LsearchObjCmd(
|
||||
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
startPtr = NULL;
|
||||
}
|
||||
if (i > objc-4) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
@@ -3084,25 +3078,47 @@ Tcl_LsearchObjCmd(
|
||||
startPtr = Tcl_DuplicateObj(objv[i]);
|
||||
} else {
|
||||
startPtr = objv[i];
|
||||
Tcl_IncrRefCount(startPtr);
|
||||
}
|
||||
Tcl_IncrRefCount(startPtr);
|
||||
break;
|
||||
case LSEARCH_STRIDE: /* -stride */
|
||||
if (i > objc-4) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"\"-stride\" option must be "
|
||||
"followed by stride length", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) {
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (groupSize < 1) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"stride length must be at least 1", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
|
||||
"BADSTRIDE", NULL);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
i++;
|
||||
break;
|
||||
case LSEARCH_INDEX: { /* -index */
|
||||
Tcl_Obj **indices;
|
||||
int j;
|
||||
|
||||
if (sortInfo.indexc > 1) {
|
||||
if (allocatedIndexVector) {
|
||||
TclStackFree(interp, sortInfo.indexv);
|
||||
allocatedIndexVector = 0;
|
||||
}
|
||||
if (i > objc-4) {
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"\"-index\" option must be followed by list index",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
|
||||
return TCL_ERROR;
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3114,10 +3130,8 @@ Tcl_LsearchObjCmd(
|
||||
i++;
|
||||
if (TclListObjGetElements(interp, objv[i],
|
||||
&sortInfo.indexc, &indices) != TCL_OK) {
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
switch (sortInfo.indexc) {
|
||||
case 0:
|
||||
@@ -3129,6 +3143,8 @@ Tcl_LsearchObjCmd(
|
||||
default:
|
||||
sortInfo.indexv =
|
||||
TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
|
||||
allocatedIndexVector = 1; /* Cannot use indexc field, as it
|
||||
* might be decreased by 1 later. */
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3138,13 +3154,26 @@ Tcl_LsearchObjCmd(
|
||||
*/
|
||||
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
|
||||
&sortInfo.indexv[j]) != TCL_OK) {
|
||||
int encoded = 0;
|
||||
if (TclIndexEncode(interp, indices[j], TCL_INDEX_BEFORE,
|
||||
TCL_INDEX_AFTER, &encoded) != TCL_OK) {
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if ((encoded == TCL_INDEX_BEFORE)
|
||||
|| (encoded == TCL_INDEX_AFTER)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"index \"%s\" cannot select an element "
|
||||
"from any list", Tcl_GetString(indices[j])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
|
||||
"OUTOFRANGE", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if (result == TCL_ERROR) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (-index option item number %d)", j));
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
sortInfo.indexv[j] = encoded;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -3156,14 +3185,12 @@ Tcl_LsearchObjCmd(
|
||||
*/
|
||||
|
||||
if (returnSubindices && sortInfo.indexc==0) {
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
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;
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (bisect && (allMatches || negatedMatch)) {
|
||||
@@ -3171,7 +3198,8 @@ Tcl_LsearchObjCmd(
|
||||
"-bisect is not compatible with -all or -not", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
|
||||
"BAD_OPTION_MIX", NULL);
|
||||
return TCL_ERROR;
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (mode == REGEXP) {
|
||||
@@ -3197,9 +3225,6 @@ Tcl_LsearchObjCmd(
|
||||
}
|
||||
|
||||
if (regexp == NULL) {
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
@@ -3212,24 +3237,64 @@ Tcl_LsearchObjCmd(
|
||||
|
||||
result = TclListObjGetElements(interp, objv[objc - 2], &listc, &listv);
|
||||
if (result != TCL_OK) {
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for sanity when grouping elements of the overall list together
|
||||
* because of the -stride option. [TIP #351]
|
||||
*/
|
||||
|
||||
if (groupSize > 1) {
|
||||
if (listc % groupSize) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"list size must be a multiple of the stride length",
|
||||
-1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH", "BADSTRIDE",
|
||||
NULL);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (sortInfo.indexc > 0) {
|
||||
/*
|
||||
* Use the first value in the list supplied to -index as the
|
||||
* offset of the element within each group by which to sort.
|
||||
*/
|
||||
|
||||
groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
|
||||
if (groupOffset < 0 || groupOffset >= groupSize) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"when used with \"-stride\", the leading \"-index\""
|
||||
" value must be within the group", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
|
||||
"BADINDEX", NULL);
|
||||
result = TCL_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (sortInfo.indexc == 1) {
|
||||
sortInfo.indexc = 0;
|
||||
sortInfo.indexv = NULL;
|
||||
} else {
|
||||
sortInfo.indexc--;
|
||||
|
||||
for (i = 0; i < sortInfo.indexc; i++) {
|
||||
sortInfo.indexv[i] = sortInfo.indexv[i+1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the user-specified start offset.
|
||||
*/
|
||||
|
||||
if (startPtr) {
|
||||
result = TclGetIntForIndexM(interp, startPtr, listc-1, &offset);
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
result = TclGetIntForIndexM(interp, startPtr, listc-1, &start);
|
||||
if (result != TCL_OK) {
|
||||
goto done;
|
||||
}
|
||||
if (offset < 0) {
|
||||
offset = 0;
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3237,16 +3302,21 @@ Tcl_LsearchObjCmd(
|
||||
* "did not match anything at all" result straight away. [Bug 1374778]
|
||||
*/
|
||||
|
||||
if (offset > listc-1) {
|
||||
if (sortInfo.indexc > 1) {
|
||||
TclStackFree(interp, sortInfo.indexv);
|
||||
}
|
||||
if (start > listc-1) {
|
||||
if (allMatches || inlineReturn) {
|
||||
Tcl_ResetResult(interp);
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
}
|
||||
return TCL_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*
|
||||
* If start points within a group, it points to the start of the group.
|
||||
*/
|
||||
|
||||
if (groupSize > 1) {
|
||||
start -= (start % groupSize);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3305,18 +3375,23 @@ Tcl_LsearchObjCmd(
|
||||
* sense in doing this when the match sense is inverted.
|
||||
*/
|
||||
|
||||
lower = offset - 1;
|
||||
/*
|
||||
* With -stride, lower, upper and i are kept as multiples of groupSize.
|
||||
*/
|
||||
|
||||
lower = start - groupSize;
|
||||
upper = listc;
|
||||
while (lower + 1 != upper && sortInfo.resultCode == TCL_OK) {
|
||||
while (lower + groupSize != upper && sortInfo.resultCode == TCL_OK) {
|
||||
i = (lower + upper)/2;
|
||||
i -= i % groupSize;
|
||||
if (sortInfo.indexc != 0) {
|
||||
itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
|
||||
itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
|
||||
if (sortInfo.resultCode != TCL_OK) {
|
||||
result = sortInfo.resultCode;
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
itemPtr = listv[i];
|
||||
itemPtr = listv[i+groupOffset];
|
||||
}
|
||||
switch ((enum datatypes) dataType) {
|
||||
case ASCII:
|
||||
@@ -3405,10 +3480,10 @@ Tcl_LsearchObjCmd(
|
||||
if (allMatches) {
|
||||
listPtr = Tcl_NewListObj(0, NULL);
|
||||
}
|
||||
for (i = offset; i < listc; i++) {
|
||||
for (i = start; i < listc; i += groupSize) {
|
||||
match = 0;
|
||||
if (sortInfo.indexc != 0) {
|
||||
itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
|
||||
itemPtr = SelectObjFromSublist(listv[i+groupOffset], &sortInfo);
|
||||
if (sortInfo.resultCode != TCL_OK) {
|
||||
if (listPtr != NULL) {
|
||||
Tcl_DecrRefCount(listPtr);
|
||||
@@ -3417,7 +3492,7 @@ Tcl_LsearchObjCmd(
|
||||
goto done;
|
||||
}
|
||||
} else {
|
||||
itemPtr = listv[i];
|
||||
itemPtr = listv[i+groupOffset];
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
@@ -3507,18 +3582,23 @@ Tcl_LsearchObjCmd(
|
||||
*/
|
||||
|
||||
if (returnSubindices && (sortInfo.indexc != 0)) {
|
||||
itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
|
||||
itemPtr = SelectObjFromSublist(listv[i+groupOffset],
|
||||
&sortInfo);
|
||||
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
|
||||
} else if (groupSize > 1) {
|
||||
Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0,
|
||||
groupSize, &listv[i]);
|
||||
} else {
|
||||
itemPtr = listv[i];
|
||||
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
|
||||
} else if (returnSubindices) {
|
||||
int j;
|
||||
|
||||
itemPtr = Tcl_NewIntObj(i);
|
||||
itemPtr = Tcl_NewIntObj(i+groupOffset);
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
Tcl_ListObjAppendElement(interp, itemPtr,
|
||||
Tcl_NewIntObj(sortInfo.indexv[j]));
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
|
||||
TclIndexDecode(sortInfo.indexv[j], listc)));
|
||||
}
|
||||
Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
|
||||
} else {
|
||||
@@ -3537,10 +3617,10 @@ Tcl_LsearchObjCmd(
|
||||
if (returnSubindices) {
|
||||
int j;
|
||||
|
||||
itemPtr = Tcl_NewIntObj(index);
|
||||
itemPtr = Tcl_NewIntObj(index+groupOffset);
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
Tcl_ListObjAppendElement(interp, itemPtr,
|
||||
Tcl_NewIntObj(sortInfo.indexv[j]));
|
||||
Tcl_ListObjAppendElement(interp, itemPtr, Tcl_NewIntObj(
|
||||
TclIndexDecode(sortInfo.indexv[j], listc)));
|
||||
}
|
||||
Tcl_SetObjResult(interp, itemPtr);
|
||||
} else {
|
||||
@@ -3554,7 +3634,14 @@ Tcl_LsearchObjCmd(
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewObj());
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, listv[index]);
|
||||
if (returnSubindices) {
|
||||
Tcl_SetObjResult(interp, SelectObjFromSublist(listv[i+groupOffset],
|
||||
&sortInfo));
|
||||
} else if (groupSize > 1) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewListObj(groupSize, &listv[index]));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, listv[index]);
|
||||
}
|
||||
}
|
||||
result = TCL_OK;
|
||||
|
||||
@@ -3563,7 +3650,10 @@ Tcl_LsearchObjCmd(
|
||||
*/
|
||||
|
||||
done:
|
||||
if (sortInfo.indexc > 1) {
|
||||
if (startPtr != NULL) {
|
||||
Tcl_DecrRefCount(startPtr);
|
||||
}
|
||||
if (allocatedIndexVector) {
|
||||
TclStackFree(interp, sortInfo.indexv);
|
||||
}
|
||||
return result;
|
||||
@@ -3757,7 +3847,7 @@ Tcl_LsortObjCmd(
|
||||
sortInfo.isIncreasing = 1;
|
||||
break;
|
||||
case LSORT_INDEX: {
|
||||
int indexc, dummy;
|
||||
int indexc;
|
||||
Tcl_Obj **indexv;
|
||||
|
||||
if (i == objc-2) {
|
||||
@@ -3783,8 +3873,20 @@ Tcl_LsortObjCmd(
|
||||
*/
|
||||
|
||||
for (j=0 ; j<indexc ; j++) {
|
||||
if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
|
||||
&dummy) != TCL_OK) {
|
||||
int encoded = 0;
|
||||
int result = TclIndexEncode(interp, indexv[j],
|
||||
TCL_INDEX_BEFORE, TCL_INDEX_AFTER, &encoded);
|
||||
|
||||
if ((result == TCL_OK) && ((encoded == TCL_INDEX_BEFORE)
|
||||
|| (encoded == TCL_INDEX_AFTER))) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"index \"%s\" cannot select an element "
|
||||
"from any list", Tcl_GetString(indexv[j])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX"
|
||||
"OUTOFRANGE", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if (result == TCL_ERROR) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (-index option item number %d)", j));
|
||||
sortInfo.resultCode = TCL_ERROR;
|
||||
@@ -3864,8 +3966,8 @@ Tcl_LsortObjCmd(
|
||||
* might be decreased by 1 later. */
|
||||
}
|
||||
for (j=0 ; j<sortInfo.indexc ; j++) {
|
||||
TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
|
||||
&sortInfo.indexv[j]);
|
||||
/* Prescreened values, no errors or out of range possible */
|
||||
TclIndexEncode(NULL, indexv[j], 0, 0, &sortInfo.indexv[j]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3936,10 +4038,7 @@ Tcl_LsortObjCmd(
|
||||
* offset of the element within each group by which to sort.
|
||||
*/
|
||||
|
||||
groupOffset = sortInfo.indexv[0];
|
||||
if (groupOffset <= SORTIDX_END) {
|
||||
groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1;
|
||||
}
|
||||
groupOffset = TclIndexDecode(sortInfo.indexv[0], groupSize - 1);
|
||||
if (groupOffset < 0 || groupOffset >= groupSize) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"when used with \"-stride\", the leading \"-index\""
|
||||
@@ -3958,6 +4057,9 @@ Tcl_LsortObjCmd(
|
||||
/*
|
||||
* Do not shrink the actual memory block used; that doesn't
|
||||
* work with TclStackAlloc-allocated memory. [Bug 2918962]
|
||||
*
|
||||
* TODO: Consider a pointer increment to replace this
|
||||
* array shift.
|
||||
*/
|
||||
|
||||
for (i = 0; i < sortInfo.indexc; i++) {
|
||||
@@ -4263,7 +4365,7 @@ SortCompare(
|
||||
int order = 0;
|
||||
|
||||
if (infoPtr->sortMode == SORTMODE_ASCII) {
|
||||
order = strcmp(elemPtr1->collationKey.strValuePtr,
|
||||
order = TclUtfCmp(elemPtr1->collationKey.strValuePtr,
|
||||
elemPtr2->collationKey.strValuePtr);
|
||||
} else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
|
||||
order = TclUtfCasecmp(elemPtr1->collationKey.strValuePtr,
|
||||
@@ -4526,15 +4628,8 @@ SelectObjFromSublist(
|
||||
infoPtr->resultCode = TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
index = infoPtr->indexv[i];
|
||||
|
||||
/*
|
||||
* Adjust for end-based indexing.
|
||||
*/
|
||||
|
||||
if (index < SORTIDX_NONE) {
|
||||
index += listLen + 1;
|
||||
}
|
||||
index = TclIndexDecode(infoPtr->indexv[i], listLen - 1);
|
||||
|
||||
if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index,
|
||||
¤tObj) != TCL_OK) {
|
||||
|
||||
+37
-51
@@ -309,7 +309,7 @@ Tcl_RegexpObjCmd(
|
||||
eflags = 0;
|
||||
} else if (offset > stringLength) {
|
||||
eflags = TCL_REG_NOTBOL;
|
||||
} else if (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar)'\n') {
|
||||
} else if (Tcl_GetUniChar(objPtr, offset-1) == '\n') {
|
||||
eflags = 0;
|
||||
} else {
|
||||
eflags = TCL_REG_NOTBOL;
|
||||
@@ -1216,13 +1216,22 @@ Tcl_SplitObjCmd(
|
||||
Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
|
||||
|
||||
for ( ; stringPtr < end; stringPtr += len) {
|
||||
int fullchar;
|
||||
len = TclUtfToUniChar(stringPtr, &ch);
|
||||
fullchar = ch;
|
||||
|
||||
#if TCL_UTF_MAX == 4
|
||||
if (!len) {
|
||||
len += TclUtfToUniChar(stringPtr, &ch);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Assume Tcl_UniChar is an integral type...
|
||||
*/
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(&charReuseTable, INT2PTR((int) ch),
|
||||
hPtr = Tcl_CreateHashEntry(&charReuseTable, INT2PTR(fullchar),
|
||||
&isNew);
|
||||
if (isNew) {
|
||||
TclNewStringObj(objPtr, stringPtr, len);
|
||||
@@ -1326,16 +1335,8 @@ StringFirstCmd(
|
||||
if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &start)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
if (start >= size) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
return TCL_OK;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFind(objv[1],
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringFirst(objv[1],
|
||||
objv[2], start)));
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1379,14 +1380,6 @@ StringLastCmd(
|
||||
if (TCL_OK != TclGetIntForIndexM(interp, objv[3], size - 1, &last)) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (last < 0) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
|
||||
return TCL_OK;
|
||||
}
|
||||
if (last >= size) {
|
||||
last = size - 1;
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewIntObj(TclStringLast(objv[1],
|
||||
objv[2], last)));
|
||||
@@ -1579,11 +1572,11 @@ StringIsCmd(
|
||||
string1 = TclGetStringFromObj(objPtr, &length1);
|
||||
result = length1 == 0;
|
||||
}
|
||||
} else if (((index == STR_IS_TRUE) &&
|
||||
objPtr->internalRep.longValue == 0)
|
||||
|| ((index == STR_IS_FALSE) &&
|
||||
objPtr->internalRep.longValue != 0)) {
|
||||
result = 0;
|
||||
} else if (index != STR_IS_BOOL) {
|
||||
TclGetBooleanFromObj(NULL, objPtr, &i);
|
||||
if ((index == STR_IS_TRUE) ^ i) {
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STR_IS_CONTROL:
|
||||
@@ -1596,9 +1589,6 @@ StringIsCmd(
|
||||
/* TODO */
|
||||
if ((objPtr->typePtr == &tclDoubleType) ||
|
||||
(objPtr->typePtr == &tclIntType) ||
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
(objPtr->typePtr == &tclWideIntType) ||
|
||||
#endif
|
||||
(objPtr->typePtr == &tclBignumType)) {
|
||||
break;
|
||||
}
|
||||
@@ -1633,9 +1623,6 @@ StringIsCmd(
|
||||
goto failedIntParse;
|
||||
case STR_IS_ENTIER:
|
||||
if ((objPtr->typePtr == &tclIntType) ||
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
(objPtr->typePtr == &tclWideIntType) ||
|
||||
#endif
|
||||
(objPtr->typePtr == &tclBignumType)) {
|
||||
break;
|
||||
}
|
||||
@@ -1814,8 +1801,16 @@ StringIsCmd(
|
||||
}
|
||||
end = string1 + length1;
|
||||
for (; string1 < end; string1 += length2, failat++) {
|
||||
int fullchar;
|
||||
length2 = TclUtfToUniChar(string1, &ch);
|
||||
if (!chcomp(ch)) {
|
||||
fullchar = ch;
|
||||
#if TCL_UTF_MAX == 4
|
||||
if (!length2) {
|
||||
length2 = TclUtfToUniChar(string1, &ch);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (ch & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
if (!chcomp(fullchar)) {
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
@@ -2277,11 +2272,12 @@ StringReptCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (TCL_OK != TclStringRepeat(interp, objv[1], count, &resultPtr)) {
|
||||
return TCL_ERROR;
|
||||
resultPtr = TclStringRepeat(interp, objv[1], count, TCL_STRING_IN_PLACE);
|
||||
if (resultPtr) {
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
Tcl_SetObjResult(interp, resultPtr);
|
||||
return TCL_OK;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2380,7 +2376,7 @@ StringRevCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
Tcl_SetObjResult(interp, TclStringObjReverse(objv[1]));
|
||||
Tcl_SetObjResult(interp, TclStringReverse(objv[1], TCL_STRING_IN_PLACE));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2829,7 +2825,6 @@ StringCatCmd(
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
int code;
|
||||
Tcl_Obj *objResultPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
@@ -2839,23 +2834,15 @@ StringCatCmd(
|
||||
*/
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objc == 2) {
|
||||
/*
|
||||
* Other trivial case, single arg, just return it.
|
||||
*/
|
||||
Tcl_SetObjResult(interp, objv[1]);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
code = TclStringCatObjv(interp, /* inPlace */ 1, objc-1, objv+1,
|
||||
&objResultPtr);
|
||||
objResultPtr = TclStringCat(interp, objc-1, objv+1, TCL_STRING_IN_PLACE);
|
||||
|
||||
if (code == TCL_OK) {
|
||||
if (objResultPtr) {
|
||||
Tcl_SetObjResult(interp, objResultPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
return code;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2876,7 +2863,6 @@ StringCatCmd(
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
StringBytesCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
@@ -3530,7 +3516,7 @@ TclNRSwitchObjCmd(
|
||||
OPT_LAST
|
||||
};
|
||||
typedef int (*strCmpFn_t)(const char *, const char *);
|
||||
strCmpFn_t strCmpFn = strcmp;
|
||||
strCmpFn_t strCmpFn = TclUtfCmp;
|
||||
|
||||
mode = OPT_EXACT;
|
||||
foundmode = 0;
|
||||
@@ -4293,7 +4279,7 @@ TclNRTryObjCmd(
|
||||
}
|
||||
|
||||
info[0] = objv[i]; /* type */
|
||||
TclNewLongObj(info[1], code); /* returnCode */
|
||||
TclNewIntObj(info[1], code); /* returnCode */
|
||||
if (info[2] == NULL) { /* errorCodePrefix */
|
||||
TclNewObj(info[2]);
|
||||
}
|
||||
|
||||
+195
-270
@@ -28,56 +28,39 @@ static void CompileReturnInternal(CompileEnv *envPtr,
|
||||
static int IndexTailVarIfKnown(Tcl_Interp *interp,
|
||||
Tcl_Token *varTokenPtr, CompileEnv *envPtr);
|
||||
|
||||
#define INDEX_END (-2)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* GetIndexFromToken --
|
||||
* TclGetIndexFromToken --
|
||||
*
|
||||
* Parse a token and get the encoded version of the index (as understood
|
||||
* by TEBC), assuming it is at all knowable at compile time. Only handles
|
||||
* indices that are integers or 'end' or 'end-integer'.
|
||||
* Parse a token to determine if an index value is known at
|
||||
* compile time.
|
||||
*
|
||||
* Returns:
|
||||
* TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets *index to the index value if successful.
|
||||
* When TCL_OK is returned, the encoded index value is written
|
||||
* to *index.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline int
|
||||
GetIndexFromToken(
|
||||
int
|
||||
TclGetIndexFromToken(
|
||||
Tcl_Token *tokenPtr,
|
||||
int *index)
|
||||
int before,
|
||||
int after,
|
||||
int *indexPtr)
|
||||
{
|
||||
Tcl_Obj *tmpObj = Tcl_NewObj();
|
||||
int result, idx;
|
||||
int result = TCL_ERROR;
|
||||
|
||||
if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
|
||||
Tcl_DecrRefCount(tmpObj);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
result = TclGetIntFromObj(NULL, tmpObj, &idx);
|
||||
if (result == TCL_OK) {
|
||||
if (idx < 0) {
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx);
|
||||
if (result == TCL_OK && idx > INDEX_END) {
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if (TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
|
||||
result = TclIndexEncode(NULL, tmpObj, before, after, indexPtr);
|
||||
}
|
||||
Tcl_DecrRefCount(tmpObj);
|
||||
|
||||
if (result == TCL_OK) {
|
||||
*index = idx;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -144,7 +127,7 @@ TclCompileGlobalCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* TODO: Consider what value can pass throug the
|
||||
/* TODO: Consider what value can pass through the
|
||||
* IndexTailVarIfKnown() screen. Full CompileWord()
|
||||
* likely does not apply here. Push known value instead. */
|
||||
CompileWord(envPtr, varTokenPtr, interp, i);
|
||||
@@ -1053,7 +1036,7 @@ TclCompileLassignCmd(
|
||||
*/
|
||||
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
|
||||
TclEmitInt4( INDEX_END, envPtr);
|
||||
TclEmitInt4( TCL_INDEX_END, envPtr);
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1104,14 +1087,14 @@ TclCompileLindexCmd(
|
||||
}
|
||||
|
||||
idxTokenPtr = TokenAfter(valTokenPtr);
|
||||
if (GetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) {
|
||||
if (TclGetIndexFromToken(idxTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_BEFORE,
|
||||
&idx) == TCL_OK) {
|
||||
/*
|
||||
* All checks have been completed, and we have exactly one of these
|
||||
* constructs:
|
||||
* lindex <arbitraryValue> <posInt>
|
||||
* lindex <arbitraryValue> end-<posInt>
|
||||
* This is best compiled as a push of the arbitrary value followed by
|
||||
* an "immediate lindex" which is the most efficient variety.
|
||||
* The idxTokenPtr parsed as a valid index value and was
|
||||
* encoded as expected by INST_LIST_INDEX_IMM.
|
||||
*
|
||||
* NOTE: that we rely on indexing before a list producing the
|
||||
* same result as indexing after a list.
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, valTokenPtr, interp, 1);
|
||||
@@ -1258,7 +1241,7 @@ TclCompileListCmd(
|
||||
|
||||
if (concat && numWords == 2) {
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( INDEX_END, envPtr);
|
||||
TclEmitInt4( TCL_INDEX_END, envPtr);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -1332,21 +1315,25 @@ TclCompileLrangeCmd(
|
||||
}
|
||||
listTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
tokenPtr = TokenAfter(listTokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
&idx1) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
/*
|
||||
* Parse the indices. Will only compile if both are constants and not an
|
||||
* _integer_ less than zero (since we reserve negative indices here for
|
||||
* end-relative indexing) or an end-based index greater than 'end' itself.
|
||||
* Token was an index value, and we treat all "first" indices
|
||||
* before the list same as the start of the list.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(listTokenPtr);
|
||||
if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
/*
|
||||
* Token was an index value, and we treat all "last" indices
|
||||
* after the list same as the end of the list.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Issue instructions. It's not safe to skip doing the LIST_RANGE, as
|
||||
@@ -1396,21 +1383,30 @@ TclCompileLinsertCmd(
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(listTokenPtr);
|
||||
if (GetIndexFromToken(tokenPtr, &idx) != TCL_OK) {
|
||||
|
||||
/*
|
||||
* NOTE: This command treats all inserts at indices before the list
|
||||
* the same as inserts at the start of the list, and all inserts
|
||||
* after the list the same as inserts at the end of the list. We
|
||||
* make that transformation here so we can use the optimized bytecode
|
||||
* as much as possible.
|
||||
*/
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_END,
|
||||
&idx) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* There are four main cases. If there are no values to insert, this is
|
||||
* just a confirm-listiness check. If the index is '0', this is a prepend.
|
||||
* If the index is 'end' (== INDEX_END), this is an append. Otherwise,
|
||||
* If the index is 'end' (== TCL_INDEX_END), this is an append. Otherwise,
|
||||
* this is a splice (== split, insert values as list, concat-3).
|
||||
*/
|
||||
|
||||
CompileWord(envPtr, listTokenPtr, interp, 1);
|
||||
if (parsePtr->numWords == 3) {
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( INDEX_END, envPtr);
|
||||
TclEmitInt4( TCL_INDEX_END, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -1420,13 +1416,25 @@ TclCompileLinsertCmd(
|
||||
}
|
||||
TclEmitInstInt4( INST_LIST, i-3, envPtr);
|
||||
|
||||
if (idx == 0 /*start*/) {
|
||||
if (idx == TCL_INDEX_START) {
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
} else if (idx == INDEX_END /*end*/) {
|
||||
} else if (idx == TCL_INDEX_END) {
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
} else {
|
||||
if (idx < 0) {
|
||||
/*
|
||||
* Here we handle two ranges for idx. First when idx > 0, we
|
||||
* want the first half of the split to end at index idx-1 and
|
||||
* the second half to start at index idx.
|
||||
* Second when idx < TCL_INDEX_END, indicating "end-N" indexing,
|
||||
* we want the first half of the split to end at index end-N and
|
||||
* the second half to start at index end-N+1. We accomplish this
|
||||
* with a pre-adjustment of the end-N value.
|
||||
* The root of this is that the commands [lrange] and [linsert]
|
||||
* differ in their interpretation of the "end" index.
|
||||
*/
|
||||
|
||||
if (idx < TCL_INDEX_END) {
|
||||
idx++;
|
||||
}
|
||||
TclEmitInstInt4( INST_OVER, 1, envPtr);
|
||||
@@ -1434,7 +1442,7 @@ TclCompileLinsertCmd(
|
||||
TclEmitInt4( idx-1, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 3, envPtr);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr);
|
||||
TclEmitInt4( INDEX_END, envPtr);
|
||||
TclEmitInt4( TCL_INDEX_END, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
@@ -1464,250 +1472,167 @@ TclCompileLreplaceCmd(
|
||||
{
|
||||
Tcl_Token *tokenPtr, *listTokenPtr;
|
||||
DefineLineInformation; /* TIP #280 */
|
||||
Tcl_Obj *tmpObj;
|
||||
int idx1, idx2, i, offset, offset2;
|
||||
int emptyPrefix=1, suffixStart = 0;
|
||||
|
||||
if (parsePtr->numWords < 4) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
listTokenPtr = TokenAfter(parsePtr->tokenPtr);
|
||||
|
||||
/*
|
||||
* Parse the indices. Will only compile if both are constants and not an
|
||||
* _integer_ less than zero (since we reserve negative indices here for
|
||||
* end-relative indexing) or an end-based index greater than 'end' itself.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(listTokenPtr);
|
||||
if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
&idx1) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* idx1, idx2 are now in canonical form:
|
||||
* idx1, idx2 are the conventional encoded forms of the tokens parsed
|
||||
* as all forms of index values. Values of idx1 that come before the
|
||||
* list are treated the same as if they were the start of the list.
|
||||
* Values of idx2 that come after the list are treated the same as if
|
||||
* they were the end of the list.
|
||||
*/
|
||||
|
||||
if (idx1 == TCL_INDEX_AFTER) {
|
||||
/*
|
||||
* [lreplace] treats idx1 value end+1 differently from end+2, etc.
|
||||
* The operand encoding cannot distinguish them, so we must bail
|
||||
* out to direct evaluation.
|
||||
*/
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* General structure of the [lreplace] result is
|
||||
* prefix replacement suffix
|
||||
* In a few cases we can predict various parts will be empty and
|
||||
* take advantage.
|
||||
*
|
||||
* - integer: [0,len+1]
|
||||
* - end index: INDEX_END
|
||||
* - -ive offset: INDEX_END-[len-1,0]
|
||||
* - +ive offset: INDEX_END+1
|
||||
* The proper suffix begins with the greater of indices idx1 or
|
||||
* idx2 + 1. If we cannot tell at compile time which is greater,
|
||||
* we must defer to direct evaluation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Compilation fails when one index is end-based but the other isn't.
|
||||
* Fixing this will require more bytecodes, but this is a workaround for
|
||||
* now. [Bug 47ac84309b]
|
||||
*/
|
||||
|
||||
if ((idx1 <= INDEX_END) != (idx2 <= INDEX_END)) {
|
||||
if (idx2 == TCL_INDEX_BEFORE) {
|
||||
suffixStart = idx1;
|
||||
} else if (idx2 == TCL_INDEX_END) {
|
||||
suffixStart = TCL_INDEX_AFTER;
|
||||
} else if (((idx2 < TCL_INDEX_END) && (idx1 <= TCL_INDEX_END))
|
||||
|| ((idx2 >= TCL_INDEX_START) && (idx1 >= TCL_INDEX_START))) {
|
||||
suffixStart = (idx1 > idx2 + 1) ? idx1 : idx2 + 1;
|
||||
} else {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) {
|
||||
idx2 = idx1 - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Work out what this [lreplace] is actually doing.
|
||||
*/
|
||||
|
||||
tmpObj = NULL;
|
||||
/* All paths start with computing/pushing the original value. */
|
||||
CompileWord(envPtr, listTokenPtr, interp, 1);
|
||||
if (parsePtr->numWords == 4) {
|
||||
if (idx1 == 0) {
|
||||
if (idx2 == INDEX_END) {
|
||||
goto dropAll;
|
||||
}
|
||||
idx1 = idx2 + 1;
|
||||
idx2 = INDEX_END;
|
||||
goto dropEnd;
|
||||
} else if (idx2 == INDEX_END) {
|
||||
idx2 = idx1 - 1;
|
||||
idx1 = 0;
|
||||
goto dropEnd;
|
||||
} else {
|
||||
if (idx2 < idx1) {
|
||||
idx2 = idx1 - 1;
|
||||
}
|
||||
if (idx1 > 0) {
|
||||
tmpObj = Tcl_NewIntObj(idx1);
|
||||
Tcl_IncrRefCount(tmpObj);
|
||||
}
|
||||
goto dropRange;
|
||||
}
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
for (i=4 ; i<parsePtr->numWords ; i++) {
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
/*
|
||||
* Push all the replacement values next so any errors raised in
|
||||
* creating them get raised first.
|
||||
*/
|
||||
if (parsePtr->numWords > 4) {
|
||||
/* Push the replacement arguments */
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
for (i=4 ; i<parsePtr->numWords ; i++) {
|
||||
CompileWord(envPtr, tokenPtr, interp, i);
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
|
||||
/* Make a list of them... */
|
||||
TclEmitInstInt4( INST_LIST, i - 4, envPtr);
|
||||
|
||||
emptyPrefix = 0;
|
||||
}
|
||||
TclEmitInstInt4( INST_LIST, i - 4, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
if (idx1 == 0) {
|
||||
if (idx2 == INDEX_END) {
|
||||
goto replaceAll;
|
||||
|
||||
/*
|
||||
* [lreplace] raises an error when idx1 points after the list, but
|
||||
* only when the list is not empty. This is maximum stupidity.
|
||||
*
|
||||
* TODO: TIP this nonsense away!
|
||||
*/
|
||||
if (idx1 >= TCL_INDEX_START) {
|
||||
if (emptyPrefix) {
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4( INST_OVER, 1, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
offset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr);
|
||||
|
||||
/* List is not empty */
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_NewIntObj(idx1),
|
||||
NULL), envPtr);
|
||||
TclEmitOpcode( INST_GT, envPtr);
|
||||
offset2 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
|
||||
|
||||
/* Idx1 >= list length ===> raise an error */
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
|
||||
"list doesn't contain element %d", idx1), NULL), envPtr);
|
||||
CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
|
||||
Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
|
||||
envPtr->codeStart + offset + 1);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
|
||||
envPtr->codeStart + offset2 + 1);
|
||||
}
|
||||
|
||||
if ((idx1 == suffixStart) && (parsePtr->numWords == 4)) {
|
||||
/*
|
||||
* This is a "no-op". Example: [lreplace {a b c} 2 0]
|
||||
* We still do a list operation to get list-verification
|
||||
* and canonicalization side effects.
|
||||
*/
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( TCL_INDEX_END, envPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (idx1 != TCL_INDEX_START) {
|
||||
/* Prefix may not be empty; generate bytecode to push it */
|
||||
if (emptyPrefix) {
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
} else {
|
||||
TclEmitInstInt4( INST_OVER, 1, envPtr);
|
||||
}
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( idx1 - 1, envPtr);
|
||||
if (!emptyPrefix) {
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
emptyPrefix = 0;
|
||||
}
|
||||
|
||||
if (!emptyPrefix) {
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
}
|
||||
|
||||
if (suffixStart == TCL_INDEX_AFTER) {
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
if (emptyPrefix) {
|
||||
PushStringLiteral(envPtr, "");
|
||||
}
|
||||
idx1 = idx2 + 1;
|
||||
idx2 = INDEX_END;
|
||||
goto replaceHead;
|
||||
} else if (idx2 == INDEX_END) {
|
||||
idx2 = idx1 - 1;
|
||||
idx1 = 0;
|
||||
goto replaceTail;
|
||||
} else {
|
||||
if (idx2 < idx1) {
|
||||
idx2 = idx1 - 1;
|
||||
/* Suffix may not be empty; generate bytecode to push it */
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, suffixStart, envPtr);
|
||||
TclEmitInt4( TCL_INDEX_END, envPtr);
|
||||
if (!emptyPrefix) {
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
}
|
||||
if (idx1 > 0) {
|
||||
tmpObj = Tcl_NewIntObj(idx1);
|
||||
Tcl_IncrRefCount(tmpObj);
|
||||
}
|
||||
goto replaceRange;
|
||||
}
|
||||
|
||||
/*
|
||||
* Issue instructions to perform the operations relating to configurations
|
||||
* that just drop. The only argument pushed on the stack is the list to
|
||||
* operate on.
|
||||
*/
|
||||
|
||||
dropAll: /* This just ensures the arg is a list. */
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
PushStringLiteral(envPtr, "");
|
||||
goto done;
|
||||
|
||||
dropEnd:
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
|
||||
TclEmitInt4( idx2, envPtr);
|
||||
goto done;
|
||||
|
||||
dropRange:
|
||||
if (tmpObj != NULL) {
|
||||
/*
|
||||
* Emit bytecode to check the list length.
|
||||
*/
|
||||
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr);
|
||||
TclEmitOpcode( INST_GE, envPtr);
|
||||
offset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
|
||||
|
||||
/*
|
||||
* Emit an error if we've been given an empty list.
|
||||
*/
|
||||
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
offset2 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr);
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
|
||||
"list doesn't contain element %d", idx1), NULL), envPtr);
|
||||
CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
|
||||
Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
|
||||
envPtr->codeStart + offset + 1);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
|
||||
envPtr->codeStart + offset2 + 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( idx1 - 1, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr);
|
||||
TclEmitInt4( INDEX_END, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Issue instructions to perform the operations relating to configurations
|
||||
* that do real replacement. All arguments are pushed and assembled into a
|
||||
* pair: the list of values to replace with, and the list to do the
|
||||
* surgery on.
|
||||
*/
|
||||
|
||||
replaceAll:
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
TclEmitOpcode( INST_POP, envPtr);
|
||||
goto done;
|
||||
|
||||
replaceHead:
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
|
||||
TclEmitInt4( idx2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
goto done;
|
||||
|
||||
replaceTail:
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr);
|
||||
TclEmitInt4( idx2, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
goto done;
|
||||
|
||||
replaceRange:
|
||||
if (tmpObj != NULL) {
|
||||
/*
|
||||
* Emit bytecode to check the list length.
|
||||
*/
|
||||
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
|
||||
/*
|
||||
* Check the list length vs idx1.
|
||||
*/
|
||||
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr);
|
||||
TclEmitOpcode( INST_GE, envPtr);
|
||||
offset = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr);
|
||||
|
||||
/*
|
||||
* Emit an error if we've been given an empty list.
|
||||
*/
|
||||
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitOpcode( INST_LIST_LENGTH, envPtr);
|
||||
offset2 = CurrentOffset(envPtr);
|
||||
TclEmitInstInt1( INST_JUMP_FALSE1, 0, envPtr);
|
||||
TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
|
||||
"list doesn't contain element %d", idx1), NULL), envPtr);
|
||||
CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
|
||||
Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
|
||||
envPtr->codeStart + offset + 1);
|
||||
TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
|
||||
envPtr->codeStart + offset2 + 1);
|
||||
TclAdjustStackDepth(-1, envPtr);
|
||||
}
|
||||
TclEmitOpcode( INST_DUP, envPtr);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr);
|
||||
TclEmitInt4( idx1 - 1, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr);
|
||||
TclEmitInt4( INDEX_END, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 3, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
TclEmitInstInt4( INST_REVERSE, 2, envPtr);
|
||||
TclEmitOpcode( INST_LIST_CONCAT, envPtr);
|
||||
goto done;
|
||||
|
||||
/*
|
||||
* Clean up the allocated memory.
|
||||
*/
|
||||
|
||||
done:
|
||||
if (tmpObj != NULL) {
|
||||
Tcl_DecrRefCount(tmpObj);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -2933,7 +2858,7 @@ TclCompileVariableCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* TODO: Consider what value can pass throug the
|
||||
/* TODO: Consider what value can pass through the
|
||||
* IndexTailVarIfKnown() screen. Full CompileWord()
|
||||
* likely does not apply here. Push known value instead. */
|
||||
CompileWord(envPtr, varTokenPtr, interp, i);
|
||||
|
||||
+68
-72
@@ -107,58 +107,6 @@ const AuxDataType tclJumptableInfoType = {
|
||||
#define INVOKE(name) \
|
||||
TclEmitInvoke(envPtr,INST_##name)
|
||||
|
||||
#define INDEX_END (-2)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* GetIndexFromToken --
|
||||
*
|
||||
* Parse a token and get the encoded version of the index (as understood
|
||||
* by TEBC), assuming it is at all knowable at compile time. Only handles
|
||||
* indices that are integers or 'end' or 'end-integer'.
|
||||
*
|
||||
* Returns:
|
||||
* TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
|
||||
*
|
||||
* Side effects:
|
||||
* Sets *index to the index value if successful.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static inline int
|
||||
GetIndexFromToken(
|
||||
Tcl_Token *tokenPtr,
|
||||
int *index)
|
||||
{
|
||||
Tcl_Obj *tmpObj = Tcl_NewObj();
|
||||
int result, idx;
|
||||
|
||||
if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
|
||||
Tcl_DecrRefCount(tmpObj);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
result = TclGetIntFromObj(NULL, tmpObj, &idx);
|
||||
if (result == TCL_OK) {
|
||||
if (idx < 0) {
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx);
|
||||
if (result == TCL_OK && idx > INDEX_END) {
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_DecrRefCount(tmpObj);
|
||||
|
||||
if (result == TCL_OK) {
|
||||
*index = idx;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -982,22 +930,48 @@ TclCompileStringRangeCmd(
|
||||
fromTokenPtr = TokenAfter(stringTokenPtr);
|
||||
toTokenPtr = TokenAfter(fromTokenPtr);
|
||||
|
||||
/* Every path must push the string argument */
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 1);
|
||||
|
||||
/*
|
||||
* Parse the two indices.
|
||||
*/
|
||||
|
||||
if (GetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) {
|
||||
if (TclGetIndexFromToken(fromTokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
&idx1) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
if (GetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) {
|
||||
/*
|
||||
* Token parsed as an index expression. We treat all indices before
|
||||
* the string the same as the start of the string.
|
||||
*/
|
||||
|
||||
if (idx1 == TCL_INDEX_AFTER) {
|
||||
/* [string range $s end+1 $last] must be empty string */
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (TclGetIndexFromToken(toTokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
goto nonConstantIndices;
|
||||
}
|
||||
/*
|
||||
* Token parsed as an index expression. We treat all indices after
|
||||
* the string the same as the end of the string.
|
||||
*/
|
||||
if (idx2 == TCL_INDEX_BEFORE) {
|
||||
/* [string range $s $first -1] must be empty string */
|
||||
OP( POP);
|
||||
PUSH( "");
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
@@ -1006,7 +980,6 @@ TclCompileStringRangeCmd(
|
||||
*/
|
||||
|
||||
nonConstantIndices:
|
||||
CompileWord(envPtr, stringTokenPtr, interp, 1);
|
||||
CompileWord(envPtr, fromTokenPtr, interp, 2);
|
||||
CompileWord(envPtr, toTokenPtr, interp, 3);
|
||||
OP( STR_RANGE);
|
||||
@@ -1036,27 +1009,39 @@ TclCompileStringReplaceCmd(
|
||||
replacementTokenPtr = TokenAfter(tokenPtr);
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(valueTokenPtr);
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_START, TCL_INDEX_AFTER,
|
||||
&idx1) != TCL_OK) {
|
||||
goto genericReplace;
|
||||
}
|
||||
/*
|
||||
* Parse the indices. Will only compile special cases if both are
|
||||
* constants and not an _integer_ less than zero (since we reserve
|
||||
* negative indices here for end-relative indexing) or an end-based index
|
||||
* greater than 'end' itself.
|
||||
* Token parsed as an index value. Indices before the string are
|
||||
* treated as index of start of string.
|
||||
*/
|
||||
|
||||
tokenPtr = TokenAfter(valueTokenPtr);
|
||||
if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
|
||||
goto genericReplace;
|
||||
}
|
||||
|
||||
tokenPtr = TokenAfter(tokenPtr);
|
||||
if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
|
||||
if (TclGetIndexFromToken(tokenPtr, TCL_INDEX_BEFORE, TCL_INDEX_END,
|
||||
&idx2) != TCL_OK) {
|
||||
goto genericReplace;
|
||||
}
|
||||
/*
|
||||
* Token parsed as an index value. Indices after the string are
|
||||
* treated as index of end of string.
|
||||
*/
|
||||
|
||||
/* TODO...... */
|
||||
/*
|
||||
* We handle these replacements specially: first character (where
|
||||
* idx1=idx2=0) and last character (where idx1=idx2=INDEX_END). Anything
|
||||
* idx1=idx2=0) and last character (where idx1=idx2=TCL_INDEX_END). Anything
|
||||
* else and the semantics get rather screwy.
|
||||
*
|
||||
* TODO: These seem to be very narrow cases. They are not even
|
||||
* covered by the test suite, and any programming that ends up
|
||||
* here could have been coded by the programmer using [string range]
|
||||
* and [string cat]. [*] Not clear at all to me that the bytecode
|
||||
* generated here is worthwhile.
|
||||
*
|
||||
* [*] Except for the empty string exceptions. UGGGGHHHH.
|
||||
*/
|
||||
|
||||
if (idx1 == 0 && idx2 == 0) {
|
||||
@@ -1069,11 +1054,19 @@ TclCompileStringReplaceCmd(
|
||||
CompileWord(envPtr, valueTokenPtr, interp, 1);
|
||||
if (replacementTokenPtr == NULL) {
|
||||
/* Drop first */
|
||||
OP44( STR_RANGE_IMM, 1, INDEX_END);
|
||||
OP44( STR_RANGE_IMM, 1, TCL_INDEX_END);
|
||||
return TCL_OK;
|
||||
}
|
||||
/* Replace first */
|
||||
CompileWord(envPtr, replacementTokenPtr, interp, 4);
|
||||
|
||||
/*
|
||||
* NOTE: The following tower of bullshit is present because
|
||||
* [string replace] was boneheadedly defined not to replace
|
||||
* empty strings, so we actually have to detect the empty
|
||||
* string case and treat it differently.
|
||||
*/
|
||||
|
||||
OP4( OVER, 1);
|
||||
PUSH( "");
|
||||
OP( STR_EQ);
|
||||
@@ -1083,12 +1076,12 @@ TclCompileStringReplaceCmd(
|
||||
FIXJUMP1(notEq);
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
OP4( REVERSE, 2);
|
||||
OP44( STR_RANGE_IMM, 1, INDEX_END);
|
||||
OP44( STR_RANGE_IMM, 1, TCL_INDEX_END);
|
||||
OP1( STR_CONCAT1, 2);
|
||||
FIXJUMP1(end);
|
||||
return TCL_OK;
|
||||
|
||||
} else if (idx1 == INDEX_END && idx2 == INDEX_END) {
|
||||
} else if (idx1 == TCL_INDEX_END && idx2 == TCL_INDEX_END) {
|
||||
int notEq, end;
|
||||
|
||||
/*
|
||||
@@ -1098,11 +1091,14 @@ TclCompileStringReplaceCmd(
|
||||
CompileWord(envPtr, valueTokenPtr, interp, 1);
|
||||
if (replacementTokenPtr == NULL) {
|
||||
/* Drop last */
|
||||
OP44( STR_RANGE_IMM, 0, INDEX_END-1);
|
||||
OP44( STR_RANGE_IMM, 0, TCL_INDEX_END-1);
|
||||
return TCL_OK;
|
||||
}
|
||||
/* Replace last */
|
||||
CompileWord(envPtr, replacementTokenPtr, interp, 4);
|
||||
|
||||
/* More bullshit; see NOTE above. */
|
||||
|
||||
OP4( OVER, 1);
|
||||
PUSH( "");
|
||||
OP( STR_EQ);
|
||||
@@ -1112,7 +1108,7 @@ TclCompileStringReplaceCmd(
|
||||
FIXJUMP1(notEq);
|
||||
TclAdjustStackDepth(1, envPtr);
|
||||
OP4( REVERSE, 2);
|
||||
OP44( STR_RANGE_IMM, 0, INDEX_END-1);
|
||||
OP44( STR_RANGE_IMM, 0, TCL_INDEX_END-1);
|
||||
OP4( REVERSE, 2);
|
||||
OP1( STR_CONCAT1, 2);
|
||||
FIXJUMP1(end);
|
||||
|
||||
@@ -425,11 +425,11 @@ typedef struct ByteCode {
|
||||
* compiled. If the code is executed if a
|
||||
* different namespace, it must be
|
||||
* recompiled. */
|
||||
size_t nsEpoch; /* Value of nsPtr->resolverEpoch when this
|
||||
unsigned int nsEpoch; /* Value of nsPtr->resolverEpoch when this
|
||||
* ByteCode was compiled. Used to invalidate
|
||||
* code when new namespace resolution rules
|
||||
* are put into effect. */
|
||||
int refCount; /* Reference count: set 1 when created plus 1
|
||||
unsigned int refCount; /* Reference count: set 1 when created plus 1
|
||||
* for each execution of the code currently
|
||||
* active. This structure can be freed when
|
||||
* refCount becomes zero. */
|
||||
@@ -1120,6 +1120,8 @@ MODULE_SCOPE int TclFixupForwardJump(CompileEnv *envPtr,
|
||||
int distThreshold);
|
||||
MODULE_SCOPE void TclFreeCompileEnv(CompileEnv *envPtr);
|
||||
MODULE_SCOPE void TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr);
|
||||
MODULE_SCOPE int TclGetIndexFromToken(Tcl_Token *tokenPtr,
|
||||
int before, int after, int *indexPtr);
|
||||
MODULE_SCOPE ByteCode * TclInitByteCode(CompileEnv *envPtr);
|
||||
MODULE_SCOPE ByteCode * TclInitByteCodeObj(Tcl_Obj *objPtr,
|
||||
const Tcl_ObjType *typePtr, CompileEnv *envPtr);
|
||||
|
||||
+138
-126
@@ -53,7 +53,7 @@ EXTERN int Tcl_PkgProvideEx(Tcl_Interp *interp,
|
||||
const char *name, const char *version,
|
||||
const void *clientData);
|
||||
/* 1 */
|
||||
EXTERN CONST84_RETURN char * Tcl_PkgRequireEx(Tcl_Interp *interp,
|
||||
EXTERN const char * Tcl_PkgRequireEx(Tcl_Interp *interp,
|
||||
const char *name, const char *version,
|
||||
int exact, void *clientDataPtr);
|
||||
/* 2 */
|
||||
@@ -159,8 +159,7 @@ EXTERN int Tcl_GetDoubleFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr, double *doublePtr);
|
||||
/* 36 */
|
||||
EXTERN int Tcl_GetIndexFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr,
|
||||
CONST84 char *const *tablePtr,
|
||||
Tcl_Obj *objPtr, const char *const *tablePtr,
|
||||
const char *msg, int flags, int *indexPtr);
|
||||
/* 37 */
|
||||
EXTERN int Tcl_GetInt(Tcl_Interp *interp, const char *src,
|
||||
@@ -263,7 +262,8 @@ EXTERN int Tcl_AsyncReady(void);
|
||||
/* 76 */
|
||||
EXTERN void Tcl_BackgroundError(Tcl_Interp *interp);
|
||||
/* 77 */
|
||||
EXTERN char Tcl_Backslash(const char *src, int *readPtr);
|
||||
TCL_DEPRECATED("Use Tcl_UtfBackslash")
|
||||
char Tcl_Backslash(const char *src, int *readPtr);
|
||||
/* 78 */
|
||||
EXTERN int Tcl_BadChannelOption(Tcl_Interp *interp,
|
||||
const char *optionName,
|
||||
@@ -280,7 +280,7 @@ EXTERN int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan);
|
||||
/* 82 */
|
||||
EXTERN int Tcl_CommandComplete(const char *cmd);
|
||||
/* 83 */
|
||||
EXTERN char * Tcl_Concat(int argc, CONST84 char *const *argv);
|
||||
EXTERN char * Tcl_Concat(int argc, const char *const *argv);
|
||||
/* 84 */
|
||||
EXTERN int Tcl_ConvertElement(const char *src, char *dst,
|
||||
int flags);
|
||||
@@ -291,7 +291,7 @@ EXTERN int Tcl_ConvertCountedElement(const char *src,
|
||||
EXTERN int Tcl_CreateAlias(Tcl_Interp *slave,
|
||||
const char *slaveCmd, Tcl_Interp *target,
|
||||
const char *targetCmd, int argc,
|
||||
CONST84 char *const *argv);
|
||||
const char *const *argv);
|
||||
/* 87 */
|
||||
EXTERN int Tcl_CreateAliasObj(Tcl_Interp *slave,
|
||||
const char *slaveCmd, Tcl_Interp *target,
|
||||
@@ -322,7 +322,8 @@ EXTERN void Tcl_CreateExitHandler(Tcl_ExitProc *proc,
|
||||
/* 94 */
|
||||
EXTERN Tcl_Interp * Tcl_CreateInterp(void);
|
||||
/* 95 */
|
||||
EXTERN void Tcl_CreateMathFunc(Tcl_Interp *interp,
|
||||
TCL_DEPRECATED("")
|
||||
void Tcl_CreateMathFunc(Tcl_Interp *interp,
|
||||
const char *name, int numArgs,
|
||||
Tcl_ValueType *argTypes, Tcl_MathProc *proc,
|
||||
ClientData clientData);
|
||||
@@ -412,9 +413,9 @@ EXTERN void Tcl_DStringStartSublist(Tcl_DString *dsPtr);
|
||||
/* 126 */
|
||||
EXTERN int Tcl_Eof(Tcl_Channel chan);
|
||||
/* 127 */
|
||||
EXTERN CONST84_RETURN char * Tcl_ErrnoId(void);
|
||||
EXTERN const char * Tcl_ErrnoId(void);
|
||||
/* 128 */
|
||||
EXTERN CONST84_RETURN char * Tcl_ErrnoMsg(int err);
|
||||
EXTERN const char * Tcl_ErrnoMsg(int err);
|
||||
/* 129 */
|
||||
EXTERN int Tcl_Eval(Tcl_Interp *interp, const char *script);
|
||||
/* 130 */
|
||||
@@ -469,13 +470,13 @@ EXTERN void Tcl_FreeResult(Tcl_Interp *interp);
|
||||
EXTERN int Tcl_GetAlias(Tcl_Interp *interp,
|
||||
const char *slaveCmd,
|
||||
Tcl_Interp **targetInterpPtr,
|
||||
CONST84 char **targetCmdPtr, int *argcPtr,
|
||||
CONST84 char ***argvPtr);
|
||||
const char **targetCmdPtr, int *argcPtr,
|
||||
const char ***argvPtr);
|
||||
/* 149 */
|
||||
EXTERN int Tcl_GetAliasObj(Tcl_Interp *interp,
|
||||
const char *slaveCmd,
|
||||
Tcl_Interp **targetInterpPtr,
|
||||
CONST84 char **targetCmdPtr, int *objcPtr,
|
||||
const char **targetCmdPtr, int *objcPtr,
|
||||
Tcl_Obj ***objv);
|
||||
/* 150 */
|
||||
EXTERN ClientData Tcl_GetAssocData(Tcl_Interp *interp,
|
||||
@@ -494,7 +495,7 @@ EXTERN ClientData Tcl_GetChannelInstanceData(Tcl_Channel chan);
|
||||
/* 155 */
|
||||
EXTERN int Tcl_GetChannelMode(Tcl_Channel chan);
|
||||
/* 156 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetChannelName(Tcl_Channel chan);
|
||||
EXTERN const char * Tcl_GetChannelName(Tcl_Channel chan);
|
||||
/* 157 */
|
||||
EXTERN int Tcl_GetChannelOption(Tcl_Interp *interp,
|
||||
Tcl_Channel chan, const char *optionName,
|
||||
@@ -505,12 +506,12 @@ EXTERN CONST86 Tcl_ChannelType * Tcl_GetChannelType(Tcl_Channel chan);
|
||||
EXTERN int Tcl_GetCommandInfo(Tcl_Interp *interp,
|
||||
const char *cmdName, Tcl_CmdInfo *infoPtr);
|
||||
/* 160 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetCommandName(Tcl_Interp *interp,
|
||||
EXTERN const char * Tcl_GetCommandName(Tcl_Interp *interp,
|
||||
Tcl_Command command);
|
||||
/* 161 */
|
||||
EXTERN int Tcl_GetErrno(void);
|
||||
/* 162 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetHostName(void);
|
||||
EXTERN const char * Tcl_GetHostName(void);
|
||||
/* 163 */
|
||||
EXTERN int Tcl_GetInterpPath(Tcl_Interp *askInterp,
|
||||
Tcl_Interp *slaveInterp);
|
||||
@@ -546,14 +547,13 @@ EXTERN Tcl_Interp * Tcl_GetSlave(Tcl_Interp *interp,
|
||||
/* 173 */
|
||||
EXTERN Tcl_Channel Tcl_GetStdChannel(int type);
|
||||
/* 174 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetStringResult(Tcl_Interp *interp);
|
||||
EXTERN const char * Tcl_GetStringResult(Tcl_Interp *interp);
|
||||
/* 175 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetVar(Tcl_Interp *interp,
|
||||
const char *varName, int flags);
|
||||
/* 176 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetVar2(Tcl_Interp *interp,
|
||||
const char *part1, const char *part2,
|
||||
EXTERN const char * Tcl_GetVar(Tcl_Interp *interp, const char *varName,
|
||||
int flags);
|
||||
/* 176 */
|
||||
EXTERN const char * Tcl_GetVar2(Tcl_Interp *interp, const char *part1,
|
||||
const char *part2, int flags);
|
||||
/* 177 */
|
||||
EXTERN int Tcl_GlobalEval(Tcl_Interp *interp,
|
||||
const char *command);
|
||||
@@ -578,7 +578,7 @@ EXTERN int Tcl_InterpDeleted(Tcl_Interp *interp);
|
||||
/* 185 */
|
||||
EXTERN int Tcl_IsSafe(Tcl_Interp *interp);
|
||||
/* 186 */
|
||||
EXTERN char * Tcl_JoinPath(int argc, CONST84 char *const *argv,
|
||||
EXTERN char * Tcl_JoinPath(int argc, const char *const *argv,
|
||||
Tcl_DString *resultPtr);
|
||||
/* 187 */
|
||||
EXTERN int Tcl_LinkVar(Tcl_Interp *interp, const char *varName,
|
||||
@@ -591,7 +591,7 @@ EXTERN int Tcl_MakeSafe(Tcl_Interp *interp);
|
||||
/* 191 */
|
||||
EXTERN Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket);
|
||||
/* 192 */
|
||||
EXTERN char * Tcl_Merge(int argc, CONST84 char *const *argv);
|
||||
EXTERN char * Tcl_Merge(int argc, const char *const *argv);
|
||||
/* 193 */
|
||||
EXTERN Tcl_HashEntry * Tcl_NextHashEntry(Tcl_HashSearch *searchPtr);
|
||||
/* 194 */
|
||||
@@ -605,7 +605,7 @@ EXTERN Tcl_Obj * Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
|
||||
int flags);
|
||||
/* 197 */
|
||||
EXTERN Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, int argc,
|
||||
CONST84 char **argv, int flags);
|
||||
const char **argv, int flags);
|
||||
/* 198 */
|
||||
EXTERN Tcl_Channel Tcl_OpenFileChannel(Tcl_Interp *interp,
|
||||
const char *fileName, const char *modeString,
|
||||
@@ -627,7 +627,7 @@ EXTERN void Tcl_PrintDouble(Tcl_Interp *interp, double value,
|
||||
/* 203 */
|
||||
EXTERN int Tcl_PutEnv(const char *assignment);
|
||||
/* 204 */
|
||||
EXTERN CONST84_RETURN char * Tcl_PosixError(Tcl_Interp *interp);
|
||||
EXTERN const char * Tcl_PosixError(Tcl_Interp *interp);
|
||||
/* 205 */
|
||||
EXTERN void Tcl_QueueEvent(Tcl_Event *evPtr,
|
||||
Tcl_QueuePosition position);
|
||||
@@ -657,8 +657,7 @@ EXTERN int Tcl_RegExpMatch(Tcl_Interp *interp, const char *text,
|
||||
const char *pattern);
|
||||
/* 215 */
|
||||
EXTERN void Tcl_RegExpRange(Tcl_RegExp regexp, int index,
|
||||
CONST84 char **startPtr,
|
||||
CONST84 char **endPtr);
|
||||
const char **startPtr, const char **endPtr);
|
||||
/* 216 */
|
||||
EXTERN void Tcl_Release(ClientData clientData);
|
||||
/* 217 */
|
||||
@@ -669,7 +668,8 @@ EXTERN int Tcl_ScanElement(const char *src, int *flagPtr);
|
||||
EXTERN int Tcl_ScanCountedElement(const char *src, int length,
|
||||
int *flagPtr);
|
||||
/* 220 */
|
||||
EXTERN int Tcl_SeekOld(Tcl_Channel chan, int offset, int mode);
|
||||
TCL_DEPRECATED("")
|
||||
int Tcl_SeekOld(Tcl_Channel chan, int offset, int mode);
|
||||
/* 221 */
|
||||
EXTERN int Tcl_ServiceAll(void);
|
||||
/* 222 */
|
||||
@@ -713,26 +713,25 @@ EXTERN void Tcl_SetObjResult(Tcl_Interp *interp,
|
||||
/* 236 */
|
||||
EXTERN void Tcl_SetStdChannel(Tcl_Channel channel, int type);
|
||||
/* 237 */
|
||||
EXTERN CONST84_RETURN char * Tcl_SetVar(Tcl_Interp *interp,
|
||||
const char *varName, const char *newValue,
|
||||
int flags);
|
||||
/* 238 */
|
||||
EXTERN CONST84_RETURN char * Tcl_SetVar2(Tcl_Interp *interp,
|
||||
const char *part1, const char *part2,
|
||||
EXTERN const char * Tcl_SetVar(Tcl_Interp *interp, const char *varName,
|
||||
const char *newValue, int flags);
|
||||
/* 238 */
|
||||
EXTERN const char * Tcl_SetVar2(Tcl_Interp *interp, const char *part1,
|
||||
const char *part2, const char *newValue,
|
||||
int flags);
|
||||
/* 239 */
|
||||
EXTERN CONST84_RETURN char * Tcl_SignalId(int sig);
|
||||
EXTERN const char * Tcl_SignalId(int sig);
|
||||
/* 240 */
|
||||
EXTERN CONST84_RETURN char * Tcl_SignalMsg(int sig);
|
||||
EXTERN const char * Tcl_SignalMsg(int sig);
|
||||
/* 241 */
|
||||
EXTERN void Tcl_SourceRCFile(Tcl_Interp *interp);
|
||||
/* 242 */
|
||||
EXTERN int Tcl_SplitList(Tcl_Interp *interp,
|
||||
const char *listStr, int *argcPtr,
|
||||
CONST84 char ***argvPtr);
|
||||
const char ***argvPtr);
|
||||
/* 243 */
|
||||
EXTERN void Tcl_SplitPath(const char *path, int *argcPtr,
|
||||
CONST84 char ***argvPtr);
|
||||
const char ***argvPtr);
|
||||
/* 244 */
|
||||
EXTERN void Tcl_StaticPackage(Tcl_Interp *interp,
|
||||
const char *pkgName,
|
||||
@@ -741,7 +740,8 @@ EXTERN void Tcl_StaticPackage(Tcl_Interp *interp,
|
||||
/* 245 */
|
||||
EXTERN int Tcl_StringMatch(const char *str, const char *pattern);
|
||||
/* 246 */
|
||||
EXTERN int Tcl_TellOld(Tcl_Channel chan);
|
||||
TCL_DEPRECATED("")
|
||||
int Tcl_TellOld(Tcl_Channel chan);
|
||||
/* 247 */
|
||||
EXTERN int Tcl_TraceVar(Tcl_Interp *interp, const char *varName,
|
||||
int flags, Tcl_VarTraceProc *proc,
|
||||
@@ -812,40 +812,43 @@ EXTERN int Tcl_DumpActiveMemory(const char *fileName);
|
||||
/* 266 */
|
||||
EXTERN void Tcl_ValidateAllMemory(const char *file, int line);
|
||||
/* 267 */
|
||||
EXTERN void Tcl_AppendResultVA(Tcl_Interp *interp,
|
||||
TCL_DEPRECATED("see TIP #422")
|
||||
void Tcl_AppendResultVA(Tcl_Interp *interp,
|
||||
va_list argList);
|
||||
/* 268 */
|
||||
EXTERN void Tcl_AppendStringsToObjVA(Tcl_Obj *objPtr,
|
||||
TCL_DEPRECATED("see TIP #422")
|
||||
void Tcl_AppendStringsToObjVA(Tcl_Obj *objPtr,
|
||||
va_list argList);
|
||||
/* 269 */
|
||||
EXTERN char * Tcl_HashStats(Tcl_HashTable *tablePtr);
|
||||
/* 270 */
|
||||
EXTERN CONST84_RETURN char * Tcl_ParseVar(Tcl_Interp *interp,
|
||||
const char *start, CONST84 char **termPtr);
|
||||
EXTERN const char * Tcl_ParseVar(Tcl_Interp *interp, const char *start,
|
||||
const char **termPtr);
|
||||
/* 271 */
|
||||
EXTERN CONST84_RETURN char * Tcl_PkgPresent(Tcl_Interp *interp,
|
||||
const char *name, const char *version,
|
||||
int exact);
|
||||
EXTERN const char * Tcl_PkgPresent(Tcl_Interp *interp, const char *name,
|
||||
const char *version, int exact);
|
||||
/* 272 */
|
||||
EXTERN CONST84_RETURN char * Tcl_PkgPresentEx(Tcl_Interp *interp,
|
||||
EXTERN const char * Tcl_PkgPresentEx(Tcl_Interp *interp,
|
||||
const char *name, const char *version,
|
||||
int exact, void *clientDataPtr);
|
||||
/* 273 */
|
||||
EXTERN int Tcl_PkgProvide(Tcl_Interp *interp, const char *name,
|
||||
const char *version);
|
||||
/* 274 */
|
||||
EXTERN CONST84_RETURN char * Tcl_PkgRequire(Tcl_Interp *interp,
|
||||
const char *name, const char *version,
|
||||
int exact);
|
||||
EXTERN const char * Tcl_PkgRequire(Tcl_Interp *interp, const char *name,
|
||||
const char *version, int exact);
|
||||
/* 275 */
|
||||
EXTERN void Tcl_SetErrorCodeVA(Tcl_Interp *interp,
|
||||
TCL_DEPRECATED("see TIP #422")
|
||||
void Tcl_SetErrorCodeVA(Tcl_Interp *interp,
|
||||
va_list argList);
|
||||
/* 276 */
|
||||
EXTERN int Tcl_VarEvalVA(Tcl_Interp *interp, va_list argList);
|
||||
TCL_DEPRECATED("see TIP #422")
|
||||
int Tcl_VarEvalVA(Tcl_Interp *interp, va_list argList);
|
||||
/* 277 */
|
||||
EXTERN Tcl_Pid Tcl_WaitPid(Tcl_Pid pid, int *statPtr, int options);
|
||||
/* 278 */
|
||||
EXTERN TCL_NORETURN void Tcl_PanicVA(const char *format, va_list argList);
|
||||
TCL_DEPRECATED("see TIP #422")
|
||||
TCL_NORETURN void Tcl_PanicVA(const char *format, va_list argList);
|
||||
/* 279 */
|
||||
EXTERN void Tcl_GetVersion(int *major, int *minor,
|
||||
int *patchLevel, int *type);
|
||||
@@ -910,7 +913,7 @@ EXTERN Tcl_ThreadId Tcl_GetCurrentThread(void);
|
||||
/* 301 */
|
||||
EXTERN Tcl_Encoding Tcl_GetEncoding(Tcl_Interp *interp, const char *name);
|
||||
/* 302 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetEncodingName(Tcl_Encoding encoding);
|
||||
EXTERN const char * Tcl_GetEncodingName(Tcl_Encoding encoding);
|
||||
/* 303 */
|
||||
EXTERN void Tcl_GetEncodingNames(Tcl_Interp *interp);
|
||||
/* 304 */
|
||||
@@ -969,20 +972,20 @@ EXTERN Tcl_UniChar Tcl_UniCharToUpper(int ch);
|
||||
/* 324 */
|
||||
EXTERN int Tcl_UniCharToUtf(int ch, char *buf);
|
||||
/* 325 */
|
||||
EXTERN CONST84_RETURN char * Tcl_UtfAtIndex(const char *src, int index);
|
||||
EXTERN const char * Tcl_UtfAtIndex(const char *src, int index);
|
||||
/* 326 */
|
||||
EXTERN int Tcl_UtfCharComplete(const char *src, int length);
|
||||
/* 327 */
|
||||
EXTERN int Tcl_UtfBackslash(const char *src, int *readPtr,
|
||||
char *dst);
|
||||
/* 328 */
|
||||
EXTERN CONST84_RETURN char * Tcl_UtfFindFirst(const char *src, int ch);
|
||||
EXTERN const char * Tcl_UtfFindFirst(const char *src, int ch);
|
||||
/* 329 */
|
||||
EXTERN CONST84_RETURN char * Tcl_UtfFindLast(const char *src, int ch);
|
||||
EXTERN const char * Tcl_UtfFindLast(const char *src, int ch);
|
||||
/* 330 */
|
||||
EXTERN CONST84_RETURN char * Tcl_UtfNext(const char *src);
|
||||
EXTERN const char * Tcl_UtfNext(const char *src);
|
||||
/* 331 */
|
||||
EXTERN CONST84_RETURN char * Tcl_UtfPrev(const char *src, const char *start);
|
||||
EXTERN const char * Tcl_UtfPrev(const char *src, const char *start);
|
||||
/* 332 */
|
||||
EXTERN int Tcl_UtfToExternal(Tcl_Interp *interp,
|
||||
Tcl_Encoding encoding, const char *src,
|
||||
@@ -1010,9 +1013,11 @@ EXTERN int Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr);
|
||||
/* 340 */
|
||||
EXTERN char * Tcl_GetString(Tcl_Obj *objPtr);
|
||||
/* 341 */
|
||||
EXTERN CONST84_RETURN char * Tcl_GetDefaultEncodingDir(void);
|
||||
TCL_DEPRECATED("Use Tcl_GetEncodingSearchPath")
|
||||
const char * Tcl_GetDefaultEncodingDir(void);
|
||||
/* 342 */
|
||||
EXTERN void Tcl_SetDefaultEncodingDir(const char *path);
|
||||
TCL_DEPRECATED("Use Tcl_SetEncodingSearchPath")
|
||||
void Tcl_SetDefaultEncodingDir(const char *path);
|
||||
/* 343 */
|
||||
EXTERN void Tcl_AlertNotifier(ClientData clientData);
|
||||
/* 344 */
|
||||
@@ -1047,7 +1052,8 @@ EXTERN Tcl_UniChar * Tcl_UtfToUniCharDString(const char *src, int length,
|
||||
EXTERN Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *patObj, int flags);
|
||||
/* 357 */
|
||||
EXTERN Tcl_Obj * Tcl_EvalTokens(Tcl_Interp *interp,
|
||||
TCL_DEPRECATED("Use Tcl_EvalTokensStandard")
|
||||
Tcl_Obj * Tcl_EvalTokens(Tcl_Interp *interp,
|
||||
Tcl_Token *tokenPtr, int count);
|
||||
/* 358 */
|
||||
EXTERN void Tcl_FreeParse(Tcl_Parse *parsePtr);
|
||||
@@ -1059,7 +1065,7 @@ EXTERN void Tcl_LogCommandInfo(Tcl_Interp *interp,
|
||||
EXTERN int Tcl_ParseBraces(Tcl_Interp *interp,
|
||||
const char *start, int numBytes,
|
||||
Tcl_Parse *parsePtr, int append,
|
||||
CONST84 char **termPtr);
|
||||
const char **termPtr);
|
||||
/* 361 */
|
||||
EXTERN int Tcl_ParseCommand(Tcl_Interp *interp,
|
||||
const char *start, int numBytes, int nested,
|
||||
@@ -1071,7 +1077,7 @@ EXTERN int Tcl_ParseExpr(Tcl_Interp *interp, const char *start,
|
||||
EXTERN int Tcl_ParseQuotedString(Tcl_Interp *interp,
|
||||
const char *start, int numBytes,
|
||||
Tcl_Parse *parsePtr, int append,
|
||||
CONST84 char **termPtr);
|
||||
const char **termPtr);
|
||||
/* 364 */
|
||||
EXTERN int Tcl_ParseVarName(Tcl_Interp *interp,
|
||||
const char *start, int numBytes,
|
||||
@@ -1161,8 +1167,7 @@ EXTERN Tcl_Channel Tcl_GetTopChannel(Tcl_Channel chan);
|
||||
/* 397 */
|
||||
EXTERN int Tcl_ChannelBuffered(Tcl_Channel chan);
|
||||
/* 398 */
|
||||
EXTERN CONST84_RETURN char * Tcl_ChannelName(
|
||||
const Tcl_ChannelType *chanTypePtr);
|
||||
EXTERN const char * Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr);
|
||||
/* 399 */
|
||||
EXTERN Tcl_ChannelTypeVersion Tcl_ChannelVersion(
|
||||
const Tcl_ChannelType *chanTypePtr);
|
||||
@@ -1268,13 +1273,15 @@ EXTERN Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel);
|
||||
EXTERN Tcl_UniChar * Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr,
|
||||
int *lengthPtr);
|
||||
/* 435 */
|
||||
EXTERN int Tcl_GetMathFuncInfo(Tcl_Interp *interp,
|
||||
TCL_DEPRECATED("")
|
||||
int Tcl_GetMathFuncInfo(Tcl_Interp *interp,
|
||||
const char *name, int *numArgsPtr,
|
||||
Tcl_ValueType **argTypesPtr,
|
||||
Tcl_MathProc **procPtr,
|
||||
ClientData *clientDataPtr);
|
||||
/* 436 */
|
||||
EXTERN Tcl_Obj * Tcl_ListMathFuncs(Tcl_Interp *interp,
|
||||
TCL_DEPRECATED("")
|
||||
Tcl_Obj * Tcl_ListMathFuncs(Tcl_Interp *interp,
|
||||
const char *pattern);
|
||||
/* 437 */
|
||||
EXTERN Tcl_Obj * Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
@@ -1843,7 +1850,7 @@ typedef struct TclStubs {
|
||||
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 */
|
||||
const char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */
|
||||
TCL_NORETURN1 void (*tcl_Panic) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 2 */
|
||||
char * (*tcl_Alloc) (unsigned int size); /* 3 */
|
||||
void (*tcl_Free) (char *ptr); /* 4 */
|
||||
@@ -1894,7 +1901,7 @@ typedef struct TclStubs {
|
||||
unsigned char * (*tcl_GetByteArrayFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 33 */
|
||||
int (*tcl_GetDouble) (Tcl_Interp *interp, const char *src, double *doublePtr); /* 34 */
|
||||
int (*tcl_GetDoubleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr); /* 35 */
|
||||
int (*tcl_GetIndexFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, CONST84 char *const *tablePtr, const char *msg, int flags, int *indexPtr); /* 36 */
|
||||
int (*tcl_GetIndexFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, const char *const *tablePtr, const char *msg, int flags, int *indexPtr); /* 36 */
|
||||
int (*tcl_GetInt) (Tcl_Interp *interp, const char *src, int *intPtr); /* 37 */
|
||||
int (*tcl_GetIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr); /* 38 */
|
||||
int (*tcl_GetLongFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr); /* 39 */
|
||||
@@ -1935,16 +1942,16 @@ typedef struct TclStubs {
|
||||
void (*tcl_AsyncMark) (Tcl_AsyncHandler async); /* 74 */
|
||||
int (*tcl_AsyncReady) (void); /* 75 */
|
||||
void (*tcl_BackgroundError) (Tcl_Interp *interp); /* 76 */
|
||||
char (*tcl_Backslash) (const char *src, int *readPtr); /* 77 */
|
||||
TCL_DEPRECATED_API("Use Tcl_UtfBackslash") char (*tcl_Backslash) (const char *src, int *readPtr); /* 77 */
|
||||
int (*tcl_BadChannelOption) (Tcl_Interp *interp, const char *optionName, const char *optionList); /* 78 */
|
||||
void (*tcl_CallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 79 */
|
||||
void (*tcl_CancelIdleCall) (Tcl_IdleProc *idleProc, ClientData clientData); /* 80 */
|
||||
int (*tcl_Close) (Tcl_Interp *interp, Tcl_Channel chan); /* 81 */
|
||||
int (*tcl_CommandComplete) (const char *cmd); /* 82 */
|
||||
char * (*tcl_Concat) (int argc, CONST84 char *const *argv); /* 83 */
|
||||
char * (*tcl_Concat) (int argc, const char *const *argv); /* 83 */
|
||||
int (*tcl_ConvertElement) (const char *src, char *dst, int flags); /* 84 */
|
||||
int (*tcl_ConvertCountedElement) (const char *src, int length, char *dst, int flags); /* 85 */
|
||||
int (*tcl_CreateAlias) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, int argc, CONST84 char *const *argv); /* 86 */
|
||||
int (*tcl_CreateAlias) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, int argc, const char *const *argv); /* 86 */
|
||||
int (*tcl_CreateAliasObj) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, int objc, Tcl_Obj *const objv[]); /* 87 */
|
||||
Tcl_Channel (*tcl_CreateChannel) (const Tcl_ChannelType *typePtr, const char *chanName, ClientData instanceData, int mask); /* 88 */
|
||||
void (*tcl_CreateChannelHandler) (Tcl_Channel chan, int mask, Tcl_ChannelProc *proc, ClientData clientData); /* 89 */
|
||||
@@ -1953,7 +1960,7 @@ typedef struct TclStubs {
|
||||
void (*tcl_CreateEventSource) (Tcl_EventSetupProc *setupProc, Tcl_EventCheckProc *checkProc, ClientData clientData); /* 92 */
|
||||
void (*tcl_CreateExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 93 */
|
||||
Tcl_Interp * (*tcl_CreateInterp) (void); /* 94 */
|
||||
void (*tcl_CreateMathFunc) (Tcl_Interp *interp, const char *name, int numArgs, Tcl_ValueType *argTypes, Tcl_MathProc *proc, ClientData clientData); /* 95 */
|
||||
TCL_DEPRECATED_API("") void (*tcl_CreateMathFunc) (Tcl_Interp *interp, const char *name, int numArgs, Tcl_ValueType *argTypes, Tcl_MathProc *proc, ClientData clientData); /* 95 */
|
||||
Tcl_Command (*tcl_CreateObjCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 96 */
|
||||
Tcl_Interp * (*tcl_CreateSlave) (Tcl_Interp *interp, const char *slaveName, int isSafe); /* 97 */
|
||||
Tcl_TimerToken (*tcl_CreateTimerHandler) (int milliseconds, Tcl_TimerProc *proc, ClientData clientData); /* 98 */
|
||||
@@ -1985,8 +1992,8 @@ typedef struct TclStubs {
|
||||
void (*tcl_DStringSetLength) (Tcl_DString *dsPtr, int length); /* 124 */
|
||||
void (*tcl_DStringStartSublist) (Tcl_DString *dsPtr); /* 125 */
|
||||
int (*tcl_Eof) (Tcl_Channel chan); /* 126 */
|
||||
CONST84_RETURN char * (*tcl_ErrnoId) (void); /* 127 */
|
||||
CONST84_RETURN char * (*tcl_ErrnoMsg) (int err); /* 128 */
|
||||
const char * (*tcl_ErrnoId) (void); /* 127 */
|
||||
const char * (*tcl_ErrnoMsg) (int err); /* 128 */
|
||||
int (*tcl_Eval) (Tcl_Interp *interp, const char *script); /* 129 */
|
||||
int (*tcl_EvalFile) (Tcl_Interp *interp, const char *fileName); /* 130 */
|
||||
int (*tcl_EvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 131 */
|
||||
@@ -2006,21 +2013,21 @@ typedef struct TclStubs {
|
||||
Tcl_HashEntry * (*tcl_FirstHashEntry) (Tcl_HashTable *tablePtr, Tcl_HashSearch *searchPtr); /* 145 */
|
||||
int (*tcl_Flush) (Tcl_Channel chan); /* 146 */
|
||||
void (*tcl_FreeResult) (Tcl_Interp *interp); /* 147 */
|
||||
int (*tcl_GetAlias) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr, int *argcPtr, CONST84 char ***argvPtr); /* 148 */
|
||||
int (*tcl_GetAliasObj) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr, int *objcPtr, Tcl_Obj ***objv); /* 149 */
|
||||
int (*tcl_GetAlias) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, int *argcPtr, const char ***argvPtr); /* 148 */
|
||||
int (*tcl_GetAliasObj) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, int *objcPtr, Tcl_Obj ***objv); /* 149 */
|
||||
ClientData (*tcl_GetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc **procPtr); /* 150 */
|
||||
Tcl_Channel (*tcl_GetChannel) (Tcl_Interp *interp, const char *chanName, int *modePtr); /* 151 */
|
||||
int (*tcl_GetChannelBufferSize) (Tcl_Channel chan); /* 152 */
|
||||
int (*tcl_GetChannelHandle) (Tcl_Channel chan, int direction, ClientData *handlePtr); /* 153 */
|
||||
ClientData (*tcl_GetChannelInstanceData) (Tcl_Channel chan); /* 154 */
|
||||
int (*tcl_GetChannelMode) (Tcl_Channel chan); /* 155 */
|
||||
CONST84_RETURN char * (*tcl_GetChannelName) (Tcl_Channel chan); /* 156 */
|
||||
const char * (*tcl_GetChannelName) (Tcl_Channel chan); /* 156 */
|
||||
int (*tcl_GetChannelOption) (Tcl_Interp *interp, Tcl_Channel chan, const char *optionName, Tcl_DString *dsPtr); /* 157 */
|
||||
CONST86 Tcl_ChannelType * (*tcl_GetChannelType) (Tcl_Channel chan); /* 158 */
|
||||
int (*tcl_GetCommandInfo) (Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); /* 159 */
|
||||
CONST84_RETURN char * (*tcl_GetCommandName) (Tcl_Interp *interp, Tcl_Command command); /* 160 */
|
||||
const char * (*tcl_GetCommandName) (Tcl_Interp *interp, Tcl_Command command); /* 160 */
|
||||
int (*tcl_GetErrno) (void); /* 161 */
|
||||
CONST84_RETURN char * (*tcl_GetHostName) (void); /* 162 */
|
||||
const char * (*tcl_GetHostName) (void); /* 162 */
|
||||
int (*tcl_GetInterpPath) (Tcl_Interp *askInterp, Tcl_Interp *slaveInterp); /* 163 */
|
||||
Tcl_Interp * (*tcl_GetMaster) (Tcl_Interp *interp); /* 164 */
|
||||
const char * (*tcl_GetNameOfExecutable) (void); /* 165 */
|
||||
@@ -2040,9 +2047,9 @@ typedef struct TclStubs {
|
||||
int (*tcl_GetServiceMode) (void); /* 171 */
|
||||
Tcl_Interp * (*tcl_GetSlave) (Tcl_Interp *interp, const char *slaveName); /* 172 */
|
||||
Tcl_Channel (*tcl_GetStdChannel) (int type); /* 173 */
|
||||
CONST84_RETURN char * (*tcl_GetStringResult) (Tcl_Interp *interp); /* 174 */
|
||||
CONST84_RETURN char * (*tcl_GetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 175 */
|
||||
CONST84_RETURN char * (*tcl_GetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 176 */
|
||||
const char * (*tcl_GetStringResult) (Tcl_Interp *interp); /* 174 */
|
||||
const char * (*tcl_GetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 175 */
|
||||
const char * (*tcl_GetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 176 */
|
||||
int (*tcl_GlobalEval) (Tcl_Interp *interp, const char *command); /* 177 */
|
||||
int (*tcl_GlobalEvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 178 */
|
||||
int (*tcl_HideCommand) (Tcl_Interp *interp, const char *cmdName, const char *hiddenCmdToken); /* 179 */
|
||||
@@ -2052,25 +2059,25 @@ typedef struct TclStubs {
|
||||
int (*tcl_InputBuffered) (Tcl_Channel chan); /* 183 */
|
||||
int (*tcl_InterpDeleted) (Tcl_Interp *interp); /* 184 */
|
||||
int (*tcl_IsSafe) (Tcl_Interp *interp); /* 185 */
|
||||
char * (*tcl_JoinPath) (int argc, CONST84 char *const *argv, Tcl_DString *resultPtr); /* 186 */
|
||||
char * (*tcl_JoinPath) (int argc, const char *const *argv, Tcl_DString *resultPtr); /* 186 */
|
||||
int (*tcl_LinkVar) (Tcl_Interp *interp, const char *varName, char *addr, int type); /* 187 */
|
||||
void (*reserved188)(void);
|
||||
Tcl_Channel (*tcl_MakeFileChannel) (ClientData handle, int mode); /* 189 */
|
||||
int (*tcl_MakeSafe) (Tcl_Interp *interp); /* 190 */
|
||||
Tcl_Channel (*tcl_MakeTcpClientChannel) (ClientData tcpSocket); /* 191 */
|
||||
char * (*tcl_Merge) (int argc, CONST84 char *const *argv); /* 192 */
|
||||
char * (*tcl_Merge) (int argc, const char *const *argv); /* 192 */
|
||||
Tcl_HashEntry * (*tcl_NextHashEntry) (Tcl_HashSearch *searchPtr); /* 193 */
|
||||
void (*tcl_NotifyChannel) (Tcl_Channel channel, int mask); /* 194 */
|
||||
Tcl_Obj * (*tcl_ObjGetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); /* 195 */
|
||||
Tcl_Obj * (*tcl_ObjSetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); /* 196 */
|
||||
Tcl_Channel (*tcl_OpenCommandChannel) (Tcl_Interp *interp, int argc, CONST84 char **argv, int flags); /* 197 */
|
||||
Tcl_Channel (*tcl_OpenCommandChannel) (Tcl_Interp *interp, int argc, const char **argv, int flags); /* 197 */
|
||||
Tcl_Channel (*tcl_OpenFileChannel) (Tcl_Interp *interp, const char *fileName, const char *modeString, int permissions); /* 198 */
|
||||
Tcl_Channel (*tcl_OpenTcpClient) (Tcl_Interp *interp, int port, const char *address, const char *myaddr, int myport, int async); /* 199 */
|
||||
Tcl_Channel (*tcl_OpenTcpServer) (Tcl_Interp *interp, int port, const char *host, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 200 */
|
||||
void (*tcl_Preserve) (ClientData data); /* 201 */
|
||||
void (*tcl_PrintDouble) (Tcl_Interp *interp, double value, char *dst); /* 202 */
|
||||
int (*tcl_PutEnv) (const char *assignment); /* 203 */
|
||||
CONST84_RETURN char * (*tcl_PosixError) (Tcl_Interp *interp); /* 204 */
|
||||
const char * (*tcl_PosixError) (Tcl_Interp *interp); /* 204 */
|
||||
void (*tcl_QueueEvent) (Tcl_Event *evPtr, Tcl_QueuePosition position); /* 205 */
|
||||
int (*tcl_Read) (Tcl_Channel chan, char *bufPtr, int toRead); /* 206 */
|
||||
void (*tcl_ReapDetachedProcs) (void); /* 207 */
|
||||
@@ -2081,12 +2088,12 @@ typedef struct TclStubs {
|
||||
Tcl_RegExp (*tcl_RegExpCompile) (Tcl_Interp *interp, const char *pattern); /* 212 */
|
||||
int (*tcl_RegExpExec) (Tcl_Interp *interp, Tcl_RegExp regexp, const char *text, const char *start); /* 213 */
|
||||
int (*tcl_RegExpMatch) (Tcl_Interp *interp, const char *text, const char *pattern); /* 214 */
|
||||
void (*tcl_RegExpRange) (Tcl_RegExp regexp, int index, CONST84 char **startPtr, CONST84 char **endPtr); /* 215 */
|
||||
void (*tcl_RegExpRange) (Tcl_RegExp regexp, int index, const char **startPtr, const char **endPtr); /* 215 */
|
||||
void (*tcl_Release) (ClientData clientData); /* 216 */
|
||||
void (*tcl_ResetResult) (Tcl_Interp *interp); /* 217 */
|
||||
int (*tcl_ScanElement) (const char *src, int *flagPtr); /* 218 */
|
||||
int (*tcl_ScanCountedElement) (const char *src, int length, int *flagPtr); /* 219 */
|
||||
int (*tcl_SeekOld) (Tcl_Channel chan, int offset, int mode); /* 220 */
|
||||
TCL_DEPRECATED_API("") int (*tcl_SeekOld) (Tcl_Channel chan, int offset, int mode); /* 220 */
|
||||
int (*tcl_ServiceAll) (void); /* 221 */
|
||||
int (*tcl_ServiceEvent) (int flags); /* 222 */
|
||||
void (*tcl_SetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 223 */
|
||||
@@ -2103,16 +2110,16 @@ typedef struct TclStubs {
|
||||
void (*tcl_SetObjErrorCode) (Tcl_Interp *interp, Tcl_Obj *errorObjPtr); /* 234 */
|
||||
void (*tcl_SetObjResult) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr); /* 235 */
|
||||
void (*tcl_SetStdChannel) (Tcl_Channel channel, int type); /* 236 */
|
||||
CONST84_RETURN char * (*tcl_SetVar) (Tcl_Interp *interp, const char *varName, const char *newValue, int flags); /* 237 */
|
||||
CONST84_RETURN char * (*tcl_SetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, const char *newValue, int flags); /* 238 */
|
||||
CONST84_RETURN char * (*tcl_SignalId) (int sig); /* 239 */
|
||||
CONST84_RETURN char * (*tcl_SignalMsg) (int sig); /* 240 */
|
||||
const char * (*tcl_SetVar) (Tcl_Interp *interp, const char *varName, const char *newValue, int flags); /* 237 */
|
||||
const char * (*tcl_SetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, const char *newValue, int flags); /* 238 */
|
||||
const char * (*tcl_SignalId) (int sig); /* 239 */
|
||||
const char * (*tcl_SignalMsg) (int sig); /* 240 */
|
||||
void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */
|
||||
int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, int *argcPtr, CONST84 char ***argvPtr); /* 242 */
|
||||
void (*tcl_SplitPath) (const char *path, int *argcPtr, CONST84 char ***argvPtr); /* 243 */
|
||||
int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, int *argcPtr, const char ***argvPtr); /* 242 */
|
||||
void (*tcl_SplitPath) (const char *path, int *argcPtr, const char ***argvPtr); /* 243 */
|
||||
void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */
|
||||
int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */
|
||||
int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */
|
||||
TCL_DEPRECATED_API("") int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */
|
||||
int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */
|
||||
int (*tcl_TraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 248 */
|
||||
char * (*tcl_TranslateFileName) (Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr); /* 249 */
|
||||
@@ -2133,18 +2140,18 @@ typedef struct TclStubs {
|
||||
void (*tcl_WrongNumArgs) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char *message); /* 264 */
|
||||
int (*tcl_DumpActiveMemory) (const char *fileName); /* 265 */
|
||||
void (*tcl_ValidateAllMemory) (const char *file, int line); /* 266 */
|
||||
void (*tcl_AppendResultVA) (Tcl_Interp *interp, va_list argList); /* 267 */
|
||||
void (*tcl_AppendStringsToObjVA) (Tcl_Obj *objPtr, va_list argList); /* 268 */
|
||||
TCL_DEPRECATED_API("see TIP #422") void (*tcl_AppendResultVA) (Tcl_Interp *interp, va_list argList); /* 267 */
|
||||
TCL_DEPRECATED_API("see TIP #422") void (*tcl_AppendStringsToObjVA) (Tcl_Obj *objPtr, va_list argList); /* 268 */
|
||||
char * (*tcl_HashStats) (Tcl_HashTable *tablePtr); /* 269 */
|
||||
CONST84_RETURN char * (*tcl_ParseVar) (Tcl_Interp *interp, const char *start, CONST84 char **termPtr); /* 270 */
|
||||
CONST84_RETURN char * (*tcl_PkgPresent) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 271 */
|
||||
CONST84_RETURN char * (*tcl_PkgPresentEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 272 */
|
||||
const char * (*tcl_ParseVar) (Tcl_Interp *interp, const char *start, const char **termPtr); /* 270 */
|
||||
const char * (*tcl_PkgPresent) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 271 */
|
||||
const char * (*tcl_PkgPresentEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 272 */
|
||||
int (*tcl_PkgProvide) (Tcl_Interp *interp, const char *name, const char *version); /* 273 */
|
||||
CONST84_RETURN char * (*tcl_PkgRequire) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 274 */
|
||||
void (*tcl_SetErrorCodeVA) (Tcl_Interp *interp, va_list argList); /* 275 */
|
||||
int (*tcl_VarEvalVA) (Tcl_Interp *interp, va_list argList); /* 276 */
|
||||
const char * (*tcl_PkgRequire) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 274 */
|
||||
TCL_DEPRECATED_API("see TIP #422") void (*tcl_SetErrorCodeVA) (Tcl_Interp *interp, va_list argList); /* 275 */
|
||||
TCL_DEPRECATED_API("see TIP #422") int (*tcl_VarEvalVA) (Tcl_Interp *interp, va_list argList); /* 276 */
|
||||
Tcl_Pid (*tcl_WaitPid) (Tcl_Pid pid, int *statPtr, int options); /* 277 */
|
||||
TCL_NORETURN1 void (*tcl_PanicVA) (const char *format, va_list argList); /* 278 */
|
||||
TCL_DEPRECATED_API("see TIP #422") TCL_NORETURN1 void (*tcl_PanicVA) (const char *format, va_list argList); /* 278 */
|
||||
void (*tcl_GetVersion) (int *major, int *minor, int *patchLevel, int *type); /* 279 */
|
||||
void (*tcl_InitMemory) (Tcl_Interp *interp); /* 280 */
|
||||
Tcl_Channel (*tcl_StackChannel) (Tcl_Interp *interp, const Tcl_ChannelType *typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan); /* 281 */
|
||||
@@ -2168,7 +2175,7 @@ typedef struct TclStubs {
|
||||
void (*tcl_FreeEncoding) (Tcl_Encoding encoding); /* 299 */
|
||||
Tcl_ThreadId (*tcl_GetCurrentThread) (void); /* 300 */
|
||||
Tcl_Encoding (*tcl_GetEncoding) (Tcl_Interp *interp, const char *name); /* 301 */
|
||||
CONST84_RETURN char * (*tcl_GetEncodingName) (Tcl_Encoding encoding); /* 302 */
|
||||
const char * (*tcl_GetEncodingName) (Tcl_Encoding encoding); /* 302 */
|
||||
void (*tcl_GetEncodingNames) (Tcl_Interp *interp); /* 303 */
|
||||
int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, int *indexPtr); /* 304 */
|
||||
void * (*tcl_GetThreadData) (Tcl_ThreadDataKey *keyPtr, int size); /* 305 */
|
||||
@@ -2191,13 +2198,13 @@ typedef struct TclStubs {
|
||||
Tcl_UniChar (*tcl_UniCharToTitle) (int ch); /* 322 */
|
||||
Tcl_UniChar (*tcl_UniCharToUpper) (int ch); /* 323 */
|
||||
int (*tcl_UniCharToUtf) (int ch, char *buf); /* 324 */
|
||||
CONST84_RETURN char * (*tcl_UtfAtIndex) (const char *src, int index); /* 325 */
|
||||
const char * (*tcl_UtfAtIndex) (const char *src, int index); /* 325 */
|
||||
int (*tcl_UtfCharComplete) (const char *src, int length); /* 326 */
|
||||
int (*tcl_UtfBackslash) (const char *src, int *readPtr, char *dst); /* 327 */
|
||||
CONST84_RETURN char * (*tcl_UtfFindFirst) (const char *src, int ch); /* 328 */
|
||||
CONST84_RETURN char * (*tcl_UtfFindLast) (const char *src, int ch); /* 329 */
|
||||
CONST84_RETURN char * (*tcl_UtfNext) (const char *src); /* 330 */
|
||||
CONST84_RETURN char * (*tcl_UtfPrev) (const char *src, const char *start); /* 331 */
|
||||
const char * (*tcl_UtfFindFirst) (const char *src, int ch); /* 328 */
|
||||
const char * (*tcl_UtfFindLast) (const char *src, int ch); /* 329 */
|
||||
const char * (*tcl_UtfNext) (const char *src); /* 330 */
|
||||
const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 331 */
|
||||
int (*tcl_UtfToExternal) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 332 */
|
||||
char * (*tcl_UtfToExternalDString) (Tcl_Encoding encoding, const char *src, int srcLen, Tcl_DString *dsPtr); /* 333 */
|
||||
int (*tcl_UtfToLower) (char *src); /* 334 */
|
||||
@@ -2207,8 +2214,8 @@ typedef struct TclStubs {
|
||||
int (*tcl_WriteChars) (Tcl_Channel chan, const char *src, int srcLen); /* 338 */
|
||||
int (*tcl_WriteObj) (Tcl_Channel chan, Tcl_Obj *objPtr); /* 339 */
|
||||
char * (*tcl_GetString) (Tcl_Obj *objPtr); /* 340 */
|
||||
CONST84_RETURN char * (*tcl_GetDefaultEncodingDir) (void); /* 341 */
|
||||
void (*tcl_SetDefaultEncodingDir) (const char *path); /* 342 */
|
||||
TCL_DEPRECATED_API("Use Tcl_GetEncodingSearchPath") const char * (*tcl_GetDefaultEncodingDir) (void); /* 341 */
|
||||
TCL_DEPRECATED_API("Use Tcl_SetEncodingSearchPath") void (*tcl_SetDefaultEncodingDir) (const char *path); /* 342 */
|
||||
void (*tcl_AlertNotifier) (ClientData clientData); /* 343 */
|
||||
void (*tcl_ServiceModeHook) (int mode); /* 344 */
|
||||
int (*tcl_UniCharIsAlnum) (int ch); /* 345 */
|
||||
@@ -2223,13 +2230,13 @@ typedef struct TclStubs {
|
||||
char * (*tcl_UniCharToUtfDString) (const Tcl_UniChar *uniStr, int uniLength, Tcl_DString *dsPtr); /* 354 */
|
||||
Tcl_UniChar * (*tcl_UtfToUniCharDString) (const char *src, int length, Tcl_DString *dsPtr); /* 355 */
|
||||
Tcl_RegExp (*tcl_GetRegExpFromObj) (Tcl_Interp *interp, Tcl_Obj *patObj, int flags); /* 356 */
|
||||
Tcl_Obj * (*tcl_EvalTokens) (Tcl_Interp *interp, Tcl_Token *tokenPtr, int count); /* 357 */
|
||||
TCL_DEPRECATED_API("Use Tcl_EvalTokensStandard") Tcl_Obj * (*tcl_EvalTokens) (Tcl_Interp *interp, Tcl_Token *tokenPtr, int count); /* 357 */
|
||||
void (*tcl_FreeParse) (Tcl_Parse *parsePtr); /* 358 */
|
||||
void (*tcl_LogCommandInfo) (Tcl_Interp *interp, const char *script, const char *command, int length); /* 359 */
|
||||
int (*tcl_ParseBraces) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append, CONST84 char **termPtr); /* 360 */
|
||||
int (*tcl_ParseBraces) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 360 */
|
||||
int (*tcl_ParseCommand) (Tcl_Interp *interp, const char *start, int numBytes, int nested, Tcl_Parse *parsePtr); /* 361 */
|
||||
int (*tcl_ParseExpr) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr); /* 362 */
|
||||
int (*tcl_ParseQuotedString) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append, CONST84 char **termPtr); /* 363 */
|
||||
int (*tcl_ParseQuotedString) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 363 */
|
||||
int (*tcl_ParseVarName) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append); /* 364 */
|
||||
char * (*tcl_GetCwd) (Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 365 */
|
||||
int (*tcl_Chdir) (const char *dirName); /* 366 */
|
||||
@@ -2264,7 +2271,7 @@ typedef struct TclStubs {
|
||||
int (*tcl_WriteRaw) (Tcl_Channel chan, const char *src, int srcLen); /* 395 */
|
||||
Tcl_Channel (*tcl_GetTopChannel) (Tcl_Channel chan); /* 396 */
|
||||
int (*tcl_ChannelBuffered) (Tcl_Channel chan); /* 397 */
|
||||
CONST84_RETURN char * (*tcl_ChannelName) (const Tcl_ChannelType *chanTypePtr); /* 398 */
|
||||
const char * (*tcl_ChannelName) (const Tcl_ChannelType *chanTypePtr); /* 398 */
|
||||
Tcl_ChannelTypeVersion (*tcl_ChannelVersion) (const Tcl_ChannelType *chanTypePtr); /* 399 */
|
||||
Tcl_DriverBlockModeProc * (*tcl_ChannelBlockModeProc) (const Tcl_ChannelType *chanTypePtr); /* 400 */
|
||||
Tcl_DriverCloseProc * (*tcl_ChannelCloseProc) (const Tcl_ChannelType *chanTypePtr); /* 401 */
|
||||
@@ -2301,8 +2308,8 @@ typedef struct TclStubs {
|
||||
int (*tcl_AttemptSetObjLength) (Tcl_Obj *objPtr, int length); /* 432 */
|
||||
Tcl_ThreadId (*tcl_GetChannelThread) (Tcl_Channel channel); /* 433 */
|
||||
Tcl_UniChar * (*tcl_GetUnicodeFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 434 */
|
||||
int (*tcl_GetMathFuncInfo) (Tcl_Interp *interp, const char *name, int *numArgsPtr, Tcl_ValueType **argTypesPtr, Tcl_MathProc **procPtr, ClientData *clientDataPtr); /* 435 */
|
||||
Tcl_Obj * (*tcl_ListMathFuncs) (Tcl_Interp *interp, const char *pattern); /* 436 */
|
||||
TCL_DEPRECATED_API("") int (*tcl_GetMathFuncInfo) (Tcl_Interp *interp, const char *name, int *numArgsPtr, Tcl_ValueType **argTypesPtr, Tcl_MathProc **procPtr, ClientData *clientDataPtr); /* 435 */
|
||||
TCL_DEPRECATED_API("") Tcl_Obj * (*tcl_ListMathFuncs) (Tcl_Interp *interp, const char *pattern); /* 436 */
|
||||
Tcl_Obj * (*tcl_SubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 437 */
|
||||
int (*tcl_DetachChannel) (Tcl_Interp *interp, Tcl_Channel channel); /* 438 */
|
||||
int (*tcl_IsStandardChannel) (Tcl_Channel channel); /* 439 */
|
||||
@@ -3927,20 +3934,14 @@ extern const TclStubs *tclStubsPtr;
|
||||
* possible. Tcl 9 must find a better solution, but that cannot be done
|
||||
* without introducing a binary incompatibility.
|
||||
*/
|
||||
# undef Tcl_DbNewLongObj
|
||||
# undef Tcl_GetLongFromObj
|
||||
# undef Tcl_NewLongObj
|
||||
# undef Tcl_SetLongObj
|
||||
# undef Tcl_ExprLong
|
||||
# undef Tcl_ExprLongObj
|
||||
# undef Tcl_UniCharNcmp
|
||||
# undef Tcl_UtfNcmp
|
||||
# undef Tcl_UtfNcasecmp
|
||||
# undef Tcl_UniCharNcasecmp
|
||||
# define Tcl_DbNewLongObj ((Tcl_Obj*(*)(long,const char*,int))Tcl_DbNewWideIntObj)
|
||||
# define Tcl_GetLongFromObj ((int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetWideIntFromObj)
|
||||
# define Tcl_NewLongObj ((Tcl_Obj*(*)(long))Tcl_NewWideIntObj)
|
||||
# define Tcl_SetLongObj ((void(*)(Tcl_Obj*,long))Tcl_SetWideIntObj)
|
||||
# define Tcl_ExprLong TclExprLong
|
||||
static inline int TclExprLong(Tcl_Interp *interp, const char *string, long *ptr){
|
||||
int intValue;
|
||||
@@ -3966,6 +3967,17 @@ extern const TclStubs *tclStubsPtr;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#undef Tcl_NewLongObj
|
||||
#define Tcl_NewLongObj(value) Tcl_NewWideIntObj((long)(value))
|
||||
#undef Tcl_NewIntObj
|
||||
#define Tcl_NewIntObj(value) Tcl_NewWideIntObj((int)(value))
|
||||
#undef Tcl_DbNewLongObj
|
||||
#define Tcl_DbNewLongObj(value, file, line) Tcl_DbNewWideIntObj((long)(value), file, line)
|
||||
#undef Tcl_SetIntObj
|
||||
#define Tcl_SetIntObj(objPtr, value) Tcl_SetWideIntObj(objPtr, (int)(value))
|
||||
#undef Tcl_SetLongObj
|
||||
#define Tcl_SetLongObj(objPtr, value) Tcl_SetWideIntObj(objPtr, (long)(value))
|
||||
|
||||
/*
|
||||
* Deprecated Tcl procedures:
|
||||
*/
|
||||
|
||||
+18
-18
@@ -141,7 +141,7 @@ typedef struct Dict {
|
||||
* the dictionary. Used for doing traversal of
|
||||
* the entries in the order that they are
|
||||
* created. */
|
||||
int epoch; /* Epoch counter */
|
||||
unsigned int epoch; /* Epoch counter */
|
||||
size_t refCount; /* Reference counter (see above) */
|
||||
Tcl_Obj *chain; /* Linked list used for invalidating the
|
||||
* string representations of updated nested
|
||||
@@ -390,7 +390,7 @@ DupDictInternalRep(
|
||||
* Initialise other fields.
|
||||
*/
|
||||
|
||||
newDict->epoch = 0;
|
||||
newDict->epoch = 1;
|
||||
newDict->chain = NULL;
|
||||
newDict->refCount = 1;
|
||||
|
||||
@@ -487,15 +487,14 @@ static void
|
||||
UpdateStringOfDict(
|
||||
Tcl_Obj *dictPtr)
|
||||
{
|
||||
#define LOCAL_SIZE 20
|
||||
int localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
#define LOCAL_SIZE 64
|
||||
char localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
Dict *dict = DICT(dictPtr);
|
||||
ChainEntry *cPtr;
|
||||
Tcl_Obj *keyPtr, *valuePtr;
|
||||
int i, length, bytesNeeded = 0;
|
||||
const char *elem;
|
||||
char *dst;
|
||||
const int maxFlags = UINT_MAX / sizeof(int);
|
||||
|
||||
/*
|
||||
* This field is the most useful one in the whole hash structure, and it
|
||||
@@ -517,10 +516,8 @@ UpdateStringOfDict(
|
||||
|
||||
if (numElems <= LOCAL_SIZE) {
|
||||
flagPtr = localFlags;
|
||||
} else if (numElems > maxFlags) {
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
} else {
|
||||
flagPtr = ckalloc(numElems * sizeof(int));
|
||||
flagPtr = ckalloc(numElems);
|
||||
}
|
||||
for (i=0,cPtr=dict->entryChainHead; i<numElems; i+=2,cPtr=cPtr->nextPtr) {
|
||||
/*
|
||||
@@ -710,7 +707,7 @@ SetDictFromAny(
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
dict->epoch = 0;
|
||||
dict->epoch = 1;
|
||||
dict->chain = NULL;
|
||||
dict->refCount = 1;
|
||||
DICT(objPtr) = dict;
|
||||
@@ -1109,7 +1106,7 @@ Tcl_DictObjFirst(
|
||||
dict = DICT(dictPtr);
|
||||
cPtr = dict->entryChainHead;
|
||||
if (cPtr == NULL) {
|
||||
searchPtr->epoch = -1;
|
||||
searchPtr->epoch = 0;
|
||||
*donePtr = 1;
|
||||
} else {
|
||||
*donePtr = 0;
|
||||
@@ -1170,7 +1167,7 @@ Tcl_DictObjNext(
|
||||
* If the searh is done; we do no work.
|
||||
*/
|
||||
|
||||
if (searchPtr->epoch == -1) {
|
||||
if (!searchPtr->epoch) {
|
||||
*donePtr = 1;
|
||||
return;
|
||||
}
|
||||
@@ -1227,8 +1224,8 @@ Tcl_DictObjDone(
|
||||
{
|
||||
Dict *dict;
|
||||
|
||||
if (searchPtr->epoch != -1) {
|
||||
searchPtr->epoch = -1;
|
||||
if (searchPtr->epoch) {
|
||||
searchPtr->epoch = 0;
|
||||
dict = (Dict *) searchPtr->dictionaryPtr;
|
||||
if (dict->refCount-- <= 1) {
|
||||
DeleteDict(dict);
|
||||
@@ -1380,7 +1377,7 @@ Tcl_NewDictObj(void)
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
dict = ckalloc(sizeof(Dict));
|
||||
InitChainTable(dict);
|
||||
dict->epoch = 0;
|
||||
dict->epoch = 1;
|
||||
dict->chain = NULL;
|
||||
dict->refCount = 1;
|
||||
DICT(dictPtr) = dict;
|
||||
@@ -1430,7 +1427,7 @@ Tcl_DbNewDictObj(
|
||||
TclInvalidateStringRep(dictPtr);
|
||||
dict = ckalloc(sizeof(Dict));
|
||||
InitChainTable(dict);
|
||||
dict->epoch = 0;
|
||||
dict->epoch = 1;
|
||||
dict->chain = NULL;
|
||||
dict->refCount = 1;
|
||||
DICT(dictPtr) = dict;
|
||||
@@ -2312,9 +2309,12 @@ DictAppendCmd(
|
||||
|
||||
if (objc == 4) {
|
||||
appendObjPtr = objv[3];
|
||||
} else if (TCL_OK != TclStringCatObjv(interp, /* inPlace */ 1,
|
||||
objc-3, objv+3, &appendObjPtr)) {
|
||||
return TCL_ERROR;
|
||||
} else {
|
||||
appendObjPtr = TclStringCat(interp, objc-3, objv+3,
|
||||
TCL_STRING_IN_PLACE);
|
||||
if (appendObjPtr == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ DisassembleByteCodeObj(
|
||||
Tcl_Obj *bufferObj, *fileObj;
|
||||
|
||||
TclNewObj(bufferObj);
|
||||
if (codePtr->refCount <= 0) {
|
||||
if (!codePtr->refCount) {
|
||||
return bufferObj; /* Already freed. */
|
||||
}
|
||||
|
||||
@@ -312,7 +312,7 @@ DisassembleByteCodeObj(
|
||||
int numCompiledLocals = procPtr->numCompiledLocals;
|
||||
|
||||
Tcl_AppendPrintfToObj(bufferObj,
|
||||
" Proc %p, refCt %d, args %d, compiled locals %d\n",
|
||||
" Proc %p, refCt %u, args %d, compiled locals %d\n",
|
||||
procPtr, procPtr->refCount, procPtr->numArgs,
|
||||
numCompiledLocals);
|
||||
if (numCompiledLocals > 0) {
|
||||
@@ -797,7 +797,7 @@ TclNewInstNameObj(
|
||||
Tcl_Obj *objPtr = Tcl_NewObj();
|
||||
|
||||
objPtr->typePtr = &tclInstNameType;
|
||||
objPtr->internalRep.longValue = (long) inst;
|
||||
objPtr->internalRep.wideValue = (long) inst;
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
return objPtr;
|
||||
@@ -817,17 +817,17 @@ static void
|
||||
UpdateStringOfInstName(
|
||||
Tcl_Obj *objPtr)
|
||||
{
|
||||
int inst = objPtr->internalRep.longValue;
|
||||
char *s, buf[20];
|
||||
int len;
|
||||
size_t len, inst = (size_t)objPtr->internalRep.wideValue;
|
||||
char *s, buf[TCL_INTEGER_SPACE + 5];
|
||||
|
||||
if ((inst < 0) || (inst > LAST_INST_OPCODE)) {
|
||||
sprintf(buf, "inst_%d", inst);
|
||||
if (inst > LAST_INST_OPCODE) {
|
||||
sprintf(buf, "inst_%" TCL_Z_MODIFIER "d", inst);
|
||||
s = buf;
|
||||
} else {
|
||||
s = (char *) tclInstructionTable[objPtr->internalRep.longValue].name;
|
||||
s = (char *) tclInstructionTable[inst].name;
|
||||
}
|
||||
len = strlen(s);
|
||||
/* assert (len < UINT_MAX) */
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, s, len + 1);
|
||||
objPtr->length = len;
|
||||
|
||||
@@ -18,7 +18,7 @@ typedef size_t (LengthProc)(const char *src);
|
||||
* convert between various character sets and UTF-8.
|
||||
*/
|
||||
|
||||
typedef struct Encoding {
|
||||
typedef struct {
|
||||
char *name; /* Name of encoding. Malloced because (1) hash
|
||||
* table entry that owns this encoding may be
|
||||
* freed prior to this encoding being freed,
|
||||
@@ -57,7 +57,7 @@ typedef struct Encoding {
|
||||
* encoding.
|
||||
*/
|
||||
|
||||
typedef struct TableEncodingData {
|
||||
typedef struct {
|
||||
int fallback; /* Character (in this encoding) to substitute
|
||||
* when this encoding cannot represent a UTF-8
|
||||
* character. */
|
||||
@@ -91,7 +91,7 @@ typedef struct TableEncodingData {
|
||||
* for switching character sets.
|
||||
*/
|
||||
|
||||
typedef struct EscapeSubTable {
|
||||
typedef struct {
|
||||
unsigned sequenceLen; /* Length of following string. */
|
||||
char sequence[16]; /* Escape code that marks this encoding. */
|
||||
char name[32]; /* Name for encoding. */
|
||||
@@ -100,7 +100,7 @@ typedef struct EscapeSubTable {
|
||||
* yet. */
|
||||
} EscapeSubTable;
|
||||
|
||||
typedef struct EscapeEncodingData {
|
||||
typedef struct {
|
||||
int fallback; /* Character (in this encoding) to substitute
|
||||
* when this encoding cannot represent a UTF-8
|
||||
* character. */
|
||||
@@ -693,6 +693,7 @@ TclFinalizeEncodingSubsystem(void)
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
const char *
|
||||
Tcl_GetDefaultEncodingDir(void)
|
||||
{
|
||||
@@ -736,6 +737,7 @@ Tcl_SetDefaultEncodingDir(
|
||||
Tcl_ListObjReplace(NULL, searchPath, 0, 0, 1, &directory);
|
||||
Tcl_SetEncodingSearchPath(searchPath);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*-------------------------------------------------------------------------
|
||||
@@ -3609,7 +3611,7 @@ unilen(
|
||||
static void
|
||||
InitializeEncodingSearchPath(
|
||||
char **valuePtr,
|
||||
size_t *lengthPtr,
|
||||
unsigned int *lengthPtr,
|
||||
Tcl_Encoding *encodingPtr)
|
||||
{
|
||||
const char *bytes;
|
||||
|
||||
+188
-150
@@ -92,7 +92,7 @@ static const Tcl_ObjType ensembleCmdType = {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
size_t epoch; /* Used to confirm when the data in this
|
||||
unsigned int epoch; /* Used to confirm when the data in this
|
||||
* really structure matches up with the
|
||||
* ensemble. */
|
||||
Command *token; /* Reference to the command for which this
|
||||
@@ -146,10 +146,12 @@ TclNamespaceEnsembleCmd(
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
Tcl_Namespace *namespacePtr;
|
||||
Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
|
||||
Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp), *cxtPtr,
|
||||
*foundNsPtr, *altFoundNsPtr, *actualCxtPtr;
|
||||
Tcl_Command token;
|
||||
Tcl_DictSearch search;
|
||||
Tcl_Obj *listObj;
|
||||
const char *simpleName;
|
||||
int index, done;
|
||||
|
||||
if (nsPtr == NULL || nsPtr->flags & NS_DYING) {
|
||||
@@ -195,13 +197,8 @@ TclNamespaceEnsembleCmd(
|
||||
objv += 2;
|
||||
objc -= 2;
|
||||
|
||||
/*
|
||||
* Work out what name to use for the command to create. If supplied,
|
||||
* it is either fully specified or relative to the current namespace.
|
||||
* If not supplied, it is exactly the name of the current namespace.
|
||||
*/
|
||||
|
||||
name = nsPtr->fullName;
|
||||
name = nsPtr->name;
|
||||
cxtPtr = (Namespace *) nsPtr->parentPtr;
|
||||
|
||||
/*
|
||||
* Parse the option list, applying type checks as we go. Note that we
|
||||
@@ -221,6 +218,7 @@ TclNamespaceEnsembleCmd(
|
||||
switch ((enum EnsCreateOpts) index) {
|
||||
case CRT_CMD:
|
||||
name = TclGetString(objv[1]);
|
||||
cxtPtr = nsPtr;
|
||||
continue;
|
||||
case CRT_SUBCMDS:
|
||||
if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
|
||||
@@ -337,6 +335,10 @@ TclNamespaceEnsembleCmd(
|
||||
}
|
||||
}
|
||||
|
||||
TclGetNamespaceForQualName(interp, name, cxtPtr,
|
||||
TCL_CREATE_NS_IF_UNKNOWN, &foundNsPtr, &altFoundNsPtr, &actualCxtPtr,
|
||||
&simpleName);
|
||||
|
||||
/*
|
||||
* Create the ensemble. Note that this might delete another ensemble
|
||||
* linked to the same namespace, so we must be careful. However, we
|
||||
@@ -344,8 +346,9 @@ TclNamespaceEnsembleCmd(
|
||||
* we've created it (and after any deletions have occurred.)
|
||||
*/
|
||||
|
||||
token = Tcl_CreateEnsemble(interp, name, NULL,
|
||||
(permitPrefix ? TCL_ENSEMBLE_PREFIX : 0));
|
||||
token = TclCreateEnsembleInNs(interp, simpleName,
|
||||
(Tcl_Namespace *) foundNsPtr, (Tcl_Namespace *) nsPtr,
|
||||
(permitPrefix ? TCL_ENSEMBLE_PREFIX : 0));
|
||||
Tcl_SetEnsembleSubcommandList(interp, token, subcmdObj);
|
||||
Tcl_SetEnsembleMappingDict(interp, token, mapObj);
|
||||
Tcl_SetEnsembleUnknownHandler(interp, token, unknownObj);
|
||||
@@ -636,48 +639,38 @@ TclNamespaceEnsembleCmd(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_CreateEnsemble --
|
||||
* TclCreateEnsembleInNs --
|
||||
*
|
||||
* Create a simple ensemble attached to the given namespace.
|
||||
*
|
||||
* Results:
|
||||
* The token for the command created.
|
||||
*
|
||||
* Side effects:
|
||||
* The ensemble is created and marked for compilation.
|
||||
* Like Tcl_CreateEnsemble, but additionally accepts as an argument the
|
||||
* name of the namespace to create the command in.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Command
|
||||
Tcl_CreateEnsemble(
|
||||
TclCreateEnsembleInNs(
|
||||
Tcl_Interp *interp,
|
||||
const char *name,
|
||||
Tcl_Namespace *namespacePtr,
|
||||
int flags)
|
||||
|
||||
const char *name, /* Simple name of command to create (no */
|
||||
/* namespace components). */
|
||||
Tcl_Namespace /* Name of namespace to create the command in. */
|
||||
*nameNsPtr,
|
||||
Tcl_Namespace
|
||||
*ensembleNsPtr, /* Name of the namespace for the ensemble. */
|
||||
int flags
|
||||
)
|
||||
{
|
||||
Namespace *nsPtr = (Namespace *) namespacePtr;
|
||||
EnsembleConfig *ensemblePtr = ckalloc(sizeof(EnsembleConfig));
|
||||
Tcl_Obj *nameObj = NULL;
|
||||
Namespace *nsPtr = (Namespace *) ensembleNsPtr;
|
||||
EnsembleConfig *ensemblePtr;
|
||||
Tcl_Command token;
|
||||
|
||||
if (nsPtr == NULL) {
|
||||
nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the name of the ensemble into a fully qualified name. This might
|
||||
* allocate a temporary object.
|
||||
*/
|
||||
|
||||
if (!(name[0] == ':' && name[1] == ':')) {
|
||||
nameObj = NewNsObj((Tcl_Namespace *) nsPtr);
|
||||
if (nsPtr->parentPtr == NULL) {
|
||||
Tcl_AppendStringsToObj(nameObj, name, NULL);
|
||||
} else {
|
||||
Tcl_AppendStringsToObj(nameObj, "::", name, NULL);
|
||||
}
|
||||
Tcl_IncrRefCount(nameObj);
|
||||
name = TclGetString(nameObj);
|
||||
ensemblePtr = ckalloc(sizeof(EnsembleConfig));
|
||||
token = TclNRCreateCommandInNs(interp, name,
|
||||
(Tcl_Namespace *) nameNsPtr, NsEnsembleImplementationCmd,
|
||||
NsEnsembleImplementationCmdNR, ensemblePtr, DeleteEnsembleConfig);
|
||||
if (token == NULL) {
|
||||
ckfree(ensemblePtr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ensemblePtr->nsPtr = nsPtr;
|
||||
@@ -690,9 +683,7 @@ Tcl_CreateEnsemble(
|
||||
ensemblePtr->numParameters = 0;
|
||||
ensemblePtr->parameterList = NULL;
|
||||
ensemblePtr->unknownHandler = NULL;
|
||||
ensemblePtr->token = Tcl_NRCreateCommand(interp, name,
|
||||
NsEnsembleImplementationCmd, NsEnsembleImplementationCmdNR,
|
||||
ensemblePtr, DeleteEnsembleConfig);
|
||||
ensemblePtr->token = token;
|
||||
ensemblePtr->next = (EnsembleConfig *) nsPtr->ensembles;
|
||||
nsPtr->ensembles = (Tcl_Ensemble *) ensemblePtr;
|
||||
|
||||
@@ -709,11 +700,52 @@ Tcl_CreateEnsemble(
|
||||
((Command *) ensemblePtr->token)->compileProc = TclCompileEnsemble;
|
||||
}
|
||||
|
||||
if (nameObj != NULL) {
|
||||
TclDecrRefCount(nameObj);
|
||||
}
|
||||
return ensemblePtr->token;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_CreateEnsemble
|
||||
*
|
||||
* Create a simple ensemble attached to the given namespace.
|
||||
*
|
||||
* Deprecated by TclCreateEnsembleInNs.
|
||||
*
|
||||
* Value
|
||||
*
|
||||
* The token for the command created.
|
||||
*
|
||||
* Effect
|
||||
* The ensemble is created and marked for compilation.
|
||||
*
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Command
|
||||
Tcl_CreateEnsemble(
|
||||
Tcl_Interp *interp,
|
||||
const char *name,
|
||||
Tcl_Namespace *namespacePtr,
|
||||
int flags)
|
||||
{
|
||||
Namespace *nsPtr = (Namespace *)namespacePtr, *foundNsPtr, *altNsPtr,
|
||||
*actualNsPtr;
|
||||
const char * simpleName;
|
||||
|
||||
if (nsPtr == NULL) {
|
||||
nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
|
||||
}
|
||||
|
||||
TclGetNamespaceForQualName(interp, name, nsPtr, TCL_CREATE_NS_IF_UNKNOWN,
|
||||
&foundNsPtr, &altNsPtr, &actualNsPtr, &simpleName);
|
||||
return TclCreateEnsembleInNs(interp, simpleName,
|
||||
(Tcl_Namespace *) foundNsPtr, (Tcl_Namespace *) nsPtr, flags);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1885,6 +1917,7 @@ NsEnsembleImplementationCmdNR(
|
||||
|
||||
TclSkipTailcall(interp);
|
||||
Tcl_ListObjGetElements(NULL, copyPtr, ©Objc, ©Objv);
|
||||
((Interp *)interp)->lookupNsPtr = ensemblePtr->nsPtr;
|
||||
return TclNREvalObjv(interp, copyObjc, copyObjv, TCL_EVAL_INVOKE, NULL);
|
||||
}
|
||||
|
||||
@@ -2398,14 +2431,32 @@ MakeCachedEnsembleCommand(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
ClearTable(
|
||||
EnsembleConfig *ensemblePtr)
|
||||
{
|
||||
Tcl_HashTable *hash = &ensemblePtr->subcommandTable;
|
||||
|
||||
if (hash->numEntries != 0) {
|
||||
Tcl_HashSearch search;
|
||||
Tcl_HashEntry *hPtr = Tcl_FirstHashEntry(hash, &search);
|
||||
|
||||
while (hPtr != NULL) {
|
||||
Tcl_Obj *prefixObj = Tcl_GetHashValue(hPtr);
|
||||
Tcl_DecrRefCount(prefixObj);
|
||||
hPtr = Tcl_NextHashEntry(&search);
|
||||
}
|
||||
ckfree((char *) ensemblePtr->subcommandArrayPtr);
|
||||
}
|
||||
Tcl_DeleteHashTable(hash);
|
||||
}
|
||||
|
||||
static void
|
||||
DeleteEnsembleConfig(
|
||||
ClientData clientData)
|
||||
{
|
||||
EnsembleConfig *ensemblePtr = clientData;
|
||||
Namespace *nsPtr = ensemblePtr->nsPtr;
|
||||
Tcl_HashSearch search;
|
||||
Tcl_HashEntry *hEnt;
|
||||
|
||||
/*
|
||||
* Unlink from the ensemble chain if it has not been marked as having been
|
||||
@@ -2439,17 +2490,7 @@ DeleteEnsembleConfig(
|
||||
* Kill the pointer-containing fields.
|
||||
*/
|
||||
|
||||
if (ensemblePtr->subcommandTable.numEntries != 0) {
|
||||
ckfree(ensemblePtr->subcommandArrayPtr);
|
||||
}
|
||||
hEnt = Tcl_FirstHashEntry(&ensemblePtr->subcommandTable, &search);
|
||||
while (hEnt != NULL) {
|
||||
Tcl_Obj *prefixObj = Tcl_GetHashValue(hEnt);
|
||||
|
||||
Tcl_DecrRefCount(prefixObj);
|
||||
hEnt = Tcl_NextHashEntry(&search);
|
||||
}
|
||||
Tcl_DeleteHashTable(&ensemblePtr->subcommandTable);
|
||||
ClearTable(ensemblePtr);
|
||||
if (ensemblePtr->subcmdList != NULL) {
|
||||
Tcl_DecrRefCount(ensemblePtr->subcmdList);
|
||||
}
|
||||
@@ -2505,100 +2546,101 @@ BuildEnsembleConfig(
|
||||
int i, j, isNew;
|
||||
Tcl_HashTable *hash = &ensemblePtr->subcommandTable;
|
||||
Tcl_HashEntry *hPtr;
|
||||
Tcl_Obj *mapDict = ensemblePtr->subcommandDict;
|
||||
Tcl_Obj *subList = ensemblePtr->subcmdList;
|
||||
|
||||
if (hash->numEntries != 0) {
|
||||
/*
|
||||
* Remove pre-existing table.
|
||||
*/
|
||||
ClearTable(ensemblePtr);
|
||||
Tcl_InitHashTable(hash, TCL_STRING_KEYS);
|
||||
|
||||
ckfree(ensemblePtr->subcommandArrayPtr);
|
||||
hPtr = Tcl_FirstHashEntry(hash, &search);
|
||||
while (hPtr != NULL) {
|
||||
Tcl_Obj *prefixObj = Tcl_GetHashValue(hPtr);
|
||||
if (subList) {
|
||||
int subc;
|
||||
Tcl_Obj **subv, *target, *cmdObj, *cmdPrefixObj;
|
||||
char *name;
|
||||
|
||||
Tcl_DecrRefCount(prefixObj);
|
||||
hPtr = Tcl_NextHashEntry(&search);
|
||||
}
|
||||
Tcl_DeleteHashTable(hash);
|
||||
Tcl_InitHashTable(hash, TCL_STRING_KEYS);
|
||||
}
|
||||
/*
|
||||
* There is a list of exactly what subcommands go in the table.
|
||||
* Must determine the target for each.
|
||||
*/
|
||||
|
||||
/*
|
||||
* See if we've got an export list. If so, we will only export exactly
|
||||
* those commands, which may be either implemented by the prefix in the
|
||||
* subcommandDict or mapped directly onto the namespace's commands.
|
||||
*/
|
||||
Tcl_ListObjGetElements(NULL, subList, &subc, &subv);
|
||||
if (subList == mapDict) {
|
||||
/*
|
||||
* Strange case where explicit list of subcommands is same value
|
||||
* as the dict mapping to targets.
|
||||
*/
|
||||
|
||||
if (ensemblePtr->subcmdList != NULL) {
|
||||
Tcl_Obj **subcmdv, *target, *cmdObj, *cmdPrefixObj;
|
||||
int subcmdc;
|
||||
for (i = 0; i < subc; i += 2) {
|
||||
name = TclGetString(subv[i]);
|
||||
hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
|
||||
if (!isNew) {
|
||||
cmdObj = (Tcl_Obj *)Tcl_GetHashValue(hPtr);
|
||||
Tcl_DecrRefCount(cmdObj);
|
||||
}
|
||||
Tcl_SetHashValue(hPtr, subv[i+1]);
|
||||
Tcl_IncrRefCount(subv[i+1]);
|
||||
|
||||
TclListObjGetElements(NULL, ensemblePtr->subcmdList, &subcmdc,
|
||||
&subcmdv);
|
||||
for (i=0 ; i<subcmdc ; i++) {
|
||||
const char *name = TclGetString(subcmdv[i]);
|
||||
name = TclGetString(subv[i+1]);
|
||||
hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
|
||||
if (isNew) {
|
||||
cmdObj = Tcl_NewStringObj(name, -1);
|
||||
cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
|
||||
Tcl_SetHashValue(hPtr, cmdPrefixObj);
|
||||
Tcl_IncrRefCount(cmdPrefixObj);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Usual case where we can freely act on the list and dict. */
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
|
||||
for (i = 0; i < subc; i++) {
|
||||
name = TclGetString(subv[i]);
|
||||
hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
|
||||
if (!isNew) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip non-unique cases.
|
||||
*/
|
||||
/* Lookup target in the dictionary */
|
||||
if (mapDict) {
|
||||
Tcl_DictObjGet(NULL, mapDict, subv[i], &target);
|
||||
if (target) {
|
||||
Tcl_SetHashValue(hPtr, target);
|
||||
Tcl_IncrRefCount(target);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isNew) {
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* target was not in the dictionary so map onto the namespace.
|
||||
* Note in this case that we do not guarantee that the
|
||||
* command is actually there; that is the programmer's
|
||||
* responsibility (or [::unknown] of course).
|
||||
*/
|
||||
cmdObj = Tcl_NewStringObj(name, -1);
|
||||
cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
|
||||
Tcl_SetHashValue(hPtr, cmdPrefixObj);
|
||||
Tcl_IncrRefCount(cmdPrefixObj);
|
||||
}
|
||||
}
|
||||
} else if (mapDict) {
|
||||
/*
|
||||
* No subcmd list, but we do have a mapping dictionary so we should
|
||||
* use the keys of that. Convert the dictionary's contents into the
|
||||
* form required for the ensemble's internal hashtable.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Look in our dictionary (if present) for the command.
|
||||
*/
|
||||
Tcl_DictSearch dictSearch;
|
||||
Tcl_Obj *keyObj, *valueObj;
|
||||
int done;
|
||||
|
||||
if (ensemblePtr->subcommandDict != NULL) {
|
||||
Tcl_DictObjGet(NULL, ensemblePtr->subcommandDict, subcmdv[i],
|
||||
&target);
|
||||
if (target != NULL) {
|
||||
Tcl_SetHashValue(hPtr, target);
|
||||
Tcl_IncrRefCount(target);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Tcl_DictObjFirst(NULL, ensemblePtr->subcommandDict, &dictSearch,
|
||||
&keyObj, &valueObj, &done);
|
||||
while (!done) {
|
||||
char *name = TclGetString(keyObj);
|
||||
|
||||
/*
|
||||
* Not there, so map onto the namespace. Note in this case that we
|
||||
* do not guarantee that the command is actually there; that is
|
||||
* the programmer's responsibility (or [::unknown] of course).
|
||||
*/
|
||||
|
||||
cmdObj = NewNsObj((Tcl_Namespace *) ensemblePtr->nsPtr);
|
||||
if (ensemblePtr->nsPtr->parentPtr != NULL) {
|
||||
Tcl_AppendStringsToObj(cmdObj, "::", name, NULL);
|
||||
} else {
|
||||
Tcl_AppendStringsToObj(cmdObj, name, NULL);
|
||||
}
|
||||
cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
|
||||
Tcl_SetHashValue(hPtr, cmdPrefixObj);
|
||||
Tcl_IncrRefCount(cmdPrefixObj);
|
||||
}
|
||||
} else if (ensemblePtr->subcommandDict != NULL) {
|
||||
/*
|
||||
* No subcmd list, but we do have a mapping dictionary so we should
|
||||
* use the keys of that. Convert the dictionary's contents into the
|
||||
* form required for the ensemble's internal hashtable.
|
||||
*/
|
||||
|
||||
Tcl_DictSearch dictSearch;
|
||||
Tcl_Obj *keyObj, *valueObj;
|
||||
int done;
|
||||
|
||||
Tcl_DictObjFirst(NULL, ensemblePtr->subcommandDict, &dictSearch,
|
||||
&keyObj, &valueObj, &done);
|
||||
while (!done) {
|
||||
const char *name = TclGetString(keyObj);
|
||||
|
||||
hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
|
||||
Tcl_SetHashValue(hPtr, valueObj);
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
Tcl_DictObjNext(&dictSearch, &keyObj, &valueObj, &done);
|
||||
}
|
||||
hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
|
||||
Tcl_SetHashValue(hPtr, valueObj);
|
||||
Tcl_IncrRefCount(valueObj);
|
||||
Tcl_DictObjNext(&dictSearch, &keyObj, &valueObj, &done);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Discover what commands are actually exported by the namespace.
|
||||
@@ -2634,11 +2676,7 @@ BuildEnsembleConfig(
|
||||
if (isNew) {
|
||||
Tcl_Obj *cmdObj, *cmdPrefixObj;
|
||||
|
||||
TclNewObj(cmdObj);
|
||||
Tcl_AppendStringsToObj(cmdObj,
|
||||
ensemblePtr->nsPtr->fullName,
|
||||
(ensemblePtr->nsPtr->parentPtr ? "::" : ""),
|
||||
nsCmdName, NULL);
|
||||
cmdObj = Tcl_NewStringObj(nsCmdName, -1);
|
||||
cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
|
||||
Tcl_SetHashValue(hPtr, cmdPrefixObj);
|
||||
Tcl_IncrRefCount(cmdPrefixObj);
|
||||
|
||||
@@ -1057,7 +1057,6 @@ TclInitSubsystems(void)
|
||||
* mutexes. */
|
||||
TclInitIOSubsystem(); /* Inits a tsd key (noop). */
|
||||
TclInitEncodingSubsystem(); /* Process wide encoding init. */
|
||||
TclpSetInterfaces();
|
||||
TclInitNamespaceSubsystem();/* Register ns obj type (mutexed). */
|
||||
subsystemsInitialized = 1;
|
||||
}
|
||||
|
||||
+296
-619
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -142,7 +142,7 @@ Tcl_GetBoolean(
|
||||
Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
|
||||
}
|
||||
if (code == TCL_OK) {
|
||||
*boolPtr = obj.internalRep.longValue;
|
||||
TclGetBooleanFromObj(NULL, &obj, boolPtr);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
+8
-5
@@ -985,12 +985,18 @@ static void
|
||||
RebuildTable(
|
||||
register Tcl_HashTable *tablePtr) /* Table to enlarge. */
|
||||
{
|
||||
int oldSize, count, index;
|
||||
Tcl_HashEntry **oldBuckets;
|
||||
int count, index, oldSize = tablePtr->numBuckets;
|
||||
Tcl_HashEntry **oldBuckets = tablePtr->buckets;
|
||||
register Tcl_HashEntry **oldChainPtr, **newChainPtr;
|
||||
register Tcl_HashEntry *hPtr;
|
||||
const Tcl_HashKeyType *typePtr;
|
||||
|
||||
/* Avoid outgrowing capability of the memory allocators */
|
||||
if (oldSize > (int)(UINT_MAX / (4 * sizeof(Tcl_HashEntry *)))) {
|
||||
tablePtr->rebuildSize = INT_MAX;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tablePtr->keyType == TCL_STRING_KEYS) {
|
||||
typePtr = &tclStringHashKeyType;
|
||||
} else if (tablePtr->keyType == TCL_ONE_WORD_KEYS) {
|
||||
@@ -1002,9 +1008,6 @@ RebuildTable(
|
||||
typePtr = &tclArrayHashKeyType;
|
||||
}
|
||||
|
||||
oldSize = tablePtr->numBuckets;
|
||||
oldBuckets = tablePtr->buckets;
|
||||
|
||||
/*
|
||||
* Allocate and initialize the new bucket array, and set up hashing
|
||||
* constants for new array size.
|
||||
|
||||
+15
-9
@@ -721,17 +721,18 @@ Tcl_SetStdChannel(
|
||||
{
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
int init = channel ? 1 : -1;
|
||||
switch (type) {
|
||||
case TCL_STDIN:
|
||||
tsdPtr->stdinInitialized = 1;
|
||||
tsdPtr->stdinInitialized = init;
|
||||
tsdPtr->stdinChannel = channel;
|
||||
break;
|
||||
case TCL_STDOUT:
|
||||
tsdPtr->stdoutInitialized = 1;
|
||||
tsdPtr->stdoutInitialized = init;
|
||||
tsdPtr->stdoutChannel = channel;
|
||||
break;
|
||||
case TCL_STDERR:
|
||||
tsdPtr->stderrInitialized = 1;
|
||||
tsdPtr->stderrInitialized = init;
|
||||
tsdPtr->stderrChannel = channel;
|
||||
break;
|
||||
}
|
||||
@@ -768,8 +769,8 @@ Tcl_GetStdChannel(
|
||||
switch (type) {
|
||||
case TCL_STDIN:
|
||||
if (!tsdPtr->stdinInitialized) {
|
||||
tsdPtr->stdinInitialized = -1;
|
||||
tsdPtr->stdinChannel = TclpGetDefaultStdChannel(TCL_STDIN);
|
||||
tsdPtr->stdinInitialized = 1;
|
||||
|
||||
/*
|
||||
* Artificially bump the refcount to ensure that the channel is
|
||||
@@ -781,6 +782,7 @@ Tcl_GetStdChannel(
|
||||
*/
|
||||
|
||||
if (tsdPtr->stdinChannel != NULL) {
|
||||
tsdPtr->stdinInitialized = 1;
|
||||
Tcl_RegisterChannel(NULL, tsdPtr->stdinChannel);
|
||||
}
|
||||
}
|
||||
@@ -788,9 +790,10 @@ Tcl_GetStdChannel(
|
||||
break;
|
||||
case TCL_STDOUT:
|
||||
if (!tsdPtr->stdoutInitialized) {
|
||||
tsdPtr->stdoutInitialized = -1;
|
||||
tsdPtr->stdoutChannel = TclpGetDefaultStdChannel(TCL_STDOUT);
|
||||
tsdPtr->stdoutInitialized = 1;
|
||||
if (tsdPtr->stdoutChannel != NULL) {
|
||||
tsdPtr->stdoutInitialized = 1;
|
||||
Tcl_RegisterChannel(NULL, tsdPtr->stdoutChannel);
|
||||
}
|
||||
}
|
||||
@@ -798,9 +801,10 @@ Tcl_GetStdChannel(
|
||||
break;
|
||||
case TCL_STDERR:
|
||||
if (!tsdPtr->stderrInitialized) {
|
||||
tsdPtr->stderrInitialized = -1;
|
||||
tsdPtr->stderrChannel = TclpGetDefaultStdChannel(TCL_STDERR);
|
||||
tsdPtr->stderrInitialized = 1;
|
||||
if (tsdPtr->stderrChannel != NULL) {
|
||||
tsdPtr->stderrInitialized = 1;
|
||||
Tcl_RegisterChannel(NULL, tsdPtr->stderrChannel);
|
||||
}
|
||||
}
|
||||
@@ -1068,7 +1072,7 @@ CheckForStdChannelsBeingClosed(
|
||||
ChannelState *statePtr = ((Channel *) chan)->state;
|
||||
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
|
||||
|
||||
if (tsdPtr->stdinInitialized
|
||||
if (tsdPtr->stdinInitialized == 1
|
||||
&& tsdPtr->stdinChannel != NULL
|
||||
&& statePtr == ((Channel *)tsdPtr->stdinChannel)->state) {
|
||||
if (statePtr->refCount < 2) {
|
||||
@@ -1076,7 +1080,7 @@ CheckForStdChannelsBeingClosed(
|
||||
tsdPtr->stdinChannel = NULL;
|
||||
return;
|
||||
}
|
||||
} else if (tsdPtr->stdoutInitialized
|
||||
} else if (tsdPtr->stdoutInitialized == 1
|
||||
&& tsdPtr->stdoutChannel != NULL
|
||||
&& statePtr == ((Channel *)tsdPtr->stdoutChannel)->state) {
|
||||
if (statePtr->refCount < 2) {
|
||||
@@ -1084,7 +1088,7 @@ CheckForStdChannelsBeingClosed(
|
||||
tsdPtr->stdoutChannel = NULL;
|
||||
return;
|
||||
}
|
||||
} else if (tsdPtr->stderrInitialized
|
||||
} else if (tsdPtr->stderrInitialized == 1
|
||||
&& tsdPtr->stderrChannel != NULL
|
||||
&& statePtr == ((Channel *)tsdPtr->stderrChannel)->state) {
|
||||
if (statePtr->refCount < 2) {
|
||||
@@ -9032,6 +9036,7 @@ ZeroTransferTimerProc(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED)
|
||||
int
|
||||
TclCopyChannelOld(
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
@@ -9043,6 +9048,7 @@ TclCopyChannelOld(
|
||||
return TclCopyChannel(interp, inChan, outChan, (Tcl_WideInt) toRead,
|
||||
cmdPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
TclCopyChannel(
|
||||
|
||||
+3
-3
@@ -137,7 +137,7 @@ Tcl_PutsObjCmd(
|
||||
chanObjPtr = objv[2];
|
||||
string = objv[3];
|
||||
break;
|
||||
#if TCL_MAJOR_VERSION < 9
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
} else if (strcmp(TclGetString(objv[3]), "nonewline") == 0) {
|
||||
/*
|
||||
* The code below provides backwards compatibility with an old
|
||||
@@ -439,7 +439,7 @@ Tcl_ReadObjCmd(
|
||||
if (i < objc) {
|
||||
if ((TclGetIntFromObj(interp, objv[i], &toRead) != TCL_OK)
|
||||
|| (toRead < 0)) {
|
||||
#if TCL_MAJOR_VERSION < 9
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
/*
|
||||
* The code below provides backwards compatibility with an old
|
||||
* form of the command that is no longer recommended or
|
||||
@@ -454,7 +454,7 @@ Tcl_ReadObjCmd(
|
||||
TclGetString(objv[i])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
|
||||
return TCL_ERROR;
|
||||
#if TCL_MAJOR_VERSION < 9
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
}
|
||||
newline = 1;
|
||||
#endif
|
||||
|
||||
@@ -87,7 +87,7 @@ static const Tcl_ChannelType tclRTransformType = {
|
||||
* layers upon reading from the channel, plus the functions to manage such.
|
||||
*/
|
||||
|
||||
typedef struct _ResultBuffer_ {
|
||||
typedef struct {
|
||||
unsigned char *buf; /* Reference to the buffer area. */
|
||||
int allocated; /* Allocated size of the buffer area. */
|
||||
int used; /* Number of bytes in the buffer,
|
||||
@@ -253,7 +253,7 @@ typedef enum {
|
||||
* sharing problems.
|
||||
*/
|
||||
|
||||
typedef struct ForwardParamBase {
|
||||
typedef struct {
|
||||
int code; /* O: Ok/Fail of the cmd handler */
|
||||
char *msgStr; /* O: Error message for handler failure */
|
||||
int mustFree; /* O: True if msgStr is allocated, false if
|
||||
@@ -298,7 +298,7 @@ typedef struct ForwardingResult ForwardingResult;
|
||||
* General event structure, with reference to operation specific data.
|
||||
*/
|
||||
|
||||
typedef struct ForwardingEvent {
|
||||
typedef struct {
|
||||
Tcl_Event event; /* Basic event data, has to be first item */
|
||||
ForwardingResult *resultPtr;
|
||||
ForwardedOperation op; /* Forwarded driver operation */
|
||||
|
||||
+1
-11
@@ -245,7 +245,7 @@ static Tcl_ThreadDataKey fsDataKey;
|
||||
* code.
|
||||
*/
|
||||
|
||||
typedef struct FsDivertLoad {
|
||||
typedef struct {
|
||||
Tcl_LoadHandle loadHandle;
|
||||
Tcl_FSUnloadFileProc *unloadProcPtr;
|
||||
Tcl_Obj *divertedFile;
|
||||
@@ -412,7 +412,6 @@ Tcl_GetCwd(
|
||||
return Tcl_DStringValue(cwdPtr);
|
||||
}
|
||||
|
||||
/* Obsolete */
|
||||
int
|
||||
Tcl_EvalFile(
|
||||
Tcl_Interp *interp, /* Interpreter in which to process file. */
|
||||
@@ -831,15 +830,6 @@ TclResetFilesystem(void)
|
||||
if (++theFilesystemEpoch == 0) {
|
||||
++theFilesystemEpoch;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Cleans up the win32 API filesystem proc lookup table. This must happen
|
||||
* very late in finalization so that deleting of copied dlls can occur.
|
||||
*/
|
||||
|
||||
TclWinResetInterfaces();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -876,7 +876,8 @@ Tcl_WrongNumArgs(
|
||||
* NULL. */
|
||||
{
|
||||
Tcl_Obj *objPtr;
|
||||
int i, len, elemLen, flags;
|
||||
int i, len, elemLen;
|
||||
char flags;
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
const char *elementStr;
|
||||
|
||||
|
||||
+42
-56
@@ -50,7 +50,7 @@ declare 6 {
|
||||
declare 7 {
|
||||
int TclCopyAndCollapse(int count, const char *src, char *dst)
|
||||
}
|
||||
declare 8 {
|
||||
declare 8 {deprecated {}} {
|
||||
int TclCopyChannelOld(Tcl_Interp *interp, Tcl_Channel inChan,
|
||||
Tcl_Channel outChan, int toRead, Tcl_Obj *cmdPtr)
|
||||
}
|
||||
@@ -73,7 +73,7 @@ declare 11 {
|
||||
declare 12 {
|
||||
void TclDeleteVars(Interp *iPtr, TclVarHashTable *tablePtr)
|
||||
}
|
||||
# Removed in 8.5
|
||||
# Removed in 8.5:
|
||||
#declare 13 {
|
||||
# int TclDoGlob(Tcl_Interp *interp, char *separators,
|
||||
# Tcl_DString *headPtr, char *tail, Tcl_GlobTypeData *types)
|
||||
@@ -88,7 +88,7 @@ declare 14 {
|
||||
declare 16 {
|
||||
void TclExprFloatError(Tcl_Interp *interp, double value)
|
||||
}
|
||||
# Removed in 8.4
|
||||
# Removed in 8.4:
|
||||
#declare 17 {
|
||||
# int TclFileAttrsCmd(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
|
||||
#}
|
||||
@@ -114,7 +114,7 @@ declare 23 {
|
||||
}
|
||||
# Replaced with macro (see tclInt.h) in Tcl 8.5.0, restored in 8.5.10
|
||||
declare 24 {
|
||||
int TclFormatInt(char *buffer, long n)
|
||||
int TclFormatInt(char *buffer, Tcl_WideInt n)
|
||||
}
|
||||
declare 25 {
|
||||
void TclFreePackageInfo(Interp *iPtr)
|
||||
@@ -123,7 +123,7 @@ declare 25 {
|
||||
# declare 26 {
|
||||
# char *TclGetCwd(Tcl_Interp *interp)
|
||||
# }
|
||||
# Removed in 8.5
|
||||
# Removed in 8.5:
|
||||
#declare 27 {
|
||||
# int TclGetDate(char *p, unsigned long now, long zone,
|
||||
# unsigned long *timePtr)
|
||||
@@ -147,7 +147,7 @@ declare 32 {
|
||||
int TclGetFrame(Tcl_Interp *interp, const char *str,
|
||||
CallFrame **framePtrPtr)
|
||||
}
|
||||
# Removed in Tcl 8.5
|
||||
# Removed in 8.5:
|
||||
#declare 33 {
|
||||
# TclCmdProcType TclGetInterpProc(void)
|
||||
#}
|
||||
@@ -160,7 +160,7 @@ declare 34 {
|
||||
# Tcl_Obj *TclGetIndexedScalar(Tcl_Interp *interp, int localIndex,
|
||||
# int flags)
|
||||
#}
|
||||
# Removed in 8.6a2
|
||||
# Removed in 8.6a2:
|
||||
#declare 36 {
|
||||
# int TclGetLong(Tcl_Interp *interp, const char *str, long *longPtr)
|
||||
#}
|
||||
@@ -185,9 +185,9 @@ declare 41 {
|
||||
declare 42 {
|
||||
CONST86 char *TclpGetUserHome(const char *name, Tcl_DString *bufferPtr)
|
||||
}
|
||||
# Removed in Tcl 8.5a2
|
||||
# Removed in 8.5a2:
|
||||
#declare 43 {
|
||||
# int TclGlobalInvoke(Tcl_Interp *interp, int argc, CONST84 char **argv,
|
||||
# int TclGlobalInvoke(Tcl_Interp *interp, int argc, const char **argv,
|
||||
# int flags)
|
||||
#}
|
||||
declare 44 {
|
||||
@@ -220,14 +220,14 @@ declare 50 {
|
||||
declare 51 {
|
||||
int TclInterpInit(Tcl_Interp *interp)
|
||||
}
|
||||
# Removed in Tcl 8.5a2
|
||||
# Removed in 8.5a2:
|
||||
#declare 52 {
|
||||
# int TclInvoke(Tcl_Interp *interp, int argc, CONST84 char **argv,
|
||||
# int TclInvoke(Tcl_Interp *interp, int argc, const char **argv,
|
||||
# int flags)
|
||||
#}
|
||||
declare 53 {
|
||||
int TclInvokeObjectCommand(ClientData clientData, Tcl_Interp *interp,
|
||||
int argc, CONST84 char **argv)
|
||||
int argc, const char **argv)
|
||||
}
|
||||
declare 54 {
|
||||
int TclInvokeStringCommand(ClientData clientData, Tcl_Interp *interp,
|
||||
@@ -273,7 +273,7 @@ declare 64 {
|
||||
int TclObjInvoke(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
|
||||
int flags)
|
||||
}
|
||||
# Removed in Tcl 8.5a2
|
||||
# Removed in 8.5a2:
|
||||
#declare 65 {
|
||||
# int TclObjInvokeGlobal(Tcl_Interp *interp, int objc,
|
||||
# Tcl_Obj *const objv[], int flags)
|
||||
@@ -313,9 +313,7 @@ declare 75 {
|
||||
declare 76 {
|
||||
unsigned long TclpGetSeconds(void)
|
||||
}
|
||||
|
||||
# deprecated
|
||||
declare 77 {
|
||||
declare 77 {deprecated {}} {
|
||||
void TclpGetTime(Tcl_Time *time)
|
||||
}
|
||||
# Removed in 8.6:
|
||||
@@ -357,7 +355,7 @@ declare 81 {
|
||||
# declare 87 {
|
||||
# void TclPlatformInit(Tcl_Interp *interp)
|
||||
# }
|
||||
declare 88 {
|
||||
declare 88 {deprecated {}} {
|
||||
char *TclPrecTraceProc(ClientData clientData, Tcl_Interp *interp,
|
||||
const char *name1, const char *name2, int flags)
|
||||
}
|
||||
@@ -380,7 +378,7 @@ declare 92 {
|
||||
declare 93 {
|
||||
void TclProcDeleteProc(ClientData clientData)
|
||||
}
|
||||
# Removed in Tcl 8.5:
|
||||
# Removed in 8.5:
|
||||
#declare 94 {
|
||||
# int TclProcInterpProc(ClientData clientData, Tcl_Interp *interp,
|
||||
# int argc, const char **argv)
|
||||
@@ -419,7 +417,7 @@ declare 103 {
|
||||
int TclSockGetPort(Tcl_Interp *interp, const char *str, const char *proto,
|
||||
int *portPtr)
|
||||
}
|
||||
declare 104 {
|
||||
declare 104 {deprecated {}} {
|
||||
int TclSockMinimumBuffersOld(int sock, int size)
|
||||
}
|
||||
# Replaced by Tcl_FSStat in 8.4:
|
||||
@@ -455,26 +453,26 @@ declare 111 {
|
||||
Tcl_ResolveCompiledVarProc *compiledVarProc)
|
||||
}
|
||||
declare 112 {
|
||||
int Tcl_AppendExportList(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
int TclAppendExportList(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
Tcl_Obj *objPtr)
|
||||
}
|
||||
declare 113 {
|
||||
Tcl_Namespace *Tcl_CreateNamespace(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Namespace *TclCreateNamespace(Tcl_Interp *interp, const char *name,
|
||||
ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc)
|
||||
}
|
||||
declare 114 {
|
||||
void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr)
|
||||
void TclDeleteNamespace(Tcl_Namespace *nsPtr)
|
||||
}
|
||||
declare 115 {
|
||||
int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
int TclExport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
const char *pattern, int resetListFirst)
|
||||
}
|
||||
declare 116 {
|
||||
Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Command TclFindCommand(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Namespace *contextNsPtr, int flags)
|
||||
}
|
||||
declare 117 {
|
||||
Tcl_Namespace *Tcl_FindNamespace(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Namespace *TclFindNamespace(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Namespace *contextNsPtr, int flags)
|
||||
}
|
||||
declare 118 {
|
||||
@@ -490,28 +488,28 @@ declare 120 {
|
||||
Tcl_Namespace *contextNsPtr, int flags)
|
||||
}
|
||||
declare 121 {
|
||||
int Tcl_ForgetImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
int TclForgetImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
const char *pattern)
|
||||
}
|
||||
declare 122 {
|
||||
Tcl_Command Tcl_GetCommandFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
|
||||
Tcl_Command TclGetCommandFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
|
||||
}
|
||||
declare 123 {
|
||||
void Tcl_GetCommandFullName(Tcl_Interp *interp, Tcl_Command command,
|
||||
void TclGetCommandFullName(Tcl_Interp *interp, Tcl_Command command,
|
||||
Tcl_Obj *objPtr)
|
||||
}
|
||||
declare 124 {
|
||||
Tcl_Namespace *Tcl_GetCurrentNamespace(Tcl_Interp *interp)
|
||||
Tcl_Namespace *TclGetCurrentNamespace_(Tcl_Interp *interp)
|
||||
}
|
||||
declare 125 {
|
||||
Tcl_Namespace *Tcl_GetGlobalNamespace(Tcl_Interp *interp)
|
||||
Tcl_Namespace *TclGetGlobalNamespace_(Tcl_Interp *interp)
|
||||
}
|
||||
declare 126 {
|
||||
void Tcl_GetVariableFullName(Tcl_Interp *interp, Tcl_Var variable,
|
||||
Tcl_Obj *objPtr)
|
||||
}
|
||||
declare 127 {
|
||||
int Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
int TclImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
const char *pattern, int allowOverwrite)
|
||||
}
|
||||
declare 128 {
|
||||
@@ -532,7 +530,7 @@ declare 131 {
|
||||
declare 132 {
|
||||
int TclpHasSockets(Tcl_Interp *interp)
|
||||
}
|
||||
declare 133 {
|
||||
declare 133 {deprecated {}} {
|
||||
struct tm *TclpGetDate(const time_t *time, int useGMT)
|
||||
}
|
||||
# Removed in 8.5
|
||||
@@ -550,7 +548,7 @@ declare 133 {
|
||||
# int TclpChdir(const char *dirName)
|
||||
#}
|
||||
declare 138 {
|
||||
CONST84_RETURN char *TclGetEnv(const char *name, Tcl_DString *valuePtr)
|
||||
const char *TclGetEnv(const char *name, Tcl_DString *valuePtr)
|
||||
}
|
||||
#declare 139 {
|
||||
# int TclpLoadFile(Tcl_Interp *interp, char *fileName, char *sym1,
|
||||
@@ -562,7 +560,7 @@ declare 138 {
|
||||
#}
|
||||
# This is used by TclX, but should otherwise be considered private
|
||||
declare 141 {
|
||||
CONST84_RETURN char *TclpGetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr)
|
||||
const char *TclpGetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr)
|
||||
}
|
||||
declare 142 {
|
||||
int TclSetByteCodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
@@ -625,12 +623,10 @@ declare 156 {
|
||||
declare 157 {
|
||||
Var *TclVarTraceExists(Tcl_Interp *interp, const char *varName)
|
||||
}
|
||||
# REMOVED (except from stub table) - use public Tcl_SetStartupScript()
|
||||
declare 158 {
|
||||
declare 158 {deprecated {use public Tcl_SetStartupScript()}} {
|
||||
void TclSetStartupScriptFileName(const char *filename)
|
||||
}
|
||||
# REMOVED (except from stub table) - use public Tcl_GetStartupScript()
|
||||
declare 159 {
|
||||
declare 159 {deprecated {use public Tcl_GetStartupScript()}} {
|
||||
const char *TclGetStartupScriptFileName(void)
|
||||
}
|
||||
#declare 160 {
|
||||
@@ -676,13 +672,10 @@ declare 166 {
|
||||
int index, Tcl_Obj *valuePtr)
|
||||
}
|
||||
|
||||
# VFS-aware versions of Tcl*StartupScriptFileName (158 and 159 above)
|
||||
# REMOVED (except from stub table) - use public Tcl_SetStartupScript()
|
||||
declare 167 {
|
||||
declare 167 {deprecated {use public Tcl_SetStartupScript()}} {
|
||||
void TclSetStartupScriptPath(Tcl_Obj *pathPtr)
|
||||
}
|
||||
# REMOVED (except from stub table) - use public Tcl_GetStartupScript()
|
||||
declare 168 {
|
||||
declare 168 {deprecated {use public Tcl_GetStartupScript()}} {
|
||||
Tcl_Obj *TclGetStartupScriptPath(void)
|
||||
}
|
||||
# variant of Tcl_UtfNCmp that takes n as bytes, not chars
|
||||
@@ -730,12 +723,11 @@ declare 177 {
|
||||
void TclVarErrMsg(Tcl_Interp *interp, const char *part1, const char *part2,
|
||||
const char *operation, const char *reason)
|
||||
}
|
||||
# TIP 338 made these public - now declared in tcl.h too
|
||||
declare 178 {
|
||||
void Tcl_SetStartupScript(Tcl_Obj *pathPtr, const char *encodingName)
|
||||
void TclSetStartupScript(Tcl_Obj *pathPtr, const char *encodingName)
|
||||
}
|
||||
declare 179 {
|
||||
Tcl_Obj *Tcl_GetStartupScript(const char **encodingNamePtr)
|
||||
Tcl_Obj *TclGetStartupScript(const char **encodingNamePtr)
|
||||
}
|
||||
|
||||
# REMOVED
|
||||
@@ -748,12 +740,10 @@ declare 179 {
|
||||
# const char *file, int line)
|
||||
#}
|
||||
|
||||
# TclpGmtime and TclpLocaltime promoted to the generic interface from unix
|
||||
|
||||
declare 182 {
|
||||
declare 182 {deprecated {}} {
|
||||
struct tm *TclpLocaltime(const time_t *clock)
|
||||
}
|
||||
declare 183 {
|
||||
declare 183 {deprecated {}} {
|
||||
struct tm *TclpGmtime(const time_t *clock)
|
||||
}
|
||||
|
||||
@@ -937,10 +927,7 @@ declare 234 {
|
||||
declare 235 {
|
||||
void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr)
|
||||
}
|
||||
|
||||
|
||||
# TIP 337 made this one public
|
||||
declare 236 {
|
||||
declare 236 {deprecated {use Tcl_BackgroundException}} {
|
||||
void TclBackgroundException(Tcl_Interp *interp, int code)
|
||||
}
|
||||
|
||||
@@ -1090,7 +1077,7 @@ declare 9 win {
|
||||
declare 10 win {
|
||||
Tcl_DirEntry *TclpReaddir(DIR *dir)
|
||||
}
|
||||
# Removed in 8.3.1 (for Win32s only)
|
||||
# Removed in 8.3.1 (for Win32s only):
|
||||
#declare 10 win {
|
||||
# int TclWinSynchSpawn(void *args, int type, void **trans, Tcl_Pid *pidPtr)
|
||||
#}
|
||||
@@ -1140,7 +1127,6 @@ declare 19 win {
|
||||
declare 20 win {
|
||||
void TclWinAddProcess(HANDLE hProcess, DWORD id)
|
||||
}
|
||||
# new for 8.4.20+/8.5.12+
|
||||
declare 21 win {
|
||||
char *TclpInetNtoa(struct in_addr addr)
|
||||
}
|
||||
|
||||
+164
-105
@@ -160,13 +160,13 @@ typedef struct Tcl_ResolvedVarInfo {
|
||||
} Tcl_ResolvedVarInfo;
|
||||
|
||||
typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp *interp,
|
||||
CONST84 char *name, int length, Tcl_Namespace *context,
|
||||
const char *name, int length, Tcl_Namespace *context,
|
||||
Tcl_ResolvedVarInfo **rPtr);
|
||||
|
||||
typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp, CONST84 char *name,
|
||||
typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Namespace *context, int flags, Tcl_Var *rPtr);
|
||||
|
||||
typedef int (Tcl_ResolveCmdProc)(Tcl_Interp *interp, CONST84 char *name,
|
||||
typedef int (Tcl_ResolveCmdProc)(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Namespace *context, int flags, Tcl_Command *rPtr);
|
||||
|
||||
typedef struct Tcl_ResolverInfo {
|
||||
@@ -265,7 +265,7 @@ typedef struct Namespace {
|
||||
* strings; values have type (Namespace *). If
|
||||
* NULL, there are no children. */
|
||||
#endif
|
||||
size_t nsId; /* Unique id for the namespace. */
|
||||
unsigned long nsId; /* Unique id for the namespace. */
|
||||
Tcl_Interp *interp; /* The interpreter containing this
|
||||
* namespace. */
|
||||
int flags; /* OR-ed combination of the namespace status
|
||||
@@ -274,7 +274,7 @@ typedef struct Namespace {
|
||||
* frames for this namespace that are on the
|
||||
* Tcl call stack. The namespace won't be
|
||||
* freed until activationCount becomes zero. */
|
||||
int refCount; /* Count of references by namespaceName
|
||||
unsigned int refCount; /* Count of references by namespaceName
|
||||
* objects. The namespace can't be freed until
|
||||
* refCount becomes zero. */
|
||||
Tcl_HashTable cmdTable; /* Contains all the commands currently
|
||||
@@ -299,12 +299,12 @@ typedef struct Namespace {
|
||||
* registered using "namespace export". */
|
||||
int maxExportPatterns; /* Mumber of export patterns for which space
|
||||
* is currently allocated. */
|
||||
size_t cmdRefEpoch; /* Incremented if a newly added command
|
||||
unsigned int cmdRefEpoch; /* Incremented if a newly added command
|
||||
* shadows a command for which this namespace
|
||||
* has already cached a Command* pointer; this
|
||||
* causes all its cached Command* pointers to
|
||||
* be invalidated. */
|
||||
size_t resolverEpoch; /* Incremented whenever (a) the name
|
||||
unsigned int resolverEpoch; /* Incremented whenever (a) the name
|
||||
* resolution rules change for this namespace
|
||||
* or (b) a newly added command shadows a
|
||||
* command that is compiled to bytecodes. This
|
||||
@@ -331,7 +331,7 @@ typedef struct Namespace {
|
||||
* LookupCompiledLocal to resolve variable
|
||||
* references within the namespace at compile
|
||||
* time. */
|
||||
size_t exportLookupEpoch; /* Incremented whenever a command is added to
|
||||
unsigned int exportLookupEpoch; /* Incremented whenever a command is added to
|
||||
* a namespace, removed from a namespace or
|
||||
* the exports of a namespace are changed.
|
||||
* Allows TIP#112-driven command lists to be
|
||||
@@ -426,13 +426,13 @@ struct NamespacePathEntry {
|
||||
*/
|
||||
|
||||
typedef struct EnsembleConfig {
|
||||
Namespace *nsPtr; /* The namspace backing this ensemble up. */
|
||||
Namespace *nsPtr; /* The namespace backing this ensemble up. */
|
||||
Tcl_Command token; /* The token for the command that provides
|
||||
* ensemble support for the namespace, or NULL
|
||||
* if the command has been deleted (or never
|
||||
* existed; the global namespace never has an
|
||||
* ensemble command.) */
|
||||
size_t epoch; /* The epoch at which this ensemble's table of
|
||||
unsigned int epoch; /* The epoch at which this ensemble's table of
|
||||
* exported commands is valid. */
|
||||
char **subcommandArrayPtr; /* Array of ensemble subcommand names. At all
|
||||
* consistent points, this will have the same
|
||||
@@ -545,7 +545,7 @@ typedef struct CommandTrace {
|
||||
struct CommandTrace *nextPtr;
|
||||
/* Next in list of traces associated with a
|
||||
* particular command. */
|
||||
int refCount; /* Used to ensure this structure is not
|
||||
size_t refCount; /* Used to ensure this structure is not
|
||||
* deleted too early. Keeps track of how many
|
||||
* pieces of code have a pointer to this
|
||||
* structure. */
|
||||
@@ -618,7 +618,7 @@ typedef struct Var {
|
||||
|
||||
typedef struct VarInHash {
|
||||
Var var;
|
||||
int refCount; /* Counts number of active uses of this
|
||||
unsigned int refCount; /* Counts number of active uses of this
|
||||
* variable: 1 for the entry in the hash
|
||||
* table, 1 for each additional variable whose
|
||||
* linkPtr points here, 1 for each nested
|
||||
@@ -950,7 +950,7 @@ typedef struct CompiledLocal {
|
||||
typedef struct Proc {
|
||||
struct Interp *iPtr; /* Interpreter for which this command is
|
||||
* defined. */
|
||||
int refCount; /* Reference count: 1 if still present in
|
||||
unsigned int refCount; /* Reference count: 1 if still present in
|
||||
* command table plus 1 for each call to the
|
||||
* procedure that is currently active. This
|
||||
* structure can be freed when refCount
|
||||
@@ -1067,7 +1067,7 @@ typedef struct AssocData {
|
||||
*/
|
||||
|
||||
typedef struct LocalCache {
|
||||
int refCount;
|
||||
unsigned int refCount;
|
||||
int numVars;
|
||||
Tcl_Obj *varName0;
|
||||
} LocalCache;
|
||||
@@ -1229,7 +1229,7 @@ typedef struct CmdFrame {
|
||||
typedef struct CFWord {
|
||||
CmdFrame *framePtr; /* CmdFrame to access. */
|
||||
int word; /* Index of the word in the command. */
|
||||
int refCount; /* Number of times the word is on the
|
||||
unsigned int refCount; /* Number of times the word is on the
|
||||
* stack. */
|
||||
} CFWord;
|
||||
|
||||
@@ -1492,11 +1492,11 @@ typedef struct LiteralEntry {
|
||||
* NULL if end of chain. */
|
||||
Tcl_Obj *objPtr; /* Points to Tcl object that holds the
|
||||
* literal's bytes and length. */
|
||||
int refCount; /* If in an interpreter's global literal
|
||||
size_t refCount; /* If in an interpreter's global literal
|
||||
* table, the number of ByteCode structures
|
||||
* that share the literal object; the literal
|
||||
* entry can be freed when refCount drops to
|
||||
* 0. If in a local literal table, -1. */
|
||||
* 0. If in a local literal table, (size_t)-1. */
|
||||
Namespace *nsPtr; /* Namespace in which this literal is used. We
|
||||
* try to avoid sharing literal non-FQ command
|
||||
* names among different namespaces to reduce
|
||||
@@ -1516,7 +1516,7 @@ typedef struct LiteralTable {
|
||||
* table. */
|
||||
int rebuildSize; /* Enlarge table when numEntries gets to be
|
||||
* this large. */
|
||||
int mask; /* Mask value used in hashing function. */
|
||||
unsigned int mask; /* Mask value used in hashing function. */
|
||||
} LiteralTable;
|
||||
|
||||
/*
|
||||
@@ -1634,12 +1634,12 @@ typedef struct Command {
|
||||
* recreated). */
|
||||
Namespace *nsPtr; /* Points to the namespace containing this
|
||||
* command. */
|
||||
int refCount; /* 1 if in command hashtable plus 1 for each
|
||||
unsigned int refCount; /* 1 if in command hashtable plus 1 for each
|
||||
* reference from a CmdName Tcl object
|
||||
* representing a command's name in a ByteCode
|
||||
* instruction sequence. This structure can be
|
||||
* freed when refCount becomes zero. */
|
||||
size_t cmdEpoch; /* Incremented to invalidate any references
|
||||
unsigned int cmdEpoch; /* Incremented to invalidate any references
|
||||
* that point to this command when it is
|
||||
* renamed, deleted, hidden, or exposed. */
|
||||
CompileProc *compileProc; /* Procedure called to compile command. NULL
|
||||
@@ -1826,7 +1826,7 @@ typedef struct Interp {
|
||||
* unused space in interp was repurposed for
|
||||
* pluggable bytecode optimizers. The core
|
||||
* contains one optimizer, which can be
|
||||
* selectively overriden by extensions. */
|
||||
* selectively overridden by extensions. */
|
||||
} extra;
|
||||
|
||||
/*
|
||||
@@ -1862,7 +1862,7 @@ typedef struct Interp {
|
||||
* See Tcl_AppendResult code for details.
|
||||
*/
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
char *appendResult; /* Storage space for results generated by
|
||||
* Tcl_AppendResult. Ckalloc-ed. NULL means
|
||||
* not yet allocated. */
|
||||
@@ -1936,11 +1936,13 @@ typedef struct Interp {
|
||||
* string. Returned by Tcl_ObjSetVar2 when
|
||||
* variable traces change a variable in a
|
||||
* gross way. */
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
char resultSpace[TCL_RESULT_SIZE+1];
|
||||
#if TCL_MAJOR_VERSION < 9
|
||||
# if !defined(TCL_NO_DEPRECATED)
|
||||
char resultSpace[TCL_DSTRING_STATIC_SIZE+1];
|
||||
/* Static space holding small results. */
|
||||
#else
|
||||
char resultSpaceDontUse[TCL_RESULT_SIZE+1];
|
||||
# else
|
||||
char resultSpaceDontUse[TCL_DSTRING_STATIC_SIZE+1];
|
||||
# endif
|
||||
#endif
|
||||
Tcl_Obj *objResultPtr; /* If the last command returned an object
|
||||
* result, this points to it. Should not be
|
||||
@@ -2251,7 +2253,7 @@ typedef struct Interp {
|
||||
* use the rand() or srand() functions.
|
||||
* SAFE_INTERP: Non zero means that the current interp is a safe
|
||||
* interp (i.e. it has only the safe commands installed,
|
||||
* less priviledge than a regular interp).
|
||||
* less privilege than a regular interp).
|
||||
* INTERP_DEBUG_FRAME: Used for switching on various extra interpreter
|
||||
* debug/info mechanisms (e.g. info frame eval/uplevel
|
||||
* tracing) which are performance intensive.
|
||||
@@ -2384,7 +2386,7 @@ typedef enum TclEolTranslation {
|
||||
*/
|
||||
|
||||
typedef struct List {
|
||||
int refCount;
|
||||
unsigned int refCount;
|
||||
int maxElemCount; /* Total number of element array slots. */
|
||||
int elemCount; /* Current number of list elements. */
|
||||
int canonicalFlag; /* Set if the string representation was
|
||||
@@ -2392,7 +2394,7 @@ typedef struct List {
|
||||
* be ignored if there is no string rep at
|
||||
* all.*/
|
||||
Tcl_Obj *elements; /* First list element; the struct is grown to
|
||||
* accomodate all elements. */
|
||||
* accommodate all elements. */
|
||||
} List;
|
||||
|
||||
#define LIST_MAX \
|
||||
@@ -2445,40 +2447,46 @@ typedef struct List {
|
||||
#define TCL_EACH_COLLECT 1 /* Collect iteration result like [lmap] */
|
||||
|
||||
/*
|
||||
* Macros providing a faster path to integers: Tcl_GetLongFromObj,
|
||||
* Tcl_GetIntFromObj and TclGetIntForIndex.
|
||||
* Macros providing a faster path to booleans and integers:
|
||||
* Tcl_GetBooleanFromObj, Tcl_GetLongFromObj, Tcl_GetIntFromObj
|
||||
* and TclGetIntForIndex.
|
||||
*
|
||||
* WARNING: these macros eval their args more than once.
|
||||
*/
|
||||
|
||||
#define TclGetBooleanFromObj(interp, objPtr, boolPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(boolPtr) = ((objPtr)->internalRep.wideValue!=0), TCL_OK) \
|
||||
: ((objPtr)->typePtr == &tclBooleanType) \
|
||||
? (*(boolPtr) = ((objPtr)->internalRep.longValue!=0), TCL_OK) \
|
||||
: Tcl_GetBooleanFromObj((interp), (objPtr), (boolPtr)))
|
||||
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
#define TclGetLongFromObj(interp, objPtr, longPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? ((*(longPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
|
||||
? ((*(longPtr) = (objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
: Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
|
||||
|
||||
#if (LONG_MAX == INT_MAX)
|
||||
#define TclGetIntFromObj(interp, objPtr, intPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
|
||||
: Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
|
||||
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
|
||||
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
|
||||
#else
|
||||
#define TclGetLongFromObj(interp, objPtr, longPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(ULONG_MAX) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(ULONG_MAX)) \
|
||||
? ((*(longPtr) = (long)(objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
: Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
|
||||
#endif
|
||||
|
||||
#define TclGetIntFromObj(interp, objPtr, intPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.longValue >= -(Tcl_WideInt)(UINT_MAX) \
|
||||
&& (objPtr)->internalRep.longValue <= (Tcl_WideInt)(UINT_MAX)) \
|
||||
? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
|
||||
&& (objPtr)->internalRep.wideValue >= -(Tcl_WideInt)(UINT_MAX) \
|
||||
&& (objPtr)->internalRep.wideValue <= (Tcl_WideInt)(UINT_MAX)) \
|
||||
? ((*(intPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
: Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
|
||||
#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType \
|
||||
&& (objPtr)->internalRep.longValue >= INT_MIN \
|
||||
&& (objPtr)->internalRep.longValue <= INT_MAX) \
|
||||
? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
|
||||
&& (objPtr)->internalRep.wideValue >= INT_MIN \
|
||||
&& (objPtr)->internalRep.wideValue <= INT_MAX) \
|
||||
? ((*(idxPtr) = (int)(objPtr)->internalRep.wideValue), TCL_OK) \
|
||||
: TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macro used to save a function call for common uses of
|
||||
@@ -2488,21 +2496,11 @@ typedef struct List {
|
||||
* Tcl_WideInt *wideIntPtr);
|
||||
*/
|
||||
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
|
||||
(((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(wideIntPtr) = (Tcl_WideInt) \
|
||||
((objPtr)->internalRep.longValue), TCL_OK) : \
|
||||
((objPtr)->internalRep.wideValue), TCL_OK) : \
|
||||
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
|
||||
#else /* !TCL_WIDE_INT_IS_LONG */
|
||||
#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
|
||||
(((objPtr)->typePtr == &tclWideIntType) \
|
||||
? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) : \
|
||||
((objPtr)->typePtr == &tclIntType) \
|
||||
? (*(wideIntPtr) = (Tcl_WideInt) \
|
||||
((objPtr)->internalRep.longValue), TCL_OK) : \
|
||||
Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
|
||||
#endif /* TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
/*
|
||||
* Flag values for TclTraceDictPath().
|
||||
@@ -2514,13 +2512,13 @@ typedef struct List {
|
||||
* tip of the path, so duplication of shared objects should be done along the
|
||||
* way.
|
||||
*
|
||||
* DICT_PATH_EXISTS indicates that we are performing an existance test and a
|
||||
* DICT_PATH_EXISTS indicates that we are performing an existence test and a
|
||||
* lookup failure should therefore not be an error. If (and only if) this flag
|
||||
* is set, TclTraceDictPath() will return the special value
|
||||
* DICT_PATH_NON_EXISTENT if the path is not traceable.
|
||||
*
|
||||
* DICT_PATH_CREATE (which also requires the DICT_PATH_UPDATE bit to be set)
|
||||
* indicates that we are to create non-existant dictionaries on the path.
|
||||
* indicates that we are to create non-existent dictionaries on the path.
|
||||
*/
|
||||
|
||||
#define DICT_PATH_READ 0
|
||||
@@ -2626,7 +2624,7 @@ typedef Tcl_ObjCmdProc *TclObjCmdProcType;
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, size_t *lengthPtr,
|
||||
typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, unsigned int *lengthPtr,
|
||||
Tcl_Encoding *encodingPtr);
|
||||
|
||||
/*
|
||||
@@ -2638,9 +2636,9 @@ typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, size_t *lengthPtr,
|
||||
*/
|
||||
|
||||
typedef struct ProcessGlobalValue {
|
||||
size_t epoch; /* Epoch counter to detect changes in the
|
||||
unsigned int epoch; /* Epoch counter to detect changes in the
|
||||
* master value. */
|
||||
size_t numBytes; /* Length of the master string. */
|
||||
unsigned int numBytes; /* Length of the master string. */
|
||||
char *value; /* The master string value. */
|
||||
Tcl_Encoding encoding; /* system encoding when master string was
|
||||
* initialized. */
|
||||
@@ -2728,9 +2726,6 @@ MODULE_SCOPE const Tcl_ObjType tclDictType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclProcBodyType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclStringType;
|
||||
MODULE_SCOPE const Tcl_ObjType tclEnsembleCmdType;
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
MODULE_SCOPE const Tcl_ObjType tclWideIntType;
|
||||
#endif
|
||||
MODULE_SCOPE const Tcl_ObjType tclRegexpType;
|
||||
MODULE_SCOPE Tcl_ObjType tclCmdNameType;
|
||||
|
||||
@@ -2780,6 +2775,7 @@ MODULE_SCOPE Tcl_ObjCmdProc TclNRForObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRIfObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRLmapCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRPackageObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRSourceObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRSubstObjCmd;
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclNRSwitchObjCmd;
|
||||
@@ -2908,6 +2904,8 @@ MODULE_SCOPE int TclChanCaughtErrorBypass(Tcl_Interp *interp,
|
||||
Tcl_Channel chan);
|
||||
MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd;
|
||||
MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble;
|
||||
MODULE_SCOPE int TclCompareTwoNumbers(Tcl_Obj *valuePtr,
|
||||
Tcl_Obj *value2Ptr);
|
||||
MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num,
|
||||
int *loc);
|
||||
MODULE_SCOPE void TclContinuationsEnterDerived(Tcl_Obj *objPtr,
|
||||
@@ -2917,12 +2915,25 @@ MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr,
|
||||
Tcl_Obj *originObjPtr);
|
||||
MODULE_SCOPE int TclConvertElement(const char *src, int length,
|
||||
char *dst, int flags);
|
||||
MODULE_SCOPE Tcl_Command TclCreateObjCommandInNs (
|
||||
Tcl_Interp *interp,
|
||||
const char *cmdName,
|
||||
Tcl_Namespace *nsPtr,
|
||||
Tcl_ObjCmdProc *proc,
|
||||
ClientData clientData,
|
||||
Tcl_CmdDeleteProc *deleteProc);
|
||||
MODULE_SCOPE Tcl_Command TclCreateEnsembleInNs(
|
||||
Tcl_Interp *interp,
|
||||
const char *name,
|
||||
Tcl_Namespace *nameNamespacePtr,
|
||||
Tcl_Namespace *ensembleNamespacePtr,
|
||||
int flags);
|
||||
MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr);
|
||||
MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp,
|
||||
const char *dict, int dictLength,
|
||||
const char **elementPtr, const char **nextPtr,
|
||||
int *sizePtr, int *literalPtr);
|
||||
/* TIP #280 - Modified token based evulation, with line information. */
|
||||
/* TIP #280 - Modified token based evaluation, with line information. */
|
||||
MODULE_SCOPE int TclEvalEx(Tcl_Interp *interp, const char *script,
|
||||
int numBytes, int flags, int line,
|
||||
int *clNextOuter, const char *outerScript);
|
||||
@@ -2945,6 +2956,8 @@ MODULE_SCOPE char * TclDStringAppendDString(Tcl_DString *dsPtr,
|
||||
MODULE_SCOPE Tcl_Obj * TclDStringToObj(Tcl_DString *dsPtr);
|
||||
MODULE_SCOPE Tcl_Obj *const * TclFetchEnsembleRoot(Tcl_Interp *interp,
|
||||
Tcl_Obj *const *objv, int objc, int *objcPtr);
|
||||
MODULE_SCOPE Tcl_Namespace * TclEnsureNamespace(Tcl_Interp *interp,
|
||||
Tcl_Namespace *namespacePtr);
|
||||
MODULE_SCOPE void TclFinalizeAllocSubsystem(void);
|
||||
MODULE_SCOPE void TclFinalizeAsync(void);
|
||||
MODULE_SCOPE void TclFinalizeDoubleConversion(void);
|
||||
@@ -2971,6 +2984,15 @@ MODULE_SCOPE double TclFloor(const mp_int *a);
|
||||
MODULE_SCOPE void TclFormatNaN(double value, char *buffer);
|
||||
MODULE_SCOPE int TclFSFileAttrIndex(Tcl_Obj *pathPtr,
|
||||
const char *attributeName, int *indexPtr);
|
||||
MODULE_SCOPE Tcl_Command TclNRCreateCommandInNs (
|
||||
Tcl_Interp *interp,
|
||||
const char *cmdName,
|
||||
Tcl_Namespace *nsPtr,
|
||||
Tcl_ObjCmdProc *proc,
|
||||
Tcl_ObjCmdProc *nreProc,
|
||||
ClientData clientData,
|
||||
Tcl_CmdDeleteProc *deleteProc);
|
||||
|
||||
MODULE_SCOPE int TclNREvalFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
|
||||
const char *encodingName);
|
||||
MODULE_SCOPE void TclFSUnloadTempFile(Tcl_LoadHandle loadHandle);
|
||||
@@ -3097,7 +3119,7 @@ MODULE_SCOPE int TclpThreadCreate(Tcl_ThreadId *idPtr,
|
||||
int stackSize, int flags);
|
||||
MODULE_SCOPE int TclpFindVariable(const char *name, int *lengthPtr);
|
||||
MODULE_SCOPE void TclpInitLibraryPath(char **valuePtr,
|
||||
size_t *lengthPtr, Tcl_Encoding *encodingPtr);
|
||||
unsigned int *lengthPtr, Tcl_Encoding *encodingPtr);
|
||||
MODULE_SCOPE void TclpInitLock(void);
|
||||
MODULE_SCOPE void TclpInitPlatform(void);
|
||||
MODULE_SCOPE void TclpInitUnlock(void);
|
||||
@@ -3131,7 +3153,6 @@ MODULE_SCOPE Tcl_Obj * TclPathPart(Tcl_Interp *interp, Tcl_Obj *pathPtr,
|
||||
Tcl_PathPart portion);
|
||||
MODULE_SCOPE char * TclpReadlink(const char *fileName,
|
||||
Tcl_DString *linkPtr);
|
||||
MODULE_SCOPE void TclpSetInterfaces(void);
|
||||
MODULE_SCOPE void TclpSetVariables(Tcl_Interp *interp);
|
||||
MODULE_SCOPE void * TclThreadStorageKeyGet(Tcl_ThreadDataKey *keyPtr);
|
||||
MODULE_SCOPE void TclThreadStorageKeySet(Tcl_ThreadDataKey *keyPtr,
|
||||
@@ -3145,7 +3166,7 @@ MODULE_SCOPE int TclReToGlob(Tcl_Interp *interp, const char *reStr,
|
||||
int reStrLen, Tcl_DString *dsPtr, int *flagsPtr,
|
||||
int *quantifiersFoundPtr);
|
||||
MODULE_SCOPE int TclScanElement(const char *string, int length,
|
||||
int *flagPtr);
|
||||
char *flagPtr);
|
||||
MODULE_SCOPE void TclSetBgErrorHandler(Tcl_Interp *interp,
|
||||
Tcl_Obj *cmdPrefix);
|
||||
MODULE_SCOPE void TclSetBignumIntRep(Tcl_Obj *objPtr,
|
||||
@@ -3162,20 +3183,10 @@ MODULE_SCOPE void TclSpellFix(Tcl_Interp *interp,
|
||||
Tcl_Obj *bad, Tcl_Obj *fix);
|
||||
MODULE_SCOPE void * TclStackRealloc(Tcl_Interp *interp, void *ptr,
|
||||
int numBytes);
|
||||
MODULE_SCOPE int TclStringCatObjv(Tcl_Interp *interp, int inPlace,
|
||||
int objc, Tcl_Obj *const objv[],
|
||||
Tcl_Obj **objPtrPtr);
|
||||
MODULE_SCOPE int TclStringFind(Tcl_Obj *needle, Tcl_Obj *haystack,
|
||||
int start);
|
||||
MODULE_SCOPE int TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack,
|
||||
int last);
|
||||
MODULE_SCOPE int TclStringMatch(const char *str, int strLen,
|
||||
const char *pattern, int ptnLen, int flags);
|
||||
MODULE_SCOPE int TclStringMatchObj(Tcl_Obj *stringObj,
|
||||
Tcl_Obj *patternObj, int flags);
|
||||
MODULE_SCOPE Tcl_Obj * TclStringObjReverse(Tcl_Obj *objPtr);
|
||||
MODULE_SCOPE int TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
int count, Tcl_Obj **objPtrPtr);
|
||||
MODULE_SCOPE void TclSubstCompile(Tcl_Interp *interp, const char *bytes,
|
||||
int numBytes, int flags, int line,
|
||||
struct CompileEnv *envPtr);
|
||||
@@ -3191,6 +3202,7 @@ MODULE_SCOPE int TclTrimLeft(const char *bytes, int numBytes,
|
||||
const char *trim, int numTrim);
|
||||
MODULE_SCOPE int TclTrimRight(const char *bytes, int numBytes,
|
||||
const char *trim, int numTrim);
|
||||
MODULE_SCOPE int TclUtfCmp(const char *cs, const char *ct);
|
||||
MODULE_SCOPE int TclUtfCasecmp(const char *cs, const char *ct);
|
||||
MODULE_SCOPE int TclUtfCount(int ch);
|
||||
MODULE_SCOPE Tcl_Obj * TclpNativeToNormalized(ClientData clientData);
|
||||
@@ -3240,7 +3252,7 @@ MODULE_SCOPE Tcl_Command TclInitBinaryCmd(Tcl_Interp *interp);
|
||||
MODULE_SCOPE int Tcl_BreakObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
MODULE_SCOPE int Tcl_CaseObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -3979,6 +3991,26 @@ MODULE_SCOPE int TclCompileAssembleCmd(Tcl_Interp *interp,
|
||||
Tcl_Parse *parsePtr, Command *cmdPtr,
|
||||
struct CompileEnv *envPtr);
|
||||
|
||||
/*
|
||||
* Routines that provide the [string] ensemble functionality. Possible
|
||||
* candidates for public interface.
|
||||
*/
|
||||
|
||||
MODULE_SCOPE Tcl_Obj * TclStringCat(Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[], int flags);
|
||||
MODULE_SCOPE int TclStringFirst(Tcl_Obj *needle, Tcl_Obj *haystack,
|
||||
int start);
|
||||
MODULE_SCOPE int TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack,
|
||||
int last);
|
||||
MODULE_SCOPE Tcl_Obj * TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
int count, int flags);
|
||||
MODULE_SCOPE Tcl_Obj * TclStringReverse(Tcl_Obj *objPtr, int flags);
|
||||
|
||||
/* Flag values for the [string] ensemble functions. */
|
||||
|
||||
#define TCL_STRING_MATCH_NOCASE TCL_MATCH_NOCASE /* (1<<0) in tcl.h */
|
||||
#define TCL_STRING_IN_PLACE (1<<1)
|
||||
|
||||
/*
|
||||
* Functions defined in generic/tclVar.c and currently exported only for use
|
||||
* by the bytecode compiler and engine. Some of these could later be placed in
|
||||
@@ -4034,6 +4066,45 @@ MODULE_SCOPE TCL_HASH_TYPE TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr);
|
||||
|
||||
MODULE_SCOPE int TclFullFinalizationRequested(void);
|
||||
|
||||
/*
|
||||
* TIP #462.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The following enum values give the status of a spawned process.
|
||||
*/
|
||||
|
||||
typedef enum TclProcessWaitStatus {
|
||||
TCL_PROCESS_ERROR = -1, /* Error waiting for process to exit */
|
||||
TCL_PROCESS_UNCHANGED = 0, /* No change since the last call. */
|
||||
TCL_PROCESS_EXITED = 1, /* Process has exited. */
|
||||
TCL_PROCESS_SIGNALED = 2, /* Child killed because of a signal. */
|
||||
TCL_PROCESS_STOPPED = 3, /* Child suspended because of a signal. */
|
||||
TCL_PROCESS_UNKNOWN_STATUS = 4
|
||||
/* Child wait status didn't make sense. */
|
||||
} TclProcessWaitStatus;
|
||||
|
||||
MODULE_SCOPE Tcl_Command TclInitProcessCmd(Tcl_Interp *interp);
|
||||
MODULE_SCOPE void TclProcessCreated(Tcl_Pid pid);
|
||||
MODULE_SCOPE TclProcessWaitStatus TclProcessWait(Tcl_Pid pid, int options,
|
||||
int *codePtr, Tcl_Obj **msgObjPtr,
|
||||
Tcl_Obj **errorObjPtr);
|
||||
|
||||
/*
|
||||
* Utility routines for encoding index values as integers. Used by both
|
||||
* some of the command compilers and by [lsort] and [lsearch].
|
||||
*/
|
||||
|
||||
MODULE_SCOPE int TclIndexEncode(Tcl_Interp *interp, Tcl_Obj *objPtr,
|
||||
int before, int after, int *indexPtr);
|
||||
MODULE_SCOPE int TclIndexDecode(int encoded, int endValue);
|
||||
|
||||
/* Constants used in index value encoding routines. */
|
||||
#define TCL_INDEX_END (-2)
|
||||
#define TCL_INDEX_BEFORE (-1)
|
||||
#define TCL_INDEX_START (0)
|
||||
#define TCL_INDEX_AFTER (INT_MAX)
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
* Macros used by the Tcl core to create and release Tcl objects.
|
||||
@@ -4418,7 +4489,7 @@ MODULE_SCOPE void TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
|
||||
*/
|
||||
|
||||
#define TclUtfToUniChar(str, chPtr) \
|
||||
((((unsigned char) *(str)) < 0xC0) ? \
|
||||
((((unsigned char) *(str)) < 0x80) ? \
|
||||
((*(chPtr) = (unsigned char) *(str)), 1) \
|
||||
: Tcl_UtfToUniChar(str, chPtr))
|
||||
|
||||
@@ -4483,7 +4554,7 @@ MODULE_SCOPE int TclIsPureByteArray(Tcl_Obj *objPtr);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------
|
||||
* Macro used by the Tcl core to increment a namespace's export export epoch
|
||||
* Macro used by the Tcl core to increment a namespace's export epoch
|
||||
* counter. The ANSI C "prototype" for this macro is:
|
||||
*
|
||||
* MODULE_SCOPE void TclInvalidateNsCmdLookup(Namespace *nsPtr);
|
||||
@@ -4543,30 +4614,19 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
* core. They should only be called on unshared objects. The ANSI C
|
||||
* "prototypes" for these macros are:
|
||||
*
|
||||
* MODULE_SCOPE void TclSetLongObj(Tcl_Obj *objPtr, long longValue);
|
||||
* MODULE_SCOPE void TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
|
||||
* MODULE_SCOPE void TclSetIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
|
||||
* MODULE_SCOPE void TclSetDoubleObj(Tcl_Obj *objPtr, double d);
|
||||
*----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define TclSetLongObj(objPtr, i) \
|
||||
#define TclSetIntObj(objPtr, i) \
|
||||
do { \
|
||||
TclInvalidateStringRep(objPtr); \
|
||||
TclFreeIntRep(objPtr); \
|
||||
(objPtr)->internalRep.longValue = (long)(i); \
|
||||
(objPtr)->internalRep.wideValue = (Tcl_WideInt)(i); \
|
||||
(objPtr)->typePtr = &tclIntType; \
|
||||
} while (0)
|
||||
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
#define TclSetWideIntObj(objPtr, w) \
|
||||
do { \
|
||||
TclInvalidateStringRep(objPtr); \
|
||||
TclFreeIntRep(objPtr); \
|
||||
(objPtr)->internalRep.wideValue = (Tcl_WideInt)(w); \
|
||||
(objPtr)->typePtr = &tclWideIntType; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define TclSetDoubleObj(objPtr, d) \
|
||||
do { \
|
||||
TclInvalidateStringRep(objPtr); \
|
||||
@@ -4581,8 +4641,7 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
* types, avoiding the corresponding function calls in time critical parts of
|
||||
* the core. The ANSI C "prototypes" for these macros are:
|
||||
*
|
||||
* MODULE_SCOPE void TclNewLongObj(Tcl_Obj *objPtr, long l);
|
||||
* MODULE_SCOPE void TclNewWideObj(Tcl_Obj *objPtr, Tcl_WideInt w);
|
||||
* MODULE_SCOPE void TclNewIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
|
||||
* MODULE_SCOPE void TclNewDoubleObj(Tcl_Obj *objPtr, double d);
|
||||
* MODULE_SCOPE void TclNewStringObj(Tcl_Obj *objPtr, const char *s, int len);
|
||||
* MODULE_SCOPE void TclNewLiteralStringObj(Tcl_Obj*objPtr, const char *sLiteral);
|
||||
@@ -4591,13 +4650,13 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
*/
|
||||
|
||||
#ifndef TCL_MEM_DEBUG
|
||||
#define TclNewLongObj(objPtr, i) \
|
||||
#define TclNewIntObj(objPtr, i) \
|
||||
do { \
|
||||
TclIncrObjsAllocated(); \
|
||||
TclAllocObjStorage(objPtr); \
|
||||
(objPtr)->refCount = 0; \
|
||||
(objPtr)->bytes = NULL; \
|
||||
(objPtr)->internalRep.longValue = (long)(i); \
|
||||
(objPtr)->internalRep.wideValue = (Tcl_WideInt)(i); \
|
||||
(objPtr)->typePtr = &tclIntType; \
|
||||
TCL_DTRACE_OBJ_CREATE(objPtr); \
|
||||
} while (0)
|
||||
@@ -4624,8 +4683,8 @@ MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
|
||||
} while (0)
|
||||
|
||||
#else /* TCL_MEM_DEBUG */
|
||||
#define TclNewLongObj(objPtr, l) \
|
||||
(objPtr) = Tcl_NewLongObj(l)
|
||||
#define TclNewIntObj(objPtr, w) \
|
||||
(objPtr) = Tcl_NewWideIntObj(w)
|
||||
|
||||
#define TclNewDoubleObj(objPtr, d) \
|
||||
(objPtr) = Tcl_NewDoubleObj(d)
|
||||
|
||||
+137
-157
@@ -28,21 +28,21 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* [Bug #803489] Tcl_FindNamespace problem in the Stubs table */
|
||||
#undef Tcl_CreateNamespace
|
||||
#undef Tcl_DeleteNamespace
|
||||
#undef Tcl_AppendExportList
|
||||
#undef Tcl_Export
|
||||
#undef Tcl_Import
|
||||
#undef Tcl_ForgetImport
|
||||
#undef Tcl_GetCurrentNamespace
|
||||
#undef Tcl_GetGlobalNamespace
|
||||
#undef Tcl_FindNamespace
|
||||
#undef Tcl_FindCommand
|
||||
#undef Tcl_GetCommandFromObj
|
||||
#undef Tcl_GetCommandFullName
|
||||
#undef Tcl_SetStartupScript
|
||||
#undef Tcl_GetStartupScript
|
||||
#if !defined(TCL_NO_DEPRECATED) && (TCL_MAJOR_VERSION < 9)
|
||||
/* Those macro's are especially for Itcl 3.4 compatibility */
|
||||
# define tclCreateNamespace tcl_CreateNamespace
|
||||
# define tclDeleteNamespace tcl_DeleteNamespace
|
||||
# define tclAppendExportList tcl_AppendExportList
|
||||
# define tclExport tcl_Export
|
||||
# define tclImport tcl_Import
|
||||
# define tclForgetImport tcl_ForgetImport
|
||||
# define tclGetCurrentNamespace_ tcl_GetCurrentNamespace
|
||||
# define tclGetGlobalNamespace_ tcl_GetGlobalNamespace
|
||||
# define tclFindNamespace tcl_FindNamespace
|
||||
# define tclFindCommand tcl_FindCommand
|
||||
# define tclGetCommandFromObj tcl_GetCommandFromObj
|
||||
# define tclGetCommandFullName tcl_GetCommandFullName
|
||||
#endif /* !defined(TCL_NO_DEPRECATED) */
|
||||
|
||||
/*
|
||||
* WARNING: This file is automatically generated by the tools/genStubs.tcl
|
||||
@@ -75,7 +75,8 @@ EXTERN void TclCleanupCommand(Command *cmdPtr);
|
||||
EXTERN int TclCopyAndCollapse(int count, const char *src,
|
||||
char *dst);
|
||||
/* 8 */
|
||||
EXTERN int TclCopyChannelOld(Tcl_Interp *interp,
|
||||
TCL_DEPRECATED("")
|
||||
int TclCopyChannelOld(Tcl_Interp *interp,
|
||||
Tcl_Channel inChan, Tcl_Channel outChan,
|
||||
int toRead, Tcl_Obj *cmdPtr);
|
||||
/* 9 */
|
||||
@@ -113,7 +114,7 @@ EXTERN int TclFindElement(Tcl_Interp *interp,
|
||||
/* 23 */
|
||||
EXTERN Proc * TclFindProc(Interp *iPtr, const char *procName);
|
||||
/* 24 */
|
||||
EXTERN int TclFormatInt(char *buffer, long n);
|
||||
EXTERN int TclFormatInt(char *buffer, Tcl_WideInt n);
|
||||
/* 25 */
|
||||
EXTERN void TclFreePackageInfo(Interp *iPtr);
|
||||
/* Slot 26 is reserved */
|
||||
@@ -173,7 +174,7 @@ EXTERN int TclInterpInit(Tcl_Interp *interp);
|
||||
/* 53 */
|
||||
EXTERN int TclInvokeObjectCommand(ClientData clientData,
|
||||
Tcl_Interp *interp, int argc,
|
||||
CONST84 char **argv);
|
||||
const char **argv);
|
||||
/* 54 */
|
||||
EXTERN int TclInvokeStringCommand(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
@@ -218,7 +219,8 @@ EXTERN unsigned long TclpGetClicks(void);
|
||||
/* 76 */
|
||||
EXTERN unsigned long TclpGetSeconds(void);
|
||||
/* 77 */
|
||||
EXTERN void TclpGetTime(Tcl_Time *time);
|
||||
TCL_DEPRECATED("")
|
||||
void TclpGetTime(Tcl_Time *time);
|
||||
/* Slot 78 is reserved */
|
||||
/* Slot 79 is reserved */
|
||||
/* Slot 80 is reserved */
|
||||
@@ -231,7 +233,8 @@ EXTERN char * TclpRealloc(char *ptr, unsigned int size);
|
||||
/* Slot 86 is reserved */
|
||||
/* Slot 87 is reserved */
|
||||
/* 88 */
|
||||
EXTERN char * TclPrecTraceProc(ClientData clientData,
|
||||
TCL_DEPRECATED("")
|
||||
char * TclPrecTraceProc(ClientData clientData,
|
||||
Tcl_Interp *interp, const char *name1,
|
||||
const char *name2, int flags);
|
||||
/* 89 */
|
||||
@@ -267,7 +270,8 @@ EXTERN void TclSetupEnv(Tcl_Interp *interp);
|
||||
EXTERN int TclSockGetPort(Tcl_Interp *interp, const char *str,
|
||||
const char *proto, int *portPtr);
|
||||
/* 104 */
|
||||
EXTERN int TclSockMinimumBuffersOld(int sock, int size);
|
||||
TCL_DEPRECATED("")
|
||||
int TclSockMinimumBuffersOld(int sock, int size);
|
||||
/* Slot 105 is reserved */
|
||||
/* Slot 106 is reserved */
|
||||
/* Slot 107 is reserved */
|
||||
@@ -284,22 +288,22 @@ EXTERN void Tcl_AddInterpResolvers(Tcl_Interp *interp,
|
||||
Tcl_ResolveVarProc *varProc,
|
||||
Tcl_ResolveCompiledVarProc *compiledVarProc);
|
||||
/* 112 */
|
||||
EXTERN int Tcl_AppendExportList(Tcl_Interp *interp,
|
||||
EXTERN int TclAppendExportList(Tcl_Interp *interp,
|
||||
Tcl_Namespace *nsPtr, Tcl_Obj *objPtr);
|
||||
/* 113 */
|
||||
EXTERN Tcl_Namespace * Tcl_CreateNamespace(Tcl_Interp *interp,
|
||||
EXTERN Tcl_Namespace * TclCreateNamespace(Tcl_Interp *interp,
|
||||
const char *name, ClientData clientData,
|
||||
Tcl_NamespaceDeleteProc *deleteProc);
|
||||
/* 114 */
|
||||
EXTERN void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr);
|
||||
EXTERN void TclDeleteNamespace(Tcl_Namespace *nsPtr);
|
||||
/* 115 */
|
||||
EXTERN int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
EXTERN int TclExport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
const char *pattern, int resetListFirst);
|
||||
/* 116 */
|
||||
EXTERN Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, const char *name,
|
||||
EXTERN Tcl_Command TclFindCommand(Tcl_Interp *interp, const char *name,
|
||||
Tcl_Namespace *contextNsPtr, int flags);
|
||||
/* 117 */
|
||||
EXTERN Tcl_Namespace * Tcl_FindNamespace(Tcl_Interp *interp,
|
||||
EXTERN Tcl_Namespace * TclFindNamespace(Tcl_Interp *interp,
|
||||
const char *name,
|
||||
Tcl_Namespace *contextNsPtr, int flags);
|
||||
/* 118 */
|
||||
@@ -314,23 +318,23 @@ EXTERN Tcl_Var Tcl_FindNamespaceVar(Tcl_Interp *interp,
|
||||
const char *name,
|
||||
Tcl_Namespace *contextNsPtr, int flags);
|
||||
/* 121 */
|
||||
EXTERN int Tcl_ForgetImport(Tcl_Interp *interp,
|
||||
EXTERN int TclForgetImport(Tcl_Interp *interp,
|
||||
Tcl_Namespace *nsPtr, const char *pattern);
|
||||
/* 122 */
|
||||
EXTERN Tcl_Command Tcl_GetCommandFromObj(Tcl_Interp *interp,
|
||||
EXTERN Tcl_Command TclGetCommandFromObj(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
/* 123 */
|
||||
EXTERN void Tcl_GetCommandFullName(Tcl_Interp *interp,
|
||||
EXTERN void TclGetCommandFullName(Tcl_Interp *interp,
|
||||
Tcl_Command command, Tcl_Obj *objPtr);
|
||||
/* 124 */
|
||||
EXTERN Tcl_Namespace * Tcl_GetCurrentNamespace(Tcl_Interp *interp);
|
||||
EXTERN Tcl_Namespace * TclGetCurrentNamespace_(Tcl_Interp *interp);
|
||||
/* 125 */
|
||||
EXTERN Tcl_Namespace * Tcl_GetGlobalNamespace(Tcl_Interp *interp);
|
||||
EXTERN Tcl_Namespace * TclGetGlobalNamespace_(Tcl_Interp *interp);
|
||||
/* 126 */
|
||||
EXTERN void Tcl_GetVariableFullName(Tcl_Interp *interp,
|
||||
Tcl_Var variable, Tcl_Obj *objPtr);
|
||||
/* 127 */
|
||||
EXTERN int Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
EXTERN int TclImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
|
||||
const char *pattern, int allowOverwrite);
|
||||
/* 128 */
|
||||
EXTERN void Tcl_PopCallFrame(Tcl_Interp *interp);
|
||||
@@ -350,19 +354,18 @@ EXTERN void Tcl_SetNamespaceResolvers(
|
||||
/* 132 */
|
||||
EXTERN int TclpHasSockets(Tcl_Interp *interp);
|
||||
/* 133 */
|
||||
EXTERN struct tm * TclpGetDate(const time_t *time, int useGMT);
|
||||
TCL_DEPRECATED("")
|
||||
struct tm * TclpGetDate(const time_t *time, int useGMT);
|
||||
/* Slot 134 is reserved */
|
||||
/* Slot 135 is reserved */
|
||||
/* Slot 136 is reserved */
|
||||
/* Slot 137 is reserved */
|
||||
/* 138 */
|
||||
EXTERN CONST84_RETURN char * TclGetEnv(const char *name,
|
||||
Tcl_DString *valuePtr);
|
||||
EXTERN const char * TclGetEnv(const char *name, Tcl_DString *valuePtr);
|
||||
/* Slot 139 is reserved */
|
||||
/* Slot 140 is reserved */
|
||||
/* 141 */
|
||||
EXTERN CONST84_RETURN char * TclpGetCwd(Tcl_Interp *interp,
|
||||
Tcl_DString *cwdPtr);
|
||||
EXTERN const char * TclpGetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr);
|
||||
/* 142 */
|
||||
EXTERN int TclSetByteCodeFromAny(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr, CompileHookProc *hookProc,
|
||||
@@ -401,9 +404,11 @@ EXTERN void TclRegError(Tcl_Interp *interp, const char *msg,
|
||||
EXTERN Var * TclVarTraceExists(Tcl_Interp *interp,
|
||||
const char *varName);
|
||||
/* 158 */
|
||||
EXTERN void TclSetStartupScriptFileName(const char *filename);
|
||||
TCL_DEPRECATED("use public Tcl_SetStartupScript()")
|
||||
void TclSetStartupScriptFileName(const char *filename);
|
||||
/* 159 */
|
||||
EXTERN const char * TclGetStartupScriptFileName(void);
|
||||
TCL_DEPRECATED("use public Tcl_GetStartupScript()")
|
||||
const char * TclGetStartupScriptFileName(void);
|
||||
/* Slot 160 is reserved */
|
||||
/* 161 */
|
||||
EXTERN int TclChannelTransform(Tcl_Interp *interp,
|
||||
@@ -422,9 +427,11 @@ EXTERN int TclListObjSetElement(Tcl_Interp *interp,
|
||||
Tcl_Obj *listPtr, int index,
|
||||
Tcl_Obj *valuePtr);
|
||||
/* 167 */
|
||||
EXTERN void TclSetStartupScriptPath(Tcl_Obj *pathPtr);
|
||||
TCL_DEPRECATED("use public Tcl_SetStartupScript()")
|
||||
void TclSetStartupScriptPath(Tcl_Obj *pathPtr);
|
||||
/* 168 */
|
||||
EXTERN Tcl_Obj * TclGetStartupScriptPath(void);
|
||||
TCL_DEPRECATED("use public Tcl_GetStartupScript()")
|
||||
Tcl_Obj * TclGetStartupScriptPath(void);
|
||||
/* 169 */
|
||||
EXTERN int TclpUtfNcmp2(const char *s1, const char *s2,
|
||||
unsigned long n);
|
||||
@@ -457,16 +464,18 @@ EXTERN void TclVarErrMsg(Tcl_Interp *interp, const char *part1,
|
||||
const char *part2, const char *operation,
|
||||
const char *reason);
|
||||
/* 178 */
|
||||
EXTERN void Tcl_SetStartupScript(Tcl_Obj *pathPtr,
|
||||
EXTERN void TclSetStartupScript(Tcl_Obj *pathPtr,
|
||||
const char *encodingName);
|
||||
/* 179 */
|
||||
EXTERN Tcl_Obj * Tcl_GetStartupScript(const char **encodingNamePtr);
|
||||
EXTERN Tcl_Obj * TclGetStartupScript(const char **encodingNamePtr);
|
||||
/* Slot 180 is reserved */
|
||||
/* Slot 181 is reserved */
|
||||
/* 182 */
|
||||
EXTERN struct tm * TclpLocaltime(const time_t *clock);
|
||||
TCL_DEPRECATED("")
|
||||
struct tm * TclpLocaltime(const time_t *clock);
|
||||
/* 183 */
|
||||
EXTERN struct tm * TclpGmtime(const time_t *clock);
|
||||
TCL_DEPRECATED("")
|
||||
struct tm * TclpGmtime(const time_t *clock);
|
||||
/* Slot 184 is reserved */
|
||||
/* Slot 185 is reserved */
|
||||
/* Slot 186 is reserved */
|
||||
@@ -570,7 +579,8 @@ EXTERN Var * TclVarHashCreateVar(TclVarHashTable *tablePtr,
|
||||
EXTERN void TclInitVarHashTable(TclVarHashTable *tablePtr,
|
||||
Namespace *nsPtr);
|
||||
/* 236 */
|
||||
EXTERN void TclBackgroundException(Tcl_Interp *interp, int code);
|
||||
TCL_DEPRECATED("use Tcl_BackgroundException")
|
||||
void TclBackgroundException(Tcl_Interp *interp, int code);
|
||||
/* 237 */
|
||||
EXTERN int TclResetCancellation(Tcl_Interp *interp, int force);
|
||||
/* 238 */
|
||||
@@ -652,7 +662,7 @@ typedef struct TclIntStubs {
|
||||
int (*tclCleanupChildren) (Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan); /* 5 */
|
||||
void (*tclCleanupCommand) (Command *cmdPtr); /* 6 */
|
||||
int (*tclCopyAndCollapse) (int count, const char *src, char *dst); /* 7 */
|
||||
int (*tclCopyChannelOld) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, int toRead, Tcl_Obj *cmdPtr); /* 8 */
|
||||
TCL_DEPRECATED_API("") int (*tclCopyChannelOld) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, int toRead, Tcl_Obj *cmdPtr); /* 8 */
|
||||
int (*tclCreatePipeline) (Tcl_Interp *interp, int argc, const char **argv, Tcl_Pid **pidArrayPtr, TclFile *inPipePtr, TclFile *outPipePtr, TclFile *errFilePtr); /* 9 */
|
||||
int (*tclCreateProc) (Tcl_Interp *interp, Namespace *nsPtr, const char *procName, Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr, Proc **procPtrPtr); /* 10 */
|
||||
void (*tclDeleteCompiledLocalVars) (Interp *iPtr, CallFrame *framePtr); /* 11 */
|
||||
@@ -668,7 +678,7 @@ typedef struct TclIntStubs {
|
||||
void (*reserved21)(void);
|
||||
int (*tclFindElement) (Tcl_Interp *interp, const char *listStr, int listLength, const char **elementPtr, const char **nextPtr, int *sizePtr, int *bracePtr); /* 22 */
|
||||
Proc * (*tclFindProc) (Interp *iPtr, const char *procName); /* 23 */
|
||||
int (*tclFormatInt) (char *buffer, long n); /* 24 */
|
||||
int (*tclFormatInt) (char *buffer, Tcl_WideInt n); /* 24 */
|
||||
void (*tclFreePackageInfo) (Interp *iPtr); /* 25 */
|
||||
void (*reserved26)(void);
|
||||
void (*reserved27)(void);
|
||||
@@ -697,7 +707,7 @@ typedef struct TclIntStubs {
|
||||
void (*tclInitCompiledLocals) (Tcl_Interp *interp, CallFrame *framePtr, Namespace *nsPtr); /* 50 */
|
||||
int (*tclInterpInit) (Tcl_Interp *interp); /* 51 */
|
||||
void (*reserved52)(void);
|
||||
int (*tclInvokeObjectCommand) (ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char **argv); /* 53 */
|
||||
int (*tclInvokeObjectCommand) (ClientData clientData, Tcl_Interp *interp, int argc, const char **argv); /* 53 */
|
||||
int (*tclInvokeStringCommand) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 54 */
|
||||
Proc * (*tclIsProc) (Command *cmdPtr); /* 55 */
|
||||
void (*reserved56)(void);
|
||||
@@ -721,7 +731,7 @@ typedef struct TclIntStubs {
|
||||
void (*tclpFree) (char *ptr); /* 74 */
|
||||
unsigned long (*tclpGetClicks) (void); /* 75 */
|
||||
unsigned long (*tclpGetSeconds) (void); /* 76 */
|
||||
void (*tclpGetTime) (Tcl_Time *time); /* 77 */
|
||||
TCL_DEPRECATED_API("") void (*tclpGetTime) (Tcl_Time *time); /* 77 */
|
||||
void (*reserved78)(void);
|
||||
void (*reserved79)(void);
|
||||
void (*reserved80)(void);
|
||||
@@ -732,7 +742,7 @@ typedef struct TclIntStubs {
|
||||
void (*reserved85)(void);
|
||||
void (*reserved86)(void);
|
||||
void (*reserved87)(void);
|
||||
char * (*tclPrecTraceProc) (ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); /* 88 */
|
||||
TCL_DEPRECATED_API("") char * (*tclPrecTraceProc) (ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); /* 88 */
|
||||
int (*tclPreventAliasLoop) (Tcl_Interp *interp, Tcl_Interp *cmdInterp, Tcl_Command cmd); /* 89 */
|
||||
void (*reserved90)(void);
|
||||
void (*tclProcCleanupProc) (Proc *procPtr); /* 91 */
|
||||
@@ -748,7 +758,7 @@ typedef struct TclIntStubs {
|
||||
CONST86 char * (*tclSetPreInitScript) (const char *string); /* 101 */
|
||||
void (*tclSetupEnv) (Tcl_Interp *interp); /* 102 */
|
||||
int (*tclSockGetPort) (Tcl_Interp *interp, const char *str, const char *proto, int *portPtr); /* 103 */
|
||||
int (*tclSockMinimumBuffersOld) (int sock, int size); /* 104 */
|
||||
TCL_DEPRECATED_API("") int (*tclSockMinimumBuffersOld) (int sock, int size); /* 104 */
|
||||
void (*reserved105)(void);
|
||||
void (*reserved106)(void);
|
||||
void (*reserved107)(void);
|
||||
@@ -756,36 +766,36 @@ typedef struct TclIntStubs {
|
||||
int (*tclUpdateReturnInfo) (Interp *iPtr); /* 109 */
|
||||
int (*tclSockMinimumBuffers) (void *sock, int size); /* 110 */
|
||||
void (*tcl_AddInterpResolvers) (Tcl_Interp *interp, const char *name, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 111 */
|
||||
int (*tcl_AppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 112 */
|
||||
Tcl_Namespace * (*tcl_CreateNamespace) (Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 113 */
|
||||
void (*tcl_DeleteNamespace) (Tcl_Namespace *nsPtr); /* 114 */
|
||||
int (*tcl_Export) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int resetListFirst); /* 115 */
|
||||
Tcl_Command (*tcl_FindCommand) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 116 */
|
||||
Tcl_Namespace * (*tcl_FindNamespace) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 117 */
|
||||
int (*tclAppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 112 */
|
||||
Tcl_Namespace * (*tclCreateNamespace) (Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 113 */
|
||||
void (*tclDeleteNamespace) (Tcl_Namespace *nsPtr); /* 114 */
|
||||
int (*tclExport) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int resetListFirst); /* 115 */
|
||||
Tcl_Command (*tclFindCommand) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 116 */
|
||||
Tcl_Namespace * (*tclFindNamespace) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 117 */
|
||||
int (*tcl_GetInterpResolvers) (Tcl_Interp *interp, const char *name, Tcl_ResolverInfo *resInfo); /* 118 */
|
||||
int (*tcl_GetNamespaceResolvers) (Tcl_Namespace *namespacePtr, Tcl_ResolverInfo *resInfo); /* 119 */
|
||||
Tcl_Var (*tcl_FindNamespaceVar) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 120 */
|
||||
int (*tcl_ForgetImport) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern); /* 121 */
|
||||
Tcl_Command (*tcl_GetCommandFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 122 */
|
||||
void (*tcl_GetCommandFullName) (Tcl_Interp *interp, Tcl_Command command, Tcl_Obj *objPtr); /* 123 */
|
||||
Tcl_Namespace * (*tcl_GetCurrentNamespace) (Tcl_Interp *interp); /* 124 */
|
||||
Tcl_Namespace * (*tcl_GetGlobalNamespace) (Tcl_Interp *interp); /* 125 */
|
||||
int (*tclForgetImport) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern); /* 121 */
|
||||
Tcl_Command (*tclGetCommandFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 122 */
|
||||
void (*tclGetCommandFullName) (Tcl_Interp *interp, Tcl_Command command, Tcl_Obj *objPtr); /* 123 */
|
||||
Tcl_Namespace * (*tclGetCurrentNamespace_) (Tcl_Interp *interp); /* 124 */
|
||||
Tcl_Namespace * (*tclGetGlobalNamespace_) (Tcl_Interp *interp); /* 125 */
|
||||
void (*tcl_GetVariableFullName) (Tcl_Interp *interp, Tcl_Var variable, Tcl_Obj *objPtr); /* 126 */
|
||||
int (*tcl_Import) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int allowOverwrite); /* 127 */
|
||||
int (*tclImport) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int allowOverwrite); /* 127 */
|
||||
void (*tcl_PopCallFrame) (Tcl_Interp *interp); /* 128 */
|
||||
int (*tcl_PushCallFrame) (Tcl_Interp *interp, Tcl_CallFrame *framePtr, Tcl_Namespace *nsPtr, int isProcCallFrame); /* 129 */
|
||||
int (*tcl_RemoveInterpResolvers) (Tcl_Interp *interp, const char *name); /* 130 */
|
||||
void (*tcl_SetNamespaceResolvers) (Tcl_Namespace *namespacePtr, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 131 */
|
||||
int (*tclpHasSockets) (Tcl_Interp *interp); /* 132 */
|
||||
struct tm * (*tclpGetDate) (const time_t *time, int useGMT); /* 133 */
|
||||
TCL_DEPRECATED_API("") struct tm * (*tclpGetDate) (const time_t *time, int useGMT); /* 133 */
|
||||
void (*reserved134)(void);
|
||||
void (*reserved135)(void);
|
||||
void (*reserved136)(void);
|
||||
void (*reserved137)(void);
|
||||
CONST84_RETURN char * (*tclGetEnv) (const char *name, Tcl_DString *valuePtr); /* 138 */
|
||||
const char * (*tclGetEnv) (const char *name, Tcl_DString *valuePtr); /* 138 */
|
||||
void (*reserved139)(void);
|
||||
void (*reserved140)(void);
|
||||
CONST84_RETURN char * (*tclpGetCwd) (Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 141 */
|
||||
const char * (*tclpGetCwd) (Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 141 */
|
||||
int (*tclSetByteCodeFromAny) (Tcl_Interp *interp, Tcl_Obj *objPtr, CompileHookProc *hookProc, ClientData clientData); /* 142 */
|
||||
int (*tclAddLiteralObj) (struct CompileEnv *envPtr, Tcl_Obj *objPtr, LiteralEntry **litPtrPtr); /* 143 */
|
||||
void (*tclHideLiteral) (Tcl_Interp *interp, struct CompileEnv *envPtr, int index); /* 144 */
|
||||
@@ -802,8 +812,8 @@ typedef struct TclIntStubs {
|
||||
void (*reserved155)(void);
|
||||
void (*tclRegError) (Tcl_Interp *interp, const char *msg, int status); /* 156 */
|
||||
Var * (*tclVarTraceExists) (Tcl_Interp *interp, const char *varName); /* 157 */
|
||||
void (*tclSetStartupScriptFileName) (const char *filename); /* 158 */
|
||||
const char * (*tclGetStartupScriptFileName) (void); /* 159 */
|
||||
TCL_DEPRECATED_API("use public Tcl_SetStartupScript()") void (*tclSetStartupScriptFileName) (const char *filename); /* 158 */
|
||||
TCL_DEPRECATED_API("use public Tcl_GetStartupScript()") const char * (*tclGetStartupScriptFileName) (void); /* 159 */
|
||||
void (*reserved160)(void);
|
||||
int (*tclChannelTransform) (Tcl_Interp *interp, Tcl_Channel chan, Tcl_Obj *cmdObjPtr); /* 161 */
|
||||
void (*tclChannelEventScriptInvoker) (ClientData clientData, int flags); /* 162 */
|
||||
@@ -811,8 +821,8 @@ typedef struct TclIntStubs {
|
||||
void (*tclExpandCodeArray) (void *envPtr); /* 164 */
|
||||
void (*tclpSetInitialEncodings) (void); /* 165 */
|
||||
int (*tclListObjSetElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, int index, Tcl_Obj *valuePtr); /* 166 */
|
||||
void (*tclSetStartupScriptPath) (Tcl_Obj *pathPtr); /* 167 */
|
||||
Tcl_Obj * (*tclGetStartupScriptPath) (void); /* 168 */
|
||||
TCL_DEPRECATED_API("use public Tcl_SetStartupScript()") void (*tclSetStartupScriptPath) (Tcl_Obj *pathPtr); /* 167 */
|
||||
TCL_DEPRECATED_API("use public Tcl_GetStartupScript()") Tcl_Obj * (*tclGetStartupScriptPath) (void); /* 168 */
|
||||
int (*tclpUtfNcmp2) (const char *s1, const char *s2, unsigned long n); /* 169 */
|
||||
int (*tclCheckInterpTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 170 */
|
||||
int (*tclCheckExecutionTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 171 */
|
||||
@@ -822,12 +832,12 @@ typedef struct TclIntStubs {
|
||||
int (*tclCallVarTraces) (Interp *iPtr, Var *arrayPtr, Var *varPtr, const char *part1, const char *part2, int flags, int leaveErrMsg); /* 175 */
|
||||
void (*tclCleanupVar) (Var *varPtr, Var *arrayPtr); /* 176 */
|
||||
void (*tclVarErrMsg) (Tcl_Interp *interp, const char *part1, const char *part2, const char *operation, const char *reason); /* 177 */
|
||||
void (*tcl_SetStartupScript) (Tcl_Obj *pathPtr, const char *encodingName); /* 178 */
|
||||
Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingNamePtr); /* 179 */
|
||||
void (*tclSetStartupScript) (Tcl_Obj *pathPtr, const char *encodingName); /* 178 */
|
||||
Tcl_Obj * (*tclGetStartupScript) (const char **encodingNamePtr); /* 179 */
|
||||
void (*reserved180)(void);
|
||||
void (*reserved181)(void);
|
||||
struct tm * (*tclpLocaltime) (const time_t *clock); /* 182 */
|
||||
struct tm * (*tclpGmtime) (const time_t *clock); /* 183 */
|
||||
TCL_DEPRECATED_API("") struct tm * (*tclpLocaltime) (const time_t *clock); /* 182 */
|
||||
TCL_DEPRECATED_API("") struct tm * (*tclpGmtime) (const time_t *clock); /* 183 */
|
||||
void (*reserved184)(void);
|
||||
void (*reserved185)(void);
|
||||
void (*reserved186)(void);
|
||||
@@ -880,7 +890,7 @@ typedef struct TclIntStubs {
|
||||
void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */
|
||||
Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */
|
||||
void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */
|
||||
void (*tclBackgroundException) (Tcl_Interp *interp, int code); /* 236 */
|
||||
TCL_DEPRECATED_API("use Tcl_BackgroundException") void (*tclBackgroundException) (Tcl_Interp *interp, int code); /* 236 */
|
||||
int (*tclResetCancellation) (Tcl_Interp *interp, int force); /* 237 */
|
||||
int (*tclNRInterpProc) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 238 */
|
||||
int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 239 */
|
||||
@@ -1088,38 +1098,38 @@ extern const TclIntStubs *tclIntStubsPtr;
|
||||
(tclIntStubsPtr->tclSockMinimumBuffers) /* 110 */
|
||||
#define Tcl_AddInterpResolvers \
|
||||
(tclIntStubsPtr->tcl_AddInterpResolvers) /* 111 */
|
||||
#define Tcl_AppendExportList \
|
||||
(tclIntStubsPtr->tcl_AppendExportList) /* 112 */
|
||||
#define Tcl_CreateNamespace \
|
||||
(tclIntStubsPtr->tcl_CreateNamespace) /* 113 */
|
||||
#define Tcl_DeleteNamespace \
|
||||
(tclIntStubsPtr->tcl_DeleteNamespace) /* 114 */
|
||||
#define Tcl_Export \
|
||||
(tclIntStubsPtr->tcl_Export) /* 115 */
|
||||
#define Tcl_FindCommand \
|
||||
(tclIntStubsPtr->tcl_FindCommand) /* 116 */
|
||||
#define Tcl_FindNamespace \
|
||||
(tclIntStubsPtr->tcl_FindNamespace) /* 117 */
|
||||
#define TclAppendExportList \
|
||||
(tclIntStubsPtr->tclAppendExportList) /* 112 */
|
||||
#define TclCreateNamespace \
|
||||
(tclIntStubsPtr->tclCreateNamespace) /* 113 */
|
||||
#define TclDeleteNamespace \
|
||||
(tclIntStubsPtr->tclDeleteNamespace) /* 114 */
|
||||
#define TclExport \
|
||||
(tclIntStubsPtr->tclExport) /* 115 */
|
||||
#define TclFindCommand \
|
||||
(tclIntStubsPtr->tclFindCommand) /* 116 */
|
||||
#define TclFindNamespace \
|
||||
(tclIntStubsPtr->tclFindNamespace) /* 117 */
|
||||
#define Tcl_GetInterpResolvers \
|
||||
(tclIntStubsPtr->tcl_GetInterpResolvers) /* 118 */
|
||||
#define Tcl_GetNamespaceResolvers \
|
||||
(tclIntStubsPtr->tcl_GetNamespaceResolvers) /* 119 */
|
||||
#define Tcl_FindNamespaceVar \
|
||||
(tclIntStubsPtr->tcl_FindNamespaceVar) /* 120 */
|
||||
#define Tcl_ForgetImport \
|
||||
(tclIntStubsPtr->tcl_ForgetImport) /* 121 */
|
||||
#define Tcl_GetCommandFromObj \
|
||||
(tclIntStubsPtr->tcl_GetCommandFromObj) /* 122 */
|
||||
#define Tcl_GetCommandFullName \
|
||||
(tclIntStubsPtr->tcl_GetCommandFullName) /* 123 */
|
||||
#define Tcl_GetCurrentNamespace \
|
||||
(tclIntStubsPtr->tcl_GetCurrentNamespace) /* 124 */
|
||||
#define Tcl_GetGlobalNamespace \
|
||||
(tclIntStubsPtr->tcl_GetGlobalNamespace) /* 125 */
|
||||
#define TclForgetImport \
|
||||
(tclIntStubsPtr->tclForgetImport) /* 121 */
|
||||
#define TclGetCommandFromObj \
|
||||
(tclIntStubsPtr->tclGetCommandFromObj) /* 122 */
|
||||
#define TclGetCommandFullName \
|
||||
(tclIntStubsPtr->tclGetCommandFullName) /* 123 */
|
||||
#define TclGetCurrentNamespace_ \
|
||||
(tclIntStubsPtr->tclGetCurrentNamespace_) /* 124 */
|
||||
#define TclGetGlobalNamespace_ \
|
||||
(tclIntStubsPtr->tclGetGlobalNamespace_) /* 125 */
|
||||
#define Tcl_GetVariableFullName \
|
||||
(tclIntStubsPtr->tcl_GetVariableFullName) /* 126 */
|
||||
#define Tcl_Import \
|
||||
(tclIntStubsPtr->tcl_Import) /* 127 */
|
||||
#define TclImport \
|
||||
(tclIntStubsPtr->tclImport) /* 127 */
|
||||
#define Tcl_PopCallFrame \
|
||||
(tclIntStubsPtr->tcl_PopCallFrame) /* 128 */
|
||||
#define Tcl_PushCallFrame \
|
||||
@@ -1210,10 +1220,10 @@ extern const TclIntStubs *tclIntStubsPtr;
|
||||
(tclIntStubsPtr->tclCleanupVar) /* 176 */
|
||||
#define TclVarErrMsg \
|
||||
(tclIntStubsPtr->tclVarErrMsg) /* 177 */
|
||||
#define Tcl_SetStartupScript \
|
||||
(tclIntStubsPtr->tcl_SetStartupScript) /* 178 */
|
||||
#define Tcl_GetStartupScript \
|
||||
(tclIntStubsPtr->tcl_GetStartupScript) /* 179 */
|
||||
#define TclSetStartupScript \
|
||||
(tclIntStubsPtr->tclSetStartupScript) /* 178 */
|
||||
#define TclGetStartupScript \
|
||||
(tclIntStubsPtr->tclGetStartupScript) /* 179 */
|
||||
/* Slot 180 is reserved */
|
||||
/* Slot 181 is reserved */
|
||||
#define TclpLocaltime \
|
||||
@@ -1350,58 +1360,28 @@ extern const TclIntStubs *tclIntStubsPtr;
|
||||
#undef TCL_STORAGE_CLASS
|
||||
#define TCL_STORAGE_CLASS DLLIMPORT
|
||||
|
||||
#undef TclGetStartupScriptFileName
|
||||
#undef TclSetStartupScriptFileName
|
||||
#undef TclGetStartupScriptPath
|
||||
#undef TclSetStartupScriptPath
|
||||
#undef TclBackgroundException
|
||||
|
||||
#if defined(USE_TCL_STUBS) && defined(TCL_NO_DEPRECATED)
|
||||
# undef Tcl_SetStartupScript
|
||||
# define Tcl_SetStartupScript \
|
||||
(tclStubsPtr->tcl_SetStartupScript) /* 622 */
|
||||
# undef Tcl_GetStartupScript
|
||||
# define Tcl_GetStartupScript \
|
||||
(tclStubsPtr->tcl_GetStartupScript) /* 623 */
|
||||
# undef Tcl_CreateNamespace
|
||||
# define Tcl_CreateNamespace \
|
||||
(tclStubsPtr->tcl_CreateNamespace) /* 506 */
|
||||
# undef Tcl_DeleteNamespace
|
||||
# define Tcl_DeleteNamespace \
|
||||
(tclStubsPtr->tcl_DeleteNamespace) /* 507 */
|
||||
# undef Tcl_AppendExportList
|
||||
# define Tcl_AppendExportList \
|
||||
(tclStubsPtr->tcl_AppendExportList) /* 508 */
|
||||
# undef Tcl_Export
|
||||
# define Tcl_Export \
|
||||
(tclStubsPtr->tcl_Export) /* 509 */
|
||||
# undef Tcl_Import
|
||||
# define Tcl_Import \
|
||||
(tclStubsPtr->tcl_Import) /* 510 */
|
||||
# undef Tcl_ForgetImport
|
||||
# define Tcl_ForgetImport \
|
||||
(tclStubsPtr->tcl_ForgetImport) /* 511 */
|
||||
# undef Tcl_GetCurrentNamespace
|
||||
# define Tcl_GetCurrentNamespace \
|
||||
(tclStubsPtr->tcl_GetCurrentNamespace) /* 512 */
|
||||
# undef Tcl_GetGlobalNamespace
|
||||
# define Tcl_GetGlobalNamespace \
|
||||
(tclStubsPtr->tcl_GetGlobalNamespace) /* 513 */
|
||||
# undef Tcl_FindNamespace
|
||||
# define Tcl_FindNamespace \
|
||||
(tclStubsPtr->tcl_FindNamespace) /* 514 */
|
||||
# undef Tcl_FindCommand
|
||||
# define Tcl_FindCommand \
|
||||
(tclStubsPtr->tcl_FindCommand) /* 515 */
|
||||
# undef Tcl_GetCommandFromObj
|
||||
# define Tcl_GetCommandFromObj \
|
||||
(tclStubsPtr->tcl_GetCommandFromObj) /* 516 */
|
||||
# undef Tcl_GetCommandFullName
|
||||
# define Tcl_GetCommandFullName \
|
||||
(tclStubsPtr->tcl_GetCommandFullName) /* 517 */
|
||||
#if defined(USE_TCL_STUBS)
|
||||
# undef TclGetStartupScriptFileName
|
||||
# undef TclSetStartupScriptFileName
|
||||
# undef TclGetStartupScriptPath
|
||||
# undef TclSetStartupScriptPath
|
||||
# undef TclBackgroundException
|
||||
# undef TclSetStartupScript
|
||||
# undef TclGetStartupScript
|
||||
# undef TclCreateNamespace
|
||||
# undef TclDeleteNamespace
|
||||
# undef TclAppendExportList
|
||||
# undef TclExport
|
||||
# undef TclImport
|
||||
# undef TclForgetImport
|
||||
# undef TclGetCurrentNamespace_
|
||||
# undef TclGetGlobalNamespace_
|
||||
# undef TclFindNamespace
|
||||
# undef TclFindCommand
|
||||
# undef TclGetCommandFromObj
|
||||
# undef TclGetCommandFullName
|
||||
# undef TclCopyChannelOld
|
||||
# undef TclSockMinimumBuffersOld
|
||||
#endif
|
||||
|
||||
#undef TclCopyChannelOld
|
||||
#undef TclSockMinimumBuffersOld
|
||||
|
||||
#endif /* _TCLINTDECLS */
|
||||
|
||||
@@ -555,10 +555,18 @@ extern const TclIntPlatStubs *tclIntPlatStubsPtr;
|
||||
# undef TclWinGetServByName
|
||||
# undef TclWinGetSockOpt
|
||||
# undef TclWinSetSockOpt
|
||||
# define TclWinNToHS ntohs
|
||||
# define TclWinGetServByName getservbyname
|
||||
# define TclWinGetSockOpt getsockopt
|
||||
# define TclWinSetSockOpt setsockopt
|
||||
# undef TclWinGetPlatformId
|
||||
# undef TclWinResetInterfaces
|
||||
# undef TclWinSetInterfaces
|
||||
# if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
# define TclWinNToHS ntohs
|
||||
# define TclWinGetServByName getservbyname
|
||||
# define TclWinGetSockOpt getsockopt
|
||||
# define TclWinSetSockOpt setsockopt
|
||||
# define TclWinGetPlatformId() (2) /* VER_PLATFORM_WIN32_NT */
|
||||
# define TclWinResetInterfaces() /* nop */
|
||||
# define TclWinSetInterfaces(dummy) /* nop */
|
||||
# endif /* TCL_NO_DEPRECATED */
|
||||
#else
|
||||
# undef TclpGetPid
|
||||
# define TclpGetPid(pid) ((unsigned long) (pid))
|
||||
|
||||
@@ -3208,10 +3208,6 @@ Tcl_MakeSafe(
|
||||
|
||||
(void) Tcl_EvalEx(interp,
|
||||
"namespace eval ::tcl {namespace eval mathfunc {}}", -1, 0);
|
||||
(void) Tcl_CreateAlias(interp, "::tcl::mathfunc::min", master,
|
||||
"::tcl::mathfunc::min", 0, NULL);
|
||||
(void) Tcl_CreateAlias(interp, "::tcl::mathfunc::max", master,
|
||||
"::tcl::mathfunc::max", 0, NULL);
|
||||
}
|
||||
|
||||
iPtr->flags |= SAFE_INTERP;
|
||||
|
||||
+1
-1
@@ -654,7 +654,7 @@ static Tcl_ObjType invalidRealType = {
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
NULL, /* updateStringProc */
|
||||
SetInvalidRealFromAny /* setFromAnyProc */
|
||||
NULL /* setFromAnyProc */
|
||||
};
|
||||
|
||||
static int
|
||||
|
||||
+7
-13
@@ -1165,17 +1165,11 @@ TclLindexList(
|
||||
return TclLindexFlat(interp, listPtr, 1, &argPtr);
|
||||
}
|
||||
|
||||
if (indexListCopy->typePtr == &tclListType) {
|
||||
List *listRepPtr = ListRepPtr(indexListCopy);
|
||||
{
|
||||
int indexCount = -1; /* Size of the array of list indices. */
|
||||
Tcl_Obj **indices = NULL; /* Array of list indices. */
|
||||
|
||||
listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount,
|
||||
&listRepPtr->elements);
|
||||
} else {
|
||||
int indexCount = -1; /* Size of the array of list indices. */
|
||||
Tcl_Obj **indices = NULL;
|
||||
/* Array of list indices. */
|
||||
|
||||
Tcl_ListObjGetElements(NULL, indexListCopy, &indexCount, &indices);
|
||||
TclListObjGetElements(NULL, indexListCopy, &indexCount, &indices);
|
||||
listPtr = TclLindexFlat(interp, listPtr, indexCount, indices);
|
||||
}
|
||||
Tcl_DecrRefCount(indexListCopy);
|
||||
@@ -1957,8 +1951,8 @@ static void
|
||||
UpdateStringOfList(
|
||||
Tcl_Obj *listPtr) /* List object with string rep to update. */
|
||||
{
|
||||
# define LOCAL_SIZE 20
|
||||
int localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
# define LOCAL_SIZE 64
|
||||
char localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
List *listRepPtr = ListRepPtr(listPtr);
|
||||
int numElems = listRepPtr->elemCount;
|
||||
int i, length, bytesNeeded = 0;
|
||||
@@ -1995,7 +1989,7 @@ UpdateStringOfList(
|
||||
* We know numElems <= LIST_MAX, so this is safe.
|
||||
*/
|
||||
|
||||
flagPtr = ckalloc(numElems * sizeof(int));
|
||||
flagPtr = ckalloc(numElems);
|
||||
}
|
||||
elemPtrs = &listRepPtr->elements;
|
||||
for (i = 0; i < numElems; i++) {
|
||||
|
||||
+12
-11
@@ -186,7 +186,7 @@ TclCreateLiteral(
|
||||
{
|
||||
LiteralTable *globalTablePtr = &iPtr->literalTable;
|
||||
LiteralEntry *globalPtr;
|
||||
int globalHash;
|
||||
unsigned int globalHash;
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
/*
|
||||
@@ -393,7 +393,8 @@ TclRegisterLiteral(
|
||||
LiteralEntry *globalPtr, *localPtr;
|
||||
Tcl_Obj *objPtr;
|
||||
unsigned hash;
|
||||
int localHash, objIndex, new;
|
||||
unsigned int localHash;
|
||||
int objIndex, new;
|
||||
Namespace *nsPtr;
|
||||
|
||||
if (length < 0) {
|
||||
@@ -537,7 +538,8 @@ TclHideLiteral(
|
||||
{
|
||||
LiteralEntry **nextPtrPtr, *entryPtr, *lPtr;
|
||||
LiteralTable *localTablePtr = &envPtr->localLitTable;
|
||||
int localHash, length;
|
||||
unsigned int localHash;
|
||||
int length;
|
||||
const char *bytes;
|
||||
Tcl_Obj *newObjPtr;
|
||||
|
||||
@@ -556,7 +558,7 @@ TclHideLiteral(
|
||||
lPtr->objPtr = newObjPtr;
|
||||
|
||||
bytes = TclGetStringFromObj(newObjPtr, &length);
|
||||
localHash = (HashString(bytes, length) & localTablePtr->mask);
|
||||
localHash = HashString(bytes, length) & localTablePtr->mask;
|
||||
nextPtrPtr = &localTablePtr->buckets[localHash];
|
||||
|
||||
for (entryPtr=*nextPtrPtr ; entryPtr!=NULL ; entryPtr=*nextPtrPtr) {
|
||||
@@ -612,7 +614,7 @@ TclAddLiteralObj(
|
||||
lPtr = &envPtr->literalArrayPtr[objIndex];
|
||||
lPtr->objPtr = objPtr;
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
lPtr->refCount = -1; /* i.e., unused */
|
||||
lPtr->refCount = (size_t)-1; /* i.e., unused */
|
||||
lPtr->nextPtr = NULL;
|
||||
|
||||
if (litPtrPtr) {
|
||||
@@ -809,7 +811,8 @@ TclReleaseLiteral(
|
||||
LiteralTable *globalTablePtr;
|
||||
register LiteralEntry *entryPtr, *prevPtr;
|
||||
const char *bytes;
|
||||
int length, index;
|
||||
int length;
|
||||
unsigned int index;
|
||||
|
||||
if (iPtr == NULL) {
|
||||
goto done;
|
||||
@@ -828,15 +831,13 @@ TclReleaseLiteral(
|
||||
for (prevPtr=NULL, entryPtr=globalTablePtr->buckets[index];
|
||||
entryPtr!=NULL ; prevPtr=entryPtr, entryPtr=entryPtr->nextPtr) {
|
||||
if (entryPtr->objPtr == objPtr) {
|
||||
entryPtr->refCount--;
|
||||
|
||||
/*
|
||||
* If the literal is no longer being used by any ByteCode, delete
|
||||
* the entry then remove the reference corresponding to the global
|
||||
* literal table entry (decrement the ref count of the object).
|
||||
*/
|
||||
|
||||
if (entryPtr->refCount == 0) {
|
||||
if (entryPtr->refCount-- <= 1) {
|
||||
if (prevPtr == NULL) {
|
||||
globalTablePtr->buckets[index] = entryPtr->nextPtr;
|
||||
} else {
|
||||
@@ -954,8 +955,8 @@ RebuildLiteralTable(
|
||||
register LiteralEntry *entryPtr;
|
||||
LiteralEntry **bucketPtr;
|
||||
const char *bytes;
|
||||
unsigned int oldSize;
|
||||
int count, index, length;
|
||||
unsigned int oldSize, index;
|
||||
int count, length;
|
||||
|
||||
oldSize = tablePtr->numBuckets;
|
||||
oldBuckets = tablePtr->buckets;
|
||||
|
||||
@@ -470,6 +470,19 @@ Tcl_LoadObjCmd(
|
||||
*/
|
||||
|
||||
if (code != TCL_OK) {
|
||||
#if defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
|
||||
Interp *iPtr = (Interp *) target;
|
||||
if (iPtr->result && *(iPtr->result) && !iPtr->freeProc) {
|
||||
/*
|
||||
* A call to Tcl_InitStubs() determined the caller extension and
|
||||
* this interp are incompatible in their stubs mechanisms, and
|
||||
* recorded the error in the oldest legacy place we have to do so.
|
||||
*/
|
||||
Tcl_SetObjResult(target, Tcl_NewStringObj(iPtr->result, -1));
|
||||
iPtr->result = &tclEmptyString;
|
||||
iPtr->freeProc = NULL;
|
||||
}
|
||||
#endif /* defined(TCL_NO_DEPRECATED) */
|
||||
Tcl_TransferResult(target, code, interp);
|
||||
goto done;
|
||||
}
|
||||
|
||||
+1
-5
@@ -266,18 +266,14 @@ Tcl_SourceRCFile(
|
||||
|
||||
c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
|
||||
if (c != NULL) {
|
||||
Tcl_Obj *fullNameObj = Tcl_NewStringObj(fullName, -1);
|
||||
|
||||
Tcl_Close(NULL, c);
|
||||
Tcl_IncrRefCount(fullNameObj);
|
||||
if (Tcl_FSEvalFileEx(interp, fullNameObj, NULL) != TCL_OK) {
|
||||
if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
|
||||
chan = Tcl_GetStdChannel(TCL_STDERR);
|
||||
if (chan) {
|
||||
Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
|
||||
Tcl_WriteChars(chan, "\n", 1);
|
||||
}
|
||||
}
|
||||
Tcl_DecrRefCount(fullNameObj);
|
||||
}
|
||||
}
|
||||
Tcl_DStringFree(&temp);
|
||||
|
||||
+39
-13
@@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
size_t numNsCreated; /* Count of the number of namespaces created
|
||||
unsigned long numNsCreated; /* Count of the number of namespaces created
|
||||
* within the thread. This value is used as a
|
||||
* unique id for each namespace. Cannot be
|
||||
* per-interp because the nsId is used to
|
||||
@@ -402,7 +402,7 @@ Tcl_PopCallFrame(
|
||||
}
|
||||
if (framePtr->numCompiledLocals > 0) {
|
||||
TclDeleteCompiledLocalVars(iPtr, framePtr);
|
||||
if (--framePtr->localCachePtr->refCount == 0) {
|
||||
if (framePtr->localCachePtr->refCount-- <= 1) {
|
||||
TclFreeLocalCache(interp, framePtr->localCachePtr);
|
||||
}
|
||||
framePtr->localCachePtr = NULL;
|
||||
@@ -915,6 +915,11 @@ Tcl_DeleteNamespace(
|
||||
Tcl_HashSearch search;
|
||||
Command *cmdPtr;
|
||||
|
||||
/*
|
||||
* Ensure that this namespace doesn't get deallocated in the meantime.
|
||||
*/
|
||||
nsPtr->refCount++;
|
||||
|
||||
/*
|
||||
* Give anyone interested - notably TclOO - a chance to use this namespace
|
||||
* normally despite the fact that the namespace is going to go. Allows the
|
||||
@@ -1047,16 +1052,7 @@ Tcl_DeleteNamespace(
|
||||
#endif
|
||||
Tcl_DeleteHashTable(&nsPtr->cmdTable);
|
||||
|
||||
/*
|
||||
* If the reference count is 0, then discard the namespace.
|
||||
* Otherwise, mark it as "dead" so that it can't be used.
|
||||
*/
|
||||
|
||||
if (nsPtr->refCount == 0) {
|
||||
NamespaceFree(nsPtr);
|
||||
} else {
|
||||
nsPtr->flags |= NS_DEAD;
|
||||
}
|
||||
nsPtr ->flags |= NS_DEAD;
|
||||
} else {
|
||||
/*
|
||||
* Restore the ::errorInfo and ::errorCode traces.
|
||||
@@ -1073,6 +1069,7 @@ Tcl_DeleteNamespace(
|
||||
nsPtr->flags &= ~(NS_DYING|NS_KILLED);
|
||||
}
|
||||
}
|
||||
TclNsDecrRefCount(nsPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2421,6 +2418,35 @@ TclGetNamespaceForQualName(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclEnsureNamespace --
|
||||
*
|
||||
* Provide a namespace that is not deleted.
|
||||
*
|
||||
* Value
|
||||
*
|
||||
* namespacePtr, if it is not scheduled for deletion, or a pointer to a
|
||||
* new namespace with the same name otherwise.
|
||||
*
|
||||
* Effect
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
Tcl_Namespace *
|
||||
TclEnsureNamespace(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Namespace *namespacePtr)
|
||||
{
|
||||
Namespace *nsPtr = (Namespace *) namespacePtr;
|
||||
if (!(nsPtr->flags & NS_DYING)) {
|
||||
return namespacePtr;
|
||||
}
|
||||
return Tcl_CreateNamespace(interp, nsPtr->fullName, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -2638,7 +2664,7 @@ Tcl_FindCommand(
|
||||
Namespace *nsPtr[2];
|
||||
register int search;
|
||||
|
||||
TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,
|
||||
TclGetNamespaceForQualName(interp, name, cxtNsPtr,
|
||||
flags, &nsPtr[0], &nsPtr[1], &cxtNsPtr, &simpleName);
|
||||
|
||||
/*
|
||||
|
||||
+567
-624
File diff suppressed because it is too large
Load Diff
@@ -1206,22 +1206,10 @@ TclOOCopyObjectCmd(
|
||||
o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, NULL, NULL);
|
||||
} else {
|
||||
const char *name, *namespaceName;
|
||||
Tcl_DString buffer;
|
||||
|
||||
name = TclGetString(objv[2]);
|
||||
Tcl_DStringInit(&buffer);
|
||||
if (name[0] == '\0') {
|
||||
name = NULL;
|
||||
} else if (name[0]!=':' || name[1]!=':') {
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
|
||||
if (iPtr->varFramePtr != NULL) {
|
||||
Tcl_DStringAppend(&buffer,
|
||||
iPtr->varFramePtr->nsPtr->fullName, -1);
|
||||
}
|
||||
TclDStringAppendLiteral(&buffer, "::");
|
||||
Tcl_DStringAppend(&buffer, name, -1);
|
||||
name = Tcl_DStringValue(&buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1243,7 +1231,6 @@ TclOOCopyObjectCmd(
|
||||
}
|
||||
|
||||
o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, name, namespaceName);
|
||||
Tcl_DStringFree(&buffer);
|
||||
}
|
||||
|
||||
if (o2Ptr == NULL) {
|
||||
|
||||
+12
-1
@@ -110,7 +110,12 @@ TclOODeleteContext(
|
||||
TclOODeleteChain(contextPtr->callPtr);
|
||||
if (oPtr != NULL) {
|
||||
TclStackFree(oPtr->fPtr->interp, contextPtr);
|
||||
DelRef(oPtr);
|
||||
|
||||
/*
|
||||
* Corresponding AddRef() in TclOO.c/TclOOObjectCmdCore
|
||||
*/
|
||||
|
||||
TclOODecrRefCount(oPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -900,6 +905,7 @@ InitCallChain(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* IsStillValid --
|
||||
*
|
||||
* Calculates whether the given call chain can be used for executing a
|
||||
* method for the given object. The condition on a chain from a cached
|
||||
* location being reusable is:
|
||||
@@ -1171,6 +1177,11 @@ TclOOGetCallContext(
|
||||
returnContext:
|
||||
contextPtr = TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext));
|
||||
contextPtr->oPtr = oPtr;
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount() in TclOODeleteContext
|
||||
*/
|
||||
|
||||
AddRef(oPtr);
|
||||
contextPtr->callPtr = callPtr;
|
||||
contextPtr->skip = 2;
|
||||
|
||||
+121
-27
@@ -123,6 +123,7 @@ static const struct DeclaredSlot slots[] = {
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* BumpGlobalEpoch --
|
||||
*
|
||||
* Utility that ensures that call chains that are invalid will get thrown
|
||||
* away at an appropriate time. Note that exactly which epoch gets
|
||||
* advanced will depend on exactly what the class is tangled up in; in
|
||||
@@ -167,6 +168,7 @@ BumpGlobalEpoch(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* RecomputeClassCacheFlag --
|
||||
*
|
||||
* Determine whether the object is prototypical of its class, and hence
|
||||
* able to use the class's method chain cache.
|
||||
*
|
||||
@@ -189,6 +191,7 @@ RecomputeClassCacheFlag(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOObjectSetFilters --
|
||||
*
|
||||
* Install a list of filter method names into an object.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -247,6 +250,7 @@ TclOOObjectSetFilters(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOClassSetFilters --
|
||||
*
|
||||
* Install a list of filter method names into a class.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -309,6 +313,7 @@ TclOOClassSetFilters(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOObjectSetMixins --
|
||||
*
|
||||
* Install a list of mixin classes into an object.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -326,9 +331,7 @@ TclOOObjectSetMixins(
|
||||
if (numMixins == 0) {
|
||||
if (oPtr->mixins.num != 0) {
|
||||
FOREACH(mixinPtr, oPtr->mixins) {
|
||||
if (mixinPtr) {
|
||||
TclOORemoveFromInstances(oPtr, mixinPtr);
|
||||
}
|
||||
TclOORemoveFromInstances(oPtr, mixinPtr);
|
||||
}
|
||||
ckfree(oPtr->mixins.list);
|
||||
oPtr->mixins.num = 0;
|
||||
@@ -352,6 +355,13 @@ TclOOObjectSetMixins(
|
||||
FOREACH(mixinPtr, oPtr->mixins) {
|
||||
if (mixinPtr != oPtr->selfCls) {
|
||||
TclOOAddToInstances(oPtr, mixinPtr);
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount() is in the caller of this
|
||||
* function.
|
||||
*/
|
||||
|
||||
TclOODecrRefCount(mixinPtr->thisPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -362,6 +372,7 @@ TclOOObjectSetMixins(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOClassSetMixins --
|
||||
*
|
||||
* Install a list of mixin classes into a class.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -399,6 +410,13 @@ TclOOClassSetMixins(
|
||||
memcpy(classPtr->mixins.list, mixins, sizeof(Class *) * numMixins);
|
||||
FOREACH(mixinPtr, classPtr->mixins) {
|
||||
TclOOAddToMixinSubs(classPtr, mixinPtr);
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount() is in the caller of this
|
||||
* function.
|
||||
*/
|
||||
|
||||
TclOODecrRefCount(mixinPtr->thisPtr);
|
||||
}
|
||||
}
|
||||
BumpGlobalEpoch(interp, classPtr);
|
||||
@@ -408,6 +426,7 @@ TclOOClassSetMixins(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* RenameDeleteMethod --
|
||||
*
|
||||
* Core of the code to rename and delete methods.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -497,6 +516,7 @@ RenameDeleteMethod(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOUnknownDefinition --
|
||||
*
|
||||
* Handles what happens when an unknown command is encountered during the
|
||||
* processing of a definition script. Works by finding a command in the
|
||||
* operating definition namespace that the requested command is a unique
|
||||
@@ -575,6 +595,7 @@ TclOOUnknownDefinition(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* FindCommand --
|
||||
*
|
||||
* Specialized version of Tcl_FindCommand that handles command prefixes
|
||||
* and disallows namespace magic.
|
||||
*
|
||||
@@ -635,6 +656,7 @@ FindCommand(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* InitDefineContext --
|
||||
*
|
||||
* Does the magic incantations necessary to push the special stack frame
|
||||
* used when processing object definitions. It is up to the caller to
|
||||
* dispose of the frame (with TclPopStackFrame) when finished.
|
||||
@@ -660,7 +682,9 @@ InitDefineContext(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules */
|
||||
/*
|
||||
* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules.
|
||||
*/
|
||||
|
||||
(void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
|
||||
namespacePtr, FRAME_IS_OO_DEFINE);
|
||||
@@ -675,6 +699,7 @@ InitDefineContext(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOGetDefineCmdContext --
|
||||
*
|
||||
* Extracts the magic token from the current stack frame, or returns NULL
|
||||
* (and leaves an error message) otherwise.
|
||||
*
|
||||
@@ -711,6 +736,7 @@ TclOOGetDefineCmdContext(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* GetClassInOuterContext --
|
||||
*
|
||||
* Wrapper round Tcl_GetObjectFromObj to perform the lookup in the
|
||||
* context that called oo::define (or equivalent). Note that this may
|
||||
* have to go up multiple levels to get the level that we started doing
|
||||
@@ -753,6 +779,7 @@ GetClassInOuterContext(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* GenerateErrorInfo --
|
||||
*
|
||||
* Factored out code to generate part of the error trace messages.
|
||||
*
|
||||
* ----------------------------------------------------------------------
|
||||
@@ -791,6 +818,7 @@ GenerateErrorInfo(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* MagicDefinitionInvoke --
|
||||
*
|
||||
* Part of the implementation of the "oo::define" and "oo::objdefine"
|
||||
* commands that is used to implement the more-than-one-argument case,
|
||||
* applying ensemble-like tricks with dispatch so that error messages are
|
||||
@@ -854,6 +882,7 @@ MagicDefinitionInvoke(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineObjCmd --
|
||||
*
|
||||
* Implementation of the "oo::define" command. Works by effectively doing
|
||||
* the same as 'namespace eval', but with extra magic applied so that the
|
||||
* object to be modified is known to the commands in the target
|
||||
@@ -914,7 +943,7 @@ TclOODefineObjCmd(
|
||||
} else {
|
||||
result = MagicDefinitionInvoke(interp, fPtr->defineNs, 2, objc, objv);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
TclOODecrRefCount(oPtr);
|
||||
|
||||
/*
|
||||
* Restore the previous "current" namespace.
|
||||
@@ -928,6 +957,7 @@ TclOODefineObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOOObjDefObjCmd --
|
||||
*
|
||||
* Implementation of the "oo::objdefine" command. Works by effectively
|
||||
* doing the same as 'namespace eval', but with extra magic applied so
|
||||
* that the object to be modified is known to the commands in the target
|
||||
@@ -981,7 +1011,7 @@ TclOOObjDefObjCmd(
|
||||
} else {
|
||||
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 2, objc, objv);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
TclOODecrRefCount(oPtr);
|
||||
|
||||
/*
|
||||
* Restore the previous "current" namespace.
|
||||
@@ -995,6 +1025,7 @@ TclOOObjDefObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineSelfObjCmd --
|
||||
*
|
||||
* Implementation of the "self" subcommand of the "oo::define" command.
|
||||
* Works by effectively doing the same as 'namespace eval', but with
|
||||
* extra magic applied so that the object to be modified is known to the
|
||||
@@ -1048,7 +1079,7 @@ TclOODefineSelfObjCmd(
|
||||
} else {
|
||||
result = MagicDefinitionInvoke(interp, fPtr->objdefNs, 1, objc, objv);
|
||||
}
|
||||
DelRef(oPtr);
|
||||
TclOODecrRefCount(oPtr);
|
||||
|
||||
/*
|
||||
* Restore the previous "current" namespace.
|
||||
@@ -1062,6 +1093,7 @@ TclOODefineSelfObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineObjSelfObjCmd --
|
||||
*
|
||||
* Implementation of the "self" subcommand of the "oo::objdefine"
|
||||
* command.
|
||||
*
|
||||
@@ -1095,6 +1127,7 @@ TclOODefineObjSelfObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineClassObjCmd --
|
||||
*
|
||||
* Implementation of the "class" subcommand of the "oo::objdefine"
|
||||
* command.
|
||||
*
|
||||
@@ -1110,7 +1143,6 @@ TclOODefineClassObjCmd(
|
||||
{
|
||||
Object *oPtr;
|
||||
Class *clsPtr;
|
||||
Foundation *fPtr = TclOOGetFoundation(interp);
|
||||
|
||||
/*
|
||||
* Parse the context to get the object to operate on.
|
||||
@@ -1147,20 +1179,6 @@ TclOODefineClassObjCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Apply semantic checks. In particular, classes and non-classes are not
|
||||
* interchangable (too complicated to do the conversion!) so we must
|
||||
* produce an error if any attempt is made to swap from one to the other.
|
||||
*/
|
||||
|
||||
if ((oPtr->classPtr==NULL) == TclOOIsReachable(fPtr->classCls, clsPtr)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"may not change a %sclass object into a %sclass object",
|
||||
(oPtr->classPtr==NULL ? "non-" : ""),
|
||||
(oPtr->classPtr==NULL ? "" : "non-")));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "TRANSMUTATION", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's class.
|
||||
@@ -1168,11 +1186,14 @@ TclOODefineClassObjCmd(
|
||||
|
||||
if (oPtr->selfCls != clsPtr) {
|
||||
TclOORemoveFromInstances(oPtr, oPtr->selfCls);
|
||||
|
||||
/*
|
||||
* Reference count already incremented a few lines up.
|
||||
*/
|
||||
|
||||
oPtr->selfCls = clsPtr;
|
||||
|
||||
TclOOAddToInstances(oPtr, oPtr->selfCls);
|
||||
if (!(clsPtr->thisPtr->flags & OBJECT_DELETED)) {
|
||||
oPtr->flags &= ~CLASS_GONE;
|
||||
}
|
||||
if (oPtr->classPtr != NULL) {
|
||||
BumpGlobalEpoch(interp, oPtr->classPtr);
|
||||
} else {
|
||||
@@ -1186,6 +1207,7 @@ TclOODefineClassObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineConstructorObjCmd --
|
||||
*
|
||||
* Implementation of the "constructor" subcommand of the "oo::define"
|
||||
* command.
|
||||
*
|
||||
@@ -1254,6 +1276,7 @@ TclOODefineConstructorObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineDeleteMethodObjCmd --
|
||||
*
|
||||
* Implementation of the "deletemethod" subcommand of the "oo::define"
|
||||
* and "oo::objdefine" commands.
|
||||
*
|
||||
@@ -1310,6 +1333,7 @@ TclOODefineDeleteMethodObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineDestructorObjCmd --
|
||||
*
|
||||
* Implementation of the "destructor" subcommand of the "oo::define"
|
||||
* command.
|
||||
*
|
||||
@@ -1374,6 +1398,7 @@ TclOODefineDestructorObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineExportObjCmd --
|
||||
*
|
||||
* Implementation of the "export" subcommand of the "oo::define" and
|
||||
* "oo::objdefine" commands.
|
||||
*
|
||||
@@ -1468,6 +1493,7 @@ TclOODefineExportObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineForwardObjCmd --
|
||||
*
|
||||
* Implementation of the "forward" subcommand of the "oo::define" and
|
||||
* "oo::objdefine" commands.
|
||||
*
|
||||
@@ -1528,6 +1554,7 @@ TclOODefineForwardObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineMethodObjCmd --
|
||||
*
|
||||
* Implementation of the "method" subcommand of the "oo::define" and
|
||||
* "oo::objdefine" commands.
|
||||
*
|
||||
@@ -1585,6 +1612,7 @@ TclOODefineMethodObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineMixinObjCmd --
|
||||
*
|
||||
* Implementation of the "mixin" subcommand of the "oo::define" and
|
||||
* "oo::objdefine" commands.
|
||||
*
|
||||
@@ -1628,6 +1656,13 @@ TclOODefineMixinObjCmd(
|
||||
goto freeAndError;
|
||||
}
|
||||
mixins[i-1] = clsPtr;
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount() is in TclOOObjectSetMixins,
|
||||
* TclOOClassSetMixinsk, or just below if this function fails.
|
||||
*/
|
||||
|
||||
AddRef(mixins[i-1]->thisPtr);
|
||||
}
|
||||
|
||||
if (isInstanceMixin) {
|
||||
@@ -1640,6 +1675,9 @@ TclOODefineMixinObjCmd(
|
||||
return TCL_OK;
|
||||
|
||||
freeAndError:
|
||||
while (--i > 0) {
|
||||
TclOODecrRefCount(mixins[i]->thisPtr);
|
||||
}
|
||||
TclStackFree(interp, mixins);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -1648,6 +1686,7 @@ TclOODefineMixinObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineRenameMethodObjCmd --
|
||||
*
|
||||
* Implementation of the "renamemethod" subcommand of the "oo::define"
|
||||
* and "oo::objdefine" commands.
|
||||
*
|
||||
@@ -1704,6 +1743,7 @@ TclOODefineRenameMethodObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineUnexportObjCmd --
|
||||
*
|
||||
* Implementation of the "unexport" subcommand of the "oo::define" and
|
||||
* "oo::objdefine" commands.
|
||||
*
|
||||
@@ -1798,6 +1838,7 @@ TclOODefineUnexportObjCmd(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_ClassSetConstructor, Tcl_ClassSetDestructor --
|
||||
*
|
||||
* How to install a constructor or destructor into a class; API to call
|
||||
* from C.
|
||||
*
|
||||
@@ -1852,6 +1893,7 @@ Tcl_ClassSetDestructor(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* TclOODefineSlots --
|
||||
*
|
||||
* Create the "::oo::Slot" class and its standard instances. Class
|
||||
* definition is empty at the stage (added by scripting).
|
||||
*
|
||||
@@ -1895,6 +1937,7 @@ TclOODefineSlots(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ClassFilterGet, ClassFilterSet --
|
||||
*
|
||||
* Implementation of the "filter" slot accessors of the "oo::define"
|
||||
* command.
|
||||
*
|
||||
@@ -1974,6 +2017,7 @@ ClassFilterSet(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ClassMixinGet, ClassMixinSet --
|
||||
*
|
||||
* Implementation of the "mixin" slot accessors of the "oo::define"
|
||||
* command.
|
||||
*
|
||||
@@ -2055,6 +2099,7 @@ ClassMixinSet(
|
||||
mixins[i] = GetClassInOuterContext(interp, mixinv[i],
|
||||
"may only mix in classes");
|
||||
if (mixins[i] == NULL) {
|
||||
i--;
|
||||
goto freeAndError;
|
||||
}
|
||||
if (TclOOIsReachable(oPtr->classPtr, mixins[i])) {
|
||||
@@ -2063,6 +2108,13 @@ ClassMixinSet(
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
|
||||
goto freeAndError;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount() is in TclOOClassSetMixins, or
|
||||
* just below if this function fails.
|
||||
*/
|
||||
|
||||
AddRef(mixins[i]->thisPtr);
|
||||
}
|
||||
|
||||
TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins);
|
||||
@@ -2070,6 +2122,9 @@ ClassMixinSet(
|
||||
return TCL_OK;
|
||||
|
||||
freeAndError:
|
||||
while (i-- > 0) {
|
||||
TclOODecrRefCount(mixins[i]->thisPtr);
|
||||
}
|
||||
TclStackFree(interp, mixins);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2078,6 +2133,7 @@ ClassMixinSet(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ClassSuperGet, ClassSuperSet --
|
||||
*
|
||||
* Implementation of the "superclass" slot accessors of the "oo::define"
|
||||
* command.
|
||||
*
|
||||
@@ -2172,16 +2228,24 @@ ClassSuperSet(
|
||||
|
||||
if (superc == 0) {
|
||||
superclasses = ckrealloc(superclasses, sizeof(Class *));
|
||||
superclasses[0] = oPtr->fPtr->objectCls;
|
||||
superc = 1;
|
||||
if (TclOOIsReachable(oPtr->fPtr->classCls, oPtr->classPtr)) {
|
||||
superclasses[0] = oPtr->fPtr->classCls;
|
||||
} else {
|
||||
superclasses[0] = oPtr->fPtr->objectCls;
|
||||
}
|
||||
superc = 1;
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount is near the end of this function.
|
||||
*/
|
||||
|
||||
AddRef(superclasses[0]->thisPtr);
|
||||
} else {
|
||||
for (i=0 ; i<superc ; i++) {
|
||||
superclasses[i] = GetClassInOuterContext(interp, superv[i],
|
||||
"only a class can be a superclass");
|
||||
if (superclasses[i] == NULL) {
|
||||
i--;
|
||||
goto failedAfterAlloc;
|
||||
}
|
||||
for (j=0 ; j<i ; j++) {
|
||||
@@ -2198,9 +2262,19 @@ ClassSuperSet(
|
||||
"attempt to form circular dependency graph", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", NULL);
|
||||
failedAfterAlloc:
|
||||
for (; i > 0; i--) {
|
||||
TclOODecrRefCount(superclasses[i]->thisPtr);
|
||||
}
|
||||
ckfree(superclasses);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount() is near the end of this
|
||||
* function.
|
||||
*/
|
||||
|
||||
AddRef(superclasses[i]->thisPtr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2221,6 +2295,12 @@ ClassSuperSet(
|
||||
oPtr->classPtr->superclasses.num = superc;
|
||||
FOREACH(superPtr, oPtr->classPtr->superclasses) {
|
||||
TclOOAddToSubclasses(oPtr->classPtr, superPtr);
|
||||
|
||||
/*
|
||||
* To account for the AddRef() earlier in this function.
|
||||
*/
|
||||
|
||||
TclOODecrRefCount(superPtr->thisPtr);
|
||||
}
|
||||
BumpGlobalEpoch(interp, oPtr->classPtr);
|
||||
|
||||
@@ -2231,6 +2311,7 @@ ClassSuperSet(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ClassVarsGet, ClassVarsSet --
|
||||
*
|
||||
* Implementation of the "variable" slot accessors of the "oo::define"
|
||||
* command.
|
||||
*
|
||||
@@ -2373,6 +2454,7 @@ ClassVarsSet(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ObjectFilterGet, ObjectFilterSet --
|
||||
*
|
||||
* Implementation of the "filter" slot accessors of the "oo::objdefine"
|
||||
* command.
|
||||
*
|
||||
@@ -2440,6 +2522,7 @@ ObjFilterSet(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ObjectMixinGet, ObjectMixinSet --
|
||||
*
|
||||
* Implementation of the "mixin" slot accessors of the "oo::objdefine"
|
||||
* command.
|
||||
*
|
||||
@@ -2511,9 +2594,19 @@ ObjMixinSet(
|
||||
mixins[i] = GetClassInOuterContext(interp, mixinv[i],
|
||||
"may only mix in classes");
|
||||
if (mixins[i] == NULL) {
|
||||
while (i-- > 0) {
|
||||
TclOODecrRefCount(mixins[i]->thisPtr);
|
||||
}
|
||||
TclStackFree(interp, mixins);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Corresponding TclOODecrRefCount() is in TclOOObjectSetMixins() or
|
||||
* just above if this function fails.
|
||||
*/
|
||||
|
||||
AddRef(mixins[i]->thisPtr);
|
||||
}
|
||||
|
||||
TclOOObjectSetMixins(oPtr, mixinc, mixins);
|
||||
@@ -2525,6 +2618,7 @@ ObjMixinSet(
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* ObjectVarsGet, ObjectVarsSet --
|
||||
*
|
||||
* Implementation of the "variable" slot accessors of the "oo::objdefine"
|
||||
* command.
|
||||
*
|
||||
|
||||
+22
-28
@@ -193,9 +193,10 @@ typedef struct Object {
|
||||
* destroyed. */
|
||||
#define DESTRUCTOR_CALLED 2 /* Flag to say that the destructor has been
|
||||
* called. */
|
||||
#define CLASS_GONE 4 /* Indicates that the class of this object has
|
||||
* been deleted, and so the object should not
|
||||
* attempt to remove itself from its class. */
|
||||
#define CLASS_GONE 4 /* Obsolete. Indicates that the class of this
|
||||
* object has been deleted, and so the object
|
||||
* should not attempt to remove itself from its
|
||||
* class. */
|
||||
#define ROOT_OBJECT 0x1000 /* Flag to say that this object is the root of
|
||||
* the class hierarchy and should be treated
|
||||
* specially during teardown. */
|
||||
@@ -222,10 +223,6 @@ typedef struct Object {
|
||||
typedef struct Class {
|
||||
Object *thisPtr; /* Reference to the object associated with
|
||||
* this class. */
|
||||
int refCount; /* Number of strong references to this class.
|
||||
* Weak references are not counted; the
|
||||
* purpose of this is to avoid Tcl_Preserve as
|
||||
* that is quite slow. */
|
||||
int flags; /* Assorted flags. */
|
||||
LIST_STATIC(struct Class *) superclasses;
|
||||
/* List of superclasses, used for generation
|
||||
@@ -495,6 +492,11 @@ MODULE_SCOPE int TclNRNewObjectInstance(Tcl_Interp *interp,
|
||||
const char *nsNameStr, int objc,
|
||||
Tcl_Obj *const *objv, int skip,
|
||||
Tcl_Object *objectPtr);
|
||||
MODULE_SCOPE Object * TclNewObjectInstanceCommon(Tcl_Interp *interp,
|
||||
Class *classPtr,
|
||||
const char *nameStr,
|
||||
const char *nsNameStr);
|
||||
MODULE_SCOPE int TclOODecrRefCount(Object *oPtr);
|
||||
MODULE_SCOPE int TclOODefineSlots(Foundation *fPtr);
|
||||
MODULE_SCOPE void TclOODeleteChain(CallChain *callPtr);
|
||||
MODULE_SCOPE void TclOODeleteChainCache(Tcl_HashTable *tablePtr);
|
||||
@@ -524,10 +526,10 @@ MODULE_SCOPE int TclNRObjectContextInvokeNext(Tcl_Interp *interp,
|
||||
MODULE_SCOPE void TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr,
|
||||
const DeclaredClassMethod *dcm);
|
||||
MODULE_SCOPE Tcl_Obj * TclOOObjectName(Tcl_Interp *interp, Object *oPtr);
|
||||
MODULE_SCOPE void TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
|
||||
MODULE_SCOPE void TclOORemoveFromMixinSubs(Class *subPtr,
|
||||
MODULE_SCOPE int TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
|
||||
MODULE_SCOPE int TclOORemoveFromMixinSubs(Class *subPtr,
|
||||
Class *mixinPtr);
|
||||
MODULE_SCOPE void TclOORemoveFromSubclasses(Class *subPtr,
|
||||
MODULE_SCOPE int TclOORemoveFromSubclasses(Class *subPtr,
|
||||
Class *superPtr);
|
||||
MODULE_SCOPE Tcl_Obj * TclOORenderCallChain(Tcl_Interp *interp,
|
||||
CallChain *callPtr);
|
||||
@@ -541,19 +543,22 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
|
||||
|
||||
#include "tclOOIntDecls.h"
|
||||
|
||||
/*
|
||||
* Alternatives to Tcl_Preserve/Tcl_EventuallyFree/Tcl_Release.
|
||||
*/
|
||||
|
||||
#define AddRef(ptr) ((ptr)->refCount++)
|
||||
|
||||
/*
|
||||
* A convenience macro for iterating through the lists used in the internal
|
||||
* memory management of objects. This is a bit gnarly because we want to do
|
||||
* the assignment of the picked-out value only when the body test succeeds,
|
||||
* but we cannot rely on the assigned value being useful, forcing us to do
|
||||
* some nasty stuff with the comma operator. The compiler's optimizer should
|
||||
* be able to sort it all out!
|
||||
*
|
||||
* memory management of objects.
|
||||
* REQUIRES DECLARATION: int i;
|
||||
*/
|
||||
|
||||
#define FOREACH(var,ary) \
|
||||
for(i=0 ; (i<(ary).num?((var=(ary).list[i]),1):0) ; i++)
|
||||
for(i=0 ; i<(ary).num; i++) if ((ary).list[i] == NULL) { \
|
||||
continue; \
|
||||
} else if (var = (ary).list[i], 1)
|
||||
|
||||
/*
|
||||
* Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
|
||||
@@ -588,17 +593,6 @@ MODULE_SCOPE void TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* Alternatives to Tcl_Preserve/Tcl_EventuallyFree/Tcl_Release.
|
||||
*/
|
||||
|
||||
#define AddRef(ptr) ((ptr)->refCount++)
|
||||
#define DelRef(ptr) do { \
|
||||
if ((ptr)->refCount-- <= 1) { \
|
||||
ckfree(ptr); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#endif /* TCL_OO_INTERNAL_H */
|
||||
|
||||
/*
|
||||
|
||||
+75
-192
@@ -210,9 +210,8 @@ static int SetDoubleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
|
||||
static int SetIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
|
||||
static void UpdateStringOfDouble(Tcl_Obj *objPtr);
|
||||
static void UpdateStringOfInt(Tcl_Obj *objPtr);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
static void UpdateStringOfWideInt(Tcl_Obj *objPtr);
|
||||
static int SetWideIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
|
||||
static void UpdateStringOfOldInt(Tcl_Obj *objPtr);
|
||||
#endif
|
||||
static void FreeBignum(Tcl_Obj *objPtr);
|
||||
static void DupBignum(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
|
||||
@@ -242,6 +241,7 @@ static int SetCmdNameFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
|
||||
* implementations.
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
static const Tcl_ObjType oldBooleanType = {
|
||||
"boolean", /* name */
|
||||
NULL, /* freeIntRepProc */
|
||||
@@ -249,6 +249,7 @@ static const Tcl_ObjType oldBooleanType = {
|
||||
NULL, /* updateStringProc */
|
||||
TclSetBooleanFromAny /* setFromAnyProc */
|
||||
};
|
||||
#endif
|
||||
const Tcl_ObjType tclBooleanType = {
|
||||
"booleanString", /* name */
|
||||
NULL, /* freeIntRepProc */
|
||||
@@ -264,19 +265,23 @@ const Tcl_ObjType tclDoubleType = {
|
||||
SetDoubleFromAny /* setFromAnyProc */
|
||||
};
|
||||
const Tcl_ObjType tclIntType = {
|
||||
#if defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8 || defined(TCL_WIDE_INT_IS_LONG)
|
||||
"int", /* name */
|
||||
#else
|
||||
"wideInt", /* name, keeping maximum compatibility with Tcl 8.6 on 32-bit platforms*/
|
||||
#endif
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
UpdateStringOfInt, /* updateStringProc */
|
||||
SetIntFromAny /* setFromAnyProc */
|
||||
};
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
const Tcl_ObjType tclWideIntType = {
|
||||
"wideInt", /* name */
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
|
||||
static const Tcl_ObjType oldIntType = {
|
||||
"int", /* name */
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
UpdateStringOfWideInt, /* updateStringProc */
|
||||
SetWideIntFromAny /* setFromAnyProc */
|
||||
UpdateStringOfOldInt, /* updateStringProc */
|
||||
SetIntFromAny /* setFromAnyProc */
|
||||
};
|
||||
#endif
|
||||
const Tcl_ObjType tclBignumType = {
|
||||
@@ -344,17 +349,17 @@ typedef struct ResolvedCmdName {
|
||||
* reference (not the namespace that contains
|
||||
* the referenced command). NULL if the name
|
||||
* is fully qualified.*/
|
||||
size_t refNsId; /* refNsPtr's unique namespace id. Used to
|
||||
unsigned long refNsId; /* refNsPtr's unique namespace id. Used to
|
||||
* verify that refNsPtr is still valid (e.g.,
|
||||
* it's possible that the cmd's containing
|
||||
* namespace was deleted and a new one created
|
||||
* at the same address). */
|
||||
size_t refNsCmdEpoch; /* Value of the referencing namespace's
|
||||
unsigned int refNsCmdEpoch; /* Value of the referencing namespace's
|
||||
* cmdRefEpoch when the pointer was cached.
|
||||
* Before using the cached pointer, we check
|
||||
* if the namespace's epoch was incremented;
|
||||
* if so, this cached pointer is invalid. */
|
||||
size_t cmdEpoch; /* Value of the command's cmdEpoch when this
|
||||
unsigned int cmdEpoch; /* Value of the command's cmdEpoch when this
|
||||
* pointer was cached. Before using the cached
|
||||
* pointer, we check if the cmd's epoch was
|
||||
* incremented; if so, the cmd was renamed,
|
||||
@@ -395,8 +400,6 @@ TclInitObjSubsystem(void)
|
||||
|
||||
Tcl_RegisterObjType(&tclByteArrayType);
|
||||
Tcl_RegisterObjType(&tclDoubleType);
|
||||
Tcl_RegisterObjType(&tclEndOffsetType);
|
||||
Tcl_RegisterObjType(&tclIntType);
|
||||
Tcl_RegisterObjType(&tclStringType);
|
||||
Tcl_RegisterObjType(&tclListType);
|
||||
Tcl_RegisterObjType(&tclDictType);
|
||||
@@ -406,9 +409,12 @@ TclInitObjSubsystem(void)
|
||||
Tcl_RegisterObjType(&tclProcBodyType);
|
||||
|
||||
/* For backward compatibility only ... */
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
Tcl_RegisterObjType(&tclIntType);
|
||||
#if !defined(TCL_WIDE_INT_IS_LONG)
|
||||
Tcl_RegisterObjType(&oldIntType);
|
||||
#endif
|
||||
Tcl_RegisterObjType(&oldBooleanType);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
Tcl_RegisterObjType(&tclWideIntType);
|
||||
#endif
|
||||
|
||||
#ifdef TCL_COMPILE_STATS
|
||||
@@ -1762,7 +1768,7 @@ Tcl_NewBooleanObj(
|
||||
{
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclNewLongObj(objPtr, boolValue!=0);
|
||||
TclNewIntObj(objPtr, boolValue!=0);
|
||||
return objPtr;
|
||||
}
|
||||
#endif /* TCL_MEM_DEBUG */
|
||||
@@ -1810,7 +1816,7 @@ Tcl_DbNewBooleanObj(
|
||||
TclDbNewObj(objPtr, file, line);
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
objPtr->internalRep.longValue = (boolValue != 0);
|
||||
objPtr->internalRep.wideValue = (boolValue != 0);
|
||||
objPtr->typePtr = &tclIntType;
|
||||
return objPtr;
|
||||
}
|
||||
@@ -1857,7 +1863,7 @@ Tcl_SetBooleanObj(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetBooleanObj");
|
||||
}
|
||||
|
||||
TclSetLongObj(objPtr, boolValue!=0);
|
||||
TclSetIntObj(objPtr, boolValue!=0);
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
@@ -1888,11 +1894,11 @@ Tcl_GetBooleanFromObj(
|
||||
{
|
||||
do {
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
*boolPtr = (objPtr->internalRep.longValue != 0);
|
||||
*boolPtr = (objPtr->internalRep.wideValue != 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclBooleanType) {
|
||||
*boolPtr = (int) objPtr->internalRep.longValue;
|
||||
*boolPtr = objPtr->internalRep.longValue != 0;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
@@ -1916,12 +1922,6 @@ Tcl_GetBooleanFromObj(
|
||||
*boolPtr = 1;
|
||||
return TCL_OK;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
*boolPtr = (objPtr->internalRep.wideValue != 0);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
} while ((ParseBoolean(objPtr) == TCL_OK) || (TCL_OK ==
|
||||
TclParseNumber(interp, objPtr, "boolean value", NULL,-1,NULL,0)));
|
||||
return TCL_ERROR;
|
||||
@@ -1942,7 +1942,12 @@ Tcl_GetBooleanFromObj(
|
||||
*
|
||||
* Side effects:
|
||||
* If no error occurs, an integer 1 or 0 is stored as "objPtr"s internal
|
||||
* representation and the type of "objPtr" is set to boolean.
|
||||
* representation and the type of "objPtr" is set to boolean or int/wideInt.
|
||||
*
|
||||
* Warning: If the returned type is "wideInt" (32-bit platforms) and your
|
||||
* platform is bigendian, you cannot use internalRep.longValue to distinguish
|
||||
* between false and true. On Windows and most other platforms this still will
|
||||
* work fine, but basically it is non-portable.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
@@ -1960,8 +1965,7 @@ TclSetBooleanFromAny(
|
||||
|
||||
if (objPtr->bytes == NULL) {
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
switch (objPtr->internalRep.longValue) {
|
||||
case 0L: case 1L:
|
||||
if ((Tcl_WideUInt)objPtr->internalRep.wideValue < 2) {
|
||||
return TCL_OK;
|
||||
}
|
||||
goto badBoolean;
|
||||
@@ -1971,12 +1975,6 @@ TclSetBooleanFromAny(
|
||||
goto badBoolean;
|
||||
}
|
||||
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
goto badBoolean;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
goto badBoolean;
|
||||
}
|
||||
@@ -2113,7 +2111,7 @@ ParseBoolean(
|
||||
|
||||
numericBoolean:
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->internalRep.longValue = newBool;
|
||||
objPtr->internalRep.wideValue = newBool;
|
||||
objPtr->typePtr = &tclIntType;
|
||||
return TCL_OK;
|
||||
}
|
||||
@@ -2294,7 +2292,7 @@ Tcl_GetDoubleFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
*dblPtr = objPtr->internalRep.longValue;
|
||||
*dblPtr = (double) objPtr->internalRep.wideValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclBignumType) {
|
||||
@@ -2304,12 +2302,6 @@ Tcl_GetDoubleFromObj(
|
||||
*dblPtr = TclBignumToDouble(&big);
|
||||
return TCL_OK;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
*dblPtr = (double) objPtr->internalRep.wideValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
} while (SetDoubleFromAny(interp, objPtr) == TCL_OK);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -2427,7 +2419,7 @@ Tcl_NewIntObj(
|
||||
{
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclNewLongObj(objPtr, intValue);
|
||||
TclNewIntObj(objPtr, intValue);
|
||||
return objPtr;
|
||||
}
|
||||
#endif /* if TCL_MEM_DEBUG */
|
||||
@@ -2460,7 +2452,7 @@ Tcl_SetIntObj(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetIntObj");
|
||||
}
|
||||
|
||||
TclSetLongObj(objPtr, intValue);
|
||||
TclSetIntObj(objPtr, intValue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2538,9 +2530,8 @@ SetIntFromAny(
|
||||
Tcl_Interp *interp, /* Tcl interpreter */
|
||||
Tcl_Obj *objPtr) /* Pointer to the object to convert */
|
||||
{
|
||||
long l;
|
||||
|
||||
return TclGetLongFromObj(interp, objPtr, &l);
|
||||
Tcl_WideInt w;
|
||||
return Tcl_GetWideIntFromObj(interp, objPtr, &w);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2569,12 +2560,28 @@ UpdateStringOfInt(
|
||||
char buffer[TCL_INTEGER_SPACE];
|
||||
register int len;
|
||||
|
||||
len = TclFormatInt(buffer, objPtr->internalRep.wideValue);
|
||||
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
|
||||
objPtr->length = len;
|
||||
}
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 && !defined(TCL_WIDE_INT_IS_LONG)
|
||||
static void
|
||||
UpdateStringOfOldInt(
|
||||
register Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
{
|
||||
char buffer[TCL_INTEGER_SPACE];
|
||||
register int len;
|
||||
|
||||
len = TclFormatInt(buffer, objPtr->internalRep.longValue);
|
||||
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
|
||||
objPtr->length = len;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2606,8 +2613,8 @@ UpdateStringOfInt(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
#undef Tcl_NewLongObj
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
|
||||
Tcl_Obj *
|
||||
Tcl_NewLongObj(
|
||||
@@ -2626,7 +2633,7 @@ Tcl_NewLongObj(
|
||||
{
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclNewLongObj(objPtr, longValue);
|
||||
TclNewIntObj(objPtr, longValue);
|
||||
return objPtr;
|
||||
}
|
||||
#endif /* if TCL_MEM_DEBUG */
|
||||
@@ -2663,6 +2670,7 @@ Tcl_NewLongObj(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#undef Tcl_DbNewLongObj
|
||||
#ifdef TCL_MEM_DEBUG
|
||||
|
||||
Tcl_Obj *
|
||||
@@ -2679,7 +2687,7 @@ Tcl_DbNewLongObj(
|
||||
TclDbNewObj(objPtr, file, line);
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
objPtr->internalRep.longValue = longValue;
|
||||
objPtr->internalRep.wideValue = longValue;
|
||||
objPtr->typePtr = &tclIntType;
|
||||
return objPtr;
|
||||
}
|
||||
@@ -2717,6 +2725,7 @@ Tcl_DbNewLongObj(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#undef Tcl_SetLongObj
|
||||
void
|
||||
Tcl_SetLongObj(
|
||||
register Tcl_Obj *objPtr, /* Object whose internal rep to init. */
|
||||
@@ -2727,7 +2736,7 @@ Tcl_SetLongObj(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetLongObj");
|
||||
}
|
||||
|
||||
TclSetLongObj(objPtr, longValue);
|
||||
TclSetIntObj(objPtr, longValue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2758,12 +2767,13 @@ Tcl_GetLongFromObj(
|
||||
register long *longPtr) /* Place to store resulting long. */
|
||||
{
|
||||
do {
|
||||
#ifdef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
*longPtr = objPtr->internalRep.longValue;
|
||||
*longPtr = objPtr->internalRep.wideValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
#else
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
/*
|
||||
* We return any integer in the range -ULONG_MAX to ULONG_MAX
|
||||
* converted to a long, ignoring overflow. The rule preserves
|
||||
@@ -2836,49 +2846,6 @@ Tcl_GetLongFromObj(
|
||||
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* UpdateStringOfWideInt --
|
||||
*
|
||||
* Update the string representation for a wide integer object. Note: this
|
||||
* function does not free an existing old string rep so storage will be
|
||||
* lost if this has not already been done.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The object's string is set to a valid string that results from the
|
||||
* wideInt-to-string conversion.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
UpdateStringOfWideInt(
|
||||
register Tcl_Obj *objPtr) /* Int object whose string rep to update. */
|
||||
{
|
||||
char buffer[TCL_INTEGER_SPACE+2];
|
||||
register unsigned len;
|
||||
register Tcl_WideInt wideVal = objPtr->internalRep.wideValue;
|
||||
|
||||
/*
|
||||
* Note that sprintf will generate a compiler warning under Mingw claiming
|
||||
* %I64 is an unknown format specifier. Just ignore this warning. We can't
|
||||
* use %L as the format specifier since that gets printed as a 32 bit
|
||||
* value.
|
||||
*/
|
||||
|
||||
sprintf(buffer, "%" TCL_LL_MODIFIER "d", wideVal);
|
||||
len = strlen(buffer);
|
||||
objPtr->bytes = ckalloc(len + 1);
|
||||
memcpy(objPtr->bytes, buffer, len + 1);
|
||||
objPtr->length = len;
|
||||
}
|
||||
#endif /* !TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -2928,7 +2895,7 @@ Tcl_NewWideIntObj(
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclNewObj(objPtr);
|
||||
Tcl_SetWideIntObj(objPtr, wideValue);
|
||||
TclSetIntObj(objPtr, wideValue);
|
||||
return objPtr;
|
||||
}
|
||||
#endif /* if TCL_MEM_DEBUG */
|
||||
@@ -2980,7 +2947,7 @@ Tcl_DbNewWideIntObj(
|
||||
register Tcl_Obj *objPtr;
|
||||
|
||||
TclDbNewObj(objPtr, file, line);
|
||||
Tcl_SetWideIntObj(objPtr, wideValue);
|
||||
TclSetIntObj(objPtr, wideValue);
|
||||
return objPtr;
|
||||
}
|
||||
|
||||
@@ -3029,19 +2996,7 @@ Tcl_SetWideIntObj(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetWideIntObj");
|
||||
}
|
||||
|
||||
if ((wideValue >= (Tcl_WideInt) LONG_MIN)
|
||||
&& (wideValue <= (Tcl_WideInt) LONG_MAX)) {
|
||||
TclSetLongObj(objPtr, (long) wideValue);
|
||||
} else {
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
TclSetWideIntObj(objPtr, wideValue);
|
||||
#else
|
||||
mp_int big;
|
||||
|
||||
TclInitBignumFromWideInt(&big, wideValue);
|
||||
Tcl_SetBignumObj(objPtr, &big);
|
||||
#endif
|
||||
}
|
||||
TclSetIntObj(objPtr, wideValue);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3073,14 +3028,8 @@ Tcl_GetWideIntFromObj(
|
||||
/* Place to store resulting long. */
|
||||
{
|
||||
do {
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
*wideIntPtr = objPtr->internalRep.wideValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
*wideIntPtr = (Tcl_WideInt) objPtr->internalRep.longValue;
|
||||
*wideIntPtr = objPtr->internalRep.wideValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
@@ -3133,33 +3082,6 @@ Tcl_GetWideIntFromObj(
|
||||
TCL_PARSE_INTEGER_ONLY)==TCL_OK);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* SetWideIntFromAny --
|
||||
*
|
||||
* Attempts to force the internal representation for a Tcl object to
|
||||
* tclWideIntType, specifically.
|
||||
*
|
||||
* Results:
|
||||
* The return value is a standard object Tcl result. If an error occurs
|
||||
* during conversion, an error message is left in the interpreter's
|
||||
* result unless "interp" is NULL.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
SetWideIntFromAny(
|
||||
Tcl_Interp *interp, /* Tcl interpreter */
|
||||
Tcl_Obj *objPtr) /* Pointer to the object to convert */
|
||||
{
|
||||
Tcl_WideInt w;
|
||||
return Tcl_GetWideIntFromObj(interp, objPtr, &w);
|
||||
}
|
||||
#endif /* !TCL_WIDE_INT_IS_LONG */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -3402,16 +3324,10 @@ GetBignumFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
TclInitBignumFromLong(bignumValue, objPtr->internalRep.longValue);
|
||||
return TCL_OK;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
TclInitBignumFromWideInt(bignumValue,
|
||||
objPtr->internalRep.wideValue);
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
if (objPtr->typePtr == &tclDoubleType) {
|
||||
if (interp != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
@@ -3521,36 +3437,11 @@ Tcl_SetBignumObj(
|
||||
Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj");
|
||||
}
|
||||
if ((size_t) bignumValue->used
|
||||
<= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT) {
|
||||
unsigned long value = 0, numBytes = sizeof(long);
|
||||
long scratch;
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
|
||||
goto tooLargeForLong;
|
||||
}
|
||||
while (numBytes-- > 0) {
|
||||
value = (value << CHAR_BIT) | *bytes++;
|
||||
}
|
||||
if (value > (((~(unsigned long)0) >> 1) + bignumValue->sign)) {
|
||||
goto tooLargeForLong;
|
||||
}
|
||||
if (bignumValue->sign) {
|
||||
TclSetLongObj(objPtr, -(long)value);
|
||||
} else {
|
||||
TclSetLongObj(objPtr, (long)value);
|
||||
}
|
||||
mp_clear(bignumValue);
|
||||
return;
|
||||
}
|
||||
tooLargeForLong:
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if ((size_t) bignumValue->used
|
||||
<= (CHAR_BIT * sizeof(Tcl_WideInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
|
||||
<= (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
|
||||
Tcl_WideUInt value = 0;
|
||||
unsigned long numBytes = sizeof(Tcl_WideInt);
|
||||
Tcl_WideInt scratch;
|
||||
unsigned char *bytes = (unsigned char *)&scratch;
|
||||
unsigned long numBytes = sizeof(Tcl_WideUInt);
|
||||
Tcl_WideUInt scratch;
|
||||
unsigned char *bytes = (unsigned char *) &scratch;
|
||||
|
||||
if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
|
||||
goto tooLargeForWide;
|
||||
@@ -3562,15 +3453,14 @@ Tcl_SetBignumObj(
|
||||
goto tooLargeForWide;
|
||||
}
|
||||
if (bignumValue->sign) {
|
||||
TclSetWideIntObj(objPtr, -(Tcl_WideInt)value);
|
||||
TclSetIntObj(objPtr, -(Tcl_WideInt)value);
|
||||
} else {
|
||||
TclSetWideIntObj(objPtr, (Tcl_WideInt)value);
|
||||
TclSetIntObj(objPtr, (Tcl_WideInt)value);
|
||||
}
|
||||
mp_clear(bignumValue);
|
||||
return;
|
||||
}
|
||||
tooLargeForWide:
|
||||
#endif
|
||||
TclInvalidateStringRep(objPtr);
|
||||
TclFreeIntRep(objPtr);
|
||||
TclSetBignumIntRep(objPtr, bignumValue);
|
||||
@@ -3652,17 +3542,10 @@ TclGetNumberFromObj(
|
||||
return TCL_OK;
|
||||
}
|
||||
if (objPtr->typePtr == &tclIntType) {
|
||||
*typePtr = TCL_NUMBER_LONG;
|
||||
*clientDataPtr = &objPtr->internalRep.longValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (objPtr->typePtr == &tclWideIntType) {
|
||||
*typePtr = TCL_NUMBER_WIDE;
|
||||
*clientDataPtr = &objPtr->internalRep.wideValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
#endif
|
||||
if (objPtr->typePtr == &tclBignumType) {
|
||||
static Tcl_ThreadDataKey bignumKey;
|
||||
mp_int *bigPtr = Tcl_GetThreadData(&bignumKey,
|
||||
|
||||
@@ -1809,7 +1809,6 @@ Tcl_FSGetNormalizedPath(
|
||||
*/
|
||||
|
||||
(void) TclGetStringFromObj(dir, &cwdLen);
|
||||
cwdLen += (Tcl_GetString(copy)[cwdLen] == '/');
|
||||
|
||||
/* Normalize the combined string. */
|
||||
|
||||
@@ -1831,12 +1830,12 @@ Tcl_FSGetNormalizedPath(
|
||||
* normalized head, we can more efficiently normalize the combined
|
||||
* path by passing over only the unnormalized tail portion. When
|
||||
* this is sufficient, prior developers claim this should be much
|
||||
* faster. We use 'cwdLen-1' so that we are already pointing at
|
||||
* faster. We use 'cwdLen' so that we are already pointing at
|
||||
* the dir-separator that we know about. The normalization code
|
||||
* will actually start off directly after that separator.
|
||||
*/
|
||||
|
||||
TclFSNormalizeToUniquePath(interp, copy, cwdLen-1);
|
||||
TclFSNormalizeToUniquePath(interp, copy, cwdLen);
|
||||
}
|
||||
|
||||
/* Now we need to construct the new path object. */
|
||||
|
||||
+21
-57
@@ -221,13 +221,13 @@ Tcl_ReapDetachedProcs(void)
|
||||
{
|
||||
register Detached *detPtr;
|
||||
Detached *nextPtr, *prevPtr;
|
||||
int status;
|
||||
Tcl_Pid pid;
|
||||
int status, code;
|
||||
|
||||
Tcl_MutexLock(&pipeMutex);
|
||||
for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) {
|
||||
pid = Tcl_WaitPid(detPtr->pid, &status, WNOHANG);
|
||||
if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) {
|
||||
status = TclProcessWait(detPtr->pid, WNOHANG, &code, NULL, NULL);
|
||||
if (status == TCL_PROCESS_UNCHANGED || (status == TCL_PROCESS_ERROR
|
||||
&& code != ECHILD)) {
|
||||
prevPtr = detPtr;
|
||||
detPtr = detPtr->nextPtr;
|
||||
continue;
|
||||
@@ -277,38 +277,21 @@ TclCleanupChildren(
|
||||
{
|
||||
int result = TCL_OK;
|
||||
int i, abnormalExit, anyErrorInfo;
|
||||
Tcl_Pid pid;
|
||||
int waitStatus;
|
||||
const char *msg;
|
||||
unsigned long resolvedPid;
|
||||
TclProcessWaitStatus waitStatus;
|
||||
int code;
|
||||
Tcl_Obj *msg, *error;
|
||||
|
||||
abnormalExit = 0;
|
||||
for (i = 0; i < numPids; i++) {
|
||||
/*
|
||||
* We need to get the resolved pid before we wait on it as the windows
|
||||
* implementation of Tcl_WaitPid deletes the information such that any
|
||||
* following calls to TclpGetPid fail.
|
||||
*/
|
||||
|
||||
resolvedPid = TclpGetPid(pidPtr[i]);
|
||||
pid = Tcl_WaitPid(pidPtr[i], &waitStatus, 0);
|
||||
if (pid == (Tcl_Pid) -1) {
|
||||
waitStatus = TclProcessWait(pidPtr[i], 0, &code, &msg, &error);
|
||||
if (waitStatus == TCL_PROCESS_ERROR) {
|
||||
result = TCL_ERROR;
|
||||
if (interp != NULL) {
|
||||
msg = Tcl_PosixError(interp);
|
||||
if (errno == ECHILD) {
|
||||
/*
|
||||
* This changeup in message suggested by Mark Diekhans to
|
||||
* remind people that ECHILD errors can occur on some
|
||||
* systems if SIGCHLD isn't in its default state.
|
||||
*/
|
||||
|
||||
msg =
|
||||
"child process lost (is SIGCHLD ignored or trapped?)";
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"error waiting for process to exit: %s", msg));
|
||||
Tcl_SetObjErrorCode(interp, error);
|
||||
Tcl_SetObjResult(interp, msg);
|
||||
}
|
||||
Tcl_DecrRefCount(error);
|
||||
Tcl_DecrRefCount(msg);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -319,39 +302,19 @@ TclCleanupChildren(
|
||||
* removed).
|
||||
*/
|
||||
|
||||
if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) {
|
||||
char msg1[TCL_INTEGER_SPACE], msg2[TCL_INTEGER_SPACE];
|
||||
|
||||
if (waitStatus != TCL_PROCESS_EXITED || code != 0) {
|
||||
result = TCL_ERROR;
|
||||
sprintf(msg1, "%lu", resolvedPid);
|
||||
if (WIFEXITED(waitStatus)) {
|
||||
if (waitStatus == TCL_PROCESS_EXITED) {
|
||||
if (interp != NULL) {
|
||||
sprintf(msg2, "%u", WEXITSTATUS(waitStatus));
|
||||
Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, NULL);
|
||||
Tcl_SetObjErrorCode(interp, error);
|
||||
}
|
||||
abnormalExit = 1;
|
||||
} else if (interp != NULL) {
|
||||
const char *p;
|
||||
|
||||
if (WIFSIGNALED(waitStatus)) {
|
||||
p = Tcl_SignalMsg(WTERMSIG(waitStatus));
|
||||
Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
|
||||
Tcl_SignalId(WTERMSIG(waitStatus)), p, NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"child killed: %s\n", p));
|
||||
} else if (WIFSTOPPED(waitStatus)) {
|
||||
p = Tcl_SignalMsg(WSTOPSIG(waitStatus));
|
||||
Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
|
||||
Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"child suspended: %s\n", p));
|
||||
} else {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"child wait status didn't make sense\n", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
|
||||
"ODDWAITRESULT", msg1, NULL);
|
||||
}
|
||||
Tcl_SetObjErrorCode(interp, error);
|
||||
Tcl_SetObjResult(interp, msg);
|
||||
}
|
||||
Tcl_DecrRefCount(error);
|
||||
Tcl_DecrRefCount(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -936,6 +899,7 @@ TclCreatePipeline(
|
||||
|
||||
pidPtr[numPids] = pid;
|
||||
numPids++;
|
||||
TclProcessCreated(pid);
|
||||
|
||||
/*
|
||||
* Close off our copies of file descriptors that were set up for this
|
||||
|
||||
+466
-312
@@ -65,6 +65,18 @@ typedef struct Package {
|
||||
const void *clientData; /* Client data. */
|
||||
} Package;
|
||||
|
||||
typedef struct Require {
|
||||
void * clientDataPtr;
|
||||
const char *name;
|
||||
Package *pkgPtr;
|
||||
char *versionToProvide;
|
||||
} Require;
|
||||
|
||||
typedef struct RequireProcArgs {
|
||||
const char *name;
|
||||
void *clientDataPtr;
|
||||
} RequireProcArgs;
|
||||
|
||||
/*
|
||||
* Prototypes for functions defined in this file:
|
||||
*/
|
||||
@@ -85,9 +97,15 @@ static void AddRequirementsToResult(Tcl_Interp *interp, int reqc,
|
||||
static void AddRequirementsToDString(Tcl_DString *dstring,
|
||||
int reqc, Tcl_Obj *const reqv[]);
|
||||
static Package * FindPackage(Tcl_Interp *interp, const char *name);
|
||||
static const char * PkgRequireCore(Tcl_Interp *interp, const char *name,
|
||||
int reqc, Tcl_Obj *const reqv[],
|
||||
void *clientDataPtr);
|
||||
static int PkgRequireCore(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static int PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static int PkgRequireCoreCleanup(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static int PkgRequireCoreStep1(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static int PkgRequireCoreStep2(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static int TclNRPkgRequireProc(ClientData clientData, Tcl_Interp *interp, int reqc, Tcl_Obj *const reqv[]);
|
||||
static int SelectPackage(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static int SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result);
|
||||
static int TclNRPackageObjCmdCleanup(ClientData data[], Tcl_Interp *interp, int result);
|
||||
|
||||
/*
|
||||
* Helper macros.
|
||||
@@ -365,7 +383,10 @@ Tcl_PkgRequireEx(
|
||||
*/
|
||||
|
||||
if (version == NULL) {
|
||||
result = PkgRequireCore(interp, name, 0, NULL, clientDataPtr);
|
||||
if (Tcl_PkgRequireProc(interp, name, 0, NULL, clientDataPtr) == TCL_OK) {
|
||||
result = Tcl_GetStringResult(interp);
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
} else {
|
||||
if (exact && TCL_OK
|
||||
!= CheckVersionAndConvert(interp, version, NULL, NULL)) {
|
||||
@@ -376,10 +397,12 @@ Tcl_PkgRequireEx(
|
||||
Tcl_AppendStringsToObj(ov, "-", version, NULL);
|
||||
}
|
||||
Tcl_IncrRefCount(ov);
|
||||
result = PkgRequireCore(interp, name, 1, &ov, clientDataPtr);
|
||||
if (Tcl_PkgRequireProc(interp, name, 1, &ov, clientDataPtr) == TCL_OK) {
|
||||
result = Tcl_GetStringResult(interp);
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
TclDecrRefCount(ov);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -394,320 +417,130 @@ Tcl_PkgRequireProc(
|
||||
* available. */
|
||||
void *clientDataPtr)
|
||||
{
|
||||
const char *result =
|
||||
PkgRequireCore(interp, name, reqc, reqv, clientDataPtr);
|
||||
RequireProcArgs args;
|
||||
args.name = name;
|
||||
args.clientDataPtr = clientDataPtr;
|
||||
return Tcl_NRCallObjProc(interp, TclNRPkgRequireProc, (void *)&args, reqc, reqv);
|
||||
}
|
||||
|
||||
if (result == NULL) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1));
|
||||
static int
|
||||
TclNRPkgRequireProc(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int reqc,
|
||||
Tcl_Obj *const reqv[]) {
|
||||
RequireProcArgs *args = clientData;
|
||||
Tcl_NRAddCallback(interp, PkgRequireCore, (void *)args->name, INT2PTR(reqc), (void *)reqv, args->clientDataPtr);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static const char *
|
||||
PkgRequireCore(
|
||||
Tcl_Interp *interp, /* Interpreter in which package is now
|
||||
* available. */
|
||||
const char *name, /* Name of desired package. */
|
||||
int reqc, /* Requirements constraining the desired
|
||||
* version. */
|
||||
Tcl_Obj *const reqv[], /* 0 means to use the latest version
|
||||
* available. */
|
||||
void *clientDataPtr)
|
||||
static int
|
||||
PkgRequireCore(ClientData data[], Tcl_Interp *interp, int result)
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
Package *pkgPtr;
|
||||
PkgAvail *availPtr, *bestPtr, *bestStablePtr;
|
||||
char *availVersion, *bestVersion;
|
||||
/* Internal rep. of versions */
|
||||
int availStable, code, satisfies, pass;
|
||||
char *script, *pkgVersionI;
|
||||
const char *name = data[0];
|
||||
int reqc = PTR2INT(data[1]);
|
||||
Tcl_Obj *const *reqv = data[2];
|
||||
int code = CheckAllRequirements(interp, reqc, reqv);
|
||||
Require *reqPtr;
|
||||
if (code != TCL_OK) {
|
||||
return code;
|
||||
}
|
||||
reqPtr = ckalloc(sizeof(Require));
|
||||
Tcl_NRAddCallback(interp, PkgRequireCoreCleanup, reqPtr, NULL, NULL, NULL);
|
||||
reqPtr->clientDataPtr = data[3];
|
||||
reqPtr->name = name;
|
||||
reqPtr->pkgPtr = FindPackage(interp, name);
|
||||
if (reqPtr->pkgPtr->version == NULL) {
|
||||
Tcl_NRAddCallback(interp, SelectPackage, reqPtr, INT2PTR(reqc), (void *)reqv, PkgRequireCoreStep1);
|
||||
} else {
|
||||
Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
PkgRequireCoreStep1(ClientData data[], Tcl_Interp *interp, int result) {
|
||||
Tcl_DString command;
|
||||
char *script;
|
||||
Require *reqPtr = data[0];
|
||||
int reqc = PTR2INT(data[1]);
|
||||
Tcl_Obj **const reqv = data[2];
|
||||
const char *name = reqPtr->name /* Name of desired package. */;
|
||||
if (reqPtr->pkgPtr->version == NULL) {
|
||||
/*
|
||||
* The package is not in the database. If there is a "package unknown"
|
||||
* command, invoke it.
|
||||
*/
|
||||
|
||||
if (TCL_OK != CheckAllRequirements(interp, reqc, reqv)) {
|
||||
return NULL;
|
||||
script = ((Interp *) interp)->packageUnknown;
|
||||
if (script == NULL) {
|
||||
Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
|
||||
} else {
|
||||
Tcl_DStringInit(&command);
|
||||
Tcl_DStringAppend(&command, script, -1);
|
||||
Tcl_DStringAppendElement(&command, name);
|
||||
AddRequirementsToDString(&command, reqc, reqv);
|
||||
|
||||
Tcl_NRAddCallback(interp, PkgRequireCoreStep2, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
|
||||
Tcl_NREvalObj(interp,
|
||||
Tcl_NewStringObj(Tcl_DStringValue(&command), Tcl_DStringLength(&command)),
|
||||
TCL_EVAL_GLOBAL
|
||||
);
|
||||
Tcl_DStringFree(&command);
|
||||
}
|
||||
return TCL_OK;
|
||||
} else {
|
||||
Tcl_NRAddCallback(interp, PkgRequireCoreFinal, reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* It can take up to three passes to find the package: one pass to run the
|
||||
* "package unknown" script, one to run the "package ifneeded" script for
|
||||
* a specific version, and a final pass to lookup the package loaded by
|
||||
* the "package ifneeded" script.
|
||||
*/
|
||||
|
||||
for (pass=1 ;; pass++) {
|
||||
pkgPtr = FindPackage(interp, name);
|
||||
if (pkgPtr->version != NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether we're already attempting to load some version of this
|
||||
* package (circular dependency detection).
|
||||
*/
|
||||
|
||||
if (pkgPtr->clientData != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"circular package dependency:"
|
||||
" attempt to provide %s %s requires %s",
|
||||
name, (char *) pkgPtr->clientData, name));
|
||||
AddRequirementsToResult(interp, reqc, reqv);
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* The package isn't yet present. Search the list of available
|
||||
* versions and invoke the script for the best available version. We
|
||||
* are actually locating the best, and the best stable version. One of
|
||||
* them is then chosen based on the selection mode.
|
||||
*/
|
||||
|
||||
bestPtr = NULL;
|
||||
bestStablePtr = NULL;
|
||||
bestVersion = NULL;
|
||||
|
||||
for (availPtr = pkgPtr->availPtr; availPtr != NULL;
|
||||
availPtr = availPtr->nextPtr) {
|
||||
if (CheckVersionAndConvert(interp, availPtr->version,
|
||||
&availVersion, &availStable) != TCL_OK) {
|
||||
/*
|
||||
* The provided version number has invalid syntax. This
|
||||
* should not happen. This should have been caught by the
|
||||
* 'package ifneeded' registering the package.
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bestPtr != NULL) {
|
||||
int res = CompareVersions(availVersion, bestVersion, NULL);
|
||||
|
||||
/*
|
||||
* Note: Use internal reps!
|
||||
*/
|
||||
|
||||
if (res <= 0) {
|
||||
/*
|
||||
* The version of the package sought is not as good as the
|
||||
* currently selected version. Ignore it.
|
||||
*/
|
||||
|
||||
ckfree(availVersion);
|
||||
availVersion = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We have found a version which is better than our max.
|
||||
*/
|
||||
|
||||
if (reqc > 0) {
|
||||
/* Check satisfaction of requirements. */
|
||||
|
||||
satisfies = SomeRequirementSatisfied(availVersion, reqc, reqv);
|
||||
if (!satisfies) {
|
||||
ckfree(availVersion);
|
||||
availVersion = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bestPtr = availPtr;
|
||||
|
||||
if (bestVersion != NULL) {
|
||||
ckfree(bestVersion);
|
||||
}
|
||||
bestVersion = availVersion;
|
||||
|
||||
/*
|
||||
* If this new best version is stable then it also has to be
|
||||
* better than the max stable version found so far.
|
||||
*/
|
||||
|
||||
if (availStable) {
|
||||
bestStablePtr = availPtr;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestVersion != NULL) {
|
||||
ckfree(bestVersion);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now choose a version among the two best. For 'latest' we simply
|
||||
* take (actually keep) the best. For 'stable' we take the best
|
||||
* stable, if there is any, or the best if there is nothing stable.
|
||||
*/
|
||||
|
||||
if ((iPtr->packagePrefer == PKG_PREFER_STABLE)
|
||||
&& (bestStablePtr != NULL)) {
|
||||
bestPtr = bestStablePtr;
|
||||
}
|
||||
|
||||
if (bestPtr != NULL) {
|
||||
/*
|
||||
* We found an ifneeded script for the package. Be careful while
|
||||
* executing it: this could cause reentrancy, so (a) protect the
|
||||
* script itself from deletion and (b) don't assume that bestPtr
|
||||
* will still exist when the script completes.
|
||||
*/
|
||||
|
||||
char *versionToProvide = bestPtr->version;
|
||||
PkgFiles *pkgFiles;
|
||||
PkgName *pkgName;
|
||||
script = bestPtr->script;
|
||||
|
||||
pkgPtr->clientData = versionToProvide;
|
||||
Tcl_Preserve(versionToProvide);
|
||||
Tcl_Preserve(script);
|
||||
pkgFiles = TclInitPkgFiles(interp);
|
||||
/* Push "ifneeded" package name in "tclPkgFiles" assocdata. */
|
||||
pkgName = ckalloc(sizeof(PkgName) + strlen(name));
|
||||
pkgName->nextPtr = pkgFiles->names;
|
||||
strcpy(pkgName->name, name);
|
||||
pkgFiles->names = pkgName;
|
||||
if (bestPtr->pkgIndex) {
|
||||
TclPkgFileSeen(interp, bestPtr->pkgIndex);
|
||||
}
|
||||
code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
|
||||
/* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/
|
||||
pkgFiles->names = pkgName->nextPtr;
|
||||
ckfree(pkgName);
|
||||
Tcl_Release(script);
|
||||
|
||||
pkgPtr = FindPackage(interp, name);
|
||||
if (code == TCL_OK) {
|
||||
Tcl_ResetResult(interp);
|
||||
if (pkgPtr->version == NULL) {
|
||||
code = TCL_ERROR;
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"attempt to provide package %s %s failed:"
|
||||
" no version of package %s provided",
|
||||
name, versionToProvide, name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED",
|
||||
NULL);
|
||||
} else {
|
||||
char *pvi, *vi;
|
||||
|
||||
if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi,
|
||||
NULL) != TCL_OK) {
|
||||
code = TCL_ERROR;
|
||||
} else if (CheckVersionAndConvert(interp,
|
||||
versionToProvide, &vi, NULL) != TCL_OK) {
|
||||
ckfree(pvi);
|
||||
code = TCL_ERROR;
|
||||
} else {
|
||||
int res = CompareVersions(pvi, vi, NULL);
|
||||
|
||||
ckfree(pvi);
|
||||
ckfree(vi);
|
||||
if (res != 0) {
|
||||
code = TCL_ERROR;
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"attempt to provide package %s %s failed:"
|
||||
" package %s %s provided instead",
|
||||
name, versionToProvide,
|
||||
name, pkgPtr->version));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE",
|
||||
"WRONGPROVIDE", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (code != TCL_ERROR) {
|
||||
Tcl_Obj *codePtr = Tcl_NewIntObj(code);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"attempt to provide package %s %s failed:"
|
||||
" bad return code: %s",
|
||||
name, versionToProvide, TclGetString(codePtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
|
||||
TclDecrRefCount(codePtr);
|
||||
code = TCL_ERROR;
|
||||
}
|
||||
|
||||
if (code == TCL_ERROR) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (\"package ifneeded %s %s\" script)",
|
||||
name, versionToProvide));
|
||||
}
|
||||
Tcl_Release(versionToProvide);
|
||||
|
||||
if (code != TCL_OK) {
|
||||
/*
|
||||
* Take a non-TCL_OK code from the script as an indication the
|
||||
* package wasn't loaded properly, so the package system
|
||||
* should not remember an improper load.
|
||||
*
|
||||
* This is consistent with our returning NULL. If we're not
|
||||
* willing to tell our caller we got a particular version, we
|
||||
* shouldn't store that version for telling future callers
|
||||
* either.
|
||||
*/
|
||||
|
||||
if (pkgPtr->version != NULL) {
|
||||
ckfree(pkgPtr->version);
|
||||
pkgPtr->version = NULL;
|
||||
}
|
||||
pkgPtr->clientData = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* The package is not in the database. If there is a "package unknown"
|
||||
* command, invoke it (but only on the first pass; after that, we
|
||||
* should not get here in the first place).
|
||||
*/
|
||||
|
||||
if (pass > 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
script = ((Interp *) interp)->packageUnknown;
|
||||
if (script != NULL) {
|
||||
Tcl_DStringInit(&command);
|
||||
Tcl_DStringAppend(&command, script, -1);
|
||||
Tcl_DStringAppendElement(&command, name);
|
||||
AddRequirementsToDString(&command, reqc, reqv);
|
||||
|
||||
code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
|
||||
Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
|
||||
Tcl_DStringFree(&command);
|
||||
|
||||
if ((code != TCL_OK) && (code != TCL_ERROR)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad return code: %d", code));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
|
||||
code = TCL_ERROR;
|
||||
}
|
||||
if (code == TCL_ERROR) {
|
||||
Tcl_AddErrorInfo(interp,
|
||||
"\n (\"package unknown\" script)");
|
||||
return NULL;
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
static int
|
||||
PkgRequireCoreStep2(ClientData data[], Tcl_Interp *interp, int result) {
|
||||
Require *reqPtr = data[0];
|
||||
int reqc = PTR2INT(data[1]);
|
||||
Tcl_Obj **const reqv = data[2];
|
||||
const char *name = reqPtr->name /* Name of desired package. */;
|
||||
if ((result != TCL_OK) && (result != TCL_ERROR)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"bad return code: %d", result));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
if (result == TCL_ERROR) {
|
||||
Tcl_AddErrorInfo(interp,
|
||||
"\n (\"package unknown\" script)");
|
||||
return result;
|
||||
}
|
||||
Tcl_ResetResult(interp);
|
||||
/* pkgPtr may now be invalid, so refresh it. */
|
||||
reqPtr->pkgPtr = FindPackage(interp, name);
|
||||
Tcl_NRAddCallback(interp, SelectPackage, reqPtr, INT2PTR(reqc), (void *)reqv, PkgRequireCoreFinal);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (pkgPtr->version == NULL) {
|
||||
static int
|
||||
PkgRequireCoreFinal(ClientData data[], Tcl_Interp *interp, int result) {
|
||||
Require *reqPtr = data[0];
|
||||
int reqc = PTR2INT(data[1]), satisfies;
|
||||
Tcl_Obj **const reqv = data[2];
|
||||
char *pkgVersionI;
|
||||
void *clientDataPtr = reqPtr->clientDataPtr;
|
||||
const char *name = reqPtr->name /* Name of desired package. */;
|
||||
if (reqPtr->pkgPtr->version == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't find package %s", name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNFOUND", NULL);
|
||||
AddRequirementsToResult(interp, reqc, reqv);
|
||||
return NULL;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point we know that the package is present. Make sure that the
|
||||
* provided version meets the current requirements.
|
||||
* Ensure that the provided version meets the current requirements.
|
||||
*/
|
||||
|
||||
if (reqc != 0) {
|
||||
CheckVersionAndConvert(interp, pkgPtr->version, &pkgVersionI, NULL);
|
||||
CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pkgVersionI, NULL);
|
||||
satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv);
|
||||
|
||||
ckfree(pkgVersionI);
|
||||
@@ -715,20 +548,301 @@ PkgRequireCore(
|
||||
if (!satisfies) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"version conflict for package \"%s\": have %s, need",
|
||||
name, pkgPtr->version));
|
||||
name, reqPtr->pkgPtr->version));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT",
|
||||
NULL);
|
||||
AddRequirementsToResult(interp, reqc, reqv);
|
||||
return NULL;
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (clientDataPtr) {
|
||||
const void **ptr = (const void **) clientDataPtr;
|
||||
|
||||
*ptr = pkgPtr->clientData;
|
||||
*ptr = reqPtr->pkgPtr->clientData;
|
||||
}
|
||||
return pkgPtr->version;
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(reqPtr->pkgPtr->version, -1));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
PkgRequireCoreCleanup(ClientData data[], Tcl_Interp *interp, int result) {
|
||||
ckfree(data[0]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
SelectPackage(ClientData data[], Tcl_Interp *interp, int result) {
|
||||
PkgAvail *availPtr, *bestPtr, *bestStablePtr;
|
||||
char *availVersion, *bestVersion, *bestStableVersion;
|
||||
/* Internal rep. of versions */
|
||||
int availStable, satisfies;
|
||||
Require *reqPtr = data[0];
|
||||
int reqc = PTR2INT(data[1]);
|
||||
Tcl_Obj **const reqv = data[2];
|
||||
const char *name = reqPtr->name;
|
||||
Package *pkgPtr = reqPtr->pkgPtr;
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
|
||||
/*
|
||||
* Check whether we're already attempting to load some version of this
|
||||
* package (circular dependency detection).
|
||||
*/
|
||||
|
||||
if (pkgPtr->clientData != NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"circular package dependency:"
|
||||
" attempt to provide %s %s requires %s",
|
||||
name, (char *) pkgPtr->clientData, name));
|
||||
AddRequirementsToResult(interp, reqc, reqv);
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* The package isn't yet present. Search the list of available
|
||||
* versions and invoke the script for the best available version. We
|
||||
* are actually locating the best, and the best stable version. One of
|
||||
* them is then chosen based on the selection mode.
|
||||
*/
|
||||
|
||||
bestPtr = NULL;
|
||||
bestStablePtr = NULL;
|
||||
bestVersion = NULL;
|
||||
bestStableVersion = NULL;
|
||||
|
||||
for (availPtr = pkgPtr->availPtr; availPtr != NULL;
|
||||
availPtr = availPtr->nextPtr) {
|
||||
if (CheckVersionAndConvert(interp, availPtr->version,
|
||||
&availVersion, &availStable) != TCL_OK) {
|
||||
/*
|
||||
* The provided version number has invalid syntax. This
|
||||
* should not happen. This should have been caught by the
|
||||
* 'package ifneeded' registering the package.
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check satisfaction of requirements before considering the current version further. */
|
||||
if (reqc > 0) {
|
||||
satisfies = SomeRequirementSatisfied(availVersion, reqc, reqv);
|
||||
if (!satisfies) {
|
||||
ckfree(availVersion);
|
||||
availVersion = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (bestPtr != NULL) {
|
||||
int res = CompareVersions(availVersion, bestVersion, NULL);
|
||||
|
||||
/*
|
||||
* Note: Used internal reps in the comparison!
|
||||
*/
|
||||
|
||||
if (res > 0) {
|
||||
/*
|
||||
* The version of the package sought is better than the
|
||||
* currently selected version.
|
||||
*/
|
||||
ckfree(bestVersion);
|
||||
bestVersion = NULL;
|
||||
goto newbest;
|
||||
}
|
||||
} else {
|
||||
newbest:
|
||||
/* We have found a version which is better than our max. */
|
||||
|
||||
bestPtr = availPtr;
|
||||
CheckVersionAndConvert(interp, bestPtr->version, &bestVersion, NULL);
|
||||
}
|
||||
|
||||
if (!availStable) {
|
||||
ckfree(availVersion);
|
||||
availVersion = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bestStablePtr != NULL) {
|
||||
int res = CompareVersions(availVersion, bestStableVersion, NULL);
|
||||
|
||||
/*
|
||||
* Note: Used internal reps in the comparison!
|
||||
*/
|
||||
|
||||
if (res > 0) {
|
||||
/*
|
||||
* This stable version of the package sought is better
|
||||
* than the currently selected stable version.
|
||||
*/
|
||||
ckfree(bestStableVersion);
|
||||
bestStableVersion = NULL;
|
||||
goto newstable;
|
||||
}
|
||||
} else {
|
||||
newstable:
|
||||
/* We have found a stable version which is better than our max stable. */
|
||||
bestStablePtr = availPtr;
|
||||
CheckVersionAndConvert(interp, bestStablePtr->version, &bestStableVersion, NULL);
|
||||
}
|
||||
|
||||
ckfree(availVersion);
|
||||
availVersion = NULL;
|
||||
} /* end for */
|
||||
|
||||
/*
|
||||
* Clean up memorized internal reps, if any.
|
||||
*/
|
||||
|
||||
if (bestVersion != NULL) {
|
||||
ckfree(bestVersion);
|
||||
bestVersion = NULL;
|
||||
}
|
||||
|
||||
if (bestStableVersion != NULL) {
|
||||
ckfree(bestStableVersion);
|
||||
bestStableVersion = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now choose a version among the two best. For 'latest' we simply
|
||||
* take (actually keep) the best. For 'stable' we take the best
|
||||
* stable, if there is any, or the best if there is nothing stable.
|
||||
*/
|
||||
|
||||
if ((iPtr->packagePrefer == PKG_PREFER_STABLE)
|
||||
&& (bestStablePtr != NULL)) {
|
||||
bestPtr = bestStablePtr;
|
||||
}
|
||||
|
||||
if (bestPtr == NULL) {
|
||||
Tcl_NRAddCallback(interp, data[3], reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
|
||||
} else {
|
||||
/*
|
||||
* We found an ifneeded script for the package. Be careful while
|
||||
* executing it: this could cause reentrancy, so (a) protect the
|
||||
* script itself from deletion and (b) don't assume that bestPtr
|
||||
* will still exist when the script completes.
|
||||
*/
|
||||
|
||||
char *versionToProvide = bestPtr->version;
|
||||
PkgFiles *pkgFiles;
|
||||
PkgName *pkgName;
|
||||
|
||||
Tcl_Preserve(versionToProvide);
|
||||
pkgPtr->clientData = versionToProvide;
|
||||
|
||||
pkgFiles = TclInitPkgFiles(interp);
|
||||
/* Push "ifneeded" package name in "tclPkgFiles" assocdata. */
|
||||
pkgName = ckalloc(sizeof(PkgName) + strlen(name));
|
||||
pkgName->nextPtr = pkgFiles->names;
|
||||
strcpy(pkgName->name, name);
|
||||
pkgFiles->names = pkgName;
|
||||
if (bestPtr->pkgIndex) {
|
||||
TclPkgFileSeen(interp, bestPtr->pkgIndex);
|
||||
}
|
||||
reqPtr->versionToProvide = versionToProvide;
|
||||
Tcl_NRAddCallback(interp, SelectPackageFinal, reqPtr, INT2PTR(reqc), (void *)reqv, data[3]);
|
||||
Tcl_NREvalObj(interp, Tcl_NewStringObj(bestPtr->script, -1), TCL_EVAL_GLOBAL);
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
SelectPackageFinal(ClientData data[], Tcl_Interp *interp, int result) {
|
||||
Require *reqPtr = data[0];
|
||||
int reqc = PTR2INT(data[1]);
|
||||
Tcl_Obj **const reqv = data[2];
|
||||
const char *name = reqPtr->name;
|
||||
char *versionToProvide = reqPtr->versionToProvide;
|
||||
|
||||
/* Pop the "ifneeded" package name from "tclPkgFiles" assocdata*/
|
||||
PkgFiles *pkgFiles = Tcl_GetAssocData(interp, "tclPkgFiles", NULL);
|
||||
PkgName *pkgName = pkgFiles->names;
|
||||
pkgFiles->names = pkgName->nextPtr;
|
||||
ckfree(pkgName);
|
||||
|
||||
reqPtr->pkgPtr = FindPackage(interp, name);
|
||||
if (result == TCL_OK) {
|
||||
Tcl_ResetResult(interp);
|
||||
if (reqPtr->pkgPtr->version == NULL) {
|
||||
result = TCL_ERROR;
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"attempt to provide package %s %s failed:"
|
||||
" no version of package %s provided",
|
||||
name, versionToProvide, name));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED",
|
||||
NULL);
|
||||
} else {
|
||||
char *pvi, *vi;
|
||||
|
||||
if (CheckVersionAndConvert(interp, reqPtr->pkgPtr->version, &pvi,
|
||||
NULL) != TCL_OK) {
|
||||
result = TCL_ERROR;
|
||||
} else if (CheckVersionAndConvert(interp,
|
||||
versionToProvide, &vi, NULL) != TCL_OK) {
|
||||
ckfree(pvi);
|
||||
result = TCL_ERROR;
|
||||
} else {
|
||||
int res = CompareVersions(pvi, vi, NULL);
|
||||
|
||||
ckfree(pvi);
|
||||
ckfree(vi);
|
||||
if (res != 0) {
|
||||
result = TCL_ERROR;
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"attempt to provide package %s %s failed:"
|
||||
" package %s %s provided instead",
|
||||
name, versionToProvide,
|
||||
name, reqPtr->pkgPtr->version));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE",
|
||||
"WRONGPROVIDE", NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (result != TCL_ERROR) {
|
||||
Tcl_Obj *codePtr = Tcl_NewIntObj(result);
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"attempt to provide package %s %s failed:"
|
||||
" bad return code: %s",
|
||||
name, versionToProvide, TclGetString(codePtr)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
|
||||
TclDecrRefCount(codePtr);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
|
||||
if (result == TCL_ERROR) {
|
||||
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
|
||||
"\n (\"package ifneeded %s %s\" script)",
|
||||
name, versionToProvide));
|
||||
}
|
||||
Tcl_Release(versionToProvide);
|
||||
|
||||
if (result != TCL_OK) {
|
||||
/*
|
||||
* Take a non-TCL_OK code from the script as an indication the
|
||||
* package wasn't loaded properly, so the package system
|
||||
* should not remember an improper load.
|
||||
*
|
||||
* This is consistent with our returning NULL. If we're not
|
||||
* willing to tell our caller we got a particular version, we
|
||||
* shouldn't store that version for telling future callers
|
||||
* either.
|
||||
*/
|
||||
|
||||
if (reqPtr->pkgPtr->version != NULL) {
|
||||
ckfree(reqPtr->pkgPtr->version);
|
||||
reqPtr->pkgPtr->version = NULL;
|
||||
}
|
||||
reqPtr->pkgPtr->clientData = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
Tcl_NRAddCallback(interp, data[3], reqPtr, INT2PTR(reqc), (void *)reqv, NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -834,10 +948,19 @@ Tcl_PkgPresentEx(
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
Tcl_PackageObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
return Tcl_NRCallObjProc(interp, TclNRPackageObjCmd, NULL, objc, objv);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
Tcl_PackageObjCmd(
|
||||
TclNRPackageObjCmd(
|
||||
ClientData dummy, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
@@ -854,7 +977,7 @@ Tcl_PackageObjCmd(
|
||||
PKG_VERSIONS, PKG_VSATISFIES
|
||||
};
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
int optionIndex, exact, i, satisfies;
|
||||
int optionIndex, exact, i, newobjc, satisfies;
|
||||
PkgAvail *availPtr, *prevPtr;
|
||||
Package *pkgPtr;
|
||||
Tcl_HashEntry *hPtr;
|
||||
@@ -863,6 +986,7 @@ Tcl_PackageObjCmd(
|
||||
const char *version;
|
||||
const char *argv2, *argv3, *argv4;
|
||||
char *iva = NULL, *ivb = NULL;
|
||||
Tcl_Obj *objvListPtr, **newObjvPtr;
|
||||
|
||||
if (objc < 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
|
||||
@@ -921,6 +1045,7 @@ Tcl_PackageObjCmd(
|
||||
Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC);
|
||||
if (availPtr->pkgIndex) {
|
||||
Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC);
|
||||
availPtr->pkgIndex = NULL;
|
||||
}
|
||||
ckfree(availPtr);
|
||||
}
|
||||
@@ -974,6 +1099,7 @@ Tcl_PackageObjCmd(
|
||||
Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC);
|
||||
if (availPtr->pkgIndex) {
|
||||
Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC);
|
||||
availPtr->pkgIndex = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -985,7 +1111,7 @@ Tcl_PackageObjCmd(
|
||||
}
|
||||
if (availPtr == NULL) {
|
||||
availPtr = ckalloc(sizeof(PkgAvail));
|
||||
availPtr->pkgIndex = 0;
|
||||
availPtr->pkgIndex = NULL;
|
||||
DupBlock(availPtr->version, argv3, (unsigned) length + 1);
|
||||
|
||||
if (prevPtr == NULL) {
|
||||
@@ -1106,7 +1232,6 @@ Tcl_PackageObjCmd(
|
||||
argv2 = TclGetString(objv[2]);
|
||||
if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) {
|
||||
Tcl_Obj *ov;
|
||||
int res;
|
||||
|
||||
if (objc != 5) {
|
||||
goto requireSyntax;
|
||||
@@ -1126,17 +1251,38 @@ Tcl_PackageObjCmd(
|
||||
Tcl_AppendStringsToObj(ov, "-", version, NULL);
|
||||
version = NULL;
|
||||
argv3 = TclGetString(objv[3]);
|
||||
Tcl_IncrRefCount(objv[3]);
|
||||
|
||||
Tcl_IncrRefCount(ov);
|
||||
res = Tcl_PkgRequireProc(interp, argv3, 1, &ov, NULL);
|
||||
TclDecrRefCount(ov);
|
||||
return res;
|
||||
objvListPtr = Tcl_NewListObj(0, NULL);
|
||||
Tcl_IncrRefCount(objvListPtr);
|
||||
Tcl_ListObjAppendElement(interp, objvListPtr, ov);
|
||||
Tcl_ListObjGetElements(interp, objvListPtr, &newobjc, &newObjvPtr);
|
||||
|
||||
Tcl_NRAddCallback(interp, TclNRPackageObjCmdCleanup, objv[3], objvListPtr, NULL, NULL);
|
||||
Tcl_NRAddCallback(interp, PkgRequireCore, (void *)argv3, INT2PTR(newobjc), newObjvPtr, NULL);
|
||||
return TCL_OK;
|
||||
} else {
|
||||
int i, newobjc = objc-3;
|
||||
Tcl_Obj *const *newobjv = objv + 3;
|
||||
if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objvListPtr = Tcl_NewListObj(0, NULL);
|
||||
Tcl_IncrRefCount(objvListPtr);
|
||||
Tcl_IncrRefCount(objv[2]);
|
||||
for (i = 0; i < newobjc; i++) {
|
||||
|
||||
return Tcl_PkgRequireProc(interp, argv2, objc-3, objv+3, NULL);
|
||||
/*
|
||||
* Tcl_Obj structures may have come from another interpreter,
|
||||
* so duplicate them.
|
||||
*/
|
||||
|
||||
Tcl_ListObjAppendElement(interp, objvListPtr, Tcl_DuplicateObj(newobjv[i]));
|
||||
}
|
||||
Tcl_ListObjGetElements(interp, objvListPtr, &newobjc, &newObjvPtr);
|
||||
Tcl_NRAddCallback(interp, TclNRPackageObjCmdCleanup, objv[2], objvListPtr, NULL, NULL);
|
||||
Tcl_NRAddCallback(interp, PkgRequireCore, (void *)argv2, INT2PTR(newobjc), newObjvPtr, NULL);
|
||||
return TCL_OK;
|
||||
}
|
||||
break;
|
||||
case PKG_UNKNOWN: {
|
||||
@@ -1276,6 +1422,13 @@ Tcl_PackageObjCmd(
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
TclNRPackageObjCmdCleanup(ClientData data[], Tcl_Interp *interp, int result) {
|
||||
TclDecrRefCount((Tcl_Obj *)data[0]);
|
||||
TclDecrRefCount((Tcl_Obj *)data[1]);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1357,6 +1510,7 @@ TclFreePackageInfo(
|
||||
Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC);
|
||||
if (availPtr->pkgIndex) {
|
||||
Tcl_EventuallyFree(availPtr->pkgIndex, TCL_DYNAMIC);
|
||||
availPtr->pkgIndex = NULL;
|
||||
}
|
||||
ckfree(availPtr);
|
||||
}
|
||||
|
||||
+57
-93
@@ -124,11 +124,10 @@ Tcl_ProcObjCmd(
|
||||
{
|
||||
register Interp *iPtr = (Interp *) interp;
|
||||
Proc *procPtr;
|
||||
const char *fullName;
|
||||
const char *procName, *procArgs, *procBody;
|
||||
const char *procName;
|
||||
const char *simpleName, *procArgs, *procBody;
|
||||
Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
|
||||
Tcl_Command cmd;
|
||||
Tcl_DString ds;
|
||||
|
||||
if (objc != 4) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "name args body");
|
||||
@@ -141,29 +140,21 @@ Tcl_ProcObjCmd(
|
||||
* namespace.
|
||||
*/
|
||||
|
||||
fullName = TclGetString(objv[1]);
|
||||
TclGetNamespaceForQualName(interp, fullName, NULL, 0,
|
||||
&nsPtr, &altNsPtr, &cxtNsPtr, &procName);
|
||||
procName = TclGetString(objv[1]);
|
||||
TclGetNamespaceForQualName(interp, procName, NULL, 0,
|
||||
&nsPtr, &altNsPtr, &cxtNsPtr, &simpleName);
|
||||
|
||||
if (nsPtr == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\": unknown namespace",
|
||||
fullName));
|
||||
procName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (procName == NULL) {
|
||||
if (simpleName == NULL) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\": bad procedure name",
|
||||
fullName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if ((nsPtr != iPtr->globalNsPtr)
|
||||
&& (procName != NULL) && (procName[0] == ':')) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"can't create procedure \"%s\" in non-global namespace with"
|
||||
" name starting with \":\"", procName));
|
||||
procName));
|
||||
Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
@@ -172,31 +163,16 @@ Tcl_ProcObjCmd(
|
||||
* Create the data structure to represent the procedure.
|
||||
*/
|
||||
|
||||
if (TclCreateProc(interp, nsPtr, procName, objv[2], objv[3],
|
||||
if (TclCreateProc(interp, nsPtr, simpleName, objv[2], objv[3],
|
||||
&procPtr) != TCL_OK) {
|
||||
Tcl_AddErrorInfo(interp, "\n (creating proc \"");
|
||||
Tcl_AddErrorInfo(interp, procName);
|
||||
Tcl_AddErrorInfo(interp, simpleName);
|
||||
Tcl_AddErrorInfo(interp, "\")");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now create a command for the procedure. This will initially be in the
|
||||
* current namespace unless the procedure's name included namespace
|
||||
* qualifiers. To create the new command in the right namespace, we
|
||||
* generate a fully qualified name for it.
|
||||
*/
|
||||
|
||||
Tcl_DStringInit(&ds);
|
||||
if (nsPtr != iPtr->globalNsPtr) {
|
||||
Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
|
||||
TclDStringAppendLiteral(&ds, "::");
|
||||
}
|
||||
Tcl_DStringAppend(&ds, procName, -1);
|
||||
|
||||
cmd = Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds), TclObjInterpProc,
|
||||
TclNRInterpProc, procPtr, TclProcDeleteProc);
|
||||
Tcl_DStringFree(&ds);
|
||||
cmd = TclNRCreateCommandInNs(interp, simpleName, (Tcl_Namespace *) nsPtr,
|
||||
TclObjInterpProc, TclNRInterpProc, procPtr, TclProcDeleteProc);
|
||||
|
||||
/*
|
||||
* Now initialize the new procedure's cmdPtr field. This will be used
|
||||
@@ -393,13 +369,13 @@ TclCreateProc(
|
||||
Proc **procPtrPtr) /* Returns: pointer to proc data. */
|
||||
{
|
||||
Interp *iPtr = (Interp *) interp;
|
||||
const char **argArray = NULL;
|
||||
|
||||
register Proc *procPtr;
|
||||
int i, length, result, numArgs;
|
||||
const char *args, *bytes, *p;
|
||||
int i, result, numArgs, plen;
|
||||
const char *bytes, *argname, *argnamei;
|
||||
char argnamelast;
|
||||
register CompiledLocal *localPtr = NULL;
|
||||
Tcl_Obj *defPtr;
|
||||
Tcl_Obj *defPtr, *errorObj, **argArray;
|
||||
int precompiled = 0;
|
||||
|
||||
if (bodyPtr->typePtr == &tclProcBodyType) {
|
||||
@@ -436,6 +412,7 @@ TclCreateProc(
|
||||
*/
|
||||
|
||||
if (Tcl_IsShared(bodyPtr)) {
|
||||
int length;
|
||||
Tcl_Obj *sharedBodyPtr = bodyPtr;
|
||||
|
||||
bytes = TclGetStringFromObj(bodyPtr, &length);
|
||||
@@ -473,12 +450,9 @@ TclCreateProc(
|
||||
* argument specifier. If the body is precompiled, processing is limited
|
||||
* to checking that the parsed argument is consistent with the one stored
|
||||
* in the Proc.
|
||||
*
|
||||
* THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULS.
|
||||
*/
|
||||
|
||||
args = TclGetStringFromObj(argsPtr, &length);
|
||||
result = Tcl_SplitList(interp, args, &numArgs, &argArray);
|
||||
result = Tcl_ListObjGetElements(interp , argsPtr ,&numArgs ,&argArray);
|
||||
if (result != TCL_OK) {
|
||||
goto procError;
|
||||
}
|
||||
@@ -502,28 +476,28 @@ TclCreateProc(
|
||||
for (i = 0; i < numArgs; i++) {
|
||||
int fieldCount, nameLength;
|
||||
size_t valueLength;
|
||||
const char **fieldValues;
|
||||
Tcl_Obj **fieldValues;
|
||||
|
||||
/*
|
||||
* Now divide the specifier up into name and default.
|
||||
*/
|
||||
|
||||
result = Tcl_SplitList(interp, argArray[i], &fieldCount,
|
||||
result = Tcl_ListObjGetElements(interp, argArray[i], &fieldCount,
|
||||
&fieldValues);
|
||||
if (result != TCL_OK) {
|
||||
goto procError;
|
||||
}
|
||||
if (fieldCount > 2) {
|
||||
ckfree(fieldValues);
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"too many fields in argument specifier \"%s\"",
|
||||
argArray[i]));
|
||||
errorObj = Tcl_NewStringObj(
|
||||
"too many fields in argument specifier \"", -1);
|
||||
Tcl_AppendObjToObj(errorObj, argArray[i]);
|
||||
Tcl_AppendToObj(errorObj, "\"", -1);
|
||||
Tcl_SetObjResult(interp, errorObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
|
||||
"FORMALARGUMENTFORMAT", NULL);
|
||||
goto procError;
|
||||
}
|
||||
if ((fieldCount == 0) || (*fieldValues[0] == 0)) {
|
||||
ckfree(fieldValues);
|
||||
if ((fieldCount == 0) || (fieldValues[0]->length == 0)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"argument with no name", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
|
||||
@@ -531,9 +505,10 @@ TclCreateProc(
|
||||
goto procError;
|
||||
}
|
||||
|
||||
nameLength = strlen(fieldValues[0]);
|
||||
nameLength = Tcl_NumUtfChars(Tcl_GetString(fieldValues[0]), fieldValues[0]->length);
|
||||
if (fieldCount == 2) {
|
||||
valueLength = strlen(fieldValues[1]);
|
||||
valueLength = Tcl_NumUtfChars(Tcl_GetString(fieldValues[1]),
|
||||
fieldValues[1]->length);
|
||||
} else {
|
||||
valueLength = 0;
|
||||
}
|
||||
@@ -542,33 +517,29 @@ TclCreateProc(
|
||||
* Check that the formal parameter name is a scalar.
|
||||
*/
|
||||
|
||||
p = fieldValues[0];
|
||||
while (*p != '\0') {
|
||||
if (*p == '(') {
|
||||
const char *q = p;
|
||||
do {
|
||||
q++;
|
||||
} while (*q != '\0');
|
||||
q--;
|
||||
if (*q == ')') { /* We have an array element. */
|
||||
argname = Tcl_GetStringFromObj(fieldValues[0], &plen);
|
||||
argnamei = argname;
|
||||
argnamelast = argname[plen-1];
|
||||
while (plen--) {
|
||||
if (argnamei[0] == '(') {
|
||||
if (argnamelast == ')') { /* We have an array element. */
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"formal parameter \"%s\" is an array element",
|
||||
fieldValues[0]));
|
||||
ckfree(fieldValues);
|
||||
Tcl_GetString(fieldValues[0])));
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
|
||||
"FORMALARGUMENTFORMAT", NULL);
|
||||
goto procError;
|
||||
}
|
||||
} else if ((*p == ':') && (*(p+1) == ':')) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"formal parameter \"%s\" is not a simple name",
|
||||
fieldValues[0]));
|
||||
ckfree(fieldValues);
|
||||
} else if ((argnamei[0] == ':') && (argnamei[1] == ':')) {
|
||||
errorObj = Tcl_NewStringObj("formal parameter \"", -1);
|
||||
Tcl_AppendObjToObj(errorObj, fieldValues[0]);
|
||||
Tcl_AppendToObj(errorObj, "\" is not a simple name", -1);
|
||||
Tcl_SetObjResult(interp, errorObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
|
||||
"FORMALARGUMENTFORMAT", NULL);
|
||||
goto procError;
|
||||
}
|
||||
p++;
|
||||
argnamei = Tcl_UtfNext(argnamei);
|
||||
}
|
||||
|
||||
if (precompiled) {
|
||||
@@ -584,7 +555,7 @@ TclCreateProc(
|
||||
*/
|
||||
|
||||
if ((localPtr->nameLength != nameLength)
|
||||
|| (strcmp(localPtr->name, fieldValues[0]))
|
||||
|| (Tcl_UtfNcmp(localPtr->name, argname, nameLength))
|
||||
|| (localPtr->frameIndex != i)
|
||||
|| !(localPtr->flags & VAR_ARGUMENT)
|
||||
|| (localPtr->defValuePtr == NULL && fieldCount == 2)
|
||||
@@ -592,7 +563,6 @@ TclCreateProc(
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"procedure \"%s\": formal parameter %d is "
|
||||
"inconsistent with precompiled body", procName, i));
|
||||
ckfree(fieldValues);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
|
||||
"BYTECODELIES", NULL);
|
||||
goto procError;
|
||||
@@ -607,12 +577,13 @@ TclCreateProc(
|
||||
size_t tmpLength = localPtr->defValuePtr->length;
|
||||
|
||||
if ((valueLength != tmpLength) ||
|
||||
strncmp(fieldValues[1], tmpPtr, tmpLength)) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"procedure \"%s\": formal parameter \"%s\" has "
|
||||
"default value inconsistent with precompiled body",
|
||||
procName, fieldValues[0]));
|
||||
ckfree(fieldValues);
|
||||
Tcl_UtfNcmp(Tcl_GetString(fieldValues[1]), tmpPtr, tmpLength)) {
|
||||
errorObj = Tcl_ObjPrintf(
|
||||
"procedure \"%s\": formal parameter \"" ,procName);
|
||||
Tcl_AppendObjToObj(errorObj, fieldValues[0]);
|
||||
Tcl_AppendToObj(errorObj, "\" has "
|
||||
"default value inconsistent with precompiled body", -1);
|
||||
Tcl_SetObjResult(interp, errorObj);
|
||||
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
|
||||
"BYTECODELIES", NULL);
|
||||
goto procError;
|
||||
@@ -632,7 +603,7 @@ TclCreateProc(
|
||||
* local variables for the argument.
|
||||
*/
|
||||
|
||||
localPtr = ckalloc(TclOffset(CompiledLocal, name) + nameLength+1);
|
||||
localPtr = ckalloc(TclOffset(CompiledLocal, name) + fieldValues[0]->length +1);
|
||||
if (procPtr->firstLocalPtr == NULL) {
|
||||
procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
|
||||
} else {
|
||||
@@ -640,19 +611,18 @@ TclCreateProc(
|
||||
procPtr->lastLocalPtr = localPtr;
|
||||
}
|
||||
localPtr->nextPtr = NULL;
|
||||
localPtr->nameLength = nameLength;
|
||||
localPtr->nameLength = Tcl_NumUtfChars(argname, fieldValues[0]->length);
|
||||
localPtr->frameIndex = i;
|
||||
localPtr->flags = VAR_ARGUMENT;
|
||||
localPtr->resolveInfo = NULL;
|
||||
|
||||
if (fieldCount == 2) {
|
||||
localPtr->defValuePtr =
|
||||
Tcl_NewStringObj(fieldValues[1], valueLength);
|
||||
localPtr->defValuePtr = fieldValues[1];
|
||||
Tcl_IncrRefCount(localPtr->defValuePtr);
|
||||
} else {
|
||||
localPtr->defValuePtr = NULL;
|
||||
}
|
||||
memcpy(localPtr->name, fieldValues[0], nameLength + 1);
|
||||
memcpy(localPtr->name, argname, fieldValues[0]->length + 1);
|
||||
if ((i == numArgs - 1)
|
||||
&& (localPtr->nameLength == 4)
|
||||
&& (localPtr->name[0] == 'a')
|
||||
@@ -660,12 +630,9 @@ TclCreateProc(
|
||||
localPtr->flags |= VAR_IS_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
ckfree(fieldValues);
|
||||
}
|
||||
|
||||
*procPtrPtr = procPtr;
|
||||
ckfree(argArray);
|
||||
return TCL_OK;
|
||||
|
||||
procError:
|
||||
@@ -686,9 +653,6 @@ TclCreateProc(
|
||||
}
|
||||
ckfree(procPtr);
|
||||
}
|
||||
if (argArray != NULL) {
|
||||
ckfree(argArray);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -826,7 +790,7 @@ TclObjGetFrame(
|
||||
level = curLevel - level;
|
||||
result = 1;
|
||||
} else if (objPtr->typePtr == &levelReferenceType) {
|
||||
level = (int) objPtr->internalRep.longValue;
|
||||
level = (int) objPtr->internalRep.wideValue;
|
||||
result = 1;
|
||||
} else {
|
||||
name = TclGetString(objPtr);
|
||||
@@ -834,7 +798,7 @@ TclObjGetFrame(
|
||||
if (TCL_OK == Tcl_GetInt(NULL, name+1, &level) && level >= 0) {
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->typePtr = &levelReferenceType;
|
||||
objPtr->internalRep.longValue = level;
|
||||
objPtr->internalRep.wideValue = level;
|
||||
result = 1;
|
||||
} else {
|
||||
result = -1;
|
||||
@@ -2416,7 +2380,7 @@ FreeLambdaInternalRep(
|
||||
Proc *procPtr = objPtr->internalRep.twoPtrValue.ptr1;
|
||||
Tcl_Obj *nsObjPtr = objPtr->internalRep.twoPtrValue.ptr2;
|
||||
|
||||
if (procPtr->refCount-- == 1) {
|
||||
if (procPtr->refCount-- <= 1) {
|
||||
TclProcCleanupProc(procPtr);
|
||||
}
|
||||
TclDecrRefCount(nsObjPtr);
|
||||
|
||||
@@ -0,0 +1,952 @@
|
||||
/*
|
||||
* tclProcess.c --
|
||||
*
|
||||
* This file implements the "tcl::process" ensemble for subprocess
|
||||
* management as defined by TIP #462.
|
||||
*
|
||||
* Copyright (c) 2017 Frederic Bonnet.
|
||||
*
|
||||
* See the file "license.terms" for information on usage and redistribution of
|
||||
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
|
||||
/*
|
||||
* Autopurge flag. Process-global because of the way Tcl manages child
|
||||
* processes (see tclPipe.c).
|
||||
*/
|
||||
|
||||
static int autopurge = 1; /* Autopurge flag. */
|
||||
|
||||
/*
|
||||
* Hash tables that keeps track of all child process statuses. Keys are the
|
||||
* child process ids and resolved pids, values are (ProcessInfo *).
|
||||
*/
|
||||
|
||||
typedef struct ProcessInfo {
|
||||
Tcl_Pid pid; /* Process id. */
|
||||
int resolvedPid; /* Resolved process id. */
|
||||
int purge; /* Purge eventualy. */
|
||||
TclProcessWaitStatus status;/* Process status. */
|
||||
int code; /* Error code, exit status or signal
|
||||
number. */
|
||||
Tcl_Obj *msg; /* Error message. */
|
||||
Tcl_Obj *error; /* Error code. */
|
||||
} ProcessInfo;
|
||||
static Tcl_HashTable infoTablePerPid;
|
||||
static Tcl_HashTable infoTablePerResolvedPid;
|
||||
static int infoTablesInitialized = 0; /* 0 means not yet initialized. */
|
||||
TCL_DECLARE_MUTEX(infoTablesMutex)
|
||||
|
||||
/*
|
||||
* Prototypes for functions defined later in this file:
|
||||
*/
|
||||
|
||||
static void InitProcessInfo(ProcessInfo *info, Tcl_Pid pid,
|
||||
int resolvedPid);
|
||||
static void FreeProcessInfo(ProcessInfo *info);
|
||||
static int RefreshProcessInfo(ProcessInfo *info, int options);
|
||||
static TclProcessWaitStatus WaitProcessStatus(Tcl_Pid pid, int resolvedPid,
|
||||
int options, int *codePtr, Tcl_Obj **msgPtr,
|
||||
Tcl_Obj **errorObjPtr);
|
||||
static Tcl_Obj * BuildProcessStatusObj(ProcessInfo *info);
|
||||
static int ProcessListObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int ProcessStatusObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int ProcessPurgeObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int ProcessAutopurgeObjCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* InitProcessInfo --
|
||||
*
|
||||
* Initializes the ProcessInfo structure.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Memory written.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
InitProcessInfo(
|
||||
ProcessInfo *info, /* Structure to initialize. */
|
||||
Tcl_Pid pid, /* Process id. */
|
||||
int resolvedPid) /* Resolved process id. */
|
||||
{
|
||||
info->pid = pid;
|
||||
info->resolvedPid = resolvedPid;
|
||||
info->purge = 0;
|
||||
info->status = TCL_PROCESS_UNCHANGED;
|
||||
info->code = 0;
|
||||
info->msg = NULL;
|
||||
info->error = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* FreeProcessInfo --
|
||||
*
|
||||
* Free the ProcessInfo structure.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Memory deallocated, Tcl_Obj refcount decreased.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
FreeProcessInfo(
|
||||
ProcessInfo *info) /* Structure to free. */
|
||||
{
|
||||
/*
|
||||
* Free stored Tcl_Objs.
|
||||
*/
|
||||
|
||||
if (info->msg) {
|
||||
Tcl_DecrRefCount(info->msg);
|
||||
}
|
||||
if (info->error) {
|
||||
Tcl_DecrRefCount(info->error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free allocated structure.
|
||||
*/
|
||||
|
||||
ckfree(info);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* RefreshProcessInfo --
|
||||
*
|
||||
* Refresh process info.
|
||||
*
|
||||
* Results:
|
||||
* Nonzero if state changed, else zero.
|
||||
*
|
||||
* Side effects:
|
||||
* May call WaitProcessStatus, which can block if WNOHANG option is set.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
RefreshProcessInfo(
|
||||
ProcessInfo *info, /* Structure to refresh. */
|
||||
int options /* Options passed to WaitProcessStatus. */
|
||||
)
|
||||
{
|
||||
if (info->status == TCL_PROCESS_UNCHANGED) {
|
||||
/*
|
||||
* Refresh & store status.
|
||||
*/
|
||||
|
||||
info->status = WaitProcessStatus(info->pid, info->resolvedPid,
|
||||
options, &info->code, &info->msg, &info->error);
|
||||
if (info->msg) Tcl_IncrRefCount(info->msg);
|
||||
if (info->error) Tcl_IncrRefCount(info->error);
|
||||
return (info->status != TCL_PROCESS_UNCHANGED);
|
||||
} else {
|
||||
/*
|
||||
* No change.
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* WaitProcessStatus --
|
||||
*
|
||||
* Wait for process status to change.
|
||||
*
|
||||
* Results:
|
||||
* TclProcessWaitStatus enum value.
|
||||
*
|
||||
* Side effects:
|
||||
* May call WaitProcessStatus, which can block if WNOHANG option is set.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
TclProcessWaitStatus
|
||||
WaitProcessStatus(
|
||||
Tcl_Pid pid, /* Process id. */
|
||||
int resolvedPid, /* Resolved process id. */
|
||||
int options, /* Options passed to Tcl_WaitPid. */
|
||||
int *codePtr, /* If non-NULL, will receive either:
|
||||
* - 0 for normal exit.
|
||||
* - errno in case of error.
|
||||
* - non-zero exit code for abormal exit.
|
||||
* - signal number if killed or suspended.
|
||||
* - Tcl_WaitPid status in all other cases.
|
||||
*/
|
||||
Tcl_Obj **msgObjPtr, /* If non-NULL, will receive error message. */
|
||||
Tcl_Obj **errorObjPtr) /* If non-NULL, will receive error code. */
|
||||
{
|
||||
int waitStatus;
|
||||
Tcl_Obj *errorStrings[5];
|
||||
const char *msg;
|
||||
|
||||
pid = Tcl_WaitPid(pid, &waitStatus, options);
|
||||
if ((pid == 0)) {
|
||||
/*
|
||||
* No change.
|
||||
*/
|
||||
|
||||
return TCL_PROCESS_UNCHANGED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get process status.
|
||||
*/
|
||||
|
||||
if (pid == (Tcl_Pid) -1) {
|
||||
/*
|
||||
* POSIX errName msg
|
||||
*/
|
||||
|
||||
msg = Tcl_ErrnoMsg(errno);
|
||||
if (errno == ECHILD) {
|
||||
/*
|
||||
* This changeup in message suggested by Mark Diekhans to
|
||||
* remind people that ECHILD errors can occur on some
|
||||
* systems if SIGCHLD isn't in its default state.
|
||||
*/
|
||||
|
||||
msg = "child process lost (is SIGCHLD ignored or trapped?)";
|
||||
}
|
||||
if (codePtr) *codePtr = errno;
|
||||
if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf(
|
||||
"error waiting for process to exit: %s", msg);
|
||||
if (errorObjPtr) {
|
||||
errorStrings[0] = Tcl_NewStringObj("POSIX", -1);
|
||||
errorStrings[1] = Tcl_NewStringObj(Tcl_ErrnoId(), -1);
|
||||
errorStrings[2] = Tcl_NewStringObj(msg, -1);
|
||||
*errorObjPtr = Tcl_NewListObj(3, errorStrings);
|
||||
}
|
||||
return TCL_PROCESS_ERROR;
|
||||
} else if (WIFEXITED(waitStatus)) {
|
||||
if (codePtr) *codePtr = WEXITSTATUS(waitStatus);
|
||||
if (!WEXITSTATUS(waitStatus)) {
|
||||
/*
|
||||
* Normal exit.
|
||||
*/
|
||||
|
||||
if (msgObjPtr) *msgObjPtr = NULL;
|
||||
if (errorObjPtr) *errorObjPtr = NULL;
|
||||
} else {
|
||||
/*
|
||||
* CHILDSTATUS pid code
|
||||
*
|
||||
* Child exited with a non-zero exit status.
|
||||
*/
|
||||
|
||||
if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj(
|
||||
"child process exited abnormally", -1);
|
||||
if (errorObjPtr) {
|
||||
errorStrings[0] = Tcl_NewStringObj("CHILDSTATUS", -1);
|
||||
errorStrings[1] = Tcl_NewIntObj(resolvedPid);
|
||||
errorStrings[2] = Tcl_NewIntObj(WEXITSTATUS(waitStatus));
|
||||
*errorObjPtr = Tcl_NewListObj(3, errorStrings);
|
||||
}
|
||||
}
|
||||
return TCL_PROCESS_EXITED;
|
||||
} else if (WIFSIGNALED(waitStatus)) {
|
||||
/*
|
||||
* CHILDKILLED pid sigName msg
|
||||
*
|
||||
* Child killed because of a signal.
|
||||
*/
|
||||
|
||||
msg = Tcl_SignalMsg(WTERMSIG(waitStatus));
|
||||
if (codePtr) *codePtr = WTERMSIG(waitStatus);
|
||||
if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf(
|
||||
"child killed: %s", msg);
|
||||
if (errorObjPtr) {
|
||||
errorStrings[0] = Tcl_NewStringObj("CHILDKILLED", -1);
|
||||
errorStrings[1] = Tcl_NewIntObj(resolvedPid);
|
||||
errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WTERMSIG(waitStatus)), -1);
|
||||
errorStrings[3] = Tcl_NewStringObj(msg, -1);
|
||||
*errorObjPtr = Tcl_NewListObj(4, errorStrings);
|
||||
}
|
||||
return TCL_PROCESS_SIGNALED;
|
||||
} else if (WIFSTOPPED(waitStatus)) {
|
||||
/*
|
||||
* CHILDSUSP pid sigName msg
|
||||
*
|
||||
* Child suspended because of a signal.
|
||||
*/
|
||||
|
||||
msg = Tcl_SignalMsg(WSTOPSIG(waitStatus));
|
||||
if (codePtr) *codePtr = WSTOPSIG(waitStatus);
|
||||
if (msgObjPtr) *msgObjPtr = Tcl_ObjPrintf(
|
||||
"child suspended: %s", msg);
|
||||
if (errorObjPtr) {
|
||||
errorStrings[0] = Tcl_NewStringObj("CHILDSUSP", -1);
|
||||
errorStrings[1] = Tcl_NewIntObj(resolvedPid);
|
||||
errorStrings[2] = Tcl_NewStringObj(Tcl_SignalId(WSTOPSIG(waitStatus)), -1);
|
||||
errorStrings[3] = Tcl_NewStringObj(msg, -1);
|
||||
*errorObjPtr = Tcl_NewListObj(4, errorStrings);
|
||||
}
|
||||
return TCL_PROCESS_STOPPED;
|
||||
} else {
|
||||
/*
|
||||
* TCL OPERATION EXEC ODDWAITRESULT
|
||||
*
|
||||
* Child wait status didn't make sense.
|
||||
*/
|
||||
|
||||
if (codePtr) *codePtr = waitStatus;
|
||||
if (msgObjPtr) *msgObjPtr = Tcl_NewStringObj(
|
||||
"child wait status didn't make sense\n", -1);
|
||||
if (errorObjPtr) {
|
||||
errorStrings[0] = Tcl_NewStringObj("TCL", -1);
|
||||
errorStrings[1] = Tcl_NewStringObj("OPERATION", -1);
|
||||
errorStrings[2] = Tcl_NewStringObj("EXEC", -1);
|
||||
errorStrings[3] = Tcl_NewStringObj("ODDWAITRESULT", -1);
|
||||
errorStrings[4] = Tcl_NewIntObj(resolvedPid);
|
||||
*errorObjPtr = Tcl_NewListObj(5, errorStrings);
|
||||
}
|
||||
return TCL_PROCESS_UNKNOWN_STATUS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* BuildProcessStatusObj --
|
||||
*
|
||||
* Build a list object with process status. The first element is always
|
||||
* a standard Tcl return value, which can be either TCL_OK or TCL_ERROR.
|
||||
* In the latter case, the second element is the error message and the
|
||||
* third element is a Tcl error code (see tclvars).
|
||||
*
|
||||
* Results:
|
||||
* A list object.
|
||||
*
|
||||
* Side effects:
|
||||
* Tcl_Objs are created.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Obj *
|
||||
BuildProcessStatusObj(
|
||||
ProcessInfo *info)
|
||||
{
|
||||
Tcl_Obj *resultObjs[3];
|
||||
|
||||
if (info->status == TCL_PROCESS_UNCHANGED) {
|
||||
/*
|
||||
* Process still running, return empty obj.
|
||||
*/
|
||||
|
||||
return Tcl_NewObj();
|
||||
}
|
||||
if (info->status == TCL_PROCESS_EXITED && info->code == 0) {
|
||||
/*
|
||||
* Normal exit, return TCL_OK.
|
||||
*/
|
||||
|
||||
return Tcl_NewIntObj(TCL_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
* Abnormal exit, return {TCL_ERROR msg error}
|
||||
*/
|
||||
|
||||
resultObjs[0] = Tcl_NewIntObj(TCL_ERROR);
|
||||
resultObjs[1] = info->msg;
|
||||
resultObjs[2] = info->error;
|
||||
return Tcl_NewListObj(3, resultObjs);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
*
|
||||
* ProcessListObjCmd --
|
||||
*
|
||||
* This function implements the 'tcl::process list' Tcl command.
|
||||
* Refer to the user documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* Returns a standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Access to the internal structures is protected by infoTablesMutex.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
ProcessListObjCmd(
|
||||
ClientData clientData, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_Obj *list;
|
||||
Tcl_HashEntry *entry;
|
||||
Tcl_HashSearch search;
|
||||
ProcessInfo *info;
|
||||
|
||||
if (objc != 1) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the list of all chid process ids.
|
||||
*/
|
||||
|
||||
list = Tcl_NewListObj(0, NULL);
|
||||
Tcl_MutexLock(&infoTablesMutex);
|
||||
for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search);
|
||||
entry != NULL; entry = Tcl_NextHashEntry(&search)) {
|
||||
info = (ProcessInfo *) Tcl_GetHashValue(entry);
|
||||
Tcl_ListObjAppendElement(interp, list,
|
||||
Tcl_NewIntObj(info->resolvedPid));
|
||||
}
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
Tcl_SetObjResult(interp, list);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
*
|
||||
* ProcessStatusObjCmd --
|
||||
*
|
||||
* This function implements the 'tcl::process status' Tcl command.
|
||||
* Refer to the user documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* Returns a standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Access to the internal structures is protected by infoTablesMutex.
|
||||
* Calls RefreshProcessInfo, which can block if -wait switch is given.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
ProcessStatusObjCmd(
|
||||
ClientData clientData, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_Obj *dict;
|
||||
int index, options = WNOHANG;
|
||||
Tcl_HashEntry *entry;
|
||||
Tcl_HashSearch search;
|
||||
ProcessInfo *info;
|
||||
int numPids;
|
||||
Tcl_Obj **pidObjs;
|
||||
int result;
|
||||
int i;
|
||||
int pid;
|
||||
Tcl_Obj *const *savedobjv = objv;
|
||||
static const char *const switches[] = {
|
||||
"-wait", "--", NULL
|
||||
};
|
||||
enum switches {
|
||||
STATUS_WAIT, STATUS_LAST
|
||||
};
|
||||
|
||||
while (objc > 1) {
|
||||
if (TclGetString(objv[1])[0] != '-') {
|
||||
break;
|
||||
}
|
||||
if (Tcl_GetIndexFromObj(interp, objv[1], switches, "switches", 0,
|
||||
&index) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
++objv; --objc;
|
||||
if (STATUS_WAIT == (enum switches) index) {
|
||||
options = 0;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (objc != 1 && objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, savedobjv, "?switches? ?pids?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (objc == 1) {
|
||||
/*
|
||||
* Return a dict with all child process statuses.
|
||||
*/
|
||||
|
||||
dict = Tcl_NewDictObj();
|
||||
Tcl_MutexLock(&infoTablesMutex);
|
||||
for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search);
|
||||
entry != NULL; entry = Tcl_NextHashEntry(&search)) {
|
||||
info = (ProcessInfo *) Tcl_GetHashValue(entry);
|
||||
RefreshProcessInfo(info, options);
|
||||
|
||||
if (info->purge && autopurge) {
|
||||
/*
|
||||
* Purge entry.
|
||||
*/
|
||||
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid);
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
FreeProcessInfo(info);
|
||||
} else {
|
||||
/*
|
||||
* Add to result.
|
||||
*/
|
||||
|
||||
Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid),
|
||||
BuildProcessStatusObj(info));
|
||||
}
|
||||
}
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
} else {
|
||||
/*
|
||||
* Only return statuses of provided processes.
|
||||
*/
|
||||
|
||||
result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
dict = Tcl_NewDictObj();
|
||||
Tcl_MutexLock(&infoTablesMutex);
|
||||
for (i = 0; i < numPids; i++) {
|
||||
result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid);
|
||||
if (result != TCL_OK) {
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
Tcl_DecrRefCount(dict);
|
||||
return result;
|
||||
}
|
||||
|
||||
entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid));
|
||||
if (!entry) {
|
||||
/*
|
||||
* Skip unknown process.
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
info = (ProcessInfo *) Tcl_GetHashValue(entry);
|
||||
RefreshProcessInfo(info, options);
|
||||
|
||||
if (info->purge && autopurge) {
|
||||
/*
|
||||
* Purge entry.
|
||||
*/
|
||||
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid);
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
FreeProcessInfo(info);
|
||||
} else {
|
||||
/*
|
||||
* Add to result.
|
||||
*/
|
||||
|
||||
Tcl_DictObjPut(interp, dict, Tcl_NewIntObj(info->resolvedPid),
|
||||
BuildProcessStatusObj(info));
|
||||
}
|
||||
}
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
}
|
||||
Tcl_SetObjResult(interp, dict);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
*
|
||||
* ProcessPurgeObjCmd --
|
||||
*
|
||||
* This function implements the 'tcl::process purge' Tcl command.
|
||||
* Refer to the user documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* Returns a standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Frees all ProcessInfo structures with their purge flag set.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
ProcessPurgeObjCmd(
|
||||
ClientData clientData, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
Tcl_HashEntry *entry;
|
||||
Tcl_HashSearch search;
|
||||
ProcessInfo *info;
|
||||
int numPids;
|
||||
Tcl_Obj **pidObjs;
|
||||
int result;
|
||||
int i;
|
||||
int pid;
|
||||
|
||||
if (objc != 1 && objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?pids?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* First reap detached procs so that their purge flag is up-to-date.
|
||||
*/
|
||||
|
||||
Tcl_ReapDetachedProcs();
|
||||
|
||||
if (objc == 1) {
|
||||
/*
|
||||
* Purge all terminated processes.
|
||||
*/
|
||||
|
||||
Tcl_MutexLock(&infoTablesMutex);
|
||||
for (entry = Tcl_FirstHashEntry(&infoTablePerResolvedPid, &search);
|
||||
entry != NULL; entry = Tcl_NextHashEntry(&search)) {
|
||||
info = (ProcessInfo *) Tcl_GetHashValue(entry);
|
||||
if (info->purge) {
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid);
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
FreeProcessInfo(info);
|
||||
}
|
||||
}
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
} else {
|
||||
/*
|
||||
* Purge only provided processes.
|
||||
*/
|
||||
|
||||
result = Tcl_ListObjGetElements(interp, objv[1], &numPids, &pidObjs);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
Tcl_MutexLock(&infoTablesMutex);
|
||||
for (i = 0; i < numPids; i++) {
|
||||
result = Tcl_GetIntFromObj(interp, pidObjs[i], (int *) &pid);
|
||||
if (result != TCL_OK) {
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
return result;
|
||||
}
|
||||
|
||||
entry = Tcl_FindHashEntry(&infoTablePerResolvedPid, INT2PTR(pid));
|
||||
if (!entry) {
|
||||
/*
|
||||
* Skip unknown process.
|
||||
*/
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
info = (ProcessInfo *) Tcl_GetHashValue(entry);
|
||||
if (info->purge) {
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
entry = Tcl_FindHashEntry(&infoTablePerPid, info->pid);
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
FreeProcessInfo(info);
|
||||
}
|
||||
}
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
}
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
*
|
||||
* ProcessAutopurgeObjCmd --
|
||||
*
|
||||
* This function implements the 'tcl::process autopurge' Tcl command.
|
||||
* Refer to the user documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* Returns a standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* Alters detached process handling by Tcl_ReapDetachedProcs().
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static int
|
||||
ProcessAutopurgeObjCmd(
|
||||
ClientData clientData, /* Not used. */
|
||||
Tcl_Interp *interp, /* Current interpreter. */
|
||||
int objc, /* Number of arguments. */
|
||||
Tcl_Obj *const objv[]) /* Argument objects. */
|
||||
{
|
||||
if (objc != 1 && objc != 2) {
|
||||
Tcl_WrongNumArgs(interp, 1, objv, "?flag?");
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
if (objc == 2) {
|
||||
/*
|
||||
* Set given value.
|
||||
*/
|
||||
|
||||
int flag;
|
||||
int result = Tcl_GetBooleanFromObj(interp, objv[1], &flag);
|
||||
if (result != TCL_OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
autopurge = !!flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return current value.
|
||||
*/
|
||||
|
||||
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(autopurge));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclInitProcessCmd --
|
||||
*
|
||||
* This procedure creates the "tcl::process" Tcl command. See the user
|
||||
* documentation for details on what it does.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
*
|
||||
* Side effects:
|
||||
* See the user documentation.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Tcl_Command
|
||||
TclInitProcessCmd(
|
||||
Tcl_Interp *interp) /* Current interpreter. */
|
||||
{
|
||||
static const EnsembleImplMap processImplMap[] = {
|
||||
{"list", ProcessListObjCmd, TclCompileBasic0ArgCmd, NULL, NULL, 1},
|
||||
{"status", ProcessStatusObjCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 1},
|
||||
{"purge", ProcessPurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
|
||||
{"autopurge", ProcessAutopurgeObjCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 1},
|
||||
{NULL, NULL, NULL, NULL, NULL, 0}
|
||||
};
|
||||
Tcl_Command processCmd;
|
||||
|
||||
if (infoTablesInitialized == 0) {
|
||||
Tcl_MutexLock(&infoTablesMutex);
|
||||
if (infoTablesInitialized == 0) {
|
||||
Tcl_InitHashTable(&infoTablePerPid, TCL_ONE_WORD_KEYS);
|
||||
Tcl_InitHashTable(&infoTablePerResolvedPid, TCL_ONE_WORD_KEYS);
|
||||
infoTablesInitialized = 1;
|
||||
}
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
}
|
||||
|
||||
processCmd = TclMakeEnsemble(interp, "::tcl::process", processImplMap);
|
||||
Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0),
|
||||
"process", 0);
|
||||
return processCmd;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclProcessCreated --
|
||||
*
|
||||
* Called when a child process has been created by Tcl.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Internal structures are updated with a new ProcessInfo.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
TclProcessCreated(
|
||||
Tcl_Pid pid) /* Process id. */
|
||||
{
|
||||
int resolvedPid;
|
||||
Tcl_HashEntry *entry, *entry2;
|
||||
int isNew;
|
||||
ProcessInfo *info;
|
||||
|
||||
/*
|
||||
* Get resolved pid first.
|
||||
*/
|
||||
|
||||
resolvedPid = TclpGetPid(pid);
|
||||
|
||||
Tcl_MutexLock(&infoTablesMutex);
|
||||
|
||||
/*
|
||||
* Create entry in pid table.
|
||||
*/
|
||||
|
||||
entry = Tcl_CreateHashEntry(&infoTablePerPid, pid, &isNew);
|
||||
if (!isNew) {
|
||||
/*
|
||||
* Pid was reused, free old info and reuse structure.
|
||||
*/
|
||||
|
||||
info = (ProcessInfo *) Tcl_GetHashValue(entry);
|
||||
entry2 = Tcl_FindHashEntry(&infoTablePerResolvedPid,
|
||||
INT2PTR(resolvedPid));
|
||||
if (entry2) Tcl_DeleteHashEntry(entry2);
|
||||
FreeProcessInfo(info);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and initialize info structure.
|
||||
*/
|
||||
|
||||
info = (ProcessInfo *) ckalloc(sizeof(ProcessInfo));
|
||||
InitProcessInfo(info, pid, resolvedPid);
|
||||
|
||||
/*
|
||||
* Add entry to tables.
|
||||
*/
|
||||
|
||||
Tcl_SetHashValue(entry, info);
|
||||
entry = Tcl_CreateHashEntry(&infoTablePerResolvedPid, INT2PTR(resolvedPid),
|
||||
&isNew);
|
||||
Tcl_SetHashValue(entry, info);
|
||||
|
||||
Tcl_MutexUnlock(&infoTablesMutex);
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclProcessWait --
|
||||
*
|
||||
* Wait for process status to change.
|
||||
*
|
||||
* Results:
|
||||
* TclProcessWaitStatus enum value.
|
||||
*
|
||||
* Side effects:
|
||||
* Completed process info structures are purged immediately (autopurge on)
|
||||
* or eventually (autopurge off).
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
TclProcessWaitStatus
|
||||
TclProcessWait(
|
||||
Tcl_Pid pid, /* Process id. */
|
||||
int options, /* Options passed to WaitProcessStatus. */
|
||||
int *codePtr, /* If non-NULL, will receive either:
|
||||
* - 0 for normal exit.
|
||||
* - errno in case of error.
|
||||
* - non-zero exit code for abormal exit.
|
||||
* - signal number if killed or suspended.
|
||||
* - Tcl_WaitPid status in all other cases.
|
||||
*/
|
||||
Tcl_Obj **msgObjPtr, /* If non-NULL, will receive error message. */
|
||||
Tcl_Obj **errorObjPtr) /* If non-NULL, will receive error code. */
|
||||
{
|
||||
Tcl_HashEntry *entry;
|
||||
ProcessInfo *info;
|
||||
TclProcessWaitStatus result;
|
||||
|
||||
/*
|
||||
* First search for pid in table.
|
||||
*/
|
||||
|
||||
entry = Tcl_FindHashEntry(&infoTablePerPid, pid);
|
||||
if (!entry) {
|
||||
/*
|
||||
* Unknown process, just call WaitProcessStatus and return.
|
||||
*/
|
||||
|
||||
result = WaitProcessStatus(pid, TclpGetPid(pid), options, codePtr,
|
||||
msgObjPtr, errorObjPtr);
|
||||
if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr);
|
||||
if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr);
|
||||
return result;
|
||||
}
|
||||
|
||||
info = (ProcessInfo *) Tcl_GetHashValue(entry);
|
||||
if (info->purge) {
|
||||
/*
|
||||
* Process has completed but TclProcessWait has already been called,
|
||||
* so report no change.
|
||||
*/
|
||||
|
||||
return TCL_PROCESS_UNCHANGED;
|
||||
}
|
||||
|
||||
RefreshProcessInfo(info, options);
|
||||
if (info->status == TCL_PROCESS_UNCHANGED) {
|
||||
/*
|
||||
* No change, stop there.
|
||||
*/
|
||||
|
||||
return TCL_PROCESS_UNCHANGED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set return values.
|
||||
*/
|
||||
|
||||
result = info->status;
|
||||
if (codePtr) *codePtr = info->code;
|
||||
if (msgObjPtr) *msgObjPtr = info->msg;
|
||||
if (errorObjPtr) *errorObjPtr = info->error;
|
||||
if (msgObjPtr && *msgObjPtr) Tcl_IncrRefCount(*msgObjPtr);
|
||||
if (errorObjPtr && *errorObjPtr) Tcl_IncrRefCount(*errorObjPtr);
|
||||
|
||||
if (autopurge) {
|
||||
/*
|
||||
* Purge now.
|
||||
*/
|
||||
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
entry = Tcl_FindHashEntry(&infoTablePerResolvedPid,
|
||||
INT2PTR(info->resolvedPid));
|
||||
Tcl_DeleteHashEntry(entry);
|
||||
FreeProcessInfo(info);
|
||||
} else {
|
||||
/*
|
||||
* Eventually purge. Subsequent calls will return
|
||||
* TCL_PROCESS_UNCHANGED.
|
||||
*/
|
||||
|
||||
info->purge = 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -651,23 +651,6 @@ Tcl_AppendResultVA(
|
||||
}
|
||||
Tcl_AppendStringsToObjVA(objPtr, argList);
|
||||
Tcl_SetObjResult(interp, objPtr);
|
||||
|
||||
/*
|
||||
* Strictly we should call Tcl_GetStringResult(interp) here to make sure
|
||||
* that interp->result is correct according to the old contract, but that
|
||||
* makes the performance of much code (e.g. in Tk) absolutely awful. So we
|
||||
* leave it out; code that really wants interp->result can just insert the
|
||||
* calls to Tcl_GetStringResult() itself. [Patch 1041072 discussion]
|
||||
*/
|
||||
|
||||
#ifdef USE_INTERP_RESULT
|
||||
/*
|
||||
* Ensure that the interp->result is legal so old Tcl 7.* code still
|
||||
* works. There's still embarrasingly much of it about...
|
||||
*/
|
||||
|
||||
(void) Tcl_GetStringResult(interp);
|
||||
#endif /* USE_INTERP_RESULT */
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
+27
-14
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "tclInt.h"
|
||||
#include "tommath.h"
|
||||
|
||||
/*
|
||||
* Flag values used by Tcl_ScanObjCmd.
|
||||
@@ -415,14 +416,7 @@ ValidateFormat(
|
||||
case 'x':
|
||||
case 'X':
|
||||
case 'b':
|
||||
break;
|
||||
case 'u':
|
||||
if (flags & SCAN_BIG) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unsigned bignum scans are invalid", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
/*
|
||||
* Bracket terms need special checking
|
||||
@@ -885,9 +879,17 @@ Tcl_ScanObjCmd(
|
||||
* Scan a single Unicode character.
|
||||
*/
|
||||
|
||||
string += TclUtfToUniChar(string, &sch);
|
||||
offset = TclUtfToUniChar(string, &sch);
|
||||
i = (int)sch;
|
||||
#if TCL_UTF_MAX == 4
|
||||
if (!offset) {
|
||||
offset = TclUtfToUniChar(string, &sch);
|
||||
i = (((i<<10) & 0x0FFC00) + 0x10000) + (sch & 0x3FF);
|
||||
}
|
||||
#endif
|
||||
string += offset;
|
||||
if (!(flags & SCAN_SUPPRESS)) {
|
||||
objPtr = Tcl_NewIntObj((int)sch);
|
||||
objPtr = Tcl_NewIntObj(i);
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
CLANG_ASSERT(objs);
|
||||
objs[objIndex++] = objPtr;
|
||||
@@ -924,9 +926,9 @@ Tcl_ScanObjCmd(
|
||||
}
|
||||
if (flags & SCAN_LONGER) {
|
||||
if (Tcl_GetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) {
|
||||
wideValue = ~(Tcl_WideUInt)0 >> 1; /* WIDE_MAX */
|
||||
wideValue = LLONG_MAX;
|
||||
if (TclGetString(objPtr)[0] == '-') {
|
||||
wideValue++; /* WIDE_MAX + 1 = WIDE_MIN */
|
||||
wideValue = LLONG_MIN;
|
||||
}
|
||||
}
|
||||
if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) {
|
||||
@@ -934,9 +936,20 @@ Tcl_ScanObjCmd(
|
||||
(Tcl_WideUInt)wideValue);
|
||||
Tcl_SetStringObj(objPtr, buf, -1);
|
||||
} else {
|
||||
Tcl_SetWideIntObj(objPtr, wideValue);
|
||||
TclSetIntObj(objPtr, wideValue);
|
||||
}
|
||||
} else if (!(flags & SCAN_BIG)) {
|
||||
} else if (flags & SCAN_BIG) {
|
||||
if (flags & SCAN_UNSIGNED) {
|
||||
mp_int big;
|
||||
if ((Tcl_GetBignumFromObj(interp, objPtr, &big) != TCL_OK)
|
||||
|| mp_isneg(&big)) {
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(
|
||||
"unsigned bignum scans are invalid", -1));
|
||||
Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) {
|
||||
if (TclGetString(objPtr)[0] == '-') {
|
||||
value = LONG_MIN;
|
||||
@@ -948,7 +961,7 @@ Tcl_ScanObjCmd(
|
||||
sprintf(buf, "%lu", value); /* INTL: ISO digit */
|
||||
Tcl_SetStringObj(objPtr, buf, -1);
|
||||
} else {
|
||||
Tcl_SetLongObj(objPtr, value);
|
||||
TclSetIntObj(objPtr, value);
|
||||
}
|
||||
}
|
||||
objs[objIndex++] = objPtr;
|
||||
|
||||
+12
-40
@@ -1268,32 +1268,18 @@ TclParseNumber(
|
||||
}
|
||||
}
|
||||
if (!octalSignificandOverflow) {
|
||||
if (octalSignificandWide >
|
||||
(Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (octalSignificandWide <= (MOST_BITS + signum)) {
|
||||
objPtr->typePtr = &tclWideIntType;
|
||||
if (signum) {
|
||||
objPtr->internalRep.wideValue =
|
||||
- (Tcl_WideInt) octalSignificandWide;
|
||||
} else {
|
||||
objPtr->internalRep.wideValue =
|
||||
(Tcl_WideInt) octalSignificandWide;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (octalSignificandWide > (MOST_BITS + signum)) {
|
||||
TclInitBignumFromWideUInt(&octalSignificandBig,
|
||||
octalSignificandWide);
|
||||
octalSignificandOverflow = 1;
|
||||
} else {
|
||||
objPtr->typePtr = &tclIntType;
|
||||
if (signum) {
|
||||
objPtr->internalRep.longValue =
|
||||
- (long) octalSignificandWide;
|
||||
objPtr->internalRep.wideValue =
|
||||
- (Tcl_WideInt) octalSignificandWide;
|
||||
} else {
|
||||
objPtr->internalRep.longValue =
|
||||
(long) octalSignificandWide;
|
||||
objPtr->internalRep.wideValue =
|
||||
(Tcl_WideInt) octalSignificandWide;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1315,32 +1301,18 @@ TclParseNumber(
|
||||
}
|
||||
returnInteger:
|
||||
if (!significandOverflow) {
|
||||
if (significandWide >
|
||||
(Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (significandWide <= MOST_BITS+signum) {
|
||||
objPtr->typePtr = &tclWideIntType;
|
||||
if (signum) {
|
||||
objPtr->internalRep.wideValue =
|
||||
- (Tcl_WideInt) significandWide;
|
||||
} else {
|
||||
objPtr->internalRep.wideValue =
|
||||
(Tcl_WideInt) significandWide;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (significandWide > MOST_BITS+signum) {
|
||||
TclInitBignumFromWideUInt(&significandBig,
|
||||
significandWide);
|
||||
significandOverflow = 1;
|
||||
} else {
|
||||
objPtr->typePtr = &tclIntType;
|
||||
if (signum) {
|
||||
objPtr->internalRep.longValue =
|
||||
- (long) significandWide;
|
||||
objPtr->internalRep.wideValue =
|
||||
- (Tcl_WideInt) significandWide;
|
||||
} else {
|
||||
objPtr->internalRep.longValue =
|
||||
(long) significandWide;
|
||||
objPtr->internalRep.wideValue =
|
||||
(Tcl_WideInt) significandWide;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4725,7 +4697,7 @@ TclCeil(
|
||||
mp_int b;
|
||||
|
||||
mp_init(&b);
|
||||
if (mp_cmp_d(a, 0) == MP_LT) {
|
||||
if (mp_isneg(a)) {
|
||||
mp_neg(a, &b);
|
||||
r = -TclFloor(&b);
|
||||
} else {
|
||||
@@ -4782,7 +4754,7 @@ TclFloor(
|
||||
mp_int b;
|
||||
|
||||
mp_init(&b);
|
||||
if (mp_cmp_d(a, 0) == MP_LT) {
|
||||
if (mp_isneg(a)) {
|
||||
mp_neg(a, &b);
|
||||
r = -TclCeil(&b);
|
||||
} else {
|
||||
|
||||
+188
-187
@@ -140,8 +140,8 @@ GrowStringBuffer(
|
||||
objPtr->bytes = NULL;
|
||||
}
|
||||
if (flag == 0 || stringPtr->allocated > 0) {
|
||||
attempt = 2 * needed;
|
||||
if (attempt >= 0) {
|
||||
if (needed <= INT_MAX / 2) {
|
||||
attempt = 2 * needed;
|
||||
ptr = attemptckrealloc(objPtr->bytes, attempt + 1);
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
@@ -190,8 +190,8 @@ GrowUnicodeBuffer(
|
||||
* Subsequent appends - apply the growth algorithm.
|
||||
*/
|
||||
|
||||
attempt = 2 * needed;
|
||||
if (attempt >= 0 && attempt <= STRING_MAXCHARS) {
|
||||
if (needed <= STRING_MAXCHARS / 2) {
|
||||
attempt = 2 * needed;
|
||||
ptr = stringAttemptRealloc(stringPtr, attempt);
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
@@ -418,9 +418,14 @@ Tcl_GetCharLength(
|
||||
}
|
||||
|
||||
/*
|
||||
* Optimize the case where we're really dealing with a bytearray object
|
||||
* without string representation; we don't need to convert to a string to
|
||||
* perform the get-length operation.
|
||||
* Optimize the case where we're really dealing with a bytearray object;
|
||||
* we don't need to convert to a string to perform the get-length operation.
|
||||
*
|
||||
* Starting in Tcl 8.7, we check for a "pure" bytearray, because the
|
||||
* machinery behind that test is using a proper bytearray ObjType. We
|
||||
* could also compute length of an improper bytearray without shimmering
|
||||
* but there's no value in that. We *want* to shimmer an improper bytearray
|
||||
* because improper bytearrays have worthless internal reps.
|
||||
*/
|
||||
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
@@ -476,8 +481,7 @@ Tcl_GetUniChar(
|
||||
|
||||
/*
|
||||
* Optimize the case where we're really dealing with a bytearray object
|
||||
* without string representation; we don't need to convert to a string to
|
||||
* perform the indexing operation.
|
||||
* we don't need to convert to a string to perform the indexing operation.
|
||||
*/
|
||||
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
@@ -517,7 +521,7 @@ Tcl_GetUniChar(
|
||||
*
|
||||
* Get the Unicode form of the String object. If the object is not
|
||||
* already a String object, it will be converted to one. If the String
|
||||
* object does not have a Unicode rep, then one is create from the UTF
|
||||
* object does not have a Unicode rep, then one is created from the UTF
|
||||
* string format.
|
||||
*
|
||||
* Results:
|
||||
@@ -610,8 +614,7 @@ Tcl_GetRange(
|
||||
|
||||
/*
|
||||
* Optimize the case where we're really dealing with a bytearray object
|
||||
* without string representation; we don't need to convert to a string to
|
||||
* perform the substring operation.
|
||||
* we don't need to convert to a string to perform the substring operation.
|
||||
*/
|
||||
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
@@ -651,6 +654,17 @@ Tcl_GetRange(
|
||||
stringPtr = GET_STRING(objPtr);
|
||||
}
|
||||
|
||||
#if TCL_UTF_MAX == 4
|
||||
/* See: bug [11ae2be95dac9417] */
|
||||
if ((first>0) && ((stringPtr->unicode[first]&0xFC00) == 0xDC00)
|
||||
&& ((stringPtr->unicode[first-1]&0xFC00) == 0xD800)) {
|
||||
++first;
|
||||
}
|
||||
if ((last+1<stringPtr->numChars) && ((stringPtr->unicode[last+1]&0xFC00) == 0xDC00)
|
||||
&& ((stringPtr->unicode[last]&0xFC00) == 0xD800)) {
|
||||
++last;
|
||||
}
|
||||
#endif
|
||||
return Tcl_NewUnicodeObj(stringPtr->unicode + first, last-first+1);
|
||||
}
|
||||
|
||||
@@ -1208,9 +1222,9 @@ Tcl_AppendObjToObj(
|
||||
|
||||
/*
|
||||
* Handle append of one bytearray object to another as a special case.
|
||||
* Note that we only do this when the objects don't have string reps; if
|
||||
* it did, then appending the byte arrays together could well lose
|
||||
* information; this is a special-case optimization only.
|
||||
* Note that we only do this when the objects are pure so that the
|
||||
* bytearray faithfully represent the true value; Otherwise
|
||||
* appending the byte arrays together could lose information;
|
||||
*/
|
||||
|
||||
if ((TclIsPureByteArray(objPtr) || objPtr->bytes == &tclEmptyString)
|
||||
@@ -1869,31 +1883,21 @@ Tcl_AppendFormatToObj(
|
||||
} else if (ch == 'I') {
|
||||
if ((format[1] == '6') && (format[2] == '4')) {
|
||||
format += (step + 2);
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
useWide = 1;
|
||||
#endif
|
||||
} else if ((format[1] == '3') && (format[2] == '2')) {
|
||||
format += (step + 2);
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
} else {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
}
|
||||
} else if ((ch == 't') || (ch == 'z')) {
|
||||
} else if ((ch == 't') || (ch == 'z') || (ch == 'q') || (ch == 'j') || (ch == 'L')) {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (sizeof(size_t) > sizeof(int)) {
|
||||
useWide = 1;
|
||||
}
|
||||
#endif
|
||||
} else if ((ch == 'q') ||(ch == 'j')) {
|
||||
format += step;
|
||||
step = Tcl_UtfToUniChar(format, &ch);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
useWide = 1;
|
||||
#endif
|
||||
step = TclUtfToUniChar(format, &ch);
|
||||
useBig = 1;
|
||||
}
|
||||
|
||||
format += step;
|
||||
@@ -1939,11 +1943,6 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
|
||||
case 'u':
|
||||
if (useBig) {
|
||||
msg = "unsigned bignum format is invalid";
|
||||
errCode = "BADUNSIGNED";
|
||||
goto errorMsg;
|
||||
}
|
||||
case 'd':
|
||||
case 'o':
|
||||
case 'p':
|
||||
@@ -1963,13 +1962,25 @@ Tcl_AppendFormatToObj(
|
||||
}
|
||||
#endif
|
||||
if (useBig) {
|
||||
int cmpResult;
|
||||
if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) {
|
||||
goto error;
|
||||
}
|
||||
isNegative = (mp_cmp_d(&big, 0) == MP_LT);
|
||||
cmpResult = mp_cmp_d(&big, 0);
|
||||
isNegative = (cmpResult == MP_LT);
|
||||
if (cmpResult == MP_EQ) gotHash = 0;
|
||||
if (ch == 'u') {
|
||||
if (isNegative) {
|
||||
msg = "unsigned bignum format is invalid";
|
||||
errCode = "BADUNSIGNED";
|
||||
goto errorMsg;
|
||||
} else {
|
||||
ch = 'd';
|
||||
}
|
||||
}
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else if (useWide) {
|
||||
if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
|
||||
if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) {
|
||||
@@ -1978,13 +1989,14 @@ Tcl_AppendFormatToObj(
|
||||
mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big);
|
||||
objPtr = Tcl_NewBignumObj(&big);
|
||||
Tcl_IncrRefCount(objPtr);
|
||||
Tcl_GetWideIntFromObj(NULL, objPtr, &w);
|
||||
TclGetWideIntFromObj(NULL, objPtr, &w);
|
||||
Tcl_DecrRefCount(objPtr);
|
||||
}
|
||||
isNegative = (w < (Tcl_WideInt) 0);
|
||||
if (w == (Tcl_WideInt) 0) gotHash = 0;
|
||||
#endif
|
||||
} else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) {
|
||||
if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
|
||||
if (TclGetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
|
||||
Tcl_Obj *objPtr;
|
||||
|
||||
if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) {
|
||||
@@ -2001,14 +2013,18 @@ Tcl_AppendFormatToObj(
|
||||
if (useShort) {
|
||||
s = (short) l;
|
||||
isNegative = (s < (short) 0);
|
||||
if (s == (short) 0) gotHash = 0;
|
||||
} else {
|
||||
isNegative = (l < (long) 0);
|
||||
if (l == (long) 0) gotHash = 0;
|
||||
}
|
||||
} else if (useShort) {
|
||||
s = (short) l;
|
||||
isNegative = (s < (short) 0);
|
||||
if (s == (short) 0) gotHash = 0;
|
||||
} else {
|
||||
isNegative = (l < (long) 0);
|
||||
if (l == (long) 0) gotHash = 0;
|
||||
}
|
||||
|
||||
segment = Tcl_NewObj();
|
||||
@@ -2025,16 +2041,12 @@ Tcl_AppendFormatToObj(
|
||||
if (gotHash || (ch == 'p')) {
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
Tcl_AppendToObj(segment, "0", 1);
|
||||
segmentLimit -= 1;
|
||||
precision--;
|
||||
break;
|
||||
case 'X':
|
||||
Tcl_AppendToObj(segment, "0X", 2);
|
||||
Tcl_AppendToObj(segment, "0o", 2);
|
||||
segmentLimit -= 2;
|
||||
break;
|
||||
case 'p':
|
||||
case 'x':
|
||||
case 'X':
|
||||
Tcl_AppendToObj(segment, "0x", 2);
|
||||
segmentLimit -= 2;
|
||||
break;
|
||||
@@ -2042,10 +2054,14 @@ Tcl_AppendFormatToObj(
|
||||
Tcl_AppendToObj(segment, "0b", 2);
|
||||
segmentLimit -= 2;
|
||||
break;
|
||||
#if TCL_MAJOR_VERSION < 9
|
||||
case 'd':
|
||||
Tcl_AppendToObj(segment, "0d", 2);
|
||||
segmentLimit -= 2;
|
||||
if (gotZero) {
|
||||
Tcl_AppendToObj(segment, "0d", 2);
|
||||
segmentLimit -= 2;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2183,7 +2199,7 @@ Tcl_AppendFormatToObj(
|
||||
* Need to be sure zero becomes "0", not "".
|
||||
*/
|
||||
|
||||
if ((numDigits == 0) && !((ch == 'o') && gotHash)) {
|
||||
if (numDigits == 0) {
|
||||
numDigits = 1;
|
||||
}
|
||||
pure = Tcl_NewObj();
|
||||
@@ -2250,6 +2266,8 @@ Tcl_AppendFormatToObj(
|
||||
break;
|
||||
}
|
||||
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
@@ -2318,6 +2336,12 @@ Tcl_AppendFormatToObj(
|
||||
errCode = "OVERFLOW";
|
||||
goto errorMsg;
|
||||
}
|
||||
if (ch == 'A') {
|
||||
char *p = TclGetString(segment) + 1;
|
||||
*p = 'x';
|
||||
p = strchr(p, 'P');
|
||||
if (p) *p = 'p';
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -2523,15 +2547,26 @@ AppendPrintfToObjVA(
|
||||
Tcl_ListObjAppendElement(NULL, list, Tcl_NewWideIntObj(
|
||||
va_arg(argList, Tcl_WideInt)));
|
||||
break;
|
||||
case 3:
|
||||
Tcl_ListObjAppendElement(NULL, list, Tcl_NewBignumObj(
|
||||
va_arg(argList, mp_int *)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
case 'A':
|
||||
case 'e':
|
||||
case 'E':
|
||||
case 'f':
|
||||
case 'g':
|
||||
case 'G':
|
||||
if (size > 0) {
|
||||
Tcl_ListObjAppendElement(NULL, list, Tcl_NewDoubleObj(
|
||||
va_arg(argList, double)));
|
||||
(double)va_arg(argList, long double)));
|
||||
} else {
|
||||
Tcl_ListObjAppendElement(NULL, list, Tcl_NewDoubleObj(
|
||||
va_arg(argList, double)));
|
||||
}
|
||||
seekingConversion = 0;
|
||||
break;
|
||||
case '*':
|
||||
@@ -2551,7 +2586,6 @@ AppendPrintfToObjVA(
|
||||
gotPrecision = 1;
|
||||
p++;
|
||||
break;
|
||||
/* TODO: support for bignum arguments */
|
||||
case 'l':
|
||||
++size;
|
||||
p++;
|
||||
@@ -2579,6 +2613,10 @@ AppendPrintfToObjVA(
|
||||
}
|
||||
p++;
|
||||
break;
|
||||
case 'L':
|
||||
size = 3;
|
||||
p++;
|
||||
break;
|
||||
case 'h':
|
||||
size = -1;
|
||||
default:
|
||||
@@ -2692,23 +2730,24 @@ TclGetStringStorage(
|
||||
* Performs the [string repeat] function.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
* A (Tcl_Obj *) pointing to the result value, or NULL in case of an
|
||||
* error.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes to *objPtrPtr the address of Tcl_Obj that is concatenation
|
||||
* of count copies of the value in objPtr.
|
||||
* On error, when interp is not NULL, error information is left in it.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
Tcl_Obj *
|
||||
TclStringRepeat(
|
||||
Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr,
|
||||
int count,
|
||||
Tcl_Obj **objPtrPtr)
|
||||
int flags)
|
||||
{
|
||||
Tcl_Obj *objResultPtr;
|
||||
int inPlace = flags & TCL_STRING_IN_PLACE;
|
||||
int length = 0, unichar = 0, done = 1;
|
||||
int binary = TclIsPureByteArray(objPtr);
|
||||
|
||||
@@ -2743,8 +2782,7 @@ TclStringRepeat(
|
||||
|
||||
if (length == 0) {
|
||||
/* Any repeats of empty is empty. */
|
||||
*objPtrPtr = objPtr;
|
||||
return TCL_OK;
|
||||
return objPtr;
|
||||
}
|
||||
|
||||
if (count > INT_MAX/length) {
|
||||
@@ -2753,13 +2791,13 @@ TclStringRepeat(
|
||||
"max size for a Tcl value (%d bytes) exceeded", INT_MAX));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (binary) {
|
||||
/* Efficiently produce a pure byte array result */
|
||||
objResultPtr = Tcl_IsShared(objPtr) ? Tcl_DuplicateObj(objPtr)
|
||||
: objPtr;
|
||||
objResultPtr = (!inPlace || Tcl_IsShared(objPtr)) ?
|
||||
Tcl_DuplicateObj(objPtr) : objPtr;
|
||||
|
||||
Tcl_SetByteArrayLength(objResultPtr, count*length); /* PANIC? */
|
||||
Tcl_SetByteArrayLength(objResultPtr, length);
|
||||
@@ -2772,7 +2810,7 @@ TclStringRepeat(
|
||||
(count - done) * length);
|
||||
} else if (unichar) {
|
||||
/* Efficiently produce a pure Tcl_UniChar array result */
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
if (!inPlace || Tcl_IsShared(objPtr)) {
|
||||
objResultPtr = Tcl_NewUnicodeObj(Tcl_GetUnicode(objPtr), length);
|
||||
} else {
|
||||
TclInvalidateStringRep(objPtr);
|
||||
@@ -2783,11 +2821,11 @@ TclStringRepeat(
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"string size overflow: unable to alloc %"
|
||||
TCL_LL_MODIFIER "d bytes",
|
||||
(Tcl_WideUInt)STRING_SIZE(count*length)));
|
||||
TCL_Z_MODIFIER "u bytes",
|
||||
STRING_SIZE(count*length)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
Tcl_SetObjLength(objResultPtr, length);
|
||||
while (count - done > done) {
|
||||
@@ -2798,7 +2836,7 @@ TclStringRepeat(
|
||||
(count - done) * length);
|
||||
} else {
|
||||
/* Efficiently concatenate string reps */
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
if (!inPlace || Tcl_IsShared(objPtr)) {
|
||||
objResultPtr = Tcl_NewStringObj(Tcl_GetString(objPtr), length);
|
||||
} else {
|
||||
TclFreeIntRep(objPtr);
|
||||
@@ -2811,7 +2849,7 @@ TclStringRepeat(
|
||||
count*length));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
Tcl_SetObjLength(objResultPtr, length);
|
||||
while (count - done > done) {
|
||||
@@ -2821,47 +2859,45 @@ TclStringRepeat(
|
||||
Tcl_AppendToObj(objResultPtr, Tcl_GetString(objResultPtr),
|
||||
(count - done) * length);
|
||||
}
|
||||
*objPtrPtr = objResultPtr;
|
||||
return TCL_OK;
|
||||
return objResultPtr;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclStringCatObjv --
|
||||
* TclStringCat --
|
||||
*
|
||||
* Performs the [string cat] function.
|
||||
*
|
||||
* Results:
|
||||
* A standard Tcl result.
|
||||
* A (Tcl_Obj *) pointing to the result value, or NULL in case of an
|
||||
* error.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes to *objPtrPtr the address of Tcl_Obj that is concatenation
|
||||
* of all objc values in objv.
|
||||
* On error, when interp is not NULL, error information is left in it.
|
||||
*
|
||||
*---------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclStringCatObjv(
|
||||
Tcl_Obj *
|
||||
TclStringCat(
|
||||
Tcl_Interp *interp,
|
||||
int inPlace,
|
||||
int objc,
|
||||
Tcl_Obj * const objv[],
|
||||
Tcl_Obj **objPtrPtr)
|
||||
int flags)
|
||||
{
|
||||
Tcl_Obj *objResultPtr, * const *ov;
|
||||
int oc, length = 0, binary = 1;
|
||||
int allowUniChar = 1, requestUniChar = 0;
|
||||
int first = objc - 1; /* Index of first value possibly not empty */
|
||||
int last = 0; /* Index of last value possibly not empty */
|
||||
int inPlace = flags & TCL_STRING_IN_PLACE;
|
||||
|
||||
/* assert ( objc >= 0 ) */
|
||||
|
||||
if (objc <= 1) {
|
||||
/* Only one or no objects; return first or empty */
|
||||
*objPtrPtr = objc ? objv[0] : Tcl_NewObj();
|
||||
return TCL_OK;
|
||||
return objc ? objv[0] : Tcl_NewObj();
|
||||
}
|
||||
|
||||
/* assert ( objc >= 2 ) */
|
||||
@@ -2877,7 +2913,9 @@ TclStringCatObjv(
|
||||
do {
|
||||
Tcl_Obj *objPtr = *ov++;
|
||||
|
||||
if (objPtr->bytes) {
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
allowUniChar = 0;
|
||||
} else if (objPtr->bytes) {
|
||||
/* Value has a string rep. */
|
||||
if (objPtr->length) {
|
||||
/*
|
||||
@@ -2892,17 +2930,13 @@ TclStringCatObjv(
|
||||
}
|
||||
} else {
|
||||
/* assert (objPtr->typePtr != NULL) -- stork! */
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
allowUniChar = 0;
|
||||
binary = 0;
|
||||
if (objPtr->typePtr == &tclStringType) {
|
||||
/* Have a pure Unicode value; ask to preserve it */
|
||||
requestUniChar = 1;
|
||||
} else {
|
||||
binary = 0;
|
||||
if (objPtr->typePtr == &tclStringType) {
|
||||
/* Have a pure Unicode value; ask to preserve it */
|
||||
requestUniChar = 1;
|
||||
} else {
|
||||
/* Have another type; prevent shimmer */
|
||||
allowUniChar = 0;
|
||||
}
|
||||
/* Have another type; prevent shimmer */
|
||||
allowUniChar = 0;
|
||||
}
|
||||
}
|
||||
} while (--oc && (binary || allowUniChar));
|
||||
@@ -3038,8 +3072,7 @@ TclStringCatObjv(
|
||||
if (last <= first /*|| length == 0 */) {
|
||||
/* Only one non-empty value or zero length; return first */
|
||||
/* NOTE: (length == 0) implies (last <= first) */
|
||||
*objPtrPtr = objv[first];
|
||||
return TCL_OK;
|
||||
return objv[first];
|
||||
}
|
||||
|
||||
objv += first; objc = (last - first + 1);
|
||||
@@ -3089,11 +3122,11 @@ TclStringCatObjv(
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"concatenation failed: unable to alloc %"
|
||||
TCL_LL_MODIFIER "d bytes",
|
||||
(Tcl_WideUInt)STRING_SIZE(length)));
|
||||
TCL_Z_MODIFIER "u bytes",
|
||||
STRING_SIZE(length)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
dst = Tcl_GetUnicode(objResultPtr) + start;
|
||||
} else {
|
||||
@@ -3106,11 +3139,11 @@ TclStringCatObjv(
|
||||
if (interp) {
|
||||
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
|
||||
"concatenation failed: unable to alloc %"
|
||||
TCL_LL_MODIFIER "d bytes",
|
||||
(Tcl_WideUInt)STRING_SIZE(length)));
|
||||
TCL_Z_MODIFIER "u bytes",
|
||||
STRING_SIZE(length)));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
dst = Tcl_GetUnicode(objResultPtr);
|
||||
}
|
||||
@@ -3141,7 +3174,7 @@ TclStringCatObjv(
|
||||
length));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
dst = Tcl_GetString(objResultPtr) + start;
|
||||
|
||||
@@ -3157,7 +3190,7 @@ TclStringCatObjv(
|
||||
length));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
dst = Tcl_GetString(objResultPtr);
|
||||
}
|
||||
@@ -3172,8 +3205,7 @@ TclStringCatObjv(
|
||||
}
|
||||
}
|
||||
}
|
||||
*objPtrPtr = objResultPtr;
|
||||
return TCL_OK;
|
||||
return objResultPtr;
|
||||
|
||||
overflow:
|
||||
if (interp) {
|
||||
@@ -3181,13 +3213,13 @@ TclStringCatObjv(
|
||||
"max size for a Tcl value (%d bytes) exceeded", INT_MAX));
|
||||
Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
|
||||
}
|
||||
return TCL_ERROR;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclStringFind --
|
||||
* TclStringFirst --
|
||||
*
|
||||
* Implements the [string first] operation.
|
||||
*
|
||||
@@ -3203,20 +3235,20 @@ TclStringCatObjv(
|
||||
*/
|
||||
|
||||
int
|
||||
TclStringFind(
|
||||
TclStringFirst(
|
||||
Tcl_Obj *needle,
|
||||
Tcl_Obj *haystack,
|
||||
int start)
|
||||
{
|
||||
int lh, ln = Tcl_GetCharLength(needle);
|
||||
|
||||
if (start < 0) {
|
||||
start = 0;
|
||||
}
|
||||
if (ln == 0) {
|
||||
/*
|
||||
* We don't find empty substrings. Bizarre!
|
||||
*
|
||||
* TODO: When we one day make this a true substring
|
||||
* finder, change this to "return 0"
|
||||
*/
|
||||
/* We don't find empty substrings. Bizarre!
|
||||
* Whenever this routine is turned into a proper substring
|
||||
* finder, change to `return start` after limits imposed. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -3224,51 +3256,46 @@ TclStringFind(
|
||||
unsigned char *end, *try, *bh;
|
||||
unsigned char *bn = Tcl_GetByteArrayFromObj(needle, &ln);
|
||||
|
||||
/* Find bytes in bytes */
|
||||
bh = Tcl_GetByteArrayFromObj(haystack, &lh);
|
||||
end = bh + lh;
|
||||
|
||||
try = bh + start;
|
||||
while (try + ln <= end) {
|
||||
try = memchr(try, bn[0], end - try);
|
||||
|
||||
/*
|
||||
* Look for the leading byte of the needle in the haystack
|
||||
* starting at try and stopping when there's not enough room
|
||||
* for the needle left.
|
||||
*/
|
||||
try = memchr(try, bn[0], (end + 1 - ln) - try);
|
||||
if (try == NULL) {
|
||||
/* Leading byte not found -> needle cannot be found. */
|
||||
return -1;
|
||||
}
|
||||
/* Leading byte found, check rest of needle. */
|
||||
if (0 == memcmp(try+1, bn+1, ln-1)) {
|
||||
/* Checks! Return the successful index. */
|
||||
return (try - bh);
|
||||
}
|
||||
/* Rest of needle match failed; Iterate to continue search. */
|
||||
try++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we have two strings of single-byte characters. If we have, we
|
||||
* can use strstr() to do the search. Note that we can sometimes have
|
||||
* multibyte characters when the string could be minimally represented
|
||||
* using single byte characters; we can't assume that a mismatch here
|
||||
* means no match.
|
||||
* TODO: It might be nice to support some cases where it is not
|
||||
* necessary to shimmer to &tclStringType to compute the result,
|
||||
* and instead operate just on the objPtr->bytes values directly.
|
||||
* However, we also do not want the answer to change based on the
|
||||
* code pathway, or if it does we want that to be for some values
|
||||
* we explicitly decline to support. Getting there will involve
|
||||
* locking down in practice more firmly just what encodings produce
|
||||
* what supported results for the objPtr->bytes values. For now,
|
||||
* do only the well-defined Tcl_UniChar array search.
|
||||
*/
|
||||
|
||||
lh = Tcl_GetCharLength(haystack);
|
||||
if (haystack->bytes && (lh == haystack->length) && needle->bytes
|
||||
&& (ln == needle->length)) {
|
||||
/*
|
||||
* Both haystack and needle are all single-byte chars.
|
||||
*/
|
||||
|
||||
char *found = strstr(haystack->bytes + start, needle->bytes);
|
||||
|
||||
if (found) {
|
||||
return (found - haystack->bytes);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Do the search on the unicode representation for simplicity.
|
||||
*/
|
||||
|
||||
{
|
||||
Tcl_UniChar *try, *end, *uh;
|
||||
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
|
||||
|
||||
@@ -3316,24 +3343,24 @@ TclStringLast(
|
||||
* We don't find empty substrings. Bizarre!
|
||||
*
|
||||
* TODO: When we one day make this a true substring
|
||||
* finder, change this to "return 0"
|
||||
* finder, change this to "return last", after limitation.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ln > last + 1) {
|
||||
lh = Tcl_GetCharLength(haystack);
|
||||
if (last >= lh) {
|
||||
last = lh - 1;
|
||||
}
|
||||
|
||||
if (last < ln - 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (TclIsPureByteArray(needle) && TclIsPureByteArray(haystack)) {
|
||||
unsigned char *try, *bh;
|
||||
unsigned char *try, *bh = Tcl_GetByteArrayFromObj(haystack, &lh);
|
||||
unsigned char *bn = Tcl_GetByteArrayFromObj(needle, &ln);
|
||||
|
||||
bh = Tcl_GetByteArrayFromObj(haystack, &lh);
|
||||
|
||||
if (last + 1 > lh) {
|
||||
last = lh - 1;
|
||||
}
|
||||
try = bh + last + 1 - ln;
|
||||
while (try >= bh) {
|
||||
if ((*try == bn[0])
|
||||
@@ -3345,38 +3372,10 @@ TclStringLast(
|
||||
return -1;
|
||||
}
|
||||
|
||||
lh = Tcl_GetCharLength(haystack);
|
||||
if (last + 1 > lh) {
|
||||
last = lh - 1;
|
||||
}
|
||||
if (haystack->bytes && (lh == haystack->length)) {
|
||||
/* haystack is all single-byte chars */
|
||||
|
||||
if (needle->bytes && (ln == needle->length)) {
|
||||
/* needle is also all single-byte chars */
|
||||
|
||||
char *try = haystack->bytes + last + 1 - ln;
|
||||
while (try >= haystack->bytes) {
|
||||
if ((*try == needle->bytes[0])
|
||||
&& (0 == memcmp(try+1, needle->bytes + 1, ln - 1))) {
|
||||
return (try - haystack->bytes);
|
||||
}
|
||||
try--;
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
/*
|
||||
* Cannot find substring with a multi-byte char inside
|
||||
* a string with no multi-byte chars.
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
Tcl_UniChar *try, *uh;
|
||||
{
|
||||
Tcl_UniChar *try, *uh = Tcl_GetUnicodeFromObj(haystack, &lh);
|
||||
Tcl_UniChar *un = Tcl_GetUnicodeFromObj(needle, &ln);
|
||||
|
||||
uh = Tcl_GetUnicodeFromObj(haystack, &lh);
|
||||
|
||||
try = uh + last + 1 - ln;
|
||||
while (try >= uh) {
|
||||
if ((*try == un[0])
|
||||
@@ -3392,14 +3391,14 @@ TclStringLast(
|
||||
/*
|
||||
*---------------------------------------------------------------------------
|
||||
*
|
||||
* TclStringObjReverse --
|
||||
* TclStringReverse --
|
||||
*
|
||||
* Implements the [string reverse] operation.
|
||||
*
|
||||
* Results:
|
||||
* An unshared Tcl value which is the [string reverse] of the argument
|
||||
* supplied. When sharing rules permit, the returned value might be the
|
||||
* argument with modifications done in place.
|
||||
* A Tcl value which is the [string reverse] of the argument supplied.
|
||||
* When sharing rules permit and the caller requests, the returned value
|
||||
* might be the argument with modifications done in place.
|
||||
*
|
||||
* Side effects:
|
||||
* May allocate a new Tcl_Obj.
|
||||
@@ -3430,17 +3429,19 @@ ReverseBytes(
|
||||
}
|
||||
|
||||
Tcl_Obj *
|
||||
TclStringObjReverse(
|
||||
Tcl_Obj *objPtr)
|
||||
TclStringReverse(
|
||||
Tcl_Obj *objPtr,
|
||||
int flags)
|
||||
{
|
||||
String *stringPtr;
|
||||
Tcl_UniChar ch = 0;
|
||||
int inPlace = flags & TCL_STRING_IN_PLACE;
|
||||
|
||||
if (TclIsPureByteArray(objPtr)) {
|
||||
int numBytes;
|
||||
unsigned char *from = Tcl_GetByteArrayFromObj(objPtr, &numBytes);
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
if (!inPlace || Tcl_IsShared(objPtr)) {
|
||||
objPtr = Tcl_NewByteArrayObj(NULL, numBytes);
|
||||
}
|
||||
ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, NULL), from, numBytes);
|
||||
@@ -3454,7 +3455,7 @@ TclStringObjReverse(
|
||||
Tcl_UniChar *from = Tcl_GetUnicode(objPtr);
|
||||
Tcl_UniChar *src = from + stringPtr->numChars;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
if (!inPlace || Tcl_IsShared(objPtr)) {
|
||||
Tcl_UniChar *to;
|
||||
|
||||
/*
|
||||
@@ -3462,7 +3463,6 @@ TclStringObjReverse(
|
||||
* Tcl_SetObjLength into growing the unicode rep buffer.
|
||||
*/
|
||||
|
||||
ch = 0;
|
||||
objPtr = Tcl_NewUnicodeObj(&ch, 1);
|
||||
Tcl_SetObjLength(objPtr, stringPtr->numChars);
|
||||
to = Tcl_GetUnicode(objPtr);
|
||||
@@ -3484,7 +3484,7 @@ TclStringObjReverse(
|
||||
int numBytes = objPtr->length;
|
||||
char *to, *from = objPtr->bytes;
|
||||
|
||||
if (Tcl_IsShared(objPtr)) {
|
||||
if (!inPlace || Tcl_IsShared(objPtr)) {
|
||||
objPtr = Tcl_NewObj();
|
||||
Tcl_SetObjLength(objPtr, numBytes);
|
||||
}
|
||||
@@ -3565,7 +3565,7 @@ ExtendUnicodeRepWithString(
|
||||
{
|
||||
String *stringPtr = GET_STRING(objPtr);
|
||||
int needed, numOrigChars = 0;
|
||||
Tcl_UniChar *dst;
|
||||
Tcl_UniChar *dst, unichar = 0;
|
||||
|
||||
if (stringPtr->hasUnicode) {
|
||||
numOrigChars = stringPtr->numChars;
|
||||
@@ -3588,7 +3588,8 @@ ExtendUnicodeRepWithString(
|
||||
numAppendChars = 0;
|
||||
}
|
||||
for (dst=stringPtr->unicode + numOrigChars; numAppendChars-- > 0; dst++) {
|
||||
bytes += TclUtfToUniChar(bytes, dst);
|
||||
bytes += TclUtfToUniChar(bytes, &unichar);
|
||||
*dst = unichar;
|
||||
}
|
||||
*dst = 0;
|
||||
}
|
||||
|
||||
+116
-49
@@ -31,6 +31,7 @@
|
||||
#undef Tcl_NewIntObj
|
||||
#undef Tcl_NewListObj
|
||||
#undef Tcl_NewLongObj
|
||||
#undef Tcl_DbNewLongObj
|
||||
#undef Tcl_NewObj
|
||||
#undef Tcl_NewStringObj
|
||||
#undef Tcl_DumpActiveMemory
|
||||
@@ -42,6 +43,7 @@
|
||||
#undef TclpGetPid
|
||||
#undef TclSockMinimumBuffers
|
||||
#undef Tcl_SetIntObj
|
||||
#undef Tcl_SetLongObj
|
||||
#undef TclpInetNtoa
|
||||
#undef TclWinGetServByName
|
||||
#undef TclWinGetSockOpt
|
||||
@@ -49,7 +51,7 @@
|
||||
#undef TclWinNToHS
|
||||
|
||||
/* See bug 510001: TclSockMinimumBuffers needs plat imp */
|
||||
#if defined(_WIN64) || defined(TCL_NO_DEPRECATED)
|
||||
#if defined(_WIN64) || defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
|
||||
# define TclSockMinimumBuffersOld 0
|
||||
#else
|
||||
#define TclSockMinimumBuffersOld sockMinimumBuffersOld
|
||||
@@ -59,19 +61,31 @@ static int TclSockMinimumBuffersOld(int sock, int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TCL_NO_DEPRECATED)
|
||||
#if defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
|
||||
# define TclSetStartupScriptPath 0
|
||||
# define TclGetStartupScriptPath 0
|
||||
# define TclSetStartupScriptFileName 0
|
||||
# define TclGetStartupScriptFileName 0
|
||||
# define TclPrecTraceProc 0
|
||||
# define TclpInetNtoa 0
|
||||
# define TclWinGetServByName 0
|
||||
# define TclWinGetSockOpt 0
|
||||
# define TclWinSetSockOpt 0
|
||||
# define TclWinNToHS 0
|
||||
# define TclWinGetPlatformId 0
|
||||
# define TclWinResetInterfaces 0
|
||||
# define TclWinSetInterfaces 0
|
||||
# define TclWinGetPlatformId 0
|
||||
# define TclBNInitBignumFromWideUInt 0
|
||||
# define TclBNInitBignumFromWideInt 0
|
||||
# define TclBNInitBignumFromLong 0
|
||||
# define Tcl_Backslash 0
|
||||
# define Tcl_GetDefaultEncodingDir 0
|
||||
# define Tcl_SetDefaultEncodingDir 0
|
||||
# define Tcl_EvalTokens 0
|
||||
# define Tcl_CreateMathFunc 0
|
||||
# define Tcl_GetMathFuncInfo 0
|
||||
# define Tcl_ListMathFuncs 0
|
||||
#else
|
||||
#define TclSetStartupScriptPath setStartupScriptPath
|
||||
static void TclSetStartupScriptPath(Tcl_Obj *path)
|
||||
@@ -98,13 +112,28 @@ static const char *TclGetStartupScriptFileName(void)
|
||||
}
|
||||
return Tcl_GetString(path);
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#undef TclWinNToHS
|
||||
#undef TclWinGetPlatformId
|
||||
#undef TclWinResetInterfaces
|
||||
#undef TclWinSetInterfaces
|
||||
static void
|
||||
doNothing(void)
|
||||
{
|
||||
/* dummy implementation, no need to do anything */
|
||||
}
|
||||
#define TclWinNToHS winNToHS
|
||||
static unsigned short TclWinNToHS(unsigned short ns) {
|
||||
return ntohs(ns);
|
||||
}
|
||||
#define TclWinGetPlatformId winGetPlatformId
|
||||
static int
|
||||
TclWinGetPlatformId(void)
|
||||
{
|
||||
return 2; /* VER_PLATFORM_WIN32_NT */;
|
||||
}
|
||||
#define TclWinResetInterfaces doNothing
|
||||
#define TclWinSetInterfaces (void (*) (int)) doNothing
|
||||
#endif
|
||||
# define TclBNInitBignumFromWideUInt TclInitBignumFromWideUInt
|
||||
# define TclBNInitBignumFromWideInt TclInitBignumFromWideInt
|
||||
@@ -119,12 +148,15 @@ static unsigned short TclWinNToHS(unsigned short ns) {
|
||||
# define TclpIsAtty 0
|
||||
#elif defined(__CYGWIN__)
|
||||
# define TclpIsAtty TclPlatIsAtty
|
||||
# define TclWinSetInterfaces (void (*) (int)) doNothing
|
||||
#if defined(TCL_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8
|
||||
static void
|
||||
doNothing(void)
|
||||
{
|
||||
/* dummy implementation, no need to do anything */
|
||||
}
|
||||
#endif
|
||||
# define TclWinAddProcess (void (*) (void *, unsigned int)) doNothing
|
||||
# define TclWinFlushDirtyChannels doNothing
|
||||
# define TclWinResetInterfaces doNothing
|
||||
|
||||
static Tcl_Encoding winTCharEncoding;
|
||||
|
||||
static int
|
||||
TclpIsAtty(int fd)
|
||||
@@ -132,24 +164,15 @@ TclpIsAtty(int fd)
|
||||
return isatty(fd);
|
||||
}
|
||||
|
||||
#define TclWinGetPlatformId winGetPlatformId
|
||||
static int
|
||||
TclWinGetPlatformId()
|
||||
{
|
||||
/* Don't bother to determine the real platform on cygwin,
|
||||
* because VER_PLATFORM_WIN32_NT is the only supported platform */
|
||||
return 2; /* VER_PLATFORM_WIN32_NT */;
|
||||
}
|
||||
|
||||
void *TclWinGetTclInstance()
|
||||
{
|
||||
void *hInstance = NULL;
|
||||
GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
(const char *)&winTCharEncoding, &hInstance);
|
||||
(const char *)&TclpIsAtty, &hInstance);
|
||||
return hInstance;
|
||||
}
|
||||
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
#define TclWinSetSockOpt winSetSockOpt
|
||||
static int
|
||||
TclWinSetSockOpt(SOCKET s, int level, int optname,
|
||||
@@ -194,23 +217,23 @@ TclpGetPid(Tcl_Pid pid)
|
||||
return (int) (size_t) pid;
|
||||
}
|
||||
|
||||
static void
|
||||
doNothing(void)
|
||||
{
|
||||
/* dummy implementation, no need to do anything */
|
||||
}
|
||||
|
||||
char *
|
||||
Tcl_WinUtfToTChar(
|
||||
const char *string,
|
||||
int len,
|
||||
Tcl_DString *dsPtr)
|
||||
{
|
||||
if (!winTCharEncoding) {
|
||||
winTCharEncoding = Tcl_GetEncoding(0, "unicode");
|
||||
}
|
||||
return Tcl_UtfToExternalDString(winTCharEncoding,
|
||||
string, len, dsPtr);
|
||||
WCHAR *wp;
|
||||
int size = MultiByteToWideChar(CP_UTF8, 0, string, len, 0, 0);
|
||||
|
||||
Tcl_DStringInit(dsPtr);
|
||||
Tcl_DStringSetLength(dsPtr, 2*size+2);
|
||||
wp = (WCHAR *)Tcl_DStringValue(dsPtr);
|
||||
MultiByteToWideChar(CP_UTF8, 0, string, len, wp, size+1);
|
||||
if (len == -1) --size; /* account for 0-byte at string end */
|
||||
Tcl_DStringSetLength(dsPtr, 2*size);
|
||||
wp[size] = 0;
|
||||
return (char *)wp;
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -219,11 +242,21 @@ Tcl_WinTCharToUtf(
|
||||
int len,
|
||||
Tcl_DString *dsPtr)
|
||||
{
|
||||
if (!winTCharEncoding) {
|
||||
winTCharEncoding = Tcl_GetEncoding(0, "unicode");
|
||||
char *p;
|
||||
int size;
|
||||
|
||||
if (len > 0) {
|
||||
len /= 2;
|
||||
}
|
||||
return Tcl_ExternalToUtfDString(winTCharEncoding,
|
||||
string, len, dsPtr);
|
||||
size = WideCharToMultiByte(CP_UTF8, 0, string, len, 0, 0, NULL, NULL);
|
||||
Tcl_DStringInit(dsPtr);
|
||||
Tcl_DStringSetLength(dsPtr, size+1);
|
||||
p = (char *)Tcl_DStringValue(dsPtr);
|
||||
WideCharToMultiByte(CP_UTF8, 0, string, len, p, size, NULL, NULL);
|
||||
if (len == -1) --size; /* account for 0-byte at string end */
|
||||
Tcl_DStringSetLength(dsPtr, size);
|
||||
p[size] = 0;
|
||||
return p;
|
||||
}
|
||||
|
||||
#if defined(TCL_WIDE_INT_IS_LONG)
|
||||
@@ -244,7 +277,7 @@ static Tcl_Obj *dbNewLongObj(
|
||||
TclDbNewObj(objPtr, file, line);
|
||||
objPtr->bytes = NULL;
|
||||
|
||||
objPtr->internalRep.longValue = (long) intValue;
|
||||
objPtr->internalRep.wideValue = (long) intValue;
|
||||
objPtr->typePtr = &tclIntType;
|
||||
return objPtr;
|
||||
#else
|
||||
@@ -311,7 +344,7 @@ static int formatInt(char *buffer, int n){
|
||||
|
||||
#endif /* __CYGWIN__ */
|
||||
|
||||
#ifdef TCL_NO_DEPRECATED
|
||||
#if defined(TCL_NO_DEPRECATED)
|
||||
# define Tcl_SeekOld 0
|
||||
# define Tcl_TellOld 0
|
||||
# undef Tcl_SetBooleanObj
|
||||
@@ -366,6 +399,26 @@ static int formatInt(char *buffer, int n){
|
||||
# define TclBackgroundException 0
|
||||
# undef TclpReaddir
|
||||
# define TclpReaddir 0
|
||||
# define TclSetStartupScript 0
|
||||
# define TclGetStartupScript 0
|
||||
# define TclCreateNamespace 0
|
||||
# define TclDeleteNamespace 0
|
||||
# define TclAppendExportList 0
|
||||
# define TclExport 0
|
||||
# define TclImport 0
|
||||
# define TclForgetImport 0
|
||||
# define TclGetCurrentNamespace_ 0
|
||||
# define TclGetGlobalNamespace_ 0
|
||||
# define TclFindNamespace 0
|
||||
# define TclFindCommand 0
|
||||
# define TclGetCommandFromObj 0
|
||||
# define TclGetCommandFullName 0
|
||||
# define TclCopyChannelOld 0
|
||||
# define Tcl_AppendResultVA 0
|
||||
# define Tcl_AppendStringsToObjVA 0
|
||||
# define Tcl_SetErrorCodeVA 0
|
||||
# define Tcl_PanicVA 0
|
||||
# define Tcl_VarEvalVA 0
|
||||
# undef TclpGetDate
|
||||
# define TclpGetDate 0
|
||||
# undef TclpLocaltime
|
||||
@@ -378,6 +431,20 @@ static int formatInt(char *buffer, int n){
|
||||
# define Tcl_SeekOld seekOld
|
||||
# define Tcl_TellOld tellOld
|
||||
# define TclBackgroundException Tcl_BackgroundException
|
||||
# define TclSetStartupScript Tcl_SetStartupScript
|
||||
# define TclGetStartupScript Tcl_GetStartupScript
|
||||
# define TclCreateNamespace Tcl_CreateNamespace
|
||||
# define TclDeleteNamespace Tcl_DeleteNamespace
|
||||
# define TclAppendExportList Tcl_AppendExportList
|
||||
# define TclExport Tcl_Export
|
||||
# define TclImport Tcl_Import
|
||||
# define TclForgetImport Tcl_ForgetImport
|
||||
# define TclGetCurrentNamespace_ Tcl_GetCurrentNamespace
|
||||
# define TclGetGlobalNamespace_ Tcl_GetGlobalNamespace
|
||||
# define TclFindNamespace Tcl_FindNamespace
|
||||
# define TclFindCommand Tcl_FindCommand
|
||||
# define TclGetCommandFromObj Tcl_GetCommandFromObj
|
||||
# define TclGetCommandFullName Tcl_GetCommandFullName
|
||||
# define TclpLocaltime_unix TclpLocaltime
|
||||
# define TclpGmtime_unix TclpGmtime
|
||||
|
||||
@@ -530,22 +597,22 @@ static const TclIntStubs tclIntStubs = {
|
||||
TclUpdateReturnInfo, /* 109 */
|
||||
TclSockMinimumBuffers, /* 110 */
|
||||
Tcl_AddInterpResolvers, /* 111 */
|
||||
Tcl_AppendExportList, /* 112 */
|
||||
Tcl_CreateNamespace, /* 113 */
|
||||
Tcl_DeleteNamespace, /* 114 */
|
||||
Tcl_Export, /* 115 */
|
||||
Tcl_FindCommand, /* 116 */
|
||||
Tcl_FindNamespace, /* 117 */
|
||||
TclAppendExportList, /* 112 */
|
||||
TclCreateNamespace, /* 113 */
|
||||
TclDeleteNamespace, /* 114 */
|
||||
TclExport, /* 115 */
|
||||
TclFindCommand, /* 116 */
|
||||
TclFindNamespace, /* 117 */
|
||||
Tcl_GetInterpResolvers, /* 118 */
|
||||
Tcl_GetNamespaceResolvers, /* 119 */
|
||||
Tcl_FindNamespaceVar, /* 120 */
|
||||
Tcl_ForgetImport, /* 121 */
|
||||
Tcl_GetCommandFromObj, /* 122 */
|
||||
Tcl_GetCommandFullName, /* 123 */
|
||||
Tcl_GetCurrentNamespace, /* 124 */
|
||||
Tcl_GetGlobalNamespace, /* 125 */
|
||||
TclForgetImport, /* 121 */
|
||||
TclGetCommandFromObj, /* 122 */
|
||||
TclGetCommandFullName, /* 123 */
|
||||
TclGetCurrentNamespace_, /* 124 */
|
||||
TclGetGlobalNamespace_, /* 125 */
|
||||
Tcl_GetVariableFullName, /* 126 */
|
||||
Tcl_Import, /* 127 */
|
||||
TclImport, /* 127 */
|
||||
Tcl_PopCallFrame, /* 128 */
|
||||
Tcl_PushCallFrame, /* 129 */
|
||||
Tcl_RemoveInterpResolvers, /* 130 */
|
||||
@@ -596,8 +663,8 @@ static const TclIntStubs tclIntStubs = {
|
||||
TclCallVarTraces, /* 175 */
|
||||
TclCleanupVar, /* 176 */
|
||||
TclVarErrMsg, /* 177 */
|
||||
Tcl_SetStartupScript, /* 178 */
|
||||
Tcl_GetStartupScript, /* 179 */
|
||||
TclSetStartupScript, /* 178 */
|
||||
TclGetStartupScript, /* 179 */
|
||||
0, /* 180 */
|
||||
0, /* 181 */
|
||||
TclpLocaltime, /* 182 */
|
||||
|
||||
+57
-166
@@ -305,14 +305,6 @@ static int TestlinkCmd(ClientData dummy,
|
||||
static int TestlocaleCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
static int TestMathFunc(ClientData clientData,
|
||||
Tcl_Interp *interp, Tcl_Value *args,
|
||||
Tcl_Value *resultPtr);
|
||||
static int TestMathFunc2(ClientData clientData,
|
||||
Tcl_Interp *interp, Tcl_Value *args,
|
||||
Tcl_Value *resultPtr);
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
static int TestmainthreadCmd(ClientData dummy,
|
||||
Tcl_Interp *interp, int argc, const char **argv);
|
||||
static int TestsetmainloopCmd(ClientData dummy,
|
||||
@@ -424,6 +416,12 @@ static Tcl_FSMatchInDirectoryProc SimpleMatchInDirectory;
|
||||
static int TestNumUtfCharsCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int TestFindFirstCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int TestFindLastCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
static int TestHashSystemHashCmd(ClientData clientData,
|
||||
Tcl_Interp *interp, int objc,
|
||||
Tcl_Obj *const objv[]);
|
||||
@@ -549,10 +547,6 @@ int
|
||||
Tcltest_Init(
|
||||
Tcl_Interp *interp) /* Interpreter for application. */
|
||||
{
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
Tcl_ValueType t3ArgTypes[2];
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
Tcl_Obj *listPtr;
|
||||
Tcl_Obj **objv;
|
||||
int objc, index;
|
||||
@@ -692,6 +686,10 @@ Tcltest_Init(
|
||||
TestsetobjerrorcodeCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testnumutfchars",
|
||||
TestNumUtfCharsCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testfindfirst",
|
||||
TestFindFirstCmd, NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testfindlast",
|
||||
TestFindLastCmd, NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd,
|
||||
NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "testsocket", TestSocketCmd,
|
||||
@@ -701,10 +699,6 @@ Tcltest_Init(
|
||||
Tcl_CreateCommand(interp, "testtranslatefilename",
|
||||
TesttranslatefilenameCmd, NULL, NULL);
|
||||
Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL);
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
Tcl_CreateMathFunc(interp, "T1", 0, NULL, TestMathFunc, (ClientData) 123);
|
||||
Tcl_CreateMathFunc(interp, "T2", 0, NULL, TestMathFunc, (ClientData) 345);
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, NULL,
|
||||
NULL);
|
||||
Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd,
|
||||
@@ -715,13 +709,6 @@ Tcltest_Init(
|
||||
Tcl_CreateObjCommand(interp, "testcpuid", TestcpuidCmd,
|
||||
(ClientData) 0, NULL);
|
||||
#endif
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
t3ArgTypes[0] = TCL_EITHER;
|
||||
t3ArgTypes[1] = TCL_EITHER;
|
||||
Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2,
|
||||
NULL);
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
Tcl_CreateObjCommand(interp, "testnreunwind", TestNREUnwind,
|
||||
NULL, NULL);
|
||||
Tcl_CreateObjCommand(interp, "testnrelevels", TestNRELevels,
|
||||
@@ -3344,146 +3331,6 @@ TestlocaleCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TestMathFunc --
|
||||
*
|
||||
* This is a user-defined math procedure to test out math procedures
|
||||
* with no arguments.
|
||||
*
|
||||
* Results:
|
||||
* A normal Tcl completion code.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
#ifndef TCL_NO_DEPRECATED
|
||||
static int
|
||||
TestMathFunc(
|
||||
ClientData clientData, /* Integer value to return. */
|
||||
Tcl_Interp *interp, /* Not used. */
|
||||
Tcl_Value *args, /* Not used. */
|
||||
Tcl_Value *resultPtr) /* Where to store result. */
|
||||
{
|
||||
resultPtr->type = TCL_INT;
|
||||
resultPtr->intValue = PTR2INT(clientData);
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TestMathFunc2 --
|
||||
*
|
||||
* This is a user-defined math procedure to test out math procedures
|
||||
* that do have arguments, in this case 2.
|
||||
*
|
||||
* Results:
|
||||
* A normal Tcl completion code.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
TestMathFunc2(
|
||||
ClientData clientData, /* Integer value to return. */
|
||||
Tcl_Interp *interp, /* Used to report errors. */
|
||||
Tcl_Value *args, /* Points to an array of two Tcl_Value structs
|
||||
* for the two arguments. */
|
||||
Tcl_Value *resultPtr) /* Where to store the result. */
|
||||
{
|
||||
int result = TCL_OK;
|
||||
|
||||
/*
|
||||
* Return the maximum of the two arguments with the correct type.
|
||||
*/
|
||||
|
||||
if (args[0].type == TCL_INT) {
|
||||
int i0 = args[0].intValue;
|
||||
|
||||
if (args[1].type == TCL_INT) {
|
||||
int i1 = args[1].intValue;
|
||||
|
||||
resultPtr->type = TCL_INT;
|
||||
resultPtr->intValue = ((i0 > i1)? i0 : i1);
|
||||
} else if (args[1].type == TCL_DOUBLE) {
|
||||
double d0 = i0;
|
||||
double d1 = args[1].doubleValue;
|
||||
|
||||
resultPtr->type = TCL_DOUBLE;
|
||||
resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
|
||||
} else if (args[1].type == TCL_WIDE_INT) {
|
||||
Tcl_WideInt w0 = Tcl_LongAsWide(i0);
|
||||
Tcl_WideInt w1 = args[1].wideValue;
|
||||
|
||||
resultPtr->type = TCL_WIDE_INT;
|
||||
resultPtr->wideValue = ((w0 > w1)? w0 : w1);
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else if (args[0].type == TCL_DOUBLE) {
|
||||
double d0 = args[0].doubleValue;
|
||||
|
||||
if (args[1].type == TCL_INT) {
|
||||
double d1 = args[1].intValue;
|
||||
|
||||
resultPtr->type = TCL_DOUBLE;
|
||||
resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
|
||||
} else if (args[1].type == TCL_DOUBLE) {
|
||||
double d1 = args[1].doubleValue;
|
||||
|
||||
resultPtr->type = TCL_DOUBLE;
|
||||
resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
|
||||
} else if (args[1].type == TCL_WIDE_INT) {
|
||||
double d1 = Tcl_WideAsDouble(args[1].wideValue);
|
||||
|
||||
resultPtr->type = TCL_DOUBLE;
|
||||
resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else if (args[0].type == TCL_WIDE_INT) {
|
||||
Tcl_WideInt w0 = args[0].wideValue;
|
||||
|
||||
if (args[1].type == TCL_INT) {
|
||||
Tcl_WideInt w1 = Tcl_LongAsWide(args[1].intValue);
|
||||
|
||||
resultPtr->type = TCL_WIDE_INT;
|
||||
resultPtr->wideValue = ((w0 > w1)? w0 : w1);
|
||||
} else if (args[1].type == TCL_DOUBLE) {
|
||||
double d0 = Tcl_WideAsDouble(w0);
|
||||
double d1 = args[1].doubleValue;
|
||||
|
||||
resultPtr->type = TCL_DOUBLE;
|
||||
resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
|
||||
} else if (args[1].type == TCL_WIDE_INT) {
|
||||
Tcl_WideInt w1 = args[1].wideValue;
|
||||
|
||||
resultPtr->type = TCL_WIDE_INT;
|
||||
resultPtr->wideValue = ((w0 > w1)? w0 : w1);
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 2", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
} else {
|
||||
Tcl_AppendResult(interp, "T3: wrong type for arg 1", NULL);
|
||||
result = TCL_ERROR;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif /* TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -5360,7 +5207,7 @@ TestmainthreadCmd(
|
||||
const char **argv) /* Argument strings. */
|
||||
{
|
||||
if (argc == 1) {
|
||||
Tcl_Obj *idObj = Tcl_NewLongObj((long)(size_t)Tcl_GetCurrentThread());
|
||||
Tcl_Obj *idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
|
||||
|
||||
Tcl_SetObjResult(interp, idObj);
|
||||
return TCL_OK;
|
||||
@@ -5757,8 +5604,8 @@ TestChannelCmd(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
TclFormatInt(buf, (size_t) Tcl_GetChannelThread(chan));
|
||||
Tcl_AppendResult(interp, buf, NULL);
|
||||
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
|
||||
(Tcl_WideInt) (size_t) Tcl_GetChannelThread(chan)));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -6885,6 +6732,50 @@ TestNumUtfCharsCmd(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to check correct operation of Tcl_UtfFindFirst
|
||||
*/
|
||||
|
||||
static int
|
||||
TestFindFirstCmd(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
if (objc > 1) {
|
||||
int len = -1;
|
||||
|
||||
if (objc > 2) {
|
||||
(void) Tcl_GetIntFromObj(interp, objv[2], &len);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_UtfFindFirst(Tcl_GetString(objv[1]), len), -1));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Used to check correct operation of Tcl_UtfFindLast
|
||||
*/
|
||||
|
||||
static int
|
||||
TestFindLastCmd(
|
||||
ClientData clientData,
|
||||
Tcl_Interp *interp,
|
||||
int objc,
|
||||
Tcl_Obj *const objv[])
|
||||
{
|
||||
if (objc > 1) {
|
||||
int len = -1;
|
||||
|
||||
if (objc > 2) {
|
||||
(void) Tcl_GetIntFromObj(interp, objv[2], &len);
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_UtfFindLast(Tcl_GetString(objv[1]), len), -1));
|
||||
}
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
#if defined(HAVE_CPUID) || defined(_WIN32)
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
|
||||
@@ -1088,6 +1088,9 @@ TestobjCmd(
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
|
||||
} else {
|
||||
typeName = objv[2]->typePtr->name;
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (!strcmp(typeName, "wideInt")) typeName = "int";
|
||||
#endif
|
||||
Tcl_SetObjResult(interp, Tcl_NewStringObj(typeName, -1));
|
||||
}
|
||||
} else if (strcmp(subCmd, "refcount") == 0) {
|
||||
@@ -1115,6 +1118,11 @@ TestobjCmd(
|
||||
}
|
||||
if (varPtr[varIndex]->typePtr == NULL) { /* a string! */
|
||||
Tcl_AppendToObj(Tcl_GetObjResult(interp), "string", -1);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
} else if (!strcmp(varPtr[varIndex]->typePtr->name, "wideInt")) {
|
||||
Tcl_AppendToObj(Tcl_GetObjResult(interp),
|
||||
"int", -1);
|
||||
#endif
|
||||
} else {
|
||||
Tcl_AppendToObj(Tcl_GetObjResult(interp),
|
||||
varPtr[varIndex]->typePtr->name, -1);
|
||||
|
||||
@@ -248,7 +248,7 @@ ThreadObjCmd(
|
||||
|
||||
switch ((enum options)option) {
|
||||
case THREAD_CANCEL: {
|
||||
long id;
|
||||
Tcl_WideInt id;
|
||||
const char *result;
|
||||
int flags, arg;
|
||||
|
||||
@@ -264,7 +264,7 @@ ThreadObjCmd(
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
if (Tcl_GetLongFromObj(interp, objv[arg], &id) != TCL_OK) {
|
||||
if (Tcl_GetWideIntFromObj(interp, objv[arg], &id) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
arg++;
|
||||
|
||||
+11
-24
@@ -819,9 +819,6 @@ Tcl_AfterObjCmd(
|
||||
*/
|
||||
|
||||
if (objv[1]->typePtr == &tclIntType
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
|| objv[1]->typePtr == &tclWideIntType
|
||||
#endif
|
||||
|| objv[1]->typePtr == &tclBignumType
|
||||
|| (Tcl_GetIndexFromObj(NULL, objv[1], afterSubCmds, "", 0,
|
||||
&index) != TCL_OK)) {
|
||||
@@ -1045,37 +1042,27 @@ AfterDelay(
|
||||
if (iPtr->limit.timeEvent == NULL
|
||||
|| TCL_TIME_BEFORE(endTime, iPtr->limit.time)) {
|
||||
diff = TCL_TIME_DIFF_MS_CEILING(endTime, now);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (diff > LONG_MAX) {
|
||||
diff = LONG_MAX;
|
||||
}
|
||||
#endif
|
||||
if (diff > TCL_TIME_MAXIMUM_SLICE) {
|
||||
diff = TCL_TIME_MAXIMUM_SLICE;
|
||||
}
|
||||
if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) {
|
||||
diff = 1;
|
||||
}
|
||||
if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) {
|
||||
diff = 1;
|
||||
}
|
||||
if (diff > 0) {
|
||||
Tcl_Sleep((long) diff);
|
||||
if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) {
|
||||
break;
|
||||
}
|
||||
Tcl_Sleep((int) diff);
|
||||
if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now);
|
||||
#ifndef TCL_WIDE_INT_IS_LONG
|
||||
if (diff > LONG_MAX) {
|
||||
diff = LONG_MAX;
|
||||
}
|
||||
#endif
|
||||
if (diff > TCL_TIME_MAXIMUM_SLICE) {
|
||||
diff = TCL_TIME_MAXIMUM_SLICE;
|
||||
}
|
||||
if (diff > 0) {
|
||||
Tcl_Sleep((long) diff);
|
||||
Tcl_Sleep((int) diff);
|
||||
}
|
||||
if (Tcl_AsyncReady()) {
|
||||
if (Tcl_AsyncInvoke(interp, TCL_OK) != TCL_OK) {
|
||||
@@ -1089,7 +1076,7 @@ AfterDelay(
|
||||
return TCL_ERROR;
|
||||
}
|
||||
}
|
||||
Tcl_GetTime(&now);
|
||||
Tcl_GetTime(&now);
|
||||
} while (TCL_TIME_BEFORE(now, endTime));
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
+24
-24
@@ -26,9 +26,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* MS Visual C++ doesn't have a 128bit type for words, so fall back to 32bit MPI's (where words are 64bit) */
|
||||
#if defined(_MSC_VER) || defined(__LLP64__)
|
||||
# define MP_32BIT
|
||||
#endif
|
||||
|
||||
/* detect 64-bit mode if possible */
|
||||
#if defined(NEVER) /* 128-bit ints fail in too many places */
|
||||
# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
|
||||
#if defined(NEVER)
|
||||
# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT) || defined(_MSC_VER))
|
||||
# define MP_64BIT
|
||||
# endif
|
||||
#endif
|
||||
@@ -73,12 +78,7 @@ typedef uint32_t mp_word;
|
||||
typedef uint64_t mp_digit;
|
||||
#define MP_DIGIT_DECLARED
|
||||
#endif
|
||||
# if defined(_WIN32)
|
||||
#ifndef MP_WORD_DECLARED
|
||||
typedef unsigned __int128 mp_word;
|
||||
#define MP_WORD_DECLARED
|
||||
#endif
|
||||
# elif defined(__GNUC__)
|
||||
# if defined(__GNUC__)
|
||||
typedef unsigned long mp_word __attribute__((mode(TI)));
|
||||
# else
|
||||
/* it seems you have a problem
|
||||
@@ -124,7 +124,7 @@ typedef mp_digit mp_min_u32;
|
||||
/* use arc4random on platforms that support it */
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
# define MP_GEN_RANDOM() arc4random()
|
||||
# define MP_GEN_RANDOM_MAX 0xffffffff
|
||||
# define MP_GEN_RANDOM_MAX 0xffffffffu
|
||||
#endif
|
||||
|
||||
/* use rand() as fall-back if there's no better rand function */
|
||||
@@ -181,7 +181,7 @@ MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
|
||||
#endif
|
||||
|
||||
/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
|
||||
#define MP_WARRAY (1 << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
|
||||
#define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
|
||||
|
||||
/* the infamous mp_int structure */
|
||||
#ifndef MP_INT_DECLARED
|
||||
@@ -271,9 +271,9 @@ int mp_set_int(mp_int *a, unsigned long b);
|
||||
int mp_set_long(mp_int *a, unsigned long b);
|
||||
*/
|
||||
|
||||
/* set a platform dependent unsigned long long value */
|
||||
/* set a platform dependent Tcl_WideUInt value */
|
||||
/*
|
||||
int mp_set_long_long(mp_int *a, unsigned long long b);
|
||||
int mp_set_long_long(mp_int *a, Tcl_WideUInt b);
|
||||
*/
|
||||
|
||||
/* get a 32-bit value */
|
||||
@@ -286,9 +286,9 @@ unsigned long mp_get_int(const mp_int *a);
|
||||
unsigned long mp_get_long(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* get a platform dependent unsigned long long value */
|
||||
/* get a platform dependent Tcl_WideUInt value */
|
||||
/*
|
||||
unsigned long long mp_get_long_long(const mp_int *a);
|
||||
Tcl_WideUInt mp_get_long_long(const mp_int *a);
|
||||
*/
|
||||
|
||||
/* initialize and set a digit */
|
||||
@@ -553,7 +553,7 @@ int mp_sqrt(const mp_int *arg, mp_int *ret);
|
||||
|
||||
/* special sqrt (mod prime) */
|
||||
/*
|
||||
int mp_sqrtmod_prime(const mp_int *arg, const mp_int *prime, mp_int *ret);
|
||||
int mp_sqrtmod_prime(const mp_int *n, const mp_int *prime, mp_int *ret);
|
||||
*/
|
||||
|
||||
/* is number a square? */
|
||||
@@ -573,16 +573,16 @@ int mp_reduce_setup(mp_int *a, const mp_int *b);
|
||||
|
||||
/* Barrett Reduction, computes a (mod b) with a precomputed value c
|
||||
*
|
||||
* Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
|
||||
* compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
|
||||
* Assumes that 0 < x <= m*m, note if 0 > x > -(m*m) then you can merely
|
||||
* compute the reduction as -1 * mp_reduce(mp_abs(x)) [pseudo code].
|
||||
*/
|
||||
/*
|
||||
int mp_reduce(mp_int *a, const mp_int *b, const mp_int *c);
|
||||
int mp_reduce(mp_int *x, const mp_int *m, const mp_int *mu);
|
||||
*/
|
||||
|
||||
/* setups the montgomery reduction */
|
||||
/*
|
||||
int mp_montgomery_setup(const mp_int *a, mp_digit *mp);
|
||||
int mp_montgomery_setup(const mp_int *n, mp_digit *rho);
|
||||
*/
|
||||
|
||||
/* computes a = B**n mod b without division or multiplication useful for
|
||||
@@ -594,7 +594,7 @@ int mp_montgomery_calc_normalization(mp_int *a, const mp_int *b);
|
||||
|
||||
/* computes x/R == x (mod N) via Montgomery Reduction */
|
||||
/*
|
||||
int mp_montgomery_reduce(mp_int *a, const mp_int *m, mp_digit mp);
|
||||
int mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho);
|
||||
*/
|
||||
|
||||
/* returns 1 if a is a valid DR modulus */
|
||||
@@ -607,9 +607,9 @@ int mp_dr_is_modulus(const mp_int *a);
|
||||
void mp_dr_setup(const mp_int *a, mp_digit *d);
|
||||
*/
|
||||
|
||||
/* reduces a modulo b using the Diminished Radix method */
|
||||
/* reduces a modulo n using the Diminished Radix method */
|
||||
/*
|
||||
int mp_dr_reduce(mp_int *a, const mp_int *b, mp_digit mp);
|
||||
int mp_dr_reduce(mp_int *x, const mp_int *n, mp_digit k);
|
||||
*/
|
||||
|
||||
/* returns true if a can be reduced with mp_reduce_2k */
|
||||
@@ -642,9 +642,9 @@ int mp_reduce_2k_setup_l(const mp_int *a, mp_int *d);
|
||||
int mp_reduce_2k_l(mp_int *a, const mp_int *n, const mp_int *d);
|
||||
*/
|
||||
|
||||
/* d = a**b (mod c) */
|
||||
/* Y = G**X (mod P) */
|
||||
/*
|
||||
int mp_exptmod(const mp_int *a, const mp_int *b, const mp_int *c, mp_int *d);
|
||||
int mp_exptmod(const mp_int *G, const mp_int *X, const mp_int *P, mp_int *Y);
|
||||
*/
|
||||
|
||||
/* ---> Primes <--- */
|
||||
|
||||
+126
-33
@@ -68,11 +68,7 @@ static const unsigned char totalBytes[256] = {
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
#if TCL_UTF_MAX > 3
|
||||
4,4,4,4,4,4,4,4,
|
||||
#else
|
||||
1,1,1,1,1,1,1,1,
|
||||
#endif
|
||||
1,1,1,1,1,1,1,1
|
||||
};
|
||||
|
||||
@@ -94,7 +90,7 @@ static const unsigned char totalBytes[256] = {
|
||||
|
||||
int
|
||||
TclUtfCount(
|
||||
int ch) /* The Tcl_UniChar whose size is returned. */
|
||||
int ch) /* The Unicode character whose size is returned. */
|
||||
{
|
||||
if ((unsigned)(ch - 1) < (UNICODE_SELF - 1)) {
|
||||
return 1;
|
||||
@@ -328,13 +324,22 @@ Tcl_UtfToUniChar(
|
||||
* represents itself.
|
||||
*/
|
||||
}
|
||||
#if TCL_UTF_MAX > 3
|
||||
else if (byte < 0xF8) {
|
||||
if (((src[1] & 0xC0) == 0x80) && ((src[2] & 0xC0) == 0x80) && ((src[3] & 0xC0) == 0x80)) {
|
||||
/*
|
||||
* Four-byte-character lead byte followed by three trail bytes.
|
||||
*/
|
||||
#if TCL_UTF_MAX == 4
|
||||
#if TCL_UTF_MAX == 3
|
||||
byte = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
|
||||
| ((src[2] & 0x3F) << 6) | (src[3] & 0x3F)) - 0x10000;
|
||||
if (byte & 0x100000) {
|
||||
/* out of range, < 0x10000 or > 0x10ffff */
|
||||
} else {
|
||||
/* produce replacement character, and advance source pointer */
|
||||
*chPtr = (Tcl_UniChar) 0xFFFD;
|
||||
return 4;
|
||||
}
|
||||
#elif TCL_UTF_MAX == 4
|
||||
Tcl_UniChar surrogate;
|
||||
|
||||
byte = (((byte & 0x07) << 18) | ((src[1] & 0x3F) << 12)
|
||||
@@ -365,7 +370,6 @@ Tcl_UtfToUniChar(
|
||||
* represents itself.
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
*chPtr = (Tcl_UniChar) byte;
|
||||
return 1;
|
||||
@@ -398,7 +402,7 @@ Tcl_UtfToUniCharDString(
|
||||
* appended to this previously initialized
|
||||
* DString. */
|
||||
{
|
||||
Tcl_UniChar ch, *w, *wString;
|
||||
Tcl_UniChar ch = 0, *w, *wString;
|
||||
const char *p, *end;
|
||||
int oldLength;
|
||||
|
||||
@@ -499,13 +503,13 @@ Tcl_NumUtfChars(
|
||||
}
|
||||
if (i < 0) i = INT_MAX; /* Bug [2738427] */
|
||||
} else {
|
||||
register const char *endPtr = src + length - TCL_UTF_MAX;
|
||||
register const char *endPtr = src + length - 4;
|
||||
|
||||
while (src < endPtr) {
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
i++;
|
||||
}
|
||||
endPtr += TCL_UTF_MAX;
|
||||
endPtr += 4;
|
||||
while ((src < endPtr) && Tcl_UtfCharComplete(src, endPtr - src)) {
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
i++;
|
||||
@@ -522,13 +526,13 @@ Tcl_NumUtfChars(
|
||||
*
|
||||
* Tcl_UtfFindFirst --
|
||||
*
|
||||
* Returns a pointer to the first occurance of the given Tcl_UniChar in
|
||||
* the NULL-terminated UTF-8 string. The NULL terminator is considered
|
||||
* Returns a pointer to the first occurance of the given Unicode character
|
||||
* in the NULL-terminated UTF-8 string. The NULL terminator is considered
|
||||
* part of the UTF-8 string. Equivalent to Plan 9 utfrune().
|
||||
*
|
||||
* Results:
|
||||
* As above. If the Tcl_UniChar does not exist in the given string, the
|
||||
* return value is NULL.
|
||||
* As above. If the Unicode character does not exist in the given string,
|
||||
* the return value is NULL.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
@@ -539,14 +543,21 @@ Tcl_NumUtfChars(
|
||||
const char *
|
||||
Tcl_UtfFindFirst(
|
||||
const char *src, /* The UTF-8 string to be searched. */
|
||||
int ch) /* The Tcl_UniChar to search for. */
|
||||
int ch) /* The Unicode character to search for. */
|
||||
{
|
||||
int len;
|
||||
int len, fullchar;
|
||||
Tcl_UniChar find = 0;
|
||||
|
||||
while (1) {
|
||||
len = TclUtfToUniChar(src, &find);
|
||||
if (find == ch) {
|
||||
fullchar = find;
|
||||
#if TCL_UTF_MAX == 4
|
||||
if (!len) {
|
||||
len += TclUtfToUniChar(src, &find);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (find & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
if (fullchar == ch) {
|
||||
return src;
|
||||
}
|
||||
if (*src == '\0') {
|
||||
@@ -561,12 +572,12 @@ Tcl_UtfFindFirst(
|
||||
*
|
||||
* Tcl_UtfFindLast --
|
||||
*
|
||||
* Returns a pointer to the last occurance of the given Tcl_UniChar in
|
||||
* the NULL-terminated UTF-8 string. The NULL terminator is considered
|
||||
* Returns a pointer to the last occurance of the given Unicode character
|
||||
* in the NULL-terminated UTF-8 string. The NULL terminator is considered
|
||||
* part of the UTF-8 string. Equivalent to Plan 9 utfrrune().
|
||||
*
|
||||
* Results:
|
||||
* As above. If the Tcl_UniChar does not exist in the given string, the
|
||||
* As above. If the Unicode character does not exist in the given string, the
|
||||
* return value is NULL.
|
||||
*
|
||||
* Side effects:
|
||||
@@ -578,16 +589,23 @@ Tcl_UtfFindFirst(
|
||||
const char *
|
||||
Tcl_UtfFindLast(
|
||||
const char *src, /* The UTF-8 string to be searched. */
|
||||
int ch) /* The Tcl_UniChar to search for. */
|
||||
int ch) /* The Unicode character to search for. */
|
||||
{
|
||||
int len;
|
||||
int len, fullchar;
|
||||
Tcl_UniChar find = 0;
|
||||
const char *last;
|
||||
|
||||
last = NULL;
|
||||
while (1) {
|
||||
len = TclUtfToUniChar(src, &find);
|
||||
if (find == ch) {
|
||||
fullchar = find;
|
||||
#if TCL_UTF_MAX == 4
|
||||
if (!len) {
|
||||
len += TclUtfToUniChar(src, &find);
|
||||
fullchar = (((fullchar & 0x3ff) << 10) | (find & 0x3ff)) + 0x10000;
|
||||
}
|
||||
#endif
|
||||
if (fullchar == ch) {
|
||||
last = src;
|
||||
}
|
||||
if (*src == '\0') {
|
||||
@@ -663,7 +681,7 @@ Tcl_UtfPrev(
|
||||
int i, byte;
|
||||
|
||||
look = --src;
|
||||
for (i = 0; i < TCL_UTF_MAX; i++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (look < start) {
|
||||
if (src < start) {
|
||||
src = start;
|
||||
@@ -687,7 +705,7 @@ Tcl_UtfPrev(
|
||||
*
|
||||
* Tcl_UniCharAtIndex --
|
||||
*
|
||||
* Returns the Unicode character represented at the specified character
|
||||
* Returns the Tcl_UniChar represented at the specified character
|
||||
* (not byte) position in the UTF-8 string.
|
||||
*
|
||||
* Results:
|
||||
@@ -706,8 +724,7 @@ Tcl_UniCharAtIndex(
|
||||
{
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
while (index >= 0) {
|
||||
index--;
|
||||
while (index-- >= 0) {
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
}
|
||||
return ch;
|
||||
@@ -737,8 +754,7 @@ Tcl_UtfAtIndex(
|
||||
{
|
||||
Tcl_UniChar ch = 0;
|
||||
|
||||
while (index > 0) {
|
||||
index--;
|
||||
while (index-- > 0) {
|
||||
src += TclUtfToUniChar(src, &ch);
|
||||
}
|
||||
return src;
|
||||
@@ -1053,6 +1069,16 @@ Tcl_UtfNcmp(
|
||||
cs += TclUtfToUniChar(cs, &ch1);
|
||||
ct += TclUtfToUniChar(ct, &ch2);
|
||||
if (ch1 != ch2) {
|
||||
#if TCL_UTF_MAX == 4
|
||||
/* Surrogates always report higher than non-surrogates */
|
||||
if (((ch1 & 0xFC00) == 0xD800)) {
|
||||
if ((ch2 & 0xFC00) != 0xD800) {
|
||||
return ch1;
|
||||
}
|
||||
} else if ((ch2 & 0xFC00) == 0xD800) {
|
||||
return -ch2;
|
||||
}
|
||||
#endif
|
||||
return (ch1 - ch2);
|
||||
}
|
||||
}
|
||||
@@ -1084,6 +1110,7 @@ Tcl_UtfNcasecmp(
|
||||
unsigned long numChars) /* Number of UTF chars to compare. */
|
||||
{
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
|
||||
while (numChars-- > 0) {
|
||||
/*
|
||||
* n must be interpreted as chars, not bytes.
|
||||
@@ -1093,6 +1120,16 @@ Tcl_UtfNcasecmp(
|
||||
cs += TclUtfToUniChar(cs, &ch1);
|
||||
ct += TclUtfToUniChar(ct, &ch2);
|
||||
if (ch1 != ch2) {
|
||||
#if TCL_UTF_MAX == 4
|
||||
/* Surrogates always report higher than non-surrogates */
|
||||
if (((ch1 & 0xFC00) == 0xD800)) {
|
||||
if ((ch2 & 0xFC00) != 0xD800) {
|
||||
return ch1;
|
||||
}
|
||||
} else if ((ch2 & 0xFC00) == 0xD800) {
|
||||
return -ch2;
|
||||
}
|
||||
#endif
|
||||
ch1 = Tcl_UniCharToLower(ch1);
|
||||
ch2 = Tcl_UniCharToLower(ch2);
|
||||
if (ch1 != ch2) {
|
||||
@@ -1102,11 +1139,57 @@ Tcl_UtfNcasecmp(
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_UtfCmp --
|
||||
*
|
||||
* Compare UTF chars of string cs to string ct case sensitively.
|
||||
* Replacement for strcmp in Tcl core, in places where UTF-8 should
|
||||
* be handled.
|
||||
*
|
||||
* Results:
|
||||
* Return <0 if cs < ct, 0 if cs == ct, or >0 if cs > ct.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclUtfCmp(
|
||||
const char *cs, /* UTF string to compare to ct. */
|
||||
const char *ct) /* UTF string cs is compared to. */
|
||||
{
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
|
||||
while (*cs && *ct) {
|
||||
cs += TclUtfToUniChar(cs, &ch1);
|
||||
ct += TclUtfToUniChar(ct, &ch2);
|
||||
if (ch1 != ch2) {
|
||||
#if TCL_UTF_MAX == 4
|
||||
/* Surrogates always report higher than non-surrogates */
|
||||
if (((ch1 & 0xFC00) == 0xD800)) {
|
||||
if ((ch2 & 0xFC00) != 0xD800) {
|
||||
return ch1;
|
||||
}
|
||||
} else if ((ch2 & 0xFC00) == 0xD800) {
|
||||
return -ch2;
|
||||
}
|
||||
#endif
|
||||
return ch1 - ch2;
|
||||
}
|
||||
}
|
||||
return UCHAR(*cs) - UCHAR(*ct);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* Tcl_UtfNcasecmp --
|
||||
* TclUtfCasecmp --
|
||||
*
|
||||
* Compare UTF chars of string cs to string ct case insensitively.
|
||||
* Replacement for strcasecmp in Tcl core, in places where UTF-8 should
|
||||
@@ -1126,12 +1209,22 @@ TclUtfCasecmp(
|
||||
const char *cs, /* UTF string to compare to ct. */
|
||||
const char *ct) /* UTF string cs is compared to. */
|
||||
{
|
||||
while (*cs && *ct) {
|
||||
Tcl_UniChar ch1, ch2;
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
|
||||
while (*cs && *ct) {
|
||||
cs += TclUtfToUniChar(cs, &ch1);
|
||||
ct += TclUtfToUniChar(ct, &ch2);
|
||||
if (ch1 != ch2) {
|
||||
#if TCL_UTF_MAX == 4
|
||||
/* Surrogates always report higher than non-surrogates */
|
||||
if (((ch1 & 0xFC00) == 0xD800)) {
|
||||
if ((ch2 & 0xFC00) != 0xD800) {
|
||||
return ch1;
|
||||
}
|
||||
} else if ((ch2 & 0xFC00) == 0xD800) {
|
||||
return -ch2;
|
||||
}
|
||||
#endif
|
||||
ch1 = Tcl_UniCharToLower(ch1);
|
||||
ch2 = Tcl_UniCharToLower(ch2);
|
||||
if (ch1 != ch2) {
|
||||
|
||||
+203
-75
@@ -107,10 +107,11 @@ static Tcl_ThreadDataKey precisionKey;
|
||||
static void ClearHash(Tcl_HashTable *tablePtr);
|
||||
static void FreeProcessGlobalValue(ClientData clientData);
|
||||
static void FreeThreadHash(ClientData clientData);
|
||||
static int GetEndOffsetFromObj(Tcl_Obj *objPtr, int endValue,
|
||||
int *indexPtr);
|
||||
static Tcl_HashTable * GetThreadHash(Tcl_ThreadDataKey *keyPtr);
|
||||
static int SetEndOffsetFromAny(Tcl_Interp *interp,
|
||||
Tcl_Obj *objPtr);
|
||||
static void UpdateStringOfEndOffset(Tcl_Obj *objPtr);
|
||||
static int FindElement(Tcl_Interp *interp, const char *string,
|
||||
int stringLength, const char *typeStr,
|
||||
const char *typeCode, const char **elementPtr,
|
||||
@@ -119,15 +120,18 @@ static int FindElement(Tcl_Interp *interp, const char *string,
|
||||
/*
|
||||
* The following is the Tcl object type definition for an object that
|
||||
* represents a list index in the form, "end-offset". It is used as a
|
||||
* performance optimization in TclGetIntForIndex. The internal rep is an
|
||||
* integer, so no memory management is required for it.
|
||||
* performance optimization in TclGetIntForIndex. The internal rep is
|
||||
* stored directly in the wideValue, so no memory management is required
|
||||
* for it. This is a caching intrep, keeping the result of a parse
|
||||
* around. This type is only created from a pre-existing string, so an
|
||||
* updateStringProc will never be called and need not exist.
|
||||
*/
|
||||
|
||||
const Tcl_ObjType tclEndOffsetType = {
|
||||
static const Tcl_ObjType endOffsetType = {
|
||||
"end-offset", /* name */
|
||||
NULL, /* freeIntRepProc */
|
||||
NULL, /* dupIntRepProc */
|
||||
UpdateStringOfEndOffset, /* updateStringProc */
|
||||
NULL, /* updateStringProc */
|
||||
SetEndOffsetFromAny
|
||||
};
|
||||
|
||||
@@ -974,7 +978,7 @@ Tcl_ScanCountedElement(
|
||||
int *flagPtr) /* Where to store information to guide
|
||||
* Tcl_ConvertElement. */
|
||||
{
|
||||
int flags = CONVERT_ANY;
|
||||
char flags = CONVERT_ANY;
|
||||
int numBytes = TclScanElement(src, length, &flags);
|
||||
|
||||
*flagPtr = flags;
|
||||
@@ -1015,7 +1019,7 @@ int
|
||||
TclScanElement(
|
||||
const char *src, /* String to convert to Tcl list element. */
|
||||
int length, /* Number of bytes in src, or -1. */
|
||||
int *flagPtr) /* Where to store information to guide
|
||||
char *flagPtr) /* Where to store information to guide
|
||||
* Tcl_ConvertElement. */
|
||||
{
|
||||
const char *p = src;
|
||||
@@ -1547,11 +1551,10 @@ Tcl_Merge(
|
||||
int argc, /* How many strings to merge. */
|
||||
const char *const *argv) /* Array of string values. */
|
||||
{
|
||||
#define LOCAL_SIZE 20
|
||||
int localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
#define LOCAL_SIZE 64
|
||||
char localFlags[LOCAL_SIZE], *flagPtr = NULL;
|
||||
int i, bytesNeeded = 0;
|
||||
char *result, *dst;
|
||||
const int maxFlags = UINT_MAX / sizeof(int);
|
||||
|
||||
/*
|
||||
* Handle empty list case first, so logic of the general case can be
|
||||
@@ -1570,22 +1573,8 @@ Tcl_Merge(
|
||||
|
||||
if (argc <= LOCAL_SIZE) {
|
||||
flagPtr = localFlags;
|
||||
} else if (argc > maxFlags) {
|
||||
/*
|
||||
* We cannot allocate a large enough flag array to format this list in
|
||||
* one pass. We could imagine converting this routine to a multi-pass
|
||||
* implementation, but for sizeof(int) == 4, the limit is a max of
|
||||
* 2^30 list elements and since each element is at least one byte
|
||||
* formatted, and requires one byte space between it and the next one,
|
||||
* that a minimum space requirement of 2^31 bytes, which is already
|
||||
* INT_MAX. If we tried to format a list of > maxFlags elements, we're
|
||||
* just going to overflow the size limits on the formatted string
|
||||
* anyway, so just issue that same panic early.
|
||||
*/
|
||||
|
||||
Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
|
||||
} else {
|
||||
flagPtr = ckalloc(argc * sizeof(int));
|
||||
flagPtr = ckalloc(argc);
|
||||
}
|
||||
for (i = 0; i < argc; i++) {
|
||||
flagPtr[i] = ( i ? TCL_DONT_QUOTE_HASH : 0 );
|
||||
@@ -1619,6 +1608,7 @@ Tcl_Merge(
|
||||
return result;
|
||||
}
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -1652,6 +1642,7 @@ Tcl_Backslash(
|
||||
TclUtfToUniChar(buf, &ch);
|
||||
return (char) ch;
|
||||
}
|
||||
#endif /* !TCL_NO_DEPRECATED */
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -1680,6 +1671,7 @@ TclTrimRight(
|
||||
{
|
||||
const char *p = bytes + numBytes;
|
||||
int pInc;
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
|
||||
if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) {
|
||||
Tcl_Panic("TclTrimRight works only on null-terminated strings");
|
||||
@@ -1698,7 +1690,6 @@ TclTrimRight(
|
||||
*/
|
||||
|
||||
do {
|
||||
Tcl_UniChar ch1;
|
||||
const char *q = trim;
|
||||
int bytesLeft = numTrim;
|
||||
|
||||
@@ -1710,7 +1701,6 @@ TclTrimRight(
|
||||
*/
|
||||
|
||||
do {
|
||||
Tcl_UniChar ch2;
|
||||
int qInc = TclUtfToUniChar(q, &ch2);
|
||||
|
||||
if (ch1 == ch2) {
|
||||
@@ -1760,6 +1750,7 @@ TclTrimLeft(
|
||||
int numTrim) /* ...and its length in bytes */
|
||||
{
|
||||
const char *p = bytes;
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
|
||||
if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) {
|
||||
Tcl_Panic("TclTrimLeft works only on null-terminated strings");
|
||||
@@ -1778,7 +1769,6 @@ TclTrimLeft(
|
||||
*/
|
||||
|
||||
do {
|
||||
Tcl_UniChar ch1;
|
||||
int pInc = TclUtfToUniChar(p, &ch1);
|
||||
const char *q = trim;
|
||||
int bytesLeft = numTrim;
|
||||
@@ -1788,7 +1778,6 @@ TclTrimLeft(
|
||||
*/
|
||||
|
||||
do {
|
||||
Tcl_UniChar ch2;
|
||||
int qInc = TclUtfToUniChar(q, &ch2);
|
||||
|
||||
if (ch1 == ch2) {
|
||||
@@ -2122,7 +2111,7 @@ Tcl_StringCaseMatch(
|
||||
{
|
||||
int p, charLen;
|
||||
const char *pstart = pattern;
|
||||
Tcl_UniChar ch1, ch2;
|
||||
Tcl_UniChar ch1 = 0, ch2 = 0;
|
||||
|
||||
while (1) {
|
||||
p = *pattern;
|
||||
@@ -2232,7 +2221,7 @@ Tcl_StringCaseMatch(
|
||||
*/
|
||||
|
||||
if (p == '[') {
|
||||
Tcl_UniChar startChar, endChar;
|
||||
Tcl_UniChar startChar = 0, endChar = 0;
|
||||
|
||||
pattern++;
|
||||
if (UCHAR(*str) < 0x80) {
|
||||
@@ -2545,7 +2534,8 @@ TclStringMatchObj(
|
||||
udata = Tcl_GetUnicodeFromObj(strObj, &length);
|
||||
uptn = Tcl_GetUnicodeFromObj(ptnObj, &plen);
|
||||
match = TclUniCharMatch(udata, length, uptn, plen, flags);
|
||||
} else if (TclIsPureByteArray(strObj) && !flags) {
|
||||
} else if (TclIsPureByteArray(strObj) && TclIsPureByteArray(ptnObj)
|
||||
&& !flags) {
|
||||
unsigned char *data, *ptn;
|
||||
|
||||
data = Tcl_GetByteArrayFromObj(strObj, &length);
|
||||
@@ -2717,7 +2707,7 @@ Tcl_DStringAppendElement(
|
||||
{
|
||||
char *dst = dsPtr->string + dsPtr->length;
|
||||
int needSpace = TclNeedSpace(dsPtr->string, dst);
|
||||
int flags = needSpace ? TCL_DONT_QUOTE_HASH : 0;
|
||||
char flags = needSpace ? TCL_DONT_QUOTE_HASH : 0;
|
||||
int newSize = dsPtr->length + needSpace
|
||||
+ TclScanElement(element, -1, &flags);
|
||||
|
||||
@@ -3315,6 +3305,7 @@ Tcl_PrintDouble(
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#if !defined(TCL_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
|
||||
/* ARGSUSED */
|
||||
char *
|
||||
TclPrecTraceProc(
|
||||
@@ -3372,6 +3363,7 @@ TclPrecTraceProc(
|
||||
*precisionPtr = prec;
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !TCL_NO_DEPRECATED)*/
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
@@ -3489,9 +3481,9 @@ int
|
||||
TclFormatInt(
|
||||
char *buffer, /* Points to the storage into which the
|
||||
* formatted characters are written. */
|
||||
long n) /* The integer to format. */
|
||||
Tcl_WideInt n) /* The integer to format. */
|
||||
{
|
||||
long intVal;
|
||||
Tcl_WideInt intVal;
|
||||
int i;
|
||||
int numFormatted, j;
|
||||
const char *digits = "0123456789";
|
||||
@@ -3514,7 +3506,7 @@ TclFormatInt(
|
||||
|
||||
intVal = -n; /* [Bug 3390638] Workaround for*/
|
||||
if (n == -n || intVal == n) { /* broken compiler optimizers. */
|
||||
return sprintf(buffer, "%ld", n);
|
||||
return sprintf(buffer, "%" TCL_LL_MODIFIER "d", n);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3592,13 +3584,7 @@ TclGetIntForIndex(
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) {
|
||||
/*
|
||||
* If the object is already an offset from the end of the list, or can
|
||||
* be converted to one, use it.
|
||||
*/
|
||||
|
||||
*indexPtr = endValue + objPtr->internalRep.longValue;
|
||||
if (GetEndOffsetFromObj(objPtr, endValue, indexPtr) == TCL_OK) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3665,40 +3651,38 @@ TclGetIntForIndex(
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* UpdateStringOfEndOffset --
|
||||
* GetEndOffsetFromObj --
|
||||
*
|
||||
* Update the string rep of a Tcl object holding an "end-offset"
|
||||
* expression.
|
||||
* Look for a string of the form "end[+-]offset" and convert it to an
|
||||
* internal representation holding the offset.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
* Tcl return code.
|
||||
*
|
||||
* Side effects:
|
||||
* Stores a valid string in the object's string rep.
|
||||
*
|
||||
* This function does NOT free any earlier string rep. If it is called on an
|
||||
* object that already has a valid string rep, it will leak memory.
|
||||
* May store a Tcl_ObjType.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
static void
|
||||
UpdateStringOfEndOffset(
|
||||
register Tcl_Obj *objPtr)
|
||||
static int
|
||||
GetEndOffsetFromObj(
|
||||
Tcl_Obj *objPtr, /* Pointer to the object to parse */
|
||||
int endValue, /* The value to be stored at "indexPtr" if
|
||||
* "objPtr" holds "end". */
|
||||
int *indexPtr) /* Location filled in with an integer
|
||||
* representing an index. */
|
||||
{
|
||||
char buffer[TCL_INTEGER_SPACE + 5];
|
||||
register int len = 3;
|
||||
|
||||
memcpy(buffer, "end", 4);
|
||||
if (objPtr->internalRep.longValue != 0) {
|
||||
buffer[len++] = '-';
|
||||
len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue));
|
||||
if (SetEndOffsetFromAny(NULL, objPtr) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
objPtr->bytes = ckalloc((unsigned) len+1);
|
||||
memcpy(objPtr->bytes, buffer, (unsigned) len+1);
|
||||
objPtr->length = len;
|
||||
|
||||
/* TODO: Handle overflow cases sensibly */
|
||||
*indexPtr = endValue + (int)objPtr->internalRep.wideValue;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -3722,7 +3706,7 @@ SetEndOffsetFromAny(
|
||||
Tcl_Interp *interp, /* Tcl interpreter or NULL */
|
||||
Tcl_Obj *objPtr) /* Pointer to the object to parse */
|
||||
{
|
||||
int offset; /* Offset in the "end-offset" expression */
|
||||
Tcl_WideInt offset; /* Offset in the "end-offset" expression */
|
||||
register const char *bytes; /* String rep of the object */
|
||||
int length; /* Length of the object's string rep */
|
||||
|
||||
@@ -3730,7 +3714,7 @@ SetEndOffsetFromAny(
|
||||
* If it's already the right type, we're fine.
|
||||
*/
|
||||
|
||||
if (objPtr->typePtr == &tclEndOffsetType) {
|
||||
if (objPtr->typePtr == &endOffsetType) {
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
@@ -3758,16 +3742,23 @@ SetEndOffsetFromAny(
|
||||
} else if ((length > 4) && ((bytes[3] == '-') || (bytes[3] == '+'))) {
|
||||
/*
|
||||
* This is our limited string expression evaluator. Pass everything
|
||||
* after "end-" to Tcl_GetInt, then reverse for offset.
|
||||
* after "end-" to TclParseNumber.
|
||||
*/
|
||||
|
||||
if (TclIsSpaceProc(bytes[4])) {
|
||||
goto badIndexFormat;
|
||||
}
|
||||
if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) {
|
||||
if (TclParseNumber(NULL, objPtr, NULL, bytes+4, length-4, NULL,
|
||||
TCL_PARSE_INTEGER_ONLY) != TCL_OK) {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if (objPtr->typePtr != &tclIntType) {
|
||||
goto badIndexFormat;
|
||||
}
|
||||
offset = objPtr->internalRep.wideValue;
|
||||
if (bytes[3] == '-') {
|
||||
|
||||
/* TODO: Review overflow concerns here! */
|
||||
offset = -offset;
|
||||
}
|
||||
} else {
|
||||
@@ -3790,12 +3781,149 @@ SetEndOffsetFromAny(
|
||||
*/
|
||||
|
||||
TclFreeIntRep(objPtr);
|
||||
objPtr->internalRep.longValue = offset;
|
||||
objPtr->typePtr = &tclEndOffsetType;
|
||||
objPtr->internalRep.wideValue = offset;
|
||||
objPtr->typePtr = &endOffsetType;
|
||||
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclIndexEncode --
|
||||
*
|
||||
* Parse objPtr to determine if it is an index value. Two cases
|
||||
* are possible. The value objPtr might be parsed as an absolute
|
||||
* index value in the C signed int range. Note that this includes
|
||||
* index values that are integers as presented and it includes index
|
||||
* arithmetic expressions. The absolute index values that can be
|
||||
* directly meaningful as an index into either a list or a string are
|
||||
* those integer values >= TCL_INDEX_START (0)
|
||||
* and < TCL_INDEX_AFTER (INT_MAX).
|
||||
* The largest string supported in Tcl 8 has bytelength INT_MAX.
|
||||
* This means the largest supported character length is also INT_MAX,
|
||||
* and the index of the last character in a string of length INT_MAX
|
||||
* is INT_MAX-1.
|
||||
*
|
||||
* Any absolute index value parsed outside that range is encoded
|
||||
* using the before and after values passed in by the
|
||||
* caller as the encoding to use for indices that are either
|
||||
* less than or greater than the usable index range. TCL_INDEX_AFTER
|
||||
* is available as a good choice for most callers to use for
|
||||
* after. Likewise, the value TCL_INDEX_BEFORE is good for
|
||||
* most callers to use for before. Other values are possible
|
||||
* when the caller knows it is helpful in producing its own behavior
|
||||
* for indices before and after the indexed item.
|
||||
*
|
||||
* A token can also be parsed as an end-relative index expression.
|
||||
* All end-relative expressions that indicate an index larger
|
||||
* than end (end+2, end--5) point beyond the end of the indexed
|
||||
* collection, and can be encoded as after. The end-relative
|
||||
* expressions that indicate an index less than or equal to end
|
||||
* are encoded relative to the value TCL_INDEX_END (-2). The
|
||||
* index "end" is encoded as -2, down to the index "end-0x7ffffffe"
|
||||
* which is encoded as INT_MIN. Since the largest index into a
|
||||
* string possible in Tcl 8 is 0x7ffffffe, the interpretation of
|
||||
* "end-0x7ffffffe" for that largest string would be 0. Thus,
|
||||
* if the tokens "end-0x7fffffff" or "end+-0x80000000" are parsed,
|
||||
* they can be encoded with the before value.
|
||||
*
|
||||
* These details will require re-examination whenever string and
|
||||
* list length limits are increased, but that will likely also
|
||||
* mean a revised routine capable of returning Tcl_WideInt values.
|
||||
*
|
||||
* Returns:
|
||||
* TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
|
||||
*
|
||||
* Side effects:
|
||||
* When TCL_OK is returned, the encoded index value is written
|
||||
* to *indexPtr.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclIndexEncode(
|
||||
Tcl_Interp *interp, /* For error reporting, may be NULL */
|
||||
Tcl_Obj *objPtr, /* Index value to parse */
|
||||
int before, /* Value to return for index before beginning */
|
||||
int after, /* Value to return for index after end */
|
||||
int *indexPtr) /* Where to write the encoded answer, not NULL */
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &idx)) {
|
||||
/* We parsed a value in the range INT_MIN...INT_MAX */
|
||||
integerEncode:
|
||||
if (idx < TCL_INDEX_START) {
|
||||
/* All negative absolute indices are "before the beginning" */
|
||||
idx = before;
|
||||
} else if (idx == INT_MAX) {
|
||||
/* This index value is always "after the end" */
|
||||
idx = after;
|
||||
}
|
||||
/* usual case, the absolute index value encodes itself */
|
||||
} else if (TCL_OK == GetEndOffsetFromObj(objPtr, 0, &idx)) {
|
||||
/*
|
||||
* We parsed an end+offset index value.
|
||||
* idx holds the offset value in the range INT_MIN...INT_MAX.
|
||||
*/
|
||||
if (idx > 0) {
|
||||
/*
|
||||
* All end+postive or end-negative expressions
|
||||
* always indicate "after the end".
|
||||
*/
|
||||
idx = after;
|
||||
} else if (idx < INT_MIN - TCL_INDEX_END) {
|
||||
/* These indices always indicate "before the beginning */
|
||||
idx = before;
|
||||
} else {
|
||||
/* Encoded end-positive (or end+negative) are offset */
|
||||
idx += TCL_INDEX_END;
|
||||
}
|
||||
|
||||
/* TODO: Consider flag to suppress repeated end-offset parse. */
|
||||
} else if (TCL_OK == TclGetIntForIndexM(interp, objPtr, 0, &idx)) {
|
||||
/*
|
||||
* Only reach this case when the index value is a
|
||||
* constant index arithmetic expression, and idx
|
||||
* holds the result. Treat it the same as if it were
|
||||
* parsed as an absolute integer value.
|
||||
*/
|
||||
goto integerEncode;
|
||||
} else {
|
||||
return TCL_ERROR;
|
||||
}
|
||||
*indexPtr = idx;
|
||||
return TCL_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
* TclIndexDecode --
|
||||
*
|
||||
* Decodes a value previously encoded by TclIndexEncode. The argument
|
||||
* endValue indicates what value of "end" should be used in the
|
||||
* decoding.
|
||||
*
|
||||
* Results:
|
||||
* The decoded index value.
|
||||
*
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
TclIndexDecode(
|
||||
int encoded, /* Value to decode */
|
||||
int endValue) /* Meaning of "end" to use, > TCL_INDEX_END */
|
||||
{
|
||||
if (encoded <= TCL_INDEX_END) {
|
||||
return (encoded - TCL_INDEX_END) + endValue;
|
||||
}
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/*
|
||||
*----------------------------------------------------------------------
|
||||
*
|
||||
@@ -4027,7 +4155,7 @@ TclSetProcessGlobalValue(
|
||||
Tcl_IncrRefCount(newValue);
|
||||
cacheMap = GetThreadHash(&pgvPtr->key);
|
||||
ClearHash(cacheMap);
|
||||
hPtr = Tcl_CreateHashEntry(cacheMap, (void *)(pgvPtr->epoch), &dummy);
|
||||
hPtr = Tcl_CreateHashEntry(cacheMap, (void *)(size_t)(pgvPtr->epoch), &dummy);
|
||||
Tcl_SetHashValue(hPtr, newValue);
|
||||
Tcl_MutexUnlock(&pgvPtr->mutex);
|
||||
}
|
||||
@@ -4053,7 +4181,7 @@ TclGetProcessGlobalValue(
|
||||
Tcl_Obj *value = NULL;
|
||||
Tcl_HashTable *cacheMap;
|
||||
Tcl_HashEntry *hPtr;
|
||||
size_t epoch = pgvPtr->epoch;
|
||||
unsigned int epoch = pgvPtr->epoch;
|
||||
|
||||
if (pgvPtr->encoding) {
|
||||
Tcl_Encoding current = Tcl_GetEncoding(NULL, NULL);
|
||||
@@ -4087,7 +4215,7 @@ TclGetProcessGlobalValue(
|
||||
}
|
||||
}
|
||||
cacheMap = GetThreadHash(&pgvPtr->key);
|
||||
hPtr = Tcl_FindHashEntry(cacheMap, (void *) (epoch));
|
||||
hPtr = Tcl_FindHashEntry(cacheMap, (void *)(size_t)epoch);
|
||||
if (NULL == hPtr) {
|
||||
int dummy;
|
||||
|
||||
@@ -4120,7 +4248,7 @@ TclGetProcessGlobalValue(
|
||||
|
||||
value = Tcl_NewStringObj(pgvPtr->value, pgvPtr->numBytes);
|
||||
hPtr = Tcl_CreateHashEntry(cacheMap,
|
||||
(void *)(pgvPtr->epoch), &dummy);
|
||||
(void *)(size_t)(pgvPtr->epoch), &dummy);
|
||||
Tcl_MutexUnlock(&pgvPtr->mutex);
|
||||
Tcl_SetHashValue(hPtr, value);
|
||||
Tcl_IncrRefCount(value);
|
||||
|
||||
+2
-2
@@ -280,7 +280,7 @@ CleanupVar(
|
||||
{
|
||||
if (TclIsVarUndefined(varPtr) && TclIsVarInHash(varPtr)
|
||||
&& !TclIsVarTraced(varPtr)
|
||||
&& (VarHashRefCount(varPtr) == !TclIsVarDeadHash(varPtr))) {
|
||||
&& (VarHashRefCount(varPtr) == (unsigned)!TclIsVarDeadHash(varPtr))) {
|
||||
if (VarHashRefCount(varPtr) == 0) {
|
||||
ckfree(varPtr);
|
||||
} else {
|
||||
@@ -289,7 +289,7 @@ CleanupVar(
|
||||
}
|
||||
if (arrayPtr != NULL && TclIsVarUndefined(arrayPtr) &&
|
||||
TclIsVarInHash(arrayPtr) && !TclIsVarTraced(arrayPtr) &&
|
||||
(VarHashRefCount(arrayPtr) == !TclIsVarDeadHash(arrayPtr))) {
|
||||
(VarHashRefCount(arrayPtr) == (unsigned)!TclIsVarDeadHash(arrayPtr))) {
|
||||
if (VarHashRefCount(arrayPtr) == 0) {
|
||||
ckfree(arrayPtr);
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -373,7 +373,7 @@ ConvertErrorToList(
|
||||
|
||||
default:
|
||||
TclNewLiteralStringObj(objv[2], "UNKNOWN");
|
||||
TclNewLongObj(objv[3], code);
|
||||
TclNewIntObj(objv[3], code);
|
||||
return Tcl_NewListObj(4, objv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,377 +0,0 @@
|
||||
# http.tcl
|
||||
# Client-side HTTP for GET, POST, and HEAD commands.
|
||||
# These routines can be used in untrusted code that uses the Safesock
|
||||
# security policy.
|
||||
# These procedures use a callback interface to avoid using vwait,
|
||||
# which is not defined in the safe base.
|
||||
#
|
||||
# See the http.n man page for documentation
|
||||
|
||||
package provide http 1.0
|
||||
|
||||
array set http {
|
||||
-accept */*
|
||||
-proxyhost {}
|
||||
-proxyport {}
|
||||
-useragent {Tcl http client package 1.0}
|
||||
-proxyfilter httpProxyRequired
|
||||
}
|
||||
proc http_config {args} {
|
||||
global http
|
||||
set options [lsort [array names http -*]]
|
||||
set usage [join $options ", "]
|
||||
if {[llength $args] == 0} {
|
||||
set result {}
|
||||
foreach name $options {
|
||||
lappend result $name $http($name)
|
||||
}
|
||||
return $result
|
||||
}
|
||||
regsub -all -- - $options {} options
|
||||
set pat ^-([join $options |])$
|
||||
if {[llength $args] == 1} {
|
||||
set flag [lindex $args 0]
|
||||
if {[regexp -- $pat $flag]} {
|
||||
return $http($flag)
|
||||
} else {
|
||||
return -code error "Unknown option $flag, must be: $usage"
|
||||
}
|
||||
} else {
|
||||
foreach {flag value} $args {
|
||||
if {[regexp -- $pat $flag]} {
|
||||
set http($flag) $value
|
||||
} else {
|
||||
return -code error "Unknown option $flag, must be: $usage"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proc httpFinish { token {errormsg ""} } {
|
||||
upvar #0 $token state
|
||||
global errorInfo errorCode
|
||||
if {[string length $errormsg] != 0} {
|
||||
set state(error) [list $errormsg $errorInfo $errorCode]
|
||||
set state(status) error
|
||||
}
|
||||
catch {close $state(sock)}
|
||||
catch {after cancel $state(after)}
|
||||
if {[info exists state(-command)]} {
|
||||
if {[catch {eval $state(-command) {$token}} err]} {
|
||||
if {[string length $errormsg] == 0} {
|
||||
set state(error) [list $err $errorInfo $errorCode]
|
||||
set state(status) error
|
||||
}
|
||||
}
|
||||
unset state(-command)
|
||||
}
|
||||
}
|
||||
proc http_reset { token {why reset} } {
|
||||
upvar #0 $token state
|
||||
set state(status) $why
|
||||
catch {fileevent $state(sock) readable {}}
|
||||
httpFinish $token
|
||||
if {[info exists state(error)]} {
|
||||
set errorlist $state(error)
|
||||
unset state(error)
|
||||
eval error $errorlist
|
||||
}
|
||||
}
|
||||
proc http_get { url args } {
|
||||
global http
|
||||
if {![info exists http(uid)]} {
|
||||
set http(uid) 0
|
||||
}
|
||||
set token http#[incr http(uid)]
|
||||
upvar #0 $token state
|
||||
http_reset $token
|
||||
array set state {
|
||||
-blocksize 8192
|
||||
-validate 0
|
||||
-headers {}
|
||||
-timeout 0
|
||||
state header
|
||||
meta {}
|
||||
currentsize 0
|
||||
totalsize 0
|
||||
type text/html
|
||||
body {}
|
||||
status ""
|
||||
}
|
||||
set options {-blocksize -channel -command -handler -headers \
|
||||
-progress -query -validate -timeout}
|
||||
set usage [join $options ", "]
|
||||
regsub -all -- - $options {} options
|
||||
set pat ^-([join $options |])$
|
||||
foreach {flag value} $args {
|
||||
if {[regexp $pat $flag]} {
|
||||
# Validate numbers
|
||||
if {[info exists state($flag)] && \
|
||||
[regexp {^[0-9]+$} $state($flag)] && \
|
||||
![regexp {^[0-9]+$} $value]} {
|
||||
return -code error "Bad value for $flag ($value), must be integer"
|
||||
}
|
||||
set state($flag) $value
|
||||
} else {
|
||||
return -code error "Unknown option $flag, can be: $usage"
|
||||
}
|
||||
}
|
||||
if {! [regexp -nocase {^(http://)?([^/:]+)(:([0-9]+))?(/.*)?$} $url \
|
||||
x proto host y port srvurl]} {
|
||||
error "Unsupported URL: $url"
|
||||
}
|
||||
if {[string length $port] == 0} {
|
||||
set port 80
|
||||
}
|
||||
if {[string length $srvurl] == 0} {
|
||||
set srvurl /
|
||||
}
|
||||
if {[string length $proto] == 0} {
|
||||
set url http://$url
|
||||
}
|
||||
set state(url) $url
|
||||
if {![catch {$http(-proxyfilter) $host} proxy]} {
|
||||
set phost [lindex $proxy 0]
|
||||
set pport [lindex $proxy 1]
|
||||
}
|
||||
if {$state(-timeout) > 0} {
|
||||
set state(after) [after $state(-timeout) [list http_reset $token timeout]]
|
||||
}
|
||||
if {[info exists phost] && [string length $phost]} {
|
||||
set srvurl $url
|
||||
set s [socket $phost $pport]
|
||||
} else {
|
||||
set s [socket $host $port]
|
||||
}
|
||||
set state(sock) $s
|
||||
|
||||
# Send data in cr-lf format, but accept any line terminators
|
||||
|
||||
fconfigure $s -translation {auto crlf} -buffersize $state(-blocksize)
|
||||
|
||||
# The following is disallowed in safe interpreters, but the socket
|
||||
# is already in non-blocking mode in that case.
|
||||
|
||||
catch {fconfigure $s -blocking off}
|
||||
set len 0
|
||||
set how GET
|
||||
if {[info exists state(-query)]} {
|
||||
set len [string length $state(-query)]
|
||||
if {$len > 0} {
|
||||
set how POST
|
||||
}
|
||||
} elseif {$state(-validate)} {
|
||||
set how HEAD
|
||||
}
|
||||
puts $s "$how $srvurl HTTP/1.0"
|
||||
puts $s "Accept: $http(-accept)"
|
||||
puts $s "Host: $host"
|
||||
puts $s "User-Agent: $http(-useragent)"
|
||||
foreach {key value} $state(-headers) {
|
||||
regsub -all \[\n\r\] $value {} value
|
||||
set key [string trim $key]
|
||||
if {[string length $key]} {
|
||||
puts $s "$key: $value"
|
||||
}
|
||||
}
|
||||
if {$len > 0} {
|
||||
puts $s "Content-Length: $len"
|
||||
puts $s "Content-Type: application/x-www-form-urlencoded"
|
||||
puts $s ""
|
||||
fconfigure $s -translation {auto binary}
|
||||
puts -nonewline $s $state(-query)
|
||||
} else {
|
||||
puts $s ""
|
||||
}
|
||||
flush $s
|
||||
fileevent $s readable [list httpEvent $token]
|
||||
if {! [info exists state(-command)]} {
|
||||
http_wait $token
|
||||
}
|
||||
return $token
|
||||
}
|
||||
proc http_data {token} {
|
||||
upvar #0 $token state
|
||||
return $state(body)
|
||||
}
|
||||
proc http_status {token} {
|
||||
upvar #0 $token state
|
||||
return $state(status)
|
||||
}
|
||||
proc http_code {token} {
|
||||
upvar #0 $token state
|
||||
return $state(http)
|
||||
}
|
||||
proc http_size {token} {
|
||||
upvar #0 $token state
|
||||
return $state(currentsize)
|
||||
}
|
||||
|
||||
proc httpEvent {token} {
|
||||
upvar #0 $token state
|
||||
set s $state(sock)
|
||||
|
||||
if {[eof $s]} {
|
||||
httpEof $token
|
||||
return
|
||||
}
|
||||
if {$state(state) == "header"} {
|
||||
set n [gets $s line]
|
||||
if {$n == 0} {
|
||||
set state(state) body
|
||||
if {![regexp -nocase ^text $state(type)]} {
|
||||
# Turn off conversions for non-text data
|
||||
fconfigure $s -translation binary
|
||||
if {[info exists state(-channel)]} {
|
||||
fconfigure $state(-channel) -translation binary
|
||||
}
|
||||
}
|
||||
if {[info exists state(-channel)] &&
|
||||
![info exists state(-handler)]} {
|
||||
# Initiate a sequence of background fcopies
|
||||
fileevent $s readable {}
|
||||
httpCopyStart $s $token
|
||||
}
|
||||
} elseif {$n > 0} {
|
||||
if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
|
||||
set state(type) [string trim $type]
|
||||
}
|
||||
if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
|
||||
set state(totalsize) [string trim $length]
|
||||
}
|
||||
if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
|
||||
lappend state(meta) $key $value
|
||||
} elseif {[regexp ^HTTP $line]} {
|
||||
set state(http) $line
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if {[catch {
|
||||
if {[info exists state(-handler)]} {
|
||||
set n [eval $state(-handler) {$s $token}]
|
||||
} else {
|
||||
set block [read $s $state(-blocksize)]
|
||||
set n [string length $block]
|
||||
if {$n >= 0} {
|
||||
append state(body) $block
|
||||
}
|
||||
}
|
||||
if {$n >= 0} {
|
||||
incr state(currentsize) $n
|
||||
}
|
||||
} err]} {
|
||||
httpFinish $token $err
|
||||
} else {
|
||||
if {[info exists state(-progress)]} {
|
||||
eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
proc httpCopyStart {s token} {
|
||||
upvar #0 $token state
|
||||
if {[catch {
|
||||
fcopy $s $state(-channel) -size $state(-blocksize) -command \
|
||||
[list httpCopyDone $token]
|
||||
} err]} {
|
||||
httpFinish $token $err
|
||||
}
|
||||
}
|
||||
proc httpCopyDone {token count {error {}}} {
|
||||
upvar #0 $token state
|
||||
set s $state(sock)
|
||||
incr state(currentsize) $count
|
||||
if {[info exists state(-progress)]} {
|
||||
eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
|
||||
}
|
||||
if {([string length $error] != 0)} {
|
||||
httpFinish $token $error
|
||||
} elseif {[eof $s]} {
|
||||
httpEof $token
|
||||
} else {
|
||||
httpCopyStart $s $token
|
||||
}
|
||||
}
|
||||
proc httpEof {token} {
|
||||
upvar #0 $token state
|
||||
if {$state(state) == "header"} {
|
||||
# Premature eof
|
||||
set state(status) eof
|
||||
} else {
|
||||
set state(status) ok
|
||||
}
|
||||
set state(state) eof
|
||||
httpFinish $token
|
||||
}
|
||||
proc http_wait {token} {
|
||||
upvar #0 $token state
|
||||
if {![info exists state(status)] || [string length $state(status)] == 0} {
|
||||
vwait $token\(status)
|
||||
}
|
||||
if {[info exists state(error)]} {
|
||||
set errorlist $state(error)
|
||||
unset state(error)
|
||||
eval error $errorlist
|
||||
}
|
||||
return $state(status)
|
||||
}
|
||||
|
||||
# Call http_formatQuery with an even number of arguments, where the first is
|
||||
# a name, the second is a value, the third is another name, and so on.
|
||||
|
||||
proc http_formatQuery {args} {
|
||||
set result ""
|
||||
set sep ""
|
||||
foreach i $args {
|
||||
append result $sep [httpMapReply $i]
|
||||
if {$sep != "="} {
|
||||
set sep =
|
||||
} else {
|
||||
set sep &
|
||||
}
|
||||
}
|
||||
return $result
|
||||
}
|
||||
|
||||
# do x-www-urlencoded character mapping
|
||||
# The spec says: "non-alphanumeric characters are replaced by '%HH'"
|
||||
# 1 leave alphanumerics characters alone
|
||||
# 2 Convert every other character to an array lookup
|
||||
# 3 Escape constructs that are "special" to the tcl parser
|
||||
# 4 "subst" the result, doing all the array substitutions
|
||||
|
||||
proc httpMapReply {string} {
|
||||
global httpFormMap
|
||||
set alphanumeric a-zA-Z0-9
|
||||
if {![info exists httpFormMap]} {
|
||||
|
||||
for {set i 1} {$i <= 256} {incr i} {
|
||||
set c [format %c $i]
|
||||
if {![string match \[$alphanumeric\] $c]} {
|
||||
set httpFormMap($c) %[format %.2x $i]
|
||||
}
|
||||
}
|
||||
# These are handled specially
|
||||
array set httpFormMap {
|
||||
" " + \n %0d%0a
|
||||
}
|
||||
}
|
||||
regsub -all \[^$alphanumeric\] $string {$httpFormMap(&)} string
|
||||
regsub -all \n $string {\\n} string
|
||||
regsub -all \t $string {\\t} string
|
||||
regsub -all {[][{})\\]\)} $string {\\&} string
|
||||
return [subst $string]
|
||||
}
|
||||
|
||||
# Default proxy filter.
|
||||
proc httpProxyRequired {host} {
|
||||
global http
|
||||
if {[info exists http(-proxyhost)] && [string length $http(-proxyhost)]} {
|
||||
if {![info exists http(-proxyport)] || ![string length $http(-proxyport)]} {
|
||||
set http(-proxyport) 8080
|
||||
}
|
||||
return [list $http(-proxyhost) $http(-proxyport)]
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# Tcl package index file, version 1.0
|
||||
# This file is generated by the "pkg_mkIndex" command
|
||||
# and sourced either when an application starts up or
|
||||
# by a "package unknown" script. It invokes the
|
||||
# "package ifneeded" command to set up package-related
|
||||
# information so that packages will be loaded automatically
|
||||
# in response to "package require" commands. When this
|
||||
# script is sourced, the variable $dir must contain the
|
||||
# full path name of this file's directory.
|
||||
|
||||
package ifneeded http 1.0 [list tclPkgSetup $dir http 1.0 {{http.tcl source {httpCopyDone httpCopyStart httpEof httpEvent httpFinish httpMapReply httpProxyRequired http_code http_config http_data http_formatQuery http_get http_reset http_size http_status http_wait}}}]
|
||||
+2
-43
@@ -73,43 +73,6 @@ namespace eval tcl {
|
||||
encoding dirs $Path
|
||||
}
|
||||
}
|
||||
|
||||
# TIP #255 min and max functions
|
||||
namespace eval mathfunc {
|
||||
proc min {args} {
|
||||
if {![llength $args]} {
|
||||
return -code error \
|
||||
"too few arguments to math function \"min\""
|
||||
}
|
||||
set val Inf
|
||||
foreach arg $args {
|
||||
# This will handle forcing the numeric value without
|
||||
# ruining the internal type of a numeric object
|
||||
if {[catch {expr {double($arg)}} err]} {
|
||||
return -code error $err
|
||||
}
|
||||
if {$arg < $val} {set val $arg}
|
||||
}
|
||||
return $val
|
||||
}
|
||||
proc max {args} {
|
||||
if {![llength $args]} {
|
||||
return -code error \
|
||||
"too few arguments to math function \"max\""
|
||||
}
|
||||
set val -Inf
|
||||
foreach arg $args {
|
||||
# This will handle forcing the numeric value without
|
||||
# ruining the internal type of a numeric object
|
||||
if {[catch {expr {double($arg)}} err]} {
|
||||
return -code error $err
|
||||
}
|
||||
if {$arg > $val} {set val $arg}
|
||||
}
|
||||
return $val
|
||||
}
|
||||
namespace export min max
|
||||
}
|
||||
}
|
||||
|
||||
namespace eval tcl::Pkg {}
|
||||
@@ -656,8 +619,7 @@ proc auto_execok name {
|
||||
set auto_execs($name) ""
|
||||
|
||||
set shellBuiltins [list assoc cls copy date del dir echo erase ftype \
|
||||
md mkdir mklink move rd ren rename rmdir start \
|
||||
time type ver vol]
|
||||
md mkdir mklink move rd ren rename rmdir start time type ver vol]
|
||||
if {[info exists env(PATHEXT)]} {
|
||||
# Add an initial ; to have the {} extension check first.
|
||||
set execExtensions [split ";$env(PATHEXT)" ";"]
|
||||
@@ -691,10 +653,7 @@ proc auto_execok name {
|
||||
set windir $env(WINDIR)
|
||||
}
|
||||
if {[info exists windir]} {
|
||||
if {$tcl_platform(os) eq "Windows NT"} {
|
||||
append path "$windir/system32;"
|
||||
}
|
||||
append path "$windir/system;$windir;"
|
||||
append path "$windir/system32;$windir/system;$windir;"
|
||||
}
|
||||
|
||||
foreach var {PATH Path path} {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# on it. If your code does rely on this package you
|
||||
# may directly incorporate this code into your application.
|
||||
|
||||
package require Tcl 8.2-
|
||||
package require Tcl 8.5-
|
||||
# When this version number changes, update the pkgIndex.tcl file
|
||||
# and the install directory in the Makefiles.
|
||||
package provide opt 0.4.7
|
||||
|
||||
@@ -8,5 +8,5 @@
|
||||
# script is sourced, the variable $dir must contain the
|
||||
# full path name of this file's directory.
|
||||
|
||||
if {![package vsatisfies [package provide Tcl] 8.2-]} {return}
|
||||
if {![package vsatisfies [package provide Tcl] 8.5-]} {return}
|
||||
package ifneeded opt 0.4.7 [list source [file join $dir optparse.tcl]]
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# created by tools/tclZIC.tcl - do not edit
|
||||
if {![info exists TZData(Africa/Abidjan)]} {
|
||||
LoadTimeZoneFile Africa/Abidjan
|
||||
|
||||
set TZData(:Africa/Sao_Tome) {
|
||||
{-9223372036854775808 1616 0 LMT}
|
||||
{-2713912016 -2205 0 LMT}
|
||||
{-1830381795 0 0 GMT}
|
||||
{1514768400 3600 0 WAT}
|
||||
}
|
||||
set TZData(:Africa/Sao_Tome) $TZData(:Africa/Abidjan)
|
||||
|
||||
@@ -91,167 +91,167 @@ set TZData(:America/Campo_Grande) {
|
||||
{1487473200 -14400 0 -04}
|
||||
{1508040000 -10800 1 -03}
|
||||
{1518922800 -14400 0 -04}
|
||||
{1540094400 -10800 1 -03}
|
||||
{1541304000 -10800 1 -03}
|
||||
{1550372400 -14400 0 -04}
|
||||
{1571544000 -10800 1 -03}
|
||||
{1572753600 -10800 1 -03}
|
||||
{1581822000 -14400 0 -04}
|
||||
{1602993600 -10800 1 -03}
|
||||
{1604203200 -10800 1 -03}
|
||||
{1613876400 -14400 0 -04}
|
||||
{1634443200 -10800 1 -03}
|
||||
{1636257600 -10800 1 -03}
|
||||
{1645326000 -14400 0 -04}
|
||||
{1665892800 -10800 1 -03}
|
||||
{1667707200 -10800 1 -03}
|
||||
{1677380400 -14400 0 -04}
|
||||
{1697342400 -10800 1 -03}
|
||||
{1699156800 -10800 1 -03}
|
||||
{1708225200 -14400 0 -04}
|
||||
{1729396800 -10800 1 -03}
|
||||
{1730606400 -10800 1 -03}
|
||||
{1739674800 -14400 0 -04}
|
||||
{1760846400 -10800 1 -03}
|
||||
{1762056000 -10800 1 -03}
|
||||
{1771729200 -14400 0 -04}
|
||||
{1792296000 -10800 1 -03}
|
||||
{1793505600 -10800 1 -03}
|
||||
{1803178800 -14400 0 -04}
|
||||
{1823745600 -10800 1 -03}
|
||||
{1825560000 -10800 1 -03}
|
||||
{1834628400 -14400 0 -04}
|
||||
{1855195200 -10800 1 -03}
|
||||
{1857009600 -10800 1 -03}
|
||||
{1866078000 -14400 0 -04}
|
||||
{1887249600 -10800 1 -03}
|
||||
{1888459200 -10800 1 -03}
|
||||
{1897527600 -14400 0 -04}
|
||||
{1918699200 -10800 1 -03}
|
||||
{1919908800 -10800 1 -03}
|
||||
{1928977200 -14400 0 -04}
|
||||
{1950148800 -10800 1 -03}
|
||||
{1951358400 -10800 1 -03}
|
||||
{1960426800 -14400 0 -04}
|
||||
{1981598400 -10800 1 -03}
|
||||
{1983412800 -10800 1 -03}
|
||||
{1992481200 -14400 0 -04}
|
||||
{2013048000 -10800 1 -03}
|
||||
{2014862400 -10800 1 -03}
|
||||
{2024535600 -14400 0 -04}
|
||||
{2044497600 -10800 1 -03}
|
||||
{2046312000 -10800 1 -03}
|
||||
{2055380400 -14400 0 -04}
|
||||
{2076552000 -10800 1 -03}
|
||||
{2077761600 -10800 1 -03}
|
||||
{2086830000 -14400 0 -04}
|
||||
{2108001600 -10800 1 -03}
|
||||
{2109211200 -10800 1 -03}
|
||||
{2118884400 -14400 0 -04}
|
||||
{2139451200 -10800 1 -03}
|
||||
{2140660800 -10800 1 -03}
|
||||
{2150334000 -14400 0 -04}
|
||||
{2170900800 -10800 1 -03}
|
||||
{2172715200 -10800 1 -03}
|
||||
{2181783600 -14400 0 -04}
|
||||
{2202350400 -10800 1 -03}
|
||||
{2204164800 -10800 1 -03}
|
||||
{2213233200 -14400 0 -04}
|
||||
{2234404800 -10800 1 -03}
|
||||
{2235614400 -10800 1 -03}
|
||||
{2244682800 -14400 0 -04}
|
||||
{2265854400 -10800 1 -03}
|
||||
{2267064000 -10800 1 -03}
|
||||
{2276132400 -14400 0 -04}
|
||||
{2297304000 -10800 1 -03}
|
||||
{2298513600 -10800 1 -03}
|
||||
{2307582000 -14400 0 -04}
|
||||
{2328753600 -10800 1 -03}
|
||||
{2329963200 -10800 1 -03}
|
||||
{2339636400 -14400 0 -04}
|
||||
{2360203200 -10800 1 -03}
|
||||
{2362017600 -10800 1 -03}
|
||||
{2371086000 -14400 0 -04}
|
||||
{2391652800 -10800 1 -03}
|
||||
{2393467200 -10800 1 -03}
|
||||
{2402535600 -14400 0 -04}
|
||||
{2423707200 -10800 1 -03}
|
||||
{2424916800 -10800 1 -03}
|
||||
{2433985200 -14400 0 -04}
|
||||
{2455156800 -10800 1 -03}
|
||||
{2456366400 -10800 1 -03}
|
||||
{2465434800 -14400 0 -04}
|
||||
{2486606400 -10800 1 -03}
|
||||
{2487816000 -10800 1 -03}
|
||||
{2497489200 -14400 0 -04}
|
||||
{2518056000 -10800 1 -03}
|
||||
{2519870400 -10800 1 -03}
|
||||
{2528938800 -14400 0 -04}
|
||||
{2549505600 -10800 1 -03}
|
||||
{2551320000 -10800 1 -03}
|
||||
{2560388400 -14400 0 -04}
|
||||
{2580955200 -10800 1 -03}
|
||||
{2582769600 -10800 1 -03}
|
||||
{2591838000 -14400 0 -04}
|
||||
{2613009600 -10800 1 -03}
|
||||
{2614219200 -10800 1 -03}
|
||||
{2623287600 -14400 0 -04}
|
||||
{2644459200 -10800 1 -03}
|
||||
{2645668800 -10800 1 -03}
|
||||
{2654737200 -14400 0 -04}
|
||||
{2675908800 -10800 1 -03}
|
||||
{2677118400 -10800 1 -03}
|
||||
{2686791600 -14400 0 -04}
|
||||
{2707358400 -10800 1 -03}
|
||||
{2709172800 -10800 1 -03}
|
||||
{2718241200 -14400 0 -04}
|
||||
{2738808000 -10800 1 -03}
|
||||
{2740622400 -10800 1 -03}
|
||||
{2749690800 -14400 0 -04}
|
||||
{2770862400 -10800 1 -03}
|
||||
{2772072000 -10800 1 -03}
|
||||
{2781140400 -14400 0 -04}
|
||||
{2802312000 -10800 1 -03}
|
||||
{2803521600 -10800 1 -03}
|
||||
{2812590000 -14400 0 -04}
|
||||
{2833761600 -10800 1 -03}
|
||||
{2834971200 -10800 1 -03}
|
||||
{2844039600 -14400 0 -04}
|
||||
{2865211200 -10800 1 -03}
|
||||
{2867025600 -10800 1 -03}
|
||||
{2876094000 -14400 0 -04}
|
||||
{2896660800 -10800 1 -03}
|
||||
{2898475200 -10800 1 -03}
|
||||
{2907543600 -14400 0 -04}
|
||||
{2928110400 -10800 1 -03}
|
||||
{2929924800 -10800 1 -03}
|
||||
{2938993200 -14400 0 -04}
|
||||
{2960164800 -10800 1 -03}
|
||||
{2961374400 -10800 1 -03}
|
||||
{2970442800 -14400 0 -04}
|
||||
{2991614400 -10800 1 -03}
|
||||
{2992824000 -10800 1 -03}
|
||||
{3001892400 -14400 0 -04}
|
||||
{3023064000 -10800 1 -03}
|
||||
{3024273600 -10800 1 -03}
|
||||
{3033946800 -14400 0 -04}
|
||||
{3054513600 -10800 1 -03}
|
||||
{3056328000 -10800 1 -03}
|
||||
{3065396400 -14400 0 -04}
|
||||
{3085963200 -10800 1 -03}
|
||||
{3087777600 -10800 1 -03}
|
||||
{3096846000 -14400 0 -04}
|
||||
{3118017600 -10800 1 -03}
|
||||
{3119227200 -10800 1 -03}
|
||||
{3128295600 -14400 0 -04}
|
||||
{3149467200 -10800 1 -03}
|
||||
{3150676800 -10800 1 -03}
|
||||
{3159745200 -14400 0 -04}
|
||||
{3180916800 -10800 1 -03}
|
||||
{3182126400 -10800 1 -03}
|
||||
{3191194800 -14400 0 -04}
|
||||
{3212366400 -10800 1 -03}
|
||||
{3213576000 -10800 1 -03}
|
||||
{3223249200 -14400 0 -04}
|
||||
{3243816000 -10800 1 -03}
|
||||
{3245630400 -10800 1 -03}
|
||||
{3254698800 -14400 0 -04}
|
||||
{3275265600 -10800 1 -03}
|
||||
{3277080000 -10800 1 -03}
|
||||
{3286148400 -14400 0 -04}
|
||||
{3307320000 -10800 1 -03}
|
||||
{3308529600 -10800 1 -03}
|
||||
{3317598000 -14400 0 -04}
|
||||
{3338769600 -10800 1 -03}
|
||||
{3339979200 -10800 1 -03}
|
||||
{3349047600 -14400 0 -04}
|
||||
{3370219200 -10800 1 -03}
|
||||
{3371428800 -10800 1 -03}
|
||||
{3381102000 -14400 0 -04}
|
||||
{3401668800 -10800 1 -03}
|
||||
{3403483200 -10800 1 -03}
|
||||
{3412551600 -14400 0 -04}
|
||||
{3433118400 -10800 1 -03}
|
||||
{3434932800 -10800 1 -03}
|
||||
{3444001200 -14400 0 -04}
|
||||
{3464568000 -10800 1 -03}
|
||||
{3466382400 -10800 1 -03}
|
||||
{3475450800 -14400 0 -04}
|
||||
{3496622400 -10800 1 -03}
|
||||
{3497832000 -10800 1 -03}
|
||||
{3506900400 -14400 0 -04}
|
||||
{3528072000 -10800 1 -03}
|
||||
{3529281600 -10800 1 -03}
|
||||
{3538350000 -14400 0 -04}
|
||||
{3559521600 -10800 1 -03}
|
||||
{3560731200 -10800 1 -03}
|
||||
{3570404400 -14400 0 -04}
|
||||
{3590971200 -10800 1 -03}
|
||||
{3592785600 -10800 1 -03}
|
||||
{3601854000 -14400 0 -04}
|
||||
{3622420800 -10800 1 -03}
|
||||
{3624235200 -10800 1 -03}
|
||||
{3633303600 -14400 0 -04}
|
||||
{3654475200 -10800 1 -03}
|
||||
{3655684800 -10800 1 -03}
|
||||
{3664753200 -14400 0 -04}
|
||||
{3685924800 -10800 1 -03}
|
||||
{3687134400 -10800 1 -03}
|
||||
{3696202800 -14400 0 -04}
|
||||
{3717374400 -10800 1 -03}
|
||||
{3718584000 -10800 1 -03}
|
||||
{3727652400 -14400 0 -04}
|
||||
{3748824000 -10800 1 -03}
|
||||
{3750638400 -10800 1 -03}
|
||||
{3759706800 -14400 0 -04}
|
||||
{3780273600 -10800 1 -03}
|
||||
{3782088000 -10800 1 -03}
|
||||
{3791156400 -14400 0 -04}
|
||||
{3811723200 -10800 1 -03}
|
||||
{3813537600 -10800 1 -03}
|
||||
{3822606000 -14400 0 -04}
|
||||
{3843777600 -10800 1 -03}
|
||||
{3844987200 -10800 1 -03}
|
||||
{3854055600 -14400 0 -04}
|
||||
{3875227200 -10800 1 -03}
|
||||
{3876436800 -10800 1 -03}
|
||||
{3885505200 -14400 0 -04}
|
||||
{3906676800 -10800 1 -03}
|
||||
{3907886400 -10800 1 -03}
|
||||
{3917559600 -14400 0 -04}
|
||||
{3938126400 -10800 1 -03}
|
||||
{3939940800 -10800 1 -03}
|
||||
{3949009200 -14400 0 -04}
|
||||
{3969576000 -10800 1 -03}
|
||||
{3971390400 -10800 1 -03}
|
||||
{3980458800 -14400 0 -04}
|
||||
{4001630400 -10800 1 -03}
|
||||
{4002840000 -10800 1 -03}
|
||||
{4011908400 -14400 0 -04}
|
||||
{4033080000 -10800 1 -03}
|
||||
{4034289600 -10800 1 -03}
|
||||
{4043358000 -14400 0 -04}
|
||||
{4064529600 -10800 1 -03}
|
||||
{4065739200 -10800 1 -03}
|
||||
{4074807600 -14400 0 -04}
|
||||
{4095979200 -10800 1 -03}
|
||||
{4097188800 -10800 1 -03}
|
||||
}
|
||||
|
||||
@@ -91,167 +91,167 @@ set TZData(:America/Cuiaba) {
|
||||
{1487473200 -14400 0 -04}
|
||||
{1508040000 -10800 1 -03}
|
||||
{1518922800 -14400 0 -04}
|
||||
{1540094400 -10800 1 -03}
|
||||
{1541304000 -10800 1 -03}
|
||||
{1550372400 -14400 0 -04}
|
||||
{1571544000 -10800 1 -03}
|
||||
{1572753600 -10800 1 -03}
|
||||
{1581822000 -14400 0 -04}
|
||||
{1602993600 -10800 1 -03}
|
||||
{1604203200 -10800 1 -03}
|
||||
{1613876400 -14400 0 -04}
|
||||
{1634443200 -10800 1 -03}
|
||||
{1636257600 -10800 1 -03}
|
||||
{1645326000 -14400 0 -04}
|
||||
{1665892800 -10800 1 -03}
|
||||
{1667707200 -10800 1 -03}
|
||||
{1677380400 -14400 0 -04}
|
||||
{1697342400 -10800 1 -03}
|
||||
{1699156800 -10800 1 -03}
|
||||
{1708225200 -14400 0 -04}
|
||||
{1729396800 -10800 1 -03}
|
||||
{1730606400 -10800 1 -03}
|
||||
{1739674800 -14400 0 -04}
|
||||
{1760846400 -10800 1 -03}
|
||||
{1762056000 -10800 1 -03}
|
||||
{1771729200 -14400 0 -04}
|
||||
{1792296000 -10800 1 -03}
|
||||
{1793505600 -10800 1 -03}
|
||||
{1803178800 -14400 0 -04}
|
||||
{1823745600 -10800 1 -03}
|
||||
{1825560000 -10800 1 -03}
|
||||
{1834628400 -14400 0 -04}
|
||||
{1855195200 -10800 1 -03}
|
||||
{1857009600 -10800 1 -03}
|
||||
{1866078000 -14400 0 -04}
|
||||
{1887249600 -10800 1 -03}
|
||||
{1888459200 -10800 1 -03}
|
||||
{1897527600 -14400 0 -04}
|
||||
{1918699200 -10800 1 -03}
|
||||
{1919908800 -10800 1 -03}
|
||||
{1928977200 -14400 0 -04}
|
||||
{1950148800 -10800 1 -03}
|
||||
{1951358400 -10800 1 -03}
|
||||
{1960426800 -14400 0 -04}
|
||||
{1981598400 -10800 1 -03}
|
||||
{1983412800 -10800 1 -03}
|
||||
{1992481200 -14400 0 -04}
|
||||
{2013048000 -10800 1 -03}
|
||||
{2014862400 -10800 1 -03}
|
||||
{2024535600 -14400 0 -04}
|
||||
{2044497600 -10800 1 -03}
|
||||
{2046312000 -10800 1 -03}
|
||||
{2055380400 -14400 0 -04}
|
||||
{2076552000 -10800 1 -03}
|
||||
{2077761600 -10800 1 -03}
|
||||
{2086830000 -14400 0 -04}
|
||||
{2108001600 -10800 1 -03}
|
||||
{2109211200 -10800 1 -03}
|
||||
{2118884400 -14400 0 -04}
|
||||
{2139451200 -10800 1 -03}
|
||||
{2140660800 -10800 1 -03}
|
||||
{2150334000 -14400 0 -04}
|
||||
{2170900800 -10800 1 -03}
|
||||
{2172715200 -10800 1 -03}
|
||||
{2181783600 -14400 0 -04}
|
||||
{2202350400 -10800 1 -03}
|
||||
{2204164800 -10800 1 -03}
|
||||
{2213233200 -14400 0 -04}
|
||||
{2234404800 -10800 1 -03}
|
||||
{2235614400 -10800 1 -03}
|
||||
{2244682800 -14400 0 -04}
|
||||
{2265854400 -10800 1 -03}
|
||||
{2267064000 -10800 1 -03}
|
||||
{2276132400 -14400 0 -04}
|
||||
{2297304000 -10800 1 -03}
|
||||
{2298513600 -10800 1 -03}
|
||||
{2307582000 -14400 0 -04}
|
||||
{2328753600 -10800 1 -03}
|
||||
{2329963200 -10800 1 -03}
|
||||
{2339636400 -14400 0 -04}
|
||||
{2360203200 -10800 1 -03}
|
||||
{2362017600 -10800 1 -03}
|
||||
{2371086000 -14400 0 -04}
|
||||
{2391652800 -10800 1 -03}
|
||||
{2393467200 -10800 1 -03}
|
||||
{2402535600 -14400 0 -04}
|
||||
{2423707200 -10800 1 -03}
|
||||
{2424916800 -10800 1 -03}
|
||||
{2433985200 -14400 0 -04}
|
||||
{2455156800 -10800 1 -03}
|
||||
{2456366400 -10800 1 -03}
|
||||
{2465434800 -14400 0 -04}
|
||||
{2486606400 -10800 1 -03}
|
||||
{2487816000 -10800 1 -03}
|
||||
{2497489200 -14400 0 -04}
|
||||
{2518056000 -10800 1 -03}
|
||||
{2519870400 -10800 1 -03}
|
||||
{2528938800 -14400 0 -04}
|
||||
{2549505600 -10800 1 -03}
|
||||
{2551320000 -10800 1 -03}
|
||||
{2560388400 -14400 0 -04}
|
||||
{2580955200 -10800 1 -03}
|
||||
{2582769600 -10800 1 -03}
|
||||
{2591838000 -14400 0 -04}
|
||||
{2613009600 -10800 1 -03}
|
||||
{2614219200 -10800 1 -03}
|
||||
{2623287600 -14400 0 -04}
|
||||
{2644459200 -10800 1 -03}
|
||||
{2645668800 -10800 1 -03}
|
||||
{2654737200 -14400 0 -04}
|
||||
{2675908800 -10800 1 -03}
|
||||
{2677118400 -10800 1 -03}
|
||||
{2686791600 -14400 0 -04}
|
||||
{2707358400 -10800 1 -03}
|
||||
{2709172800 -10800 1 -03}
|
||||
{2718241200 -14400 0 -04}
|
||||
{2738808000 -10800 1 -03}
|
||||
{2740622400 -10800 1 -03}
|
||||
{2749690800 -14400 0 -04}
|
||||
{2770862400 -10800 1 -03}
|
||||
{2772072000 -10800 1 -03}
|
||||
{2781140400 -14400 0 -04}
|
||||
{2802312000 -10800 1 -03}
|
||||
{2803521600 -10800 1 -03}
|
||||
{2812590000 -14400 0 -04}
|
||||
{2833761600 -10800 1 -03}
|
||||
{2834971200 -10800 1 -03}
|
||||
{2844039600 -14400 0 -04}
|
||||
{2865211200 -10800 1 -03}
|
||||
{2867025600 -10800 1 -03}
|
||||
{2876094000 -14400 0 -04}
|
||||
{2896660800 -10800 1 -03}
|
||||
{2898475200 -10800 1 -03}
|
||||
{2907543600 -14400 0 -04}
|
||||
{2928110400 -10800 1 -03}
|
||||
{2929924800 -10800 1 -03}
|
||||
{2938993200 -14400 0 -04}
|
||||
{2960164800 -10800 1 -03}
|
||||
{2961374400 -10800 1 -03}
|
||||
{2970442800 -14400 0 -04}
|
||||
{2991614400 -10800 1 -03}
|
||||
{2992824000 -10800 1 -03}
|
||||
{3001892400 -14400 0 -04}
|
||||
{3023064000 -10800 1 -03}
|
||||
{3024273600 -10800 1 -03}
|
||||
{3033946800 -14400 0 -04}
|
||||
{3054513600 -10800 1 -03}
|
||||
{3056328000 -10800 1 -03}
|
||||
{3065396400 -14400 0 -04}
|
||||
{3085963200 -10800 1 -03}
|
||||
{3087777600 -10800 1 -03}
|
||||
{3096846000 -14400 0 -04}
|
||||
{3118017600 -10800 1 -03}
|
||||
{3119227200 -10800 1 -03}
|
||||
{3128295600 -14400 0 -04}
|
||||
{3149467200 -10800 1 -03}
|
||||
{3150676800 -10800 1 -03}
|
||||
{3159745200 -14400 0 -04}
|
||||
{3180916800 -10800 1 -03}
|
||||
{3182126400 -10800 1 -03}
|
||||
{3191194800 -14400 0 -04}
|
||||
{3212366400 -10800 1 -03}
|
||||
{3213576000 -10800 1 -03}
|
||||
{3223249200 -14400 0 -04}
|
||||
{3243816000 -10800 1 -03}
|
||||
{3245630400 -10800 1 -03}
|
||||
{3254698800 -14400 0 -04}
|
||||
{3275265600 -10800 1 -03}
|
||||
{3277080000 -10800 1 -03}
|
||||
{3286148400 -14400 0 -04}
|
||||
{3307320000 -10800 1 -03}
|
||||
{3308529600 -10800 1 -03}
|
||||
{3317598000 -14400 0 -04}
|
||||
{3338769600 -10800 1 -03}
|
||||
{3339979200 -10800 1 -03}
|
||||
{3349047600 -14400 0 -04}
|
||||
{3370219200 -10800 1 -03}
|
||||
{3371428800 -10800 1 -03}
|
||||
{3381102000 -14400 0 -04}
|
||||
{3401668800 -10800 1 -03}
|
||||
{3403483200 -10800 1 -03}
|
||||
{3412551600 -14400 0 -04}
|
||||
{3433118400 -10800 1 -03}
|
||||
{3434932800 -10800 1 -03}
|
||||
{3444001200 -14400 0 -04}
|
||||
{3464568000 -10800 1 -03}
|
||||
{3466382400 -10800 1 -03}
|
||||
{3475450800 -14400 0 -04}
|
||||
{3496622400 -10800 1 -03}
|
||||
{3497832000 -10800 1 -03}
|
||||
{3506900400 -14400 0 -04}
|
||||
{3528072000 -10800 1 -03}
|
||||
{3529281600 -10800 1 -03}
|
||||
{3538350000 -14400 0 -04}
|
||||
{3559521600 -10800 1 -03}
|
||||
{3560731200 -10800 1 -03}
|
||||
{3570404400 -14400 0 -04}
|
||||
{3590971200 -10800 1 -03}
|
||||
{3592785600 -10800 1 -03}
|
||||
{3601854000 -14400 0 -04}
|
||||
{3622420800 -10800 1 -03}
|
||||
{3624235200 -10800 1 -03}
|
||||
{3633303600 -14400 0 -04}
|
||||
{3654475200 -10800 1 -03}
|
||||
{3655684800 -10800 1 -03}
|
||||
{3664753200 -14400 0 -04}
|
||||
{3685924800 -10800 1 -03}
|
||||
{3687134400 -10800 1 -03}
|
||||
{3696202800 -14400 0 -04}
|
||||
{3717374400 -10800 1 -03}
|
||||
{3718584000 -10800 1 -03}
|
||||
{3727652400 -14400 0 -04}
|
||||
{3748824000 -10800 1 -03}
|
||||
{3750638400 -10800 1 -03}
|
||||
{3759706800 -14400 0 -04}
|
||||
{3780273600 -10800 1 -03}
|
||||
{3782088000 -10800 1 -03}
|
||||
{3791156400 -14400 0 -04}
|
||||
{3811723200 -10800 1 -03}
|
||||
{3813537600 -10800 1 -03}
|
||||
{3822606000 -14400 0 -04}
|
||||
{3843777600 -10800 1 -03}
|
||||
{3844987200 -10800 1 -03}
|
||||
{3854055600 -14400 0 -04}
|
||||
{3875227200 -10800 1 -03}
|
||||
{3876436800 -10800 1 -03}
|
||||
{3885505200 -14400 0 -04}
|
||||
{3906676800 -10800 1 -03}
|
||||
{3907886400 -10800 1 -03}
|
||||
{3917559600 -14400 0 -04}
|
||||
{3938126400 -10800 1 -03}
|
||||
{3939940800 -10800 1 -03}
|
||||
{3949009200 -14400 0 -04}
|
||||
{3969576000 -10800 1 -03}
|
||||
{3971390400 -10800 1 -03}
|
||||
{3980458800 -14400 0 -04}
|
||||
{4001630400 -10800 1 -03}
|
||||
{4002840000 -10800 1 -03}
|
||||
{4011908400 -14400 0 -04}
|
||||
{4033080000 -10800 1 -03}
|
||||
{4034289600 -10800 1 -03}
|
||||
{4043358000 -14400 0 -04}
|
||||
{4064529600 -10800 1 -03}
|
||||
{4065739200 -10800 1 -03}
|
||||
{4074807600 -14400 0 -04}
|
||||
{4095979200 -10800 1 -03}
|
||||
{4097188800 -10800 1 -03}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
set TZData(:America/La_Paz) {
|
||||
{-9223372036854775808 -16356 0 LMT}
|
||||
{-2524505244 -16356 0 CMT}
|
||||
{-1205954844 -12756 1 BOST}
|
||||
{-1205954844 -12756 1 BST}
|
||||
{-1192307244 -14400 0 -04}
|
||||
}
|
||||
|
||||
@@ -92,167 +92,167 @@ set TZData(:America/Sao_Paulo) {
|
||||
{1487469600 -10800 0 -03}
|
||||
{1508036400 -7200 1 -02}
|
||||
{1518919200 -10800 0 -03}
|
||||
{1540090800 -7200 1 -02}
|
||||
{1541300400 -7200 1 -02}
|
||||
{1550368800 -10800 0 -03}
|
||||
{1571540400 -7200 1 -02}
|
||||
{1572750000 -7200 1 -02}
|
||||
{1581818400 -10800 0 -03}
|
||||
{1602990000 -7200 1 -02}
|
||||
{1604199600 -7200 1 -02}
|
||||
{1613872800 -10800 0 -03}
|
||||
{1634439600 -7200 1 -02}
|
||||
{1636254000 -7200 1 -02}
|
||||
{1645322400 -10800 0 -03}
|
||||
{1665889200 -7200 1 -02}
|
||||
{1667703600 -7200 1 -02}
|
||||
{1677376800 -10800 0 -03}
|
||||
{1697338800 -7200 1 -02}
|
||||
{1699153200 -7200 1 -02}
|
||||
{1708221600 -10800 0 -03}
|
||||
{1729393200 -7200 1 -02}
|
||||
{1730602800 -7200 1 -02}
|
||||
{1739671200 -10800 0 -03}
|
||||
{1760842800 -7200 1 -02}
|
||||
{1762052400 -7200 1 -02}
|
||||
{1771725600 -10800 0 -03}
|
||||
{1792292400 -7200 1 -02}
|
||||
{1793502000 -7200 1 -02}
|
||||
{1803175200 -10800 0 -03}
|
||||
{1823742000 -7200 1 -02}
|
||||
{1825556400 -7200 1 -02}
|
||||
{1834624800 -10800 0 -03}
|
||||
{1855191600 -7200 1 -02}
|
||||
{1857006000 -7200 1 -02}
|
||||
{1866074400 -10800 0 -03}
|
||||
{1887246000 -7200 1 -02}
|
||||
{1888455600 -7200 1 -02}
|
||||
{1897524000 -10800 0 -03}
|
||||
{1918695600 -7200 1 -02}
|
||||
{1919905200 -7200 1 -02}
|
||||
{1928973600 -10800 0 -03}
|
||||
{1950145200 -7200 1 -02}
|
||||
{1951354800 -7200 1 -02}
|
||||
{1960423200 -10800 0 -03}
|
||||
{1981594800 -7200 1 -02}
|
||||
{1983409200 -7200 1 -02}
|
||||
{1992477600 -10800 0 -03}
|
||||
{2013044400 -7200 1 -02}
|
||||
{2014858800 -7200 1 -02}
|
||||
{2024532000 -10800 0 -03}
|
||||
{2044494000 -7200 1 -02}
|
||||
{2046308400 -7200 1 -02}
|
||||
{2055376800 -10800 0 -03}
|
||||
{2076548400 -7200 1 -02}
|
||||
{2077758000 -7200 1 -02}
|
||||
{2086826400 -10800 0 -03}
|
||||
{2107998000 -7200 1 -02}
|
||||
{2109207600 -7200 1 -02}
|
||||
{2118880800 -10800 0 -03}
|
||||
{2139447600 -7200 1 -02}
|
||||
{2140657200 -7200 1 -02}
|
||||
{2150330400 -10800 0 -03}
|
||||
{2170897200 -7200 1 -02}
|
||||
{2172711600 -7200 1 -02}
|
||||
{2181780000 -10800 0 -03}
|
||||
{2202346800 -7200 1 -02}
|
||||
{2204161200 -7200 1 -02}
|
||||
{2213229600 -10800 0 -03}
|
||||
{2234401200 -7200 1 -02}
|
||||
{2235610800 -7200 1 -02}
|
||||
{2244679200 -10800 0 -03}
|
||||
{2265850800 -7200 1 -02}
|
||||
{2267060400 -7200 1 -02}
|
||||
{2276128800 -10800 0 -03}
|
||||
{2297300400 -7200 1 -02}
|
||||
{2298510000 -7200 1 -02}
|
||||
{2307578400 -10800 0 -03}
|
||||
{2328750000 -7200 1 -02}
|
||||
{2329959600 -7200 1 -02}
|
||||
{2339632800 -10800 0 -03}
|
||||
{2360199600 -7200 1 -02}
|
||||
{2362014000 -7200 1 -02}
|
||||
{2371082400 -10800 0 -03}
|
||||
{2391649200 -7200 1 -02}
|
||||
{2393463600 -7200 1 -02}
|
||||
{2402532000 -10800 0 -03}
|
||||
{2423703600 -7200 1 -02}
|
||||
{2424913200 -7200 1 -02}
|
||||
{2433981600 -10800 0 -03}
|
||||
{2455153200 -7200 1 -02}
|
||||
{2456362800 -7200 1 -02}
|
||||
{2465431200 -10800 0 -03}
|
||||
{2486602800 -7200 1 -02}
|
||||
{2487812400 -7200 1 -02}
|
||||
{2497485600 -10800 0 -03}
|
||||
{2518052400 -7200 1 -02}
|
||||
{2519866800 -7200 1 -02}
|
||||
{2528935200 -10800 0 -03}
|
||||
{2549502000 -7200 1 -02}
|
||||
{2551316400 -7200 1 -02}
|
||||
{2560384800 -10800 0 -03}
|
||||
{2580951600 -7200 1 -02}
|
||||
{2582766000 -7200 1 -02}
|
||||
{2591834400 -10800 0 -03}
|
||||
{2613006000 -7200 1 -02}
|
||||
{2614215600 -7200 1 -02}
|
||||
{2623284000 -10800 0 -03}
|
||||
{2644455600 -7200 1 -02}
|
||||
{2645665200 -7200 1 -02}
|
||||
{2654733600 -10800 0 -03}
|
||||
{2675905200 -7200 1 -02}
|
||||
{2677114800 -7200 1 -02}
|
||||
{2686788000 -10800 0 -03}
|
||||
{2707354800 -7200 1 -02}
|
||||
{2709169200 -7200 1 -02}
|
||||
{2718237600 -10800 0 -03}
|
||||
{2738804400 -7200 1 -02}
|
||||
{2740618800 -7200 1 -02}
|
||||
{2749687200 -10800 0 -03}
|
||||
{2770858800 -7200 1 -02}
|
||||
{2772068400 -7200 1 -02}
|
||||
{2781136800 -10800 0 -03}
|
||||
{2802308400 -7200 1 -02}
|
||||
{2803518000 -7200 1 -02}
|
||||
{2812586400 -10800 0 -03}
|
||||
{2833758000 -7200 1 -02}
|
||||
{2834967600 -7200 1 -02}
|
||||
{2844036000 -10800 0 -03}
|
||||
{2865207600 -7200 1 -02}
|
||||
{2867022000 -7200 1 -02}
|
||||
{2876090400 -10800 0 -03}
|
||||
{2896657200 -7200 1 -02}
|
||||
{2898471600 -7200 1 -02}
|
||||
{2907540000 -10800 0 -03}
|
||||
{2928106800 -7200 1 -02}
|
||||
{2929921200 -7200 1 -02}
|
||||
{2938989600 -10800 0 -03}
|
||||
{2960161200 -7200 1 -02}
|
||||
{2961370800 -7200 1 -02}
|
||||
{2970439200 -10800 0 -03}
|
||||
{2991610800 -7200 1 -02}
|
||||
{2992820400 -7200 1 -02}
|
||||
{3001888800 -10800 0 -03}
|
||||
{3023060400 -7200 1 -02}
|
||||
{3024270000 -7200 1 -02}
|
||||
{3033943200 -10800 0 -03}
|
||||
{3054510000 -7200 1 -02}
|
||||
{3056324400 -7200 1 -02}
|
||||
{3065392800 -10800 0 -03}
|
||||
{3085959600 -7200 1 -02}
|
||||
{3087774000 -7200 1 -02}
|
||||
{3096842400 -10800 0 -03}
|
||||
{3118014000 -7200 1 -02}
|
||||
{3119223600 -7200 1 -02}
|
||||
{3128292000 -10800 0 -03}
|
||||
{3149463600 -7200 1 -02}
|
||||
{3150673200 -7200 1 -02}
|
||||
{3159741600 -10800 0 -03}
|
||||
{3180913200 -7200 1 -02}
|
||||
{3182122800 -7200 1 -02}
|
||||
{3191191200 -10800 0 -03}
|
||||
{3212362800 -7200 1 -02}
|
||||
{3213572400 -7200 1 -02}
|
||||
{3223245600 -10800 0 -03}
|
||||
{3243812400 -7200 1 -02}
|
||||
{3245626800 -7200 1 -02}
|
||||
{3254695200 -10800 0 -03}
|
||||
{3275262000 -7200 1 -02}
|
||||
{3277076400 -7200 1 -02}
|
||||
{3286144800 -10800 0 -03}
|
||||
{3307316400 -7200 1 -02}
|
||||
{3308526000 -7200 1 -02}
|
||||
{3317594400 -10800 0 -03}
|
||||
{3338766000 -7200 1 -02}
|
||||
{3339975600 -7200 1 -02}
|
||||
{3349044000 -10800 0 -03}
|
||||
{3370215600 -7200 1 -02}
|
||||
{3371425200 -7200 1 -02}
|
||||
{3381098400 -10800 0 -03}
|
||||
{3401665200 -7200 1 -02}
|
||||
{3403479600 -7200 1 -02}
|
||||
{3412548000 -10800 0 -03}
|
||||
{3433114800 -7200 1 -02}
|
||||
{3434929200 -7200 1 -02}
|
||||
{3443997600 -10800 0 -03}
|
||||
{3464564400 -7200 1 -02}
|
||||
{3466378800 -7200 1 -02}
|
||||
{3475447200 -10800 0 -03}
|
||||
{3496618800 -7200 1 -02}
|
||||
{3497828400 -7200 1 -02}
|
||||
{3506896800 -10800 0 -03}
|
||||
{3528068400 -7200 1 -02}
|
||||
{3529278000 -7200 1 -02}
|
||||
{3538346400 -10800 0 -03}
|
||||
{3559518000 -7200 1 -02}
|
||||
{3560727600 -7200 1 -02}
|
||||
{3570400800 -10800 0 -03}
|
||||
{3590967600 -7200 1 -02}
|
||||
{3592782000 -7200 1 -02}
|
||||
{3601850400 -10800 0 -03}
|
||||
{3622417200 -7200 1 -02}
|
||||
{3624231600 -7200 1 -02}
|
||||
{3633300000 -10800 0 -03}
|
||||
{3654471600 -7200 1 -02}
|
||||
{3655681200 -7200 1 -02}
|
||||
{3664749600 -10800 0 -03}
|
||||
{3685921200 -7200 1 -02}
|
||||
{3687130800 -7200 1 -02}
|
||||
{3696199200 -10800 0 -03}
|
||||
{3717370800 -7200 1 -02}
|
||||
{3718580400 -7200 1 -02}
|
||||
{3727648800 -10800 0 -03}
|
||||
{3748820400 -7200 1 -02}
|
||||
{3750634800 -7200 1 -02}
|
||||
{3759703200 -10800 0 -03}
|
||||
{3780270000 -7200 1 -02}
|
||||
{3782084400 -7200 1 -02}
|
||||
{3791152800 -10800 0 -03}
|
||||
{3811719600 -7200 1 -02}
|
||||
{3813534000 -7200 1 -02}
|
||||
{3822602400 -10800 0 -03}
|
||||
{3843774000 -7200 1 -02}
|
||||
{3844983600 -7200 1 -02}
|
||||
{3854052000 -10800 0 -03}
|
||||
{3875223600 -7200 1 -02}
|
||||
{3876433200 -7200 1 -02}
|
||||
{3885501600 -10800 0 -03}
|
||||
{3906673200 -7200 1 -02}
|
||||
{3907882800 -7200 1 -02}
|
||||
{3917556000 -10800 0 -03}
|
||||
{3938122800 -7200 1 -02}
|
||||
{3939937200 -7200 1 -02}
|
||||
{3949005600 -10800 0 -03}
|
||||
{3969572400 -7200 1 -02}
|
||||
{3971386800 -7200 1 -02}
|
||||
{3980455200 -10800 0 -03}
|
||||
{4001626800 -7200 1 -02}
|
||||
{4002836400 -7200 1 -02}
|
||||
{4011904800 -10800 0 -03}
|
||||
{4033076400 -7200 1 -02}
|
||||
{4034286000 -7200 1 -02}
|
||||
{4043354400 -10800 0 -03}
|
||||
{4064526000 -7200 1 -02}
|
||||
{4065735600 -7200 1 -02}
|
||||
{4074804000 -10800 0 -03}
|
||||
{4095975600 -7200 1 -02}
|
||||
{4097185200 -7200 1 -02}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
set TZData(:Asia/Tokyo) {
|
||||
{-9223372036854775808 33539 0 LMT}
|
||||
{-2587712400 32400 0 JST}
|
||||
{-683794800 36000 1 JDT}
|
||||
{-672393600 32400 0 JST}
|
||||
{-654764400 36000 1 JDT}
|
||||
{-640944000 32400 0 JST}
|
||||
{-620290800 36000 1 JDT}
|
||||
{-609494400 32400 0 JST}
|
||||
{-588841200 36000 1 JDT}
|
||||
{-578044800 32400 0 JST}
|
||||
{-683802000 36000 1 JDT}
|
||||
{-672314400 32400 0 JST}
|
||||
{-654771600 36000 1 JDT}
|
||||
{-640864800 32400 0 JST}
|
||||
{-620298000 36000 1 JDT}
|
||||
{-609415200 32400 0 JST}
|
||||
{-588848400 36000 1 JDT}
|
||||
{-577965600 32400 0 JST}
|
||||
}
|
||||
|
||||
+11
-3
@@ -1,8 +1,14 @@
|
||||
[](https://travis-ci.org/libtom/libtommath)
|
||||
# libtommath
|
||||
|
||||
[](https://travis-ci.org/libtom/libtommath)
|
||||
This is the git repository for [LibTomMath](http://www.libtom.net/LibTomMath/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C.
|
||||
|
||||
This is the git repository for [LibTomMath](http://www.libtom.org/), a free open source portable number theoretic multiple-precision integer (MPI) library written entirely in C.
|
||||
## Build Status
|
||||
|
||||
master - [](https://travis-ci.org/libtom/libtommath)
|
||||
|
||||
develop - [](https://travis-ci.org/libtom/libtommath)
|
||||
|
||||
## Summary
|
||||
|
||||
The `develop` branch contains the in-development version. Stable releases are tagged.
|
||||
|
||||
@@ -10,6 +16,8 @@ Documentation is built from the LaTeX file `bn.tex`. There is also limited docum
|
||||
|
||||
The project can be build by using `make`. Along with the usual `make`, `make clean` and `make install`, there are several other build targets, see the makefile for details. There are also makefiles for certain specific platforms.
|
||||
|
||||
## Testing
|
||||
|
||||
Tests are located in `demo/` and can be built in two flavors.
|
||||
* `make test` creates a test binary that is intended to be run against `mtest`. `mtest` can be built with `make mtest` and test execution is done like `./mtest/mtest | ./test`. `mtest` is creating test vectors using an alternative MPI library and `test` is consuming these vectors to verify correct behavior of ltm
|
||||
* `make test_standalone` creates a stand-alone test binary that executes several test routines.
|
||||
|
||||
@@ -27,10 +27,10 @@ static const struct {
|
||||
/* return a char * string for a given code */
|
||||
const char *mp_error_to_string(int code)
|
||||
{
|
||||
int x;
|
||||
size_t x;
|
||||
|
||||
/* scan the lookup table for the given message */
|
||||
for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
|
||||
for (x = 0; x < (sizeof(msgs) / sizeof(msgs[0])); x++) {
|
||||
if (msgs[x].code == code) {
|
||||
return msgs[x].msg;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,12 @@ int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* if one of x,y is zero return an error! */
|
||||
if ((mp_iszero(&x) == MP_YES) || (mp_iszero(&y) == MP_YES)) {
|
||||
res = MP_VAL;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
|
||||
if ((res = mp_copy(&x, &u)) != MP_OKAY) {
|
||||
goto LBL_ERR;
|
||||
@@ -53,7 +59,7 @@ int fast_mp_invmod(const mp_int *a, const mp_int *b, mp_int *c)
|
||||
if ((res = mp_copy(&y, &v)) != MP_OKAY) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
mp_set(&D, 1);
|
||||
mp_set(&D, 1uL);
|
||||
|
||||
top:
|
||||
/* 4. while u is even do */
|
||||
@@ -122,7 +128,7 @@ top:
|
||||
/* now a = C, b = D, gcd == g*v */
|
||||
|
||||
/* if v != 1 then there is no inverse */
|
||||
if (mp_cmp_d(&v, 1) != MP_EQ) {
|
||||
if (mp_cmp_d(&v, 1uL) != MP_EQ) {
|
||||
res = MP_VAL;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
|
||||
int ix, res, olduse;
|
||||
mp_word W[MP_WARRAY];
|
||||
|
||||
if (x->used > (int)MP_WARRAY) {
|
||||
return MP_VAL;
|
||||
}
|
||||
|
||||
/* get old used count */
|
||||
olduse = x->used;
|
||||
|
||||
@@ -73,7 +77,7 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
|
||||
* that W[ix-1] have the carry cleared (see after the inner loop)
|
||||
*/
|
||||
mp_digit mu;
|
||||
mu = (mp_digit)(((W[ix] & MP_MASK) * rho) & MP_MASK);
|
||||
mu = ((W[ix] & MP_MASK) * rho) & MP_MASK;
|
||||
|
||||
/* a = a + mu * m * b**i
|
||||
*
|
||||
@@ -102,12 +106,12 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
|
||||
|
||||
/* inner loop */
|
||||
for (iy = 0; iy < n->used; iy++) {
|
||||
*_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
|
||||
*_W++ += (mp_word)mu * (mp_word)*tmpn++;
|
||||
}
|
||||
}
|
||||
|
||||
/* now fix carry for next digit, W[ix+1] */
|
||||
W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
|
||||
W[ix + 1] += W[ix] >> (mp_word)DIGIT_BIT;
|
||||
}
|
||||
|
||||
/* now we have to propagate the carries and
|
||||
@@ -127,7 +131,7 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
|
||||
_W = W + ++ix;
|
||||
|
||||
for (; ix <= ((n->used * 2) + 1); ix++) {
|
||||
*_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
|
||||
*_W++ += *_W1++ >> (mp_word)DIGIT_BIT;
|
||||
}
|
||||
|
||||
/* copy out, A = A/b**n
|
||||
@@ -144,7 +148,7 @@ int fast_mp_montgomery_reduce(mp_int *x, const mp_int *n, mp_digit rho)
|
||||
_W = W + n->used;
|
||||
|
||||
for (ix = 0; ix < (n->used + 1); ix++) {
|
||||
*tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
|
||||
*tmpx++ = *_W++ & (mp_word)MP_MASK;
|
||||
}
|
||||
|
||||
/* zero oldused digits, if the input a was larger than
|
||||
|
||||
@@ -69,15 +69,15 @@ int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
|
||||
|
||||
/* execute loop */
|
||||
for (iz = 0; iz < iy; ++iz) {
|
||||
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
|
||||
_W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
|
||||
|
||||
}
|
||||
|
||||
/* store term */
|
||||
W[ix] = ((mp_digit)_W) & MP_MASK;
|
||||
W[ix] = (mp_digit)_W & MP_MASK;
|
||||
|
||||
/* make next carry */
|
||||
_W = _W >> ((mp_word)DIGIT_BIT);
|
||||
_W = _W >> (mp_word)DIGIT_BIT;
|
||||
}
|
||||
|
||||
/* setup dest */
|
||||
@@ -87,7 +87,7 @@ int fast_s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
|
||||
{
|
||||
mp_digit *tmpc;
|
||||
tmpc = c->dp;
|
||||
for (ix = 0; ix < (pa + 1); ix++) {
|
||||
for (ix = 0; ix < pa; ix++) {
|
||||
/* now extract the previous digit [below the carry] */
|
||||
*tmpc++ = W[ix];
|
||||
}
|
||||
|
||||
@@ -60,14 +60,14 @@ int fast_s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int dig
|
||||
|
||||
/* execute loop */
|
||||
for (iz = 0; iz < iy; iz++) {
|
||||
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
|
||||
_W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
|
||||
}
|
||||
|
||||
/* store term */
|
||||
W[ix] = ((mp_digit)_W) & MP_MASK;
|
||||
W[ix] = (mp_digit)_W & MP_MASK;
|
||||
|
||||
/* make next carry */
|
||||
_W = _W >> ((mp_word)DIGIT_BIT);
|
||||
_W = _W >> (mp_word)DIGIT_BIT;
|
||||
}
|
||||
|
||||
/* setup dest */
|
||||
|
||||
@@ -70,22 +70,22 @@ int fast_s_mp_sqr(const mp_int *a, mp_int *b)
|
||||
|
||||
/* execute loop */
|
||||
for (iz = 0; iz < iy; iz++) {
|
||||
_W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
|
||||
_W += (mp_word)*tmpx++ * (mp_word)*tmpy--;
|
||||
}
|
||||
|
||||
/* double the inner product and add carry */
|
||||
_W = _W + _W + W1;
|
||||
|
||||
/* even columns have the square term in them */
|
||||
if ((ix&1) == 0) {
|
||||
_W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
|
||||
if (((unsigned)ix & 1u) == 0u) {
|
||||
_W += (mp_word)a->dp[ix>>1] * (mp_word)a->dp[ix>>1];
|
||||
}
|
||||
|
||||
/* store it */
|
||||
W[ix] = (mp_digit)(_W & MP_MASK);
|
||||
W[ix] = _W & MP_MASK;
|
||||
|
||||
/* make next carry */
|
||||
W1 = _W >> ((mp_word)DIGIT_BIT);
|
||||
W1 = _W >> (mp_word)DIGIT_BIT;
|
||||
}
|
||||
|
||||
/* setup dest */
|
||||
|
||||
@@ -36,7 +36,7 @@ int mp_2expt(mp_int *a, int b)
|
||||
a->used = (b / DIGIT_BIT) + 1;
|
||||
|
||||
/* put the single bit in its place */
|
||||
a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
|
||||
a->dp[b / DIGIT_BIT] = (mp_digit)1 << (mp_digit)(b % DIGIT_BIT);
|
||||
|
||||
return MP_OKAY;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ void mp_clamp(mp_int *a)
|
||||
/* decrease used while the most significant digit is
|
||||
* zero.
|
||||
*/
|
||||
while ((a->used > 0) && (a->dp[a->used - 1] == 0)) {
|
||||
while ((a->used > 0) && (a->dp[a->used - 1] == 0u)) {
|
||||
--(a->used);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user