Compare commits
1110 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
b59708e27a | |
|
|
c0c5e1b5bf | |
|
|
3de9ed9cbf | |
|
|
846c8e0f65 | |
|
|
8bd01f5597 | |
|
|
1cb58e973a | |
|
|
516c9d7635 | |
|
|
d24d52e403 | |
|
|
a93d248a5a | |
|
|
4ccd5a78d1 | |
|
|
f998f8ee6f | |
|
|
662e21a2d1 | |
|
|
949ec7672c | |
|
|
bd417aa54b | |
|
|
73e08e0c88 | |
|
|
893a36cae7 | |
|
|
3b4d66e7d7 | |
|
|
5e8a3f038a | |
|
|
9850c5586e | |
|
|
27df5f9c5f | |
|
|
e9202c1d29 | |
|
|
ea1a89b19c | |
|
|
9489b23985 | |
|
|
c74215ad55 | |
|
|
4201f56048 | |
|
|
26372f5d50 | |
|
|
ef419258ab | |
|
|
97134848ab | |
|
|
00c692b140 | |
|
|
203ece1a16 | |
|
|
22a230edc9 | |
|
|
7f1217596e | |
|
|
ff718c3ecf | |
|
|
98aa2f760a | |
|
|
441d933148 | |
|
|
9d3fb61cf3 | |
|
|
a1fb779314 | |
|
|
abd3975997 | |
|
|
227f264838 | |
|
|
c87e5baff4 | |
|
|
957d7edd64 | |
|
|
969137d1e2 | |
|
|
f3adea8c65 | |
|
|
246c0ea7a4 | |
|
|
47778971ee | |
|
|
cccd79ab0d | |
|
|
51b9846120 | |
|
|
1afd48e840 | |
|
|
99a5a28a3e | |
|
|
0ac4d3a465 | |
|
|
42aa06f8f5 | |
|
|
4d2912a406 | |
|
|
b668b02a1f | |
|
|
6b8f5d1d67 | |
|
|
c977e4cf76 | |
|
|
9327e319da | |
|
|
0e84616af8 | |
|
|
c42db8e71b | |
|
|
27c423c2ed | |
|
|
53e7dfe04c | |
|
|
9ca81f8ea6 | |
|
|
d822353e85 | |
|
|
4951f013d5 | |
|
|
d3a0228958 | |
|
|
656d27b17a | |
|
|
3631892cfa | |
|
|
8c323803b7 | |
|
|
acdfb256a1 | |
|
|
5e74ecf9fa | |
|
|
d6d8620a7c | |
|
|
a2390167e6 | |
|
|
3cfc24f4b9 | |
|
|
7e12bec49d | |
|
|
5f1f92f30d | |
|
|
15faa19346 | |
|
|
af7b6bf119 | |
|
|
8b0616eaf5 | |
|
|
2b62123459 | |
|
|
2259ef626d | |
|
|
3c9987f460 | |
|
|
f4212d8e0e | |
|
|
a16c667290 | |
|
|
6e2babd141 | |
|
|
b80279c6db | |
|
|
722209b1ae | |
|
|
692c0f2339 | |
|
|
dbdec3aa17 | |
|
|
f7d2debb98 | |
|
|
0f047b89ce | |
|
|
3b57ae1179 | |
|
|
dc45242d46 | |
|
|
6d8c3eee1a | |
|
|
c8fe30398b | |
|
|
5093182f4a | |
|
|
4864a80179 | |
|
|
70054ccde2 | |
|
|
c007d8077c | |
|
|
da216195b3 | |
|
|
5fe586100b | |
|
|
c7ef7d743a | |
|
|
df7b9079bd | |
|
|
cfd1d567bd | |
|
|
b1424bfaf3 | |
|
|
aef23fd5f3 | |
|
|
1dfe1ed645 | |
|
|
9c5cf1a567 | |
|
|
55931e8811 | |
|
|
bb131f14d0 | |
|
|
78f7d22796 | |
|
|
b1c7b52ed2 | |
|
|
5de118b762 | |
|
|
00e3bbd12a | |
|
|
0022c502c8 | |
|
|
741216d6f3 | |
|
|
6195c20d3d | |
|
|
59a1953f3c | |
|
|
b1095b323c | |
|
|
e9f2628f41 | |
|
|
e04307c085 | |
|
|
d2acdac901 | |
|
|
8d762b4f59 | |
|
|
0301bdec9e | |
|
|
4084a6a246 | |
|
|
117ca41b8a | |
|
|
0fb19e568c | |
|
|
5791ae3701 | |
|
|
b4912fd550 | |
|
|
56598ca0f4 | |
|
|
c6fe62f64a | |
|
|
ad5383c307 | |
|
|
ab24761d88 | |
|
|
66f281c5e1 | |
|
|
5bdff336e9 | |
|
|
d4e4930de3 | |
|
|
e6f04ebb46 | |
|
|
8c61014677 | |
|
|
7a122c8619 | |
|
|
420a24ef33 | |
|
|
0141a99af5 | |
|
|
0bb29ae5f8 | |
|
|
d59a87bafa | |
|
|
6bbcd65c5f | |
|
|
e1be3fe7d2 | |
|
|
6876c007f5 | |
|
|
301a5329db | |
|
|
6df8257505 | |
|
|
e3bd60eba6 | |
|
|
d78d7eddfd | |
|
|
aa0b033053 | |
|
|
22b96d5112 | |
|
|
a00a5eb1b2 | |
|
|
fddb458339 | |
|
|
05876c63d2 | |
|
|
f031d16f50 | |
|
|
66d6931120 | |
|
|
a31018f721 | |
|
|
ddc0adcb41 | |
|
|
22ffeee2a4 | |
|
|
d7fa508067 | |
|
|
05c242a28f | |
|
|
b8170ea851 | |
|
|
a9a9efca57 | |
|
|
2e4a9fd2d2 | |
|
|
48dccc68c6 | |
|
|
b577619395 | |
|
|
7ab4911514 | |
|
|
3472474617 | |
|
|
a3d02d92cc | |
|
|
1653b982af | |
|
|
0dac3fd19c | |
|
|
63ad80b8bc | |
|
|
2630ebcde1 | |
|
|
4e08d178dc | |
|
|
3e5502b936 | |
|
|
8ed7394431 | |
|
|
1ec8b6ee1a | |
|
|
f52d90346e | |
|
|
b16bcb35bf | |
|
|
a77c4906f8 | |
|
|
8eb2ec9ead | |
|
|
a81184e205 | |
|
|
bcd17d4f85 | |
|
|
f513a0ca3b | |
|
|
4aee95e092 | |
|
|
92b4d6a1f7 | |
|
|
730d327702 | |
|
|
be6483bf4b | |
|
|
8485820526 | |
|
|
54bbedfdbb | |
|
|
b1e2913435 | |
|
|
f179d1240e | |
|
|
6f304318ec | |
|
|
6b0bc5bbdc | |
|
|
778201fbc2 | |
|
|
c3054f265b | |
|
|
a8f5291bd7 | |
|
|
aaa477e44a | |
|
|
f45aeb6cee | |
|
|
9f0f5f5b4e | |
|
|
ec7d0fc79a | |
|
|
d2449dc971 | |
|
|
e51189911b | |
|
|
3ca0b616c0 | |
|
|
412d0570e2 | |
|
|
9f1398dfcb | |
|
|
c5ebd7d3c0 | |
|
|
2db18509c5 | |
|
|
d55a2b74ac | |
|
|
5e17855f31 | |
|
|
3294524111 | |
|
|
de1b76cb11 | |
|
|
b6e70f9632 | |
|
|
f88c7a86cb | |
|
|
4a1da7fe7c | |
|
|
4d2def46f4 | |
|
|
49caa3267b | |
|
|
dd49ca21d2 | |
|
|
2a78de8cb9 | |
|
|
4e7396162d | |
|
|
d13fa6872e | |
|
|
bd541d3e6f | |
|
|
d1ff3671cd | |
|
|
3aebbbd038 | |
|
|
8b7e0aaec6 | |
|
|
2947e7ea3d | |
|
|
f0ade2fc55 | |
|
|
394a01e0d4 | |
|
|
a18acc4772 | |
|
|
acefe4811f | |
|
|
80c043db79 | |
|
|
ebf2db91b1 | |
|
|
4b094e4632 | |
|
|
73a6ac1650 | |
|
|
271aef82bd | |
|
|
0dccf5826d | |
|
|
f15e7675cd | |
|
|
62149adc16 | |
|
|
df1a27fc01 | |
|
|
dd5fa02556 | |
|
|
b042383664 | |
|
|
1cc4d83425 | |
|
|
68e1c76f88 | |
|
|
4b9d3f3003 | |
|
|
5b81fbe7fe | |
|
|
e701b6d594 | |
|
|
62a99f6167 | |
|
|
9fe7bf4ab7 | |
|
|
43bc006338 | |
|
|
669604ace3 | |
|
|
f76826eff8 | |
|
|
189c9f2452 | |
|
|
659ec36d2d | |
|
|
df6bc6bc51 | |
|
|
828cec7bca | |
|
|
f77c4cbaa1 | |
|
|
2d889b3e9d | |
|
|
1cab3852f1 | |
|
|
e258b21251 | |
|
|
d5341659fb | |
|
|
7028fbe546 | |
|
|
0badf814c5 | |
|
|
49115d7d06 | |
|
|
7c3df3ce22 | |
|
|
6a0dc54af8 | |
|
|
82a57f8714 | |
|
|
dc2de91668 | |
|
|
260e08f160 | |
|
|
20d72e9eb2 | |
|
|
a7dd64b242 | |
|
|
1f9ce81154 | |
|
|
975411f40b | |
|
|
4b855fef13 | |
|
|
2f2fd85af0 | |
|
|
bb6e55efb1 | |
|
|
22e8ab847c | |
|
|
cef9e0bede | |
|
|
27a91ee5a3 | |
|
|
b6ec131355 | |
|
|
105f8a728d | |
|
|
0b29b1cc12 | |
|
|
2173d03b14 | |
|
|
d7935930ad | |
|
|
3fd0798312 | |
|
|
5d8cfdc760 | |
|
|
046401cbd8 | |
|
|
957904a389 | |
|
|
c695980145 | |
|
|
df0623a435 | |
|
|
4023ed9da0 | |
|
|
fd50bc1f4d | |
|
|
489f4fe057 | |
|
|
f8ef715608 | |
|
|
db8e790aea | |
|
|
a6fd0ed320 | |
|
|
15e5b36f52 | |
|
|
1eb2231bbf | |
|
|
52d3feac73 | |
|
|
d4f487266f | |
|
|
c534eb318d | |
|
|
cc57510019 | |
|
|
bcc9852cba | |
|
|
bfefc7196e | |
|
|
22c074537d | |
|
|
534a56376a | |
|
|
142b7e5a78 | |
|
|
7029971c33 | |
|
|
bfbdf45b88 | |
|
|
35d455fd72 | |
|
|
9e181f0d2e | |
|
|
a53f71d5c6 | |
|
|
b7dd2f0e9c | |
|
|
c5e0165e5e | |
|
|
b9296074b2 | |
|
|
96b89a53b7 | |
|
|
6c952f98eb | |
|
|
ea5f1ed3f1 | |
|
|
66e72c748a | |
|
|
eb81da6c56 | |
|
|
ab73c716a4 | |
|
|
f947543fe3 | |
|
|
9551167e10 | |
|
|
5e32174dbb | |
|
|
490fc6f9d7 | |
|
|
5ecc55b37d | |
|
|
f1f4b82a30 | |
|
|
02669de267 | |
|
|
31400dd45f | |
|
|
e592122199 | |
|
|
44bb9327a2 | |
|
|
2c9e3a558d | |
|
|
739f0f27fe | |
|
|
56bdf9ce28 | |
|
|
dceb5cfad7 | |
|
|
ef123be806 | |
|
|
fa1f1583df | |
|
|
cface55c5b | |
|
|
67f7db9540 | |
|
|
b5ac7e4f92 | |
|
|
559eb94f3e | |
|
|
ef79d33dd4 | |
|
|
6ec826fb8b | |
|
|
1fbba4408f | |
|
|
b3384f9104 | |
|
|
be09d8d402 | |
|
|
120cea3921 | |
|
|
10f82355f5 | |
|
|
3c3ebcfd2b | |
|
|
6d2d4353d3 | |
|
|
8d6571066d | |
|
|
bcd81c74b2 | |
|
|
f5f59846da | |
|
|
c676c6b1d3 | |
|
|
61e4e155ec | |
|
|
e7c46102d6 | |
|
|
b3617f603d | |
|
|
321b2d61c7 | |
|
|
5c8510355f | |
|
|
5b03081d03 | |
|
|
16efabe9ee | |
|
|
00b479301f | |
|
|
51ec834f6c | |
|
|
1c3a059031 | |
|
|
e1238633ac | |
|
|
b9dd4bfb7c | |
|
|
52fced3544 | |
|
|
69df88520c | |
|
|
650d800b12 | |
|
|
686adc13b3 | |
|
|
0f19a20c8c | |
|
|
34dfd3686b | |
|
|
cc6e7ebe84 | |
|
|
d082c67b03 | |
|
|
e8ad7c9ac8 | |
|
|
1a84eab4ce | |
|
|
f942ae6e78 | |
|
|
606f37cc80 | |
|
|
6e83cbe2d3 | |
|
|
6b9efefc02 | |
|
|
dde7144966 | |
|
|
705b4da105 | |
|
|
9aef87c355 | |
|
|
aa35a612b0 | |
|
|
6ed8f17136 | |
|
|
c8ca1d242e | |
|
|
1166a56cff | |
|
|
934fe32436 | |
|
|
c92ded99df | |
|
|
7e1692800b | |
|
|
906e02c898 | |
|
|
8cce1bdb7e | |
|
|
6c6e48a9a3 | |
|
|
f63dc318a7 | |
|
|
12c6ccc97b | |
|
|
dd84be9172 | |
|
|
78f2c0696c | |
|
|
154c3efa5c | |
|
|
922abe6b8d | |
|
|
81d526562c | |
|
|
4f54bcf4f4 | |
|
|
5058152c8f | |
|
|
92c4fc35db | |
|
|
48708c52a4 | |
|
|
983f4cb76f | |
|
|
ac37927186 | |
|
|
451dab4b9b | |
|
|
ed87c3a98b | |
|
|
56bf27548d | |
|
|
9d0cd63a4e | |
|
|
ad6ecb5bbb | |
|
|
695692b620 | |
|
|
05a5b169bc | |
|
|
4930e0307a | |
|
|
19e03fc4f8 | |
|
|
a1f7e4ed5e | |
|
|
f7c550e82f | |
|
|
25ec9fccef | |
|
|
acf0e474e8 | |
|
|
a764fdbbd1 | |
|
|
e565b4c360 | |
|
|
37fa75dd77 | |
|
|
c33b6be2bb | |
|
|
b5d068b0ea | |
|
|
cb9333804a | |
|
|
822a95ab35 | |
|
|
7508a9e6b7 | |
|
|
99c448407c | |
|
|
6a537c4659 | |
|
|
ca9229b35a | |
|
|
ad1d9923f9 | |
|
|
38b25c5d34 | |
|
|
d18b40d401 | |
|
|
8ebad7d1a9 | |
|
|
a60259ab63 | |
|
|
e88dcba1c5 | |
|
|
7960020f7c | |
|
|
554327f1d3 | |
|
|
97ff043c1a | |
|
|
93054eb4e6 | |
|
|
8ee328811c | |
|
|
86bb97948f | |
|
|
cfd71f1b5d | |
|
|
d149c83a8a | |
|
|
cf0f9311ab | |
|
|
2ff6d6113d | |
|
|
bc5a4a0fb1 | |
|
|
6db34b6aa9 | |
|
|
97189f6219 | |
|
|
90c03738ce | |
|
|
e8d7888300 | |
|
|
144c22f579 | |
|
|
c4a2a54cb7 | |
|
|
09ff52cdc0 | |
|
|
41d77558b7 | |
|
|
df84a36659 | |
|
|
38b3d53b5f | |
|
|
cd80d38d52 | |
|
|
619191c6dd | |
|
|
a5653c8fca | |
|
|
21b810b375 | |
|
|
72368a3d13 | |
|
|
4445663cb1 | |
|
|
1cec414618 | |
|
|
82a1dc98b4 | |
|
|
cb2a79d6b1 | |
|
|
2afa222414 | |
|
|
f010d4d20b | |
|
|
4887f71ca3 | |
|
|
b1a9e10be7 | |
|
|
faadb774b4 | |
|
|
b694827bcb | |
|
|
cfdd50aa63 | |
|
|
3fc1c7e452 | |
|
|
065f31f689 | |
|
|
6afadf9809 | |
|
|
48c99a7b1d | |
|
|
c21e182b2c | |
|
|
aa5ddbaa58 | |
|
|
7e9d4cc15e | |
|
|
60c64db33a | |
|
|
ff9487de1f | |
|
|
d9cfd64d60 | |
|
|
07f9bbe1fb | |
|
|
3df2aaaa16 | |
|
|
32138ccbc7 | |
|
|
e334fb919f | |
|
|
af5b7f10cf | |
|
|
a6aac9c309 | |
|
|
efcf36f348 | |
|
|
1241e95dab | |
|
|
195dda1e06 | |
|
|
eb89ab181c | |
|
|
0376430702 | |
|
|
5c410e9dcb | |
|
|
6b4d409d74 | |
|
|
34038ee687 | |
|
|
ac56dd71a9 | |
|
|
4e768d5a3d | |
|
|
b6775f902b | |
|
|
a616dbc113 | |
|
|
4cd1235575 | |
|
|
378755e083 | |
|
|
46eb71491c | |
|
|
3f85689985 | |
|
|
76a515ca25 | |
|
|
c2a5a84a03 | |
|
|
7e5d0b0688 | |
|
|
3931c4aff1 | |
|
|
272dda3c84 | |
|
|
c339e9b845 | |
|
|
4a32a82841 | |
|
|
661b66a143 | |
|
|
77a7afc8e2 | |
|
|
0ce8265570 | |
|
|
79f2ab0f4b | |
|
|
17fe81107a | |
|
|
db7a1fe20a | |
|
|
e81ead5ad2 | |
|
|
33b9c63c41 | |
|
|
e27b8a9d19 | |
|
|
2066077c4e | |
|
|
d999e20b73 | |
|
|
60463e31be | |
|
|
93c16c8431 | |
|
|
a756fe08bd | |
|
|
6520aa19a3 | |
|
|
2bac418b44 | |
|
|
8c28342322 | |
|
|
6d0dca2551 | |
|
|
fd5511d622 | |
|
|
c4373d74aa | |
|
|
ff73a1328f | |
|
|
0259fdc990 | |
|
|
5770da2abd | |
|
|
1aee10ef4d | |
|
|
2fcd024bdb | |
|
|
91bb9935f9 | |
|
|
c8974ed2ec | |
|
|
31d7130833 | |
|
|
fc02f57d73 | |
|
|
bf96348502 | |
|
|
94ec5cf98f | |
|
|
f80540af46 | |
|
|
df19d62f51 | |
|
|
8371d797ad | |
|
|
55d15ffaa5 | |
|
|
a11352970f | |
|
|
bbc52ecd41 | |
|
|
fadd2d98b4 | |
|
|
fd5050b2b5 | |
|
|
f22ecda44a | |
|
|
2b69b07860 | |
|
|
f51ad56aea | |
|
|
5b97638ac7 | |
|
|
14a8409e40 | |
|
|
bd51438c15 | |
|
|
265ace5c9f | |
|
|
6bccbef0d4 | |
|
|
c77d3852d5 | |
|
|
fd7eab2193 | |
|
|
d077368436 | |
|
|
875d825afb | |
|
|
bfb411d19f | |
|
|
feef9730f3 | |
|
|
6a6f85862e | |
|
|
fca164715e | |
|
|
e22e5d63b9 | |
|
|
e7bfa72298 | |
|
|
2ba1d20ab4 | |
|
|
b8dae95515 | |
|
|
6851f27284 | |
|
|
3dbcb0759e | |
|
|
c2d533af3b | |
|
|
586e9f1e36 | |
|
|
882d82a8ae | |
|
|
a3dce62887 | |
|
|
14b6453707 | |
|
|
fb8f7b94aa | |
|
|
f5b41a06d6 | |
|
|
aa43cc164e | |
|
|
a224c7e21a | |
|
|
fd6c30a380 | |
|
|
efb5d9001c | |
|
|
91da638579 | |
|
|
77f04b4e80 | |
|
|
c7f99e076e | |
|
|
bd03a550d3 | |
|
|
f08793ddd7 | |
|
|
2123f7090d | |
|
|
7ebaba6b39 | |
|
|
3a41bf6ae2 | |
|
|
56139b48eb | |
|
|
afd1b0b2df | |
|
|
b3d4ab7980 | |
|
|
8a4464f443 | |
|
|
06b5870035 | |
|
|
866699f353 | |
|
|
7a7d1ab25b | |
|
|
2a4c66e222 | |
|
|
0e715ce98e | |
|
|
b716aaa59d | |
|
|
83f7a71ff3 | |
|
|
102f7ad3f2 | |
|
|
2f7f76bf9c | |
|
|
ff412b74d8 | |
|
|
f92d9d469f | |
|
|
4e83c7fcdd | |
|
|
bf45f9ea31 | |
|
|
89ed5d735c | |
|
|
ca2d6d40dd | |
|
|
b8c3060f3b | |
|
|
a1ae272dc5 | |
|
|
114ddf1b0c | |
|
|
3a35d4d28d | |
|
|
89fa935416 | |
|
|
ef7f989da6 | |
|
|
ee9d4df081 | |
|
|
86b5d591d6 | |
|
|
56317e6583 | |
|
|
55413d6b3a | |
|
|
da80d5c75d | |
|
|
26d6af464a | |
|
|
60f308826d | |
|
|
bbe447423b | |
|
|
1e916ee361 | |
|
|
6eff1c2132 | |
|
|
6a513d01a1 | |
|
|
db85521449 | |
|
|
fcb8bf57c6 | |
|
|
97913ab08c | |
|
|
dd6bb9baf4 | |
|
|
a3a40bee73 | |
|
|
ecba1b38d2 | |
|
|
fa07bd0067 | |
|
|
be2f8f9a19 | |
|
|
f1acfee34a | |
|
|
90b61caff0 | |
|
|
e54111cf6f | |
|
|
3f1344570c | |
|
|
dc79b14739 | |
|
|
bfc82e43db | |
|
|
48f8707753 | |
|
|
772bfe2f71 | |
|
|
d79533a255 | |
|
|
d92e2b70b6 | |
|
|
5f55ab825a | |
|
|
979c810c38 | |
|
|
603ce8b887 | |
|
|
a9ea08a597 | |
|
|
f3ace65a78 | |
|
|
7696f673df | |
|
|
cd63fa3c14 | |
|
|
3f4eb4120e | |
|
|
f0b6231017 | |
|
|
1fdd8bc185 | |
|
|
40b317979d | |
|
|
5ee3b180d3 | |
|
|
48abe30ea4 | |
|
|
89b6f4f92b | |
|
|
5ebbed4c12 | |
|
|
37dfe07edf | |
|
|
dc87a8c693 | |
|
|
e0c95d6d78 | |
|
|
0a67151292 | |
|
|
9184ccd395 | |
|
|
8b34aa78a9 | |
|
|
ea29aa3306 | |
|
|
1fdca3a57a | |
|
|
22c22228b3 | |
|
|
a35993a81b | |
|
|
b7942cffe6 | |
|
|
0864f8b728 | |
|
|
d0eb5349a5 | |
|
|
95d3e9f85d | |
|
|
d5ef80acda | |
|
|
38c14a0ad9 | |
|
|
7fd116c828 | |
|
|
35604400ed | |
|
|
1bb6a7f6c5 | |
|
|
60e78f4ab4 | |
|
|
fca0c2945d | |
|
|
fece689c43 | |
|
|
2b06c8cee5 | |
|
|
2f22ec6293 | |
|
|
ea41b21f67 | |
|
|
817efbbccc | |
|
|
fa3a01c486 | |
|
|
3919cc5b63 | |
|
|
4206ed2436 | |
|
|
4520112a55 | |
|
|
7feb298f7a | |
|
|
4380310e5b | |
|
|
cbf97f77ee | |
|
|
489de7fdb4 | |
|
|
fc49b40c52 | |
|
|
9ca8697659 | |
|
|
8f2acb83f9 | |
|
|
165f1b35b4 | |
|
|
ade50dfc88 | |
|
|
4460c5f1f5 | |
|
|
ef48e40f39 | |
|
|
f734e27587 | |
|
|
b723dc15d8 | |
|
|
59bfe8f6c0 | |
|
|
c1aeaa9be5 | |
|
|
04bc9032b9 | |
|
|
be09edb8d8 | |
|
|
239366d4b6 | |
|
|
4bfed56924 | |
|
|
a6e1596ba6 | |
|
|
76d8c8c911 | |
|
|
64772655dc | |
|
|
e3bfe8c59e | |
|
|
6cdb9ad167 | |
|
|
518b5f45d8 | |
|
|
d94cd72538 | |
|
|
9225fa6cf1 | |
|
|
7dfdf5aa63 | |
|
|
b654647fdc | |
|
|
bd75ddf32c | |
|
|
88d36bfd1e | |
|
|
e8f9b0af5e | |
|
|
0cde303563 | |
|
|
967b41343b | |
|
|
3300f45a22 | |
|
|
da2c7b719e | |
|
|
3477480ab0 | |
|
|
c749d01eb7 | |
|
|
cebb1a5277 | |
|
|
4ea0f6a9b7 | |
|
|
015f03307a | |
|
|
65a0dc45dc | |
|
|
63256f1a44 | |
|
|
1c326c9141 | |
|
|
6a08b31149 | |
|
|
9f88450243 | |
|
|
29bd23d40b | |
|
|
bf916d2647 | |
|
|
b81e04eed4 | |
|
|
41913fbd78 | |
|
|
66734bbaee | |
|
|
b3cb528e46 | |
|
|
1ae4518846 | |
|
|
32a7323287 | |
|
|
932deeaf2d | |
|
|
54f49829f2 | |
|
|
e5c3e703c3 | |
|
|
c90bde4961 | |
|
|
23930909b1 | |
|
|
8994a68e61 | |
|
|
0a4e2a5a27 | |
|
|
de5c54e20b | |
|
|
a3b61abe2b | |
|
|
6162a9f459 | |
|
|
80f051f79d | |
|
|
7589bdba10 | |
|
|
08affbe032 | |
|
|
a467154fec | |
|
|
e2c3eb3e20 | |
|
|
3e0ad4ff58 | |
|
|
dba6f99d93 | |
|
|
e119188f23 | |
|
|
3638d382d6 | |
|
|
18a4dddc2b | |
|
|
1ca23ca0a2 | |
|
|
8e0f34c6f1 | |
|
|
60fe6427da | |
|
|
01f9f2246b | |
|
|
cb31675174 | |
|
|
bfd818fbd3 | |
|
|
ab747a0f8c | |
|
|
8b2efd5d7d | |
|
|
0cea17e801 | |
|
|
a0aea2aa2e | |
|
|
29ee094074 | |
|
|
be258c6557 | |
|
|
ae0cdd9fea | |
|
|
10442b6534 | |
|
|
5e00e3fe1b | |
|
|
a9b707460b | |
|
|
543bd5a5b8 | |
|
|
973c9a4d1a | |
|
|
48853b98a3 | |
|
|
290887912f | |
|
|
62ebf49758 | |
|
|
7509802b3d | |
|
|
2c8c60510b | |
|
|
14a1b21fb6 | |
|
|
4dc708aea2 | |
|
|
98b5f57ea0 | |
|
|
3becc0e03f | |
|
|
a6db54c0b7 | |
|
|
7e04089872 | |
|
|
cde5418e7d | |
|
|
9327388ae0 | |
|
|
147ca7a61f | |
|
|
fe39d889f0 | |
|
|
86a6551f9b | |
|
|
82bec60ccf | |
|
|
691c27081f | |
|
|
1fb82e7225 | |
|
|
d8b886aa1d | |
|
|
846f2b4cb1 | |
|
|
40f96faff8 | |
|
|
5ffc74d915 | |
|
|
1a351efd56 | |
|
|
00086817a4 | |
|
|
d6cc790d48 | |
|
|
6cae64edc5 | |
|
|
5a8cdb68d0 | |
|
|
f809b2dfac | |
|
|
9096946a12 | |
|
|
3848ec7b4e | |
|
|
2703f55449 | |
|
|
4ddd0624cb | |
|
|
fc20977fa5 | |
|
|
aa703a67b7 | |
|
|
d1dc038cb7 | |
|
|
499ac84ac0 | |
|
|
f976005d2d | |
|
|
3c90bbbe1f | |
|
|
f69b02b092 | |
|
|
fdc81f5eec | |
|
|
cf90d50999 | |
|
|
77c1082886 | |
|
|
21924ec151 | |
|
|
66297bd7d0 | |
|
|
4359aa8d4b | |
|
|
4f5eb7da2d | |
|
|
0619cf4291 | |
|
|
c16c770d7a | |
|
|
91ec4e4cb8 | |
|
|
9f39380b6a | |
|
|
6946ea6845 | |
|
|
384e59ea98 | |
|
|
318993cb7b | |
|
|
82aa62e65d | |
|
|
e896377ead | |
|
|
4d81a77bf3 | |
|
|
c8e00ef494 | |
|
|
d2ae7f78e8 | |
|
|
1360f962a1 | |
|
|
7feec63580 | |
|
|
ce1e027c55 | |
|
|
d297b99953 | |
|
|
fff3be2f29 | |
|
|
3db35216b9 | |
|
|
49f4daa715 | |
|
|
f47a173a49 | |
|
|
88a1a9b166 | |
|
|
9f052c0e4d | |
|
|
8f60ed472b | |
|
|
a307e9d052 | |
|
|
9295240047 | |
|
|
573e59da44 | |
|
|
a5f7cbd597 | |
|
|
c89455782b | |
|
|
886a0212e8 | |
|
|
2a00ab7eb8 | |
|
|
e66e3b32ad | |
|
|
96c7e283c0 | |
|
|
4ca98dc31b | |
|
|
39e76f3f31 | |
|
|
64d94ae588 | |
|
|
4374a1918e | |
|
|
51b8161a21 | |
|
|
fed93c200d | |
|
|
881115a856 | |
|
|
f3b08ad470 | |
|
|
427547c927 | |
|
|
974621ebe7 | |
|
|
0c36365db8 | |
|
|
f3bfde60f0 | |
|
|
155f19a6d8 | |
|
|
b441d668bd | |
|
|
81b5ac2079 | |
|
|
e9db9ecbc9 | |
|
|
cf5fd867f4 | |
|
|
291ba96285 | |
|
|
e4c28ef3bf | |
|
|
f0c3ec33d6 | |
|
|
9dec47c9b2 | |
|
|
fd2b1eb9ee | |
|
|
ca99d0b76a | |
|
|
efccdbf341 | |
|
|
3dc5018af4 | |
|
|
fe9ca3a4ce | |
|
|
0ae54b500a | |
|
|
41e65b5214 | |
|
|
3a1f4dc816 | |
|
|
82d64aa4b1 | |
|
|
60049f3702 | |
|
|
38d890c407 | |
|
|
71f4dd2f9f | |
|
|
8b3524575f | |
|
|
4e5af57f3c | |
|
|
9800d98dee | |
|
|
d0f6dab896 | |
|
|
bfd938b5e2 | |
|
|
fede9d5c4d | |
|
|
54773957c9 | |
|
|
cb73ebfab0 | |
|
|
eeeaf49ec7 | |
|
|
191bff6c47 | |
|
|
3691b53dde | |
|
|
814fb6f18d | |
|
|
038f02d2b2 | |
|
|
8a93d6136b | |
|
|
b08c785c1d | |
|
|
7f5571768f | |
|
|
5f6ba3be69 | |
|
|
63109229f4 | |
|
|
6b8239e258 | |
|
|
a816da60f9 | |
|
|
006c07082b | |
|
|
8f9c328150 | |
|
|
68e537b968 | |
|
|
0cd4a10036 | |
|
|
affd68aad9 | |
|
|
943e0d4d8d | |
|
|
9e6d1d789e | |
|
|
83ed73ac52 | |
|
|
84af801608 | |
|
|
21336607e0 | |
|
|
5352a23577 | |
|
|
d09b0e8c51 | |
|
|
11080465ad | |
|
|
7db77d47f1 | |
|
|
1131085d0f | |
|
|
67d68717ca | |
|
|
8445f3eb5d | |
|
|
0894248e0a | |
|
|
40e6a28ff6 | |
|
|
df6333bb7b | |
|
|
22ea7a924f | |
|
|
7a9445ec30 | |
|
|
610c86a234 | |
|
|
98f3b39dc2 | |
|
|
fdcc178bcd | |
|
|
5b29870fce | |
|
|
8798a3256c | |
|
|
eda5f506f3 | |
|
|
9e7c104d29 | |
|
|
ce6f7840db | |
|
|
2aa7380cb6 | |
|
|
dacbfc4e1f | |
|
|
b156e79b2c | |
|
|
088bb828ac | |
|
|
656b5dbabe | |
|
|
7aa846443a | |
|
|
b244d45688 | |
|
|
f1e60fe8b1 | |
|
|
68d6632836 | |
|
|
7e5dbd17cd | |
|
|
4557dd1639 | |
|
|
a54a20ee58 | |
|
|
cb25afc5ff | |
|
|
50b1e01cfc | |
|
|
93eeb1b703 | |
|
|
dfe3a4defd | |
|
|
68a088943f | |
|
|
a8cc403e4b | |
|
|
d624b76712 | |
|
|
86630fcc02 | |
|
|
8e25303db4 | |
|
|
02e16b8bce | |
|
|
cb00ede59d | |
|
|
f4d7646c1e | |
|
|
71e6bc5dd5 | |
|
|
13a7cc32e2 | |
|
|
22fbb28656 | |
|
|
952b20d2a2 | |
|
|
96ea4aa2fb | |
|
|
2aab645308 | |
|
|
6b5bd149fc | |
|
|
89f1c4ee67 | |
|
|
d4f8fe04c5 | |
|
|
0afe4d87d4 | |
|
|
90a3cf2d72 | |
|
|
36fa9aabd1 | |
|
|
8b3bb1ae77 | |
|
|
7794b1b3cb | |
|
|
1bdf173391 | |
|
|
e249e7a0e3 | |
|
|
eb9dcbcd01 | |
|
|
f5793bbefb | |
|
|
a11d2cbaa1 | |
|
|
96eb275622 | |
|
|
c3ec56725b | |
|
|
7a4a867d6e | |
|
|
3890181ebe | |
|
|
d3b314d877 | |
|
|
081058a41b | |
|
|
b899a500d5 | |
|
|
cc4eef4eb1 | |
|
|
c8a2d06e08 | |
|
|
ca469510d5 | |
|
|
3ae24e8a8c | |
|
|
60a378842f | |
|
|
ca985edbd0 | |
|
|
07267dc126 | |
|
|
482d7534a2 | |
|
|
9b131fa96c | |
|
|
31b3c0d8b4 | |
|
|
5300f322de | |
|
|
6caab5da37 | |
|
|
666c3c2c97 | |
|
|
c514f5ce0b | |
|
|
44b269e037 | |
|
|
79dc621626 | |
|
|
c4124b033f | |
|
|
e66b2e1338 | |
|
|
a33d7b78b5 | |
|
|
bf7f1ab39e | |
|
|
c8940ab219 | |
|
|
c1f4555ba0 | |
|
|
cff2b97678 | |
|
|
adf9a7703f | |
|
|
1d8fcca09b | |
|
|
380b9245f3 | |
|
|
8ab5d465e9 | |
|
|
7b9809e567 | |
|
|
fc62a63d41 | |
|
|
8fb96db14c | |
|
|
30184cb506 | |
|
|
f0c94d59f3 | |
|
|
6dd5f4d7e3 | |
|
|
58c6a32a6c | |
|
|
d8f926865d | |
|
|
10448788f9 | |
|
|
ca0cb1322a | |
|
|
edb05fb3d1 | |
|
|
e9d434597a | |
|
|
a2687d4385 | |
|
|
a3f5f4db80 | |
|
|
c077e1acef | |
|
|
913c830dee | |
|
|
e10901e32b | |
|
|
1e7da74672 | |
|
|
5e5879c53d | |
|
|
a8c3117020 | |
|
|
73398e7e0b | |
|
|
26da5adf98 | |
|
|
0058000c22 | |
|
|
eb36edf35a | |
|
|
3da6172706 | |
|
|
e72f85fd10 | |
|
|
7b485efa9b | |
|
|
33d0d53d34 | |
|
|
be577d4318 | |
|
|
d4790d2f31 | |
|
|
c7f11d2169 | |
|
|
87702ac98a | |
|
|
5fcd4441c1 | |
|
|
adda4092d6 | |
|
|
c495b618b2 | |
|
|
1a3caee376 | |
|
|
8d08cb2f2f | |
|
|
be59d787a1 | |
|
|
05ad386500 | |
|
|
f181d97315 | |
|
|
c89b0c1ff3 | |
|
|
e4e115b23e | |
|
|
eedc0c89a1 | |
|
|
f06f3b47db | |
|
|
ff608b51f1 | |
|
|
954418d6d8 | |
|
|
c276110daa | |
|
|
a4e65afae9 | |
|
|
6d99e5326e | |
|
|
6cefbd13f1 | |
|
|
83e17706fe | |
|
|
70908a8ab5 | |
|
|
7d0d07db38 | |
|
|
0bbb558b94 | |
|
|
be40825e9a | |
|
|
583aaa1007 | |
|
|
3d1cf5aa2e | |
|
|
23b8d08f86 | |
|
|
a0f502501e | |
|
|
3b396d65f0 | |
|
|
677cd8ab5e | |
|
|
edecd81046 | |
|
|
e5813f51fa | |
|
|
13a1bfcc2e | |
|
|
53682af668 | |
|
|
86b4ac3e4c | |
|
|
11ddd559b2 | |
|
|
02bbb1064e | |
|
|
fb091fa03f | |
|
|
256a47d7b9 | |
|
|
e5e1e04146 | |
|
|
f222004d65 | |
|
|
01f2ce37b8 | |
|
|
71dffb2fd2 | |
|
|
0f05bb1356 | |
|
|
18fc328289 | |
|
|
44af9aaf9f | |
|
|
65ef9a1ad3 | |
|
|
6369c44821 | |
|
|
16da74a2f9 | |
|
|
fe89170f5a | |
|
|
f066844761 | |
|
|
2519d0a4d8 | |
|
|
05056d2f1f | |
|
|
e37a4f418a | |
|
|
70e15b1d33 | |
|
|
31ba6eeba3 | |
|
|
f4c5ec3a78 | |
|
|
2059d6fbb1 | |
|
|
a9aafebfc4 |
|
|
@ -1,28 +0,0 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
name: CI
|
||||
|
||||
jobs:
|
||||
build_appimage:
|
||||
name: Build AppImage
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: |
|
||||
export VERSION_NUM=$(ruby -e "print '$GITHUB_REF'.split('/')[2]")
|
||||
echo ::set-output name=value::${VERSION_NUM}
|
||||
- name: Build project
|
||||
run: |
|
||||
cd appimage
|
||||
make
|
||||
cp Magic-x86_64.AppImage /tmp/Magic-${{ steps.get_version.outputs.value }}-x86_64.AppImage
|
||||
- name: Upload Release Asset
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
files: /tmp/Magic-${{ steps.get_version.outputs.value }}-x86_64.AppImage
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
|
||||
name: CI-appimage10
|
||||
|
||||
env:
|
||||
APPIMAGETOOL_DOWNLOAD_URL: https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
jobs:
|
||||
build_appimage10:
|
||||
name: Build AppImage EL10
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # action-gh-release
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 149 # enough to cover between tags
|
||||
#fetch-tags: true # this should work see actions/checkout~issue#1471
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: |
|
||||
git show -s
|
||||
version=$(cat VERSION) # 8.9.999
|
||||
version_tstamp=$(git show -s "--format=%cs" | tr -d '-') # YYYYMMDD
|
||||
version_hash=$(git show -s "--format=%h") # abcdefg
|
||||
version_num=$(ruby -e "print '$GITHUB_REF'.split('/')[2]") # legacy version method: master
|
||||
echo "version=${version}"
|
||||
echo "version_tstamp=${version_tstamp}"
|
||||
echo "version_hash=${version_hash}"
|
||||
echo "version_num=${version_num}"
|
||||
VERSION_NUM="${version}~${version_tstamp}~${version_hash}"
|
||||
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_ENV
|
||||
echo "MAGIC_APPIMAGE_OUTPUT_FILENAME=Magic-${VERSION_NUM}-x86_64-EL10.AppImage" >> $GITHUB_ENV
|
||||
# Is this GHA being run due to a push-on-tag ? if so we make a GitHub release, otherwise we just publish artifact
|
||||
github_tag=$(echo -n "$GITHUB_REF" | sed -e 's#refs/tags/##') # 8.9.999
|
||||
echo "github_tag=$github_tag"
|
||||
if echo -n "$GITHUB_REF" | egrep -q "^refs/tags/" # check prefix
|
||||
then
|
||||
if [ -n "$github_tag" ]
|
||||
then
|
||||
echo "MY_GITHUB_TAG=${github_tag}" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
cd appimage/10
|
||||
make
|
||||
|
||||
ln -v Magic-x86_64.AppImage "${MAGIC_APPIMAGE_OUTPUT_FILENAME}"
|
||||
ls -l *.AppImage
|
||||
sha256sum *.AppImage
|
||||
pwd
|
||||
|
||||
- name: Create RELEASE-NOTES.txt
|
||||
run: |
|
||||
cd appimage/10
|
||||
# Find the last tag (that does not match the current GITHUB_REF)
|
||||
echo GITHUB_REF=$GITHUB_REF
|
||||
echo GITHUB_SHA=$GITHUB_SHA
|
||||
# GitHub CI is a shallow checkout by default (just the files needed to build)
|
||||
# but we also want history back to next tag, see fetch-tags/fetch-depth actions/checkout~issue#1471
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# remove only if ref of tag (to avoid conflict during fetch)
|
||||
git update-ref -d $GITHUB_REF
|
||||
echo git_update_ref_exitstatus=$?
|
||||
fi
|
||||
set +e
|
||||
git fetch --tags --prune --no-recurse-submodules --depth=149 origin +$GITHUB_SHA # fetch-tags: true # is broken
|
||||
echo git_fetch_exitstatus=$?
|
||||
git_show_ref=$(git show-ref --hash $GITHUB_REF) # get tagcommit hash
|
||||
git_show_ref_exitstatus=$?
|
||||
echo git_show_ref_exitstatus=$git_show_ref_exitstatus
|
||||
echo git_show_ref=$git_show_ref
|
||||
git_rev_list=$(git rev-list -n1 $GITHUB_REF) # get commit hash
|
||||
git_rev_list_exitstatus=$?
|
||||
echo git_rev_list_exitstatus=$git_rev_list_exitstatus
|
||||
echo git_rev_list=$git_rev_list
|
||||
set -e
|
||||
test "$git_show_ref" = "$GITHUB_SHA" || test "$git_rev_list" = "$GITHUB_SHA" # check we got the ref back (or fail CI)
|
||||
git_describe=$(git describe --tags $GITHUB_SHA | sed -e 's#\-\([0-9]\+\-g\)#\+\1#') # /-\d+-g/
|
||||
echo git_describe=$git_describe
|
||||
|
||||
# RELEASE-NOTES-EL10.txt
|
||||
echo "### ${MAGIC_APPIMAGE_OUTPUT_FILENAME} commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-EL10.txt
|
||||
echo "" >> RELEASE-NOTES-EL10.txt
|
||||
echo "This release is based on EL10 (AlmaLinux10), the AppImage format is designed to run on a wide range of Linux distributions." >> RELEASE-NOTES-EL10.txt
|
||||
echo "" >> RELEASE-NOTES-EL10.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/10/README.md" >> RELEASE-NOTES-EL10.txt
|
||||
echo "" >> RELEASE-NOTES-EL10.txt
|
||||
length_info=$(stat "--format=%s bytes" "${MAGIC_APPIMAGE_OUTPUT_FILENAME}")
|
||||
sha256_info=$(sha256sum "${MAGIC_APPIMAGE_OUTPUT_FILENAME}" | cut -d ' ' -f1)
|
||||
echo "| | |" >> RELEASE-NOTES-EL10.txt
|
||||
echo "| :-------- | :------ |" >> RELEASE-NOTES-EL10.txt
|
||||
echo "| File Name | ${MAGIC_APPIMAGE_OUTPUT_FILENAME} |" | sed -e 's#~#\\~#g' >> RELEASE-NOTES-EL10.txt
|
||||
echo "| File Length | ${length_info} |" >> RELEASE-NOTES-EL10.txt
|
||||
echo "| File SHA256 | ${sha256_info} |" >> RELEASE-NOTES-EL10.txt
|
||||
echo "" >> RELEASE-NOTES-EL10.txt
|
||||
|
||||
# RELEASE-NOTES-CL.txt
|
||||
set +e # allow this to fail to empty string
|
||||
git_previous_tag=$(git describe --tags --abbrev=0 $(git rev-list --tags --skip=1 --max-count=1))
|
||||
echo git_previous_tag=$git_previous_tag
|
||||
set -e
|
||||
if [ -n "${git_previous_tag}" ]
|
||||
then
|
||||
echo "### Change Log (since previous tag):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline --no-color --no-decorate "refs/tags/${git_previous_tag}..${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
else
|
||||
echo "### Change Log (last commit only):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline -n1 --no-color --no-decorate "${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-CL.txt
|
||||
|
||||
#echo "### Build Info:" > RELEASE-NOTES-BI.txt
|
||||
# FIXME extract package version info and DSO symvers into RELEASE-NOTES.txt
|
||||
#echo "" >> RELEASE-NOTES-BI.txt
|
||||
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-EL10.txt
|
||||
cat RELEASE-NOTES-EL10.txt
|
||||
|
||||
# RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/7/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/8/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/9/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/10/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
|
||||
# RELEASE-NOTES-GH.txt (this is shared for all AppImage for one tag)
|
||||
echo "### commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-GH.txt
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# show tag annotation with tags like before
|
||||
git tag --cleanup=strip "--format=%(contents)" -n "${GITHUB_REF:10}" | sed -e 's#\([~|]\)#\\\1#g' >> RELEASE-NOTES-GH.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-DOCS.txt >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-GH.txt
|
||||
|
||||
# Show in action/artifact output
|
||||
echo "## RELEASE NOTES" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
cat RELEASE-NOTES-EL10.txt >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: ${{ env.MY_GITHUB_TAG != '' }} # if: ${{ github.ref_type == 'tag' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body_path: ${{ github.workspace }}/appimage/10/RELEASE-NOTES-GH.txt
|
||||
files: |
|
||||
${{ github.workspace }}/appimage/10/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
${{ github.workspace }}/appimage/10/RELEASE-NOTES-EL10.txt
|
||||
|
||||
- name: Upload Artifact
|
||||
#if: ${{ env.MY_GITHUB_TAG == '' }} # commented out to always upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
path: |
|
||||
${{ github.workspace }}/appimage/10/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
|
||||
name: CI-appimage7
|
||||
|
||||
env:
|
||||
APPIMAGETOOL_DOWNLOAD_URL: https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
jobs:
|
||||
build_appimage7:
|
||||
name: Build AppImage EL7
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # action-gh-release
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 149 # enough to cover between tags
|
||||
#fetch-tags: true # this should work see actions/checkout~issue#1471
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: |
|
||||
git show -s
|
||||
version=$(cat VERSION) # 8.9.999
|
||||
version_tstamp=$(git show -s "--format=%cs" | tr -d '-') # YYYYMMDD
|
||||
version_hash=$(git show -s "--format=%h") # abcdefg
|
||||
version_num=$(ruby -e "print '$GITHUB_REF'.split('/')[2]") # legacy version method: master
|
||||
echo "version=${version}"
|
||||
echo "version_tstamp=${version_tstamp}"
|
||||
echo "version_hash=${version_hash}"
|
||||
echo "version_num=${version_num}"
|
||||
VERSION_NUM="${version}~${version_tstamp}~${version_hash}"
|
||||
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_ENV
|
||||
echo "MAGIC_APPIMAGE_OUTPUT_FILENAME=Magic-${VERSION_NUM}-x86_64-EL7.AppImage" >> $GITHUB_ENV
|
||||
# Is this GHA being run due to a push-on-tag ? if so we make a GitHub release, otherwise we just publish artifact
|
||||
github_tag=$(echo -n "$GITHUB_REF" | sed -e 's#refs/tags/##') # 8.9.999
|
||||
echo "github_tag=$github_tag"
|
||||
if echo -n "$GITHUB_REF" | egrep -q "^refs/tags/" # check prefix
|
||||
then
|
||||
if [ -n "$github_tag" ]
|
||||
then
|
||||
echo "MY_GITHUB_TAG=${github_tag}" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
cd appimage/7
|
||||
make
|
||||
|
||||
ln -v Magic-x86_64.AppImage "${MAGIC_APPIMAGE_OUTPUT_FILENAME}"
|
||||
ls -l *.AppImage
|
||||
sha256sum *.AppImage
|
||||
pwd
|
||||
|
||||
- name: Create RELEASE-NOTES.txt
|
||||
run: |
|
||||
cd appimage/7
|
||||
# Find the last tag (that does not match the current GITHUB_REF)
|
||||
echo GITHUB_REF=$GITHUB_REF
|
||||
echo GITHUB_SHA=$GITHUB_SHA
|
||||
# GitHub CI is a shallow checkout by default (just the files needed to build)
|
||||
# but we also want history back to next tag, see fetch-tags/fetch-depth actions/checkout~issue#1471
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# remove only if ref of tag (to avoid conflict during fetch)
|
||||
git update-ref -d $GITHUB_REF
|
||||
echo git_update_ref_exitstatus=$?
|
||||
fi
|
||||
set +e
|
||||
git fetch --tags --prune --no-recurse-submodules --depth=149 origin +$GITHUB_SHA # fetch-tags: true # is broken
|
||||
echo git_fetch_exitstatus=$?
|
||||
git_show_ref=$(git show-ref --hash $GITHUB_REF) # get tagcommit hash
|
||||
git_show_ref_exitstatus=$?
|
||||
echo git_show_ref_exitstatus=$git_show_ref_exitstatus
|
||||
echo git_show_ref=$git_show_ref
|
||||
git_rev_list=$(git rev-list -n1 $GITHUB_REF) # get commit hash
|
||||
git_rev_list_exitstatus=$?
|
||||
echo git_rev_list_exitstatus=$git_rev_list_exitstatus
|
||||
echo git_rev_list=$git_rev_list
|
||||
set -e
|
||||
test "$git_show_ref" = "$GITHUB_SHA" || test "$git_rev_list" = "$GITHUB_SHA" # check we got the ref back (or fail CI)
|
||||
git_describe=$(git describe --tags $GITHUB_SHA | sed -e 's#\-\([0-9]\+\-g\)#\+\1#') # /-\d+-g/
|
||||
echo git_describe=$git_describe
|
||||
|
||||
# RELEASE-NOTES-EL7.txt
|
||||
echo "### ${MAGIC_APPIMAGE_OUTPUT_FILENAME} commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-EL7.txt
|
||||
echo "" >> RELEASE-NOTES-EL7.txt
|
||||
echo "This release is based on EL7 (CentOS7), the AppImage format is designed to run on a wide range of Linux distributions." >> RELEASE-NOTES-EL7.txt
|
||||
echo "" >> RELEASE-NOTES-EL7.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/7/README.md" >> RELEASE-NOTES-EL7.txt
|
||||
echo "" >> RELEASE-NOTES-EL7.txt
|
||||
length_info=$(stat "--format=%s bytes" "${MAGIC_APPIMAGE_OUTPUT_FILENAME}")
|
||||
sha256_info=$(sha256sum "${MAGIC_APPIMAGE_OUTPUT_FILENAME}" | cut -d ' ' -f1)
|
||||
echo "| | |" >> RELEASE-NOTES-EL7.txt
|
||||
echo "| :-------- | :------ |" >> RELEASE-NOTES-EL7.txt
|
||||
echo "| File Name | ${MAGIC_APPIMAGE_OUTPUT_FILENAME} |" | sed -e 's#~#\\~#g' >> RELEASE-NOTES-EL7.txt
|
||||
echo "| File Length | ${length_info} |" >> RELEASE-NOTES-EL7.txt
|
||||
echo "| File SHA256 | ${sha256_info} |" >> RELEASE-NOTES-EL7.txt
|
||||
echo "" >> RELEASE-NOTES-EL7.txt
|
||||
|
||||
# RELEASE-NOTES-CL.txt
|
||||
set +e # allow this to fail to empty string
|
||||
git_previous_tag=$(git describe --tags --abbrev=0 $(git rev-list --tags --skip=1 --max-count=1))
|
||||
echo git_previous_tag=$git_previous_tag
|
||||
set -e
|
||||
if [ -n "${git_previous_tag}" ]
|
||||
then
|
||||
echo "### Change Log (since previous tag):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline --no-color --no-decorate "refs/tags/${git_previous_tag}..${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
else
|
||||
echo "### Change Log (last commit only):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline -n1 --no-color --no-decorate "${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-CL.txt
|
||||
|
||||
#echo "### Build Info:" > RELEASE-NOTES-BI.txt
|
||||
# FIXME extract package version info and DSO symvers into RELEASE-NOTES.txt
|
||||
#echo "" >> RELEASE-NOTES-BI.txt
|
||||
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-EL7.txt
|
||||
cat RELEASE-NOTES-EL7.txt
|
||||
|
||||
# RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/7/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/8/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/9/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/10/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
|
||||
# RELEASE-NOTES-GH.txt (this is shared for all AppImage for one tag)
|
||||
echo "### commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-GH.txt
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# show tag annotation with tags like before
|
||||
git tag --cleanup=strip "--format=%(contents)" -n "${GITHUB_REF:10}" | sed -e 's#\([~|]\)#\\\1#g' >> RELEASE-NOTES-GH.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-DOCS.txt >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-GH.txt
|
||||
|
||||
# Show in action/artifact output
|
||||
echo "## RELEASE NOTES" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
cat RELEASE-NOTES-EL7.txt >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: ${{ env.MY_GITHUB_TAG != '' }} # if: ${{ github.ref_type == 'tag' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body_path: ${{ github.workspace }}/appimage/7/RELEASE-NOTES-GH.txt
|
||||
files: |
|
||||
${{ github.workspace }}/appimage/7/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
${{ github.workspace }}/appimage/7/RELEASE-NOTES-EL7.txt
|
||||
|
||||
- name: Upload Artifact
|
||||
#if: ${{ env.MY_GITHUB_TAG == '' }} # commented out to always upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
path: |
|
||||
${{ github.workspace }}/appimage/7/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
|
||||
name: CI-appimage8
|
||||
|
||||
env:
|
||||
APPIMAGETOOL_DOWNLOAD_URL: https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
jobs:
|
||||
build_appimage8:
|
||||
name: Build AppImage EL8
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # action-gh-release
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 149 # enough to cover between tags
|
||||
#fetch-tags: true # this should work see actions/checkout~issue#1471
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: |
|
||||
git show -s
|
||||
version=$(cat VERSION) # 8.9.999
|
||||
version_tstamp=$(git show -s "--format=%cs" | tr -d '-') # YYYYMMDD
|
||||
version_hash=$(git show -s "--format=%h") # abcdefg
|
||||
version_num=$(ruby -e "print '$GITHUB_REF'.split('/')[2]") # legacy version method: master
|
||||
echo "version=${version}"
|
||||
echo "version_tstamp=${version_tstamp}"
|
||||
echo "version_hash=${version_hash}"
|
||||
echo "version_num=${version_num}"
|
||||
VERSION_NUM="${version}~${version_tstamp}~${version_hash}"
|
||||
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_ENV
|
||||
echo "MAGIC_APPIMAGE_OUTPUT_FILENAME=Magic-${VERSION_NUM}-x86_64-EL8.AppImage" >> $GITHUB_ENV
|
||||
# Is this GHA being run due to a push-on-tag ? if so we make a GitHub release, otherwise we just publish artifact
|
||||
github_tag=$(echo -n "$GITHUB_REF" | sed -e 's#refs/tags/##') # 8.9.999
|
||||
echo "github_tag=$github_tag"
|
||||
if echo -n "$GITHUB_REF" | egrep -q "^refs/tags/" # check prefix
|
||||
then
|
||||
if [ -n "$github_tag" ]
|
||||
then
|
||||
echo "MY_GITHUB_TAG=${github_tag}" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
cd appimage/8
|
||||
make
|
||||
|
||||
ln -v Magic-x86_64.AppImage "${MAGIC_APPIMAGE_OUTPUT_FILENAME}"
|
||||
ls -l *.AppImage
|
||||
sha256sum *.AppImage
|
||||
pwd
|
||||
|
||||
- name: Create RELEASE-NOTES.txt
|
||||
run: |
|
||||
cd appimage/8
|
||||
# Find the last tag (that does not match the current GITHUB_REF)
|
||||
echo GITHUB_REF=$GITHUB_REF
|
||||
echo GITHUB_SHA=$GITHUB_SHA
|
||||
# GitHub CI is a shallow checkout by default (just the files needed to build)
|
||||
# but we also want history back to next tag, see fetch-tags/fetch-depth actions/checkout~issue#1471
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# remove only if ref of tag (to avoid conflict during fetch)
|
||||
git update-ref -d $GITHUB_REF
|
||||
echo git_update_ref_exitstatus=$?
|
||||
fi
|
||||
set +e
|
||||
git fetch --tags --prune --no-recurse-submodules --depth=149 origin +$GITHUB_SHA # fetch-tags: true # is broken
|
||||
echo git_fetch_exitstatus=$?
|
||||
git_show_ref=$(git show-ref --hash $GITHUB_REF) # get tagcommit hash
|
||||
git_show_ref_exitstatus=$?
|
||||
echo git_show_ref_exitstatus=$git_show_ref_exitstatus
|
||||
echo git_show_ref=$git_show_ref
|
||||
git_rev_list=$(git rev-list -n1 $GITHUB_REF) # get commit hash
|
||||
git_rev_list_exitstatus=$?
|
||||
echo git_rev_list_exitstatus=$git_rev_list_exitstatus
|
||||
echo git_rev_list=$git_rev_list
|
||||
set -e
|
||||
test "$git_show_ref" = "$GITHUB_SHA" || test "$git_rev_list" = "$GITHUB_SHA" # check we got the ref back (or fail CI)
|
||||
git_describe=$(git describe --tags $GITHUB_SHA | sed -e 's#\-\([0-9]\+\-g\)#\+\1#') # /-\d+-g/
|
||||
echo git_describe=$git_describe
|
||||
|
||||
# RELEASE-NOTES-EL8.txt
|
||||
echo "### ${MAGIC_APPIMAGE_OUTPUT_FILENAME} commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-EL8.txt
|
||||
echo "" >> RELEASE-NOTES-EL8.txt
|
||||
echo "This release is based on EL8 (AlmaLinux8), the AppImage format is designed to run on a wide range of Linux distributions." >> RELEASE-NOTES-EL8.txt
|
||||
echo "" >> RELEASE-NOTES-EL8.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/8/README.md" >> RELEASE-NOTES-EL8.txt
|
||||
echo "" >> RELEASE-NOTES-EL8.txt
|
||||
length_info=$(stat "--format=%s bytes" "${MAGIC_APPIMAGE_OUTPUT_FILENAME}")
|
||||
sha256_info=$(sha256sum "${MAGIC_APPIMAGE_OUTPUT_FILENAME}" | cut -d ' ' -f1)
|
||||
echo "| | |" >> RELEASE-NOTES-EL8.txt
|
||||
echo "| :-------- | :------ |" >> RELEASE-NOTES-EL8.txt
|
||||
echo "| File Name | ${MAGIC_APPIMAGE_OUTPUT_FILENAME} |" | sed -e 's#~#\\~#g' >> RELEASE-NOTES-EL8.txt
|
||||
echo "| File Length | ${length_info} |" >> RELEASE-NOTES-EL8.txt
|
||||
echo "| File SHA256 | ${sha256_info} |" >> RELEASE-NOTES-EL8.txt
|
||||
echo "" >> RELEASE-NOTES-EL8.txt
|
||||
|
||||
# RELEASE-NOTES-CL.txt
|
||||
set +e # allow this to fail to empty string
|
||||
git_previous_tag=$(git describe --tags --abbrev=0 $(git rev-list --tags --skip=1 --max-count=1))
|
||||
echo git_previous_tag=$git_previous_tag
|
||||
set -e
|
||||
if [ -n "${git_previous_tag}" ]
|
||||
then
|
||||
echo "### Change Log (since previous tag):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline --no-color --no-decorate "refs/tags/${git_previous_tag}..${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
else
|
||||
echo "### Change Log (last commit only):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline -n1 --no-color --no-decorate "${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-CL.txt
|
||||
|
||||
#echo "### Build Info:" > RELEASE-NOTES-BI.txt
|
||||
# FIXME extract package version info and DSO symvers into RELEASE-NOTES.txt
|
||||
#echo "" >> RELEASE-NOTES-BI.txt
|
||||
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-EL8.txt
|
||||
cat RELEASE-NOTES-EL8.txt
|
||||
|
||||
# RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/7/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/8/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/9/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/10/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
|
||||
# RELEASE-NOTES-GH.txt (this is shared for all AppImage for one tag)
|
||||
echo "### commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-GH.txt
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# show tag annotation with tags like before
|
||||
git tag --cleanup=strip "--format=%(contents)" -n "${GITHUB_REF:10}" | sed -e 's#\([~|]\)#\\\1#g' >> RELEASE-NOTES-GH.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-DOCS.txt >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-GH.txt
|
||||
|
||||
# Show in action/artifact output
|
||||
echo "## RELEASE NOTES" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
cat RELEASE-NOTES-EL8.txt >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: ${{ env.MY_GITHUB_TAG != '' }} # if: ${{ github.ref_type == 'tag' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body_path: ${{ github.workspace }}/appimage/8/RELEASE-NOTES-GH.txt
|
||||
files: |
|
||||
${{ github.workspace }}/appimage/8/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
${{ github.workspace }}/appimage/8/RELEASE-NOTES-EL8.txt
|
||||
|
||||
- name: Upload Artifact
|
||||
#if: ${{ env.MY_GITHUB_TAG == '' }} # commented out to always upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
path: |
|
||||
${{ github.workspace }}/appimage/8/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
|
||||
name: CI-appimage9
|
||||
|
||||
env:
|
||||
APPIMAGETOOL_DOWNLOAD_URL: https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
jobs:
|
||||
build_appimage9:
|
||||
name: Build AppImage EL9
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write # action-gh-release
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 149 # enough to cover between tags
|
||||
#fetch-tags: true # this should work see actions/checkout~issue#1471
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: |
|
||||
git show -s
|
||||
version=$(cat VERSION) # 8.9.999
|
||||
version_tstamp=$(git show -s "--format=%cs" | tr -d '-') # YYYYMMDD
|
||||
version_hash=$(git show -s "--format=%h") # abcdefg
|
||||
version_num=$(ruby -e "print '$GITHUB_REF'.split('/')[2]") # legacy version method: master
|
||||
echo "version=${version}"
|
||||
echo "version_tstamp=${version_tstamp}"
|
||||
echo "version_hash=${version_hash}"
|
||||
echo "version_num=${version_num}"
|
||||
VERSION_NUM="${version}~${version_tstamp}~${version_hash}"
|
||||
echo "VERSION_NUM=${VERSION_NUM}" >> $GITHUB_ENV
|
||||
echo "MAGIC_APPIMAGE_OUTPUT_FILENAME=Magic-${VERSION_NUM}-x86_64-EL9.AppImage" >> $GITHUB_ENV
|
||||
# Is this GHA being run due to a push-on-tag ? if so we make a GitHub release, otherwise we just publish artifact
|
||||
github_tag=$(echo -n "$GITHUB_REF" | sed -e 's#refs/tags/##') # 8.9.999
|
||||
echo "github_tag=$github_tag"
|
||||
if echo -n "$GITHUB_REF" | egrep -q "^refs/tags/" # check prefix
|
||||
then
|
||||
if [ -n "$github_tag" ]
|
||||
then
|
||||
echo "MY_GITHUB_TAG=${github_tag}" >> $GITHUB_ENV
|
||||
fi
|
||||
fi
|
||||
|
||||
- name: Build project
|
||||
run: |
|
||||
cd appimage/9
|
||||
make
|
||||
|
||||
ln -v Magic-x86_64.AppImage "${MAGIC_APPIMAGE_OUTPUT_FILENAME}"
|
||||
ls -l *.AppImage
|
||||
sha256sum *.AppImage
|
||||
pwd
|
||||
|
||||
- name: Create RELEASE-NOTES.txt
|
||||
run: |
|
||||
cd appimage/9
|
||||
# Find the last tag (that does not match the current GITHUB_REF)
|
||||
echo GITHUB_REF=$GITHUB_REF
|
||||
echo GITHUB_SHA=$GITHUB_SHA
|
||||
# GitHub CI is a shallow checkout by default (just the files needed to build)
|
||||
# but we also want history back to next tag, see fetch-tags/fetch-depth actions/checkout~issue#1471
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# remove only if ref of tag (to avoid conflict during fetch)
|
||||
git update-ref -d $GITHUB_REF
|
||||
echo git_update_ref_exitstatus=$?
|
||||
fi
|
||||
set +e
|
||||
git fetch --tags --prune --no-recurse-submodules --depth=149 origin +$GITHUB_SHA # fetch-tags: true # is broken
|
||||
echo git_fetch_exitstatus=$?
|
||||
git_show_ref=$(git show-ref --hash $GITHUB_REF) # get tagcommit hash
|
||||
git_show_ref_exitstatus=$?
|
||||
echo git_show_ref_exitstatus=$git_show_ref_exitstatus
|
||||
echo git_show_ref=$git_show_ref
|
||||
git_rev_list=$(git rev-list -n1 $GITHUB_REF) # get commit hash
|
||||
git_rev_list_exitstatus=$?
|
||||
echo git_rev_list_exitstatus=$git_rev_list_exitstatus
|
||||
echo git_rev_list=$git_rev_list
|
||||
set -e
|
||||
test "$git_show_ref" = "$GITHUB_SHA" || test "$git_rev_list" = "$GITHUB_SHA" # check we got the ref back (or fail CI)
|
||||
git_describe=$(git describe --tags $GITHUB_SHA | sed -e 's#\-\([0-9]\+\-g\)#\+\1#') # /-\d+-g/
|
||||
echo git_describe=$git_describe
|
||||
|
||||
# RELEASE-NOTES-EL9.txt
|
||||
echo "### ${MAGIC_APPIMAGE_OUTPUT_FILENAME} commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-EL9.txt
|
||||
echo "" >> RELEASE-NOTES-EL9.txt
|
||||
echo "This release is based on EL9 (AlmaLinux9), the AppImage format is designed to run on a wide range of Linux distributions." >> RELEASE-NOTES-EL9.txt
|
||||
echo "" >> RELEASE-NOTES-EL9.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/9/README.md" >> RELEASE-NOTES-EL9.txt
|
||||
echo "" >> RELEASE-NOTES-EL9.txt
|
||||
length_info=$(stat "--format=%s bytes" "${MAGIC_APPIMAGE_OUTPUT_FILENAME}")
|
||||
sha256_info=$(sha256sum "${MAGIC_APPIMAGE_OUTPUT_FILENAME}" | cut -d ' ' -f1)
|
||||
echo "| | |" >> RELEASE-NOTES-EL9.txt
|
||||
echo "| :-------- | :------ |" >> RELEASE-NOTES-EL9.txt
|
||||
echo "| File Name | ${MAGIC_APPIMAGE_OUTPUT_FILENAME} |" | sed -e 's#~#\\~#g' >> RELEASE-NOTES-EL9.txt
|
||||
echo "| File Length | ${length_info} |" >> RELEASE-NOTES-EL9.txt
|
||||
echo "| File SHA256 | ${sha256_info} |" >> RELEASE-NOTES-EL9.txt
|
||||
echo "" >> RELEASE-NOTES-EL9.txt
|
||||
|
||||
# RELEASE-NOTES-CL.txt
|
||||
set +e # allow this to fail to empty string
|
||||
git_previous_tag=$(git describe --tags --abbrev=0 $(git rev-list --tags --skip=1 --max-count=1))
|
||||
echo git_previous_tag=$git_previous_tag
|
||||
set -e
|
||||
if [ -n "${git_previous_tag}" ]
|
||||
then
|
||||
echo "### Change Log (since previous tag):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline --no-color --no-decorate "refs/tags/${git_previous_tag}..${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
else
|
||||
echo "### Change Log (last commit only):" > RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
git log --oneline -n1 --no-color --no-decorate "${GITHUB_REF}" >> RELEASE-NOTES-CL.txt
|
||||
echo "\`\`\`" >> RELEASE-NOTES-CL.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-CL.txt
|
||||
|
||||
#echo "### Build Info:" > RELEASE-NOTES-BI.txt
|
||||
# FIXME extract package version info and DSO symvers into RELEASE-NOTES.txt
|
||||
#echo "" >> RELEASE-NOTES-BI.txt
|
||||
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-EL9.txt
|
||||
cat RELEASE-NOTES-EL9.txt
|
||||
|
||||
# RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/7/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/8/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/9/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
echo "See documentation at https://github.com/${GITHUB_REPOSITORY}/blob/${GITHUB_SHA:0:8}/appimage/10/README.md" >> RELEASE-NOTES-DOCS.txt
|
||||
|
||||
# RELEASE-NOTES-GH.txt (this is shared for all AppImage for one tag)
|
||||
echo "### commit ${git_describe}" | sed -e 's#~#\\~#g' > RELEASE-NOTES-GH.txt
|
||||
if [[ "$GITHUB_REF" =~ ^refs/tags/ ]]
|
||||
then
|
||||
# show tag annotation with tags like before
|
||||
git tag --cleanup=strip "--format=%(contents)" -n "${GITHUB_REF:10}" | sed -e 's#\([~|]\)#\\\1#g' >> RELEASE-NOTES-GH.txt
|
||||
fi
|
||||
echo "" >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-DOCS.txt >> RELEASE-NOTES-GH.txt
|
||||
cat RELEASE-NOTES-CL.txt >> RELEASE-NOTES-GH.txt
|
||||
|
||||
# Show in action/artifact output
|
||||
echo "## RELEASE NOTES" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
cat RELEASE-NOTES-EL9.txt >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Upload Release Asset
|
||||
if: ${{ env.MY_GITHUB_TAG != '' }} # if: ${{ github.ref_type == 'tag' }}
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
body_path: ${{ github.workspace }}/appimage/9/RELEASE-NOTES-GH.txt
|
||||
files: |
|
||||
${{ github.workspace }}/appimage/9/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
${{ github.workspace }}/appimage/9/RELEASE-NOTES-EL9.txt
|
||||
|
||||
- name: Upload Artifact
|
||||
#if: ${{ env.MY_GITHUB_TAG == '' }} # commented out to always upload
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
path: |
|
||||
${{ github.workspace }}/appimage/9/${{env.MAGIC_APPIMAGE_OUTPUT_FILENAME}}
|
||||
|
|
@ -0,0 +1,289 @@
|
|||
|
||||
name: CI-canary-matrix
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
canary:
|
||||
strategy:
|
||||
max-parallel: 3
|
||||
matrix:
|
||||
os: [ubuntu-24.04, ubuntu-22.04]
|
||||
# Configure Options
|
||||
# X11 OGL CAIRO
|
||||
pkgs: [all, none, no_tk_tcl_rl, no_tk_tcl_brl, no_zlib, no_gc_gl_gu, no_gc, no_gl_gu]
|
||||
# Toolchain
|
||||
# ubuntu-20.04 [gcc-9, clang-10]
|
||||
# ubuntu-22.04 [gcc-11, clang-14]
|
||||
# ubuntu-24.04 [gcc-13, clang-18]
|
||||
tc: [default, gcc-10, gcc-11, gcc-12, gcc-13, gcc-14, clang-14, clang-15, clang-17, clang-18, clang-19]
|
||||
exclude:
|
||||
- os: ubuntu-22.04
|
||||
tc: gcc-13
|
||||
- os: ubuntu-22.04
|
||||
tc: gcc-14
|
||||
- os: ubuntu-22.04
|
||||
tc: clang-17
|
||||
- os: ubuntu-22.04 # some sources show this as present but not found
|
||||
tc: clang-18
|
||||
- os: ubuntu-22.04
|
||||
tc: clang-19
|
||||
|
||||
- os: ubuntu-24.04
|
||||
tc: gcc-10
|
||||
- os: ubuntu-24.04
|
||||
tc: gcc-11
|
||||
- os: ubuntu-24.04
|
||||
tc: clang-14
|
||||
- os: ubuntu-24.04
|
||||
tc: clang-15
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Matrix Check
|
||||
env:
|
||||
MATRIX_OS: ${{ matrix.os }}
|
||||
MATRIX_PKGS: ${{ matrix.pkgs }}
|
||||
MATRIX_TC: ${{ matrix.tc }}
|
||||
run: |
|
||||
# This takes the macros params ENV and processes into options list
|
||||
|
||||
if [ "${MATRIX_PKGS}" = "none" ]
|
||||
then
|
||||
pkgs=""
|
||||
cfgs=""
|
||||
else
|
||||
pkgs="kcnrzCLUX"
|
||||
cfgs=""
|
||||
fi
|
||||
|
||||
# z no.*_zl zlib1g-dev
|
||||
# n no.*_nc libncurses-dev
|
||||
# r no.*_rl libreadline-dev
|
||||
# R no.*_brl --enable-readline-bundled
|
||||
# c no.*_tcl tcl-dev
|
||||
# k no.*_tk tk-dev
|
||||
# C no.*_gc libcairo-dev
|
||||
# L no.*_gl libgl-dev
|
||||
# U no.*_gu libglu1-mesa-dev # GLU requires GL
|
||||
# X no.*_gx libx11-dev
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#z##'); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_nc"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#n##'); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_brl"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#r#R#'); fi # replace
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_rl"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#r##'); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#c##'); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tk"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#k##'); fi
|
||||
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gc"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#C##'); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gl"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#L##'); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gu"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#U##'); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gx"; then
|
||||
pkgs=$(echo -n "$pkgs" | sed -e 's#X##'); fi
|
||||
|
||||
_package_list=()
|
||||
echo -n $pkgs | grep -q "z" && _package_list+=(zlib1g-dev)
|
||||
echo -n $pkgs | grep -q "n" && _package_list+=(libncurses-dev)
|
||||
echo -n $pkgs | grep -q "r" && _package_list+=(libreadline-dev)
|
||||
echo -n $pkgs | grep -q "c" && _package_list+=(tcl-dev)
|
||||
echo -n $pkgs | grep -q "k" && _package_list+=(tk-dev)
|
||||
echo -n $pkgs | grep -q "C" && _package_list+=(libcairo-dev)
|
||||
echo -n $pkgs | grep -q "L" && _package_list+=(libgl-dev)
|
||||
echo -n $pkgs | grep -q "U" && _package_list+=(libglu1-mesa-dev)
|
||||
echo -n $pkgs | grep -q "X" && _package_list+=(libx11-dev)
|
||||
echo "PACKAGE_LIST=${_package_list[*]}" >> $GITHUB_ENV
|
||||
|
||||
#
|
||||
_configure_args=()
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then
|
||||
_configure_args+=(--disable-compression); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_brl"; then
|
||||
_configure_args+=(--enable-readline-bundled); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_rl"; then
|
||||
_configure_args+=(--disable-readline); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then
|
||||
_configure_args+=(--without-tcl); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tk"; then
|
||||
_configure_args+=(--without-tk); fi
|
||||
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gc"; then
|
||||
_configure_args+=(--without-cairo); fi
|
||||
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gl"; then
|
||||
_configure_args+=(--without-opengl); fi
|
||||
|
||||
echo "CONFIGURE_ARGS=${_configure_args[*]}" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Toolchain
|
||||
env:
|
||||
MATRIX_TC: ${{ matrix.tc }}
|
||||
run: |
|
||||
# decode settings
|
||||
BUILD_GCC_VERSION=$( echo -n "$MATRIX_TC" | grep -i "^gcc" | sed -e 's#^gcc\-\?##i')
|
||||
BUILD_CLANG_VERSION=$(echo -n "$MATRIX_TC" | grep -i "^clang" | sed -e 's#^clang\-\?##i')
|
||||
echo "BUILD_GCC_VERSION=$BUILD_GCC_VERSION" >> $GITHUB_ENV
|
||||
echo "BUILD_CLANG_VERSION=$BUILD_CLANG_VERSION" >> $GITHUB_ENV
|
||||
|
||||
if [ -n "$BUILD_GCC_VERSION" ]
|
||||
then
|
||||
GCCV=$BUILD_GCC_VERSION
|
||||
# https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
|
||||
sudo apt-get install gcc-${GCCV} g++-${GCCV} cpp-${GCCV}
|
||||
gcc-${GCCV} -v
|
||||
g++-${GCCV} -v
|
||||
cpp-${GCCV} -v < /dev/null
|
||||
ls -l /usr/bin/g++ /usr/bin/g++-[0-9]* /usr/bin/gcc /usr/bin/gcc-[0-9]* /usr/bin/cpp-* /usr/bin/*-gnu-cpp* || true
|
||||
update-alternatives --list gcc || true
|
||||
update-alternatives --list g++ || true
|
||||
update-alternatives --list cpp || true
|
||||
update-alternatives --query gcc || true
|
||||
update-alternatives --query g++ || true
|
||||
update-alternatives --query cpp || true
|
||||
ls -l /usr/bin/g++ /usr/bin/g++-[0-9]* /usr/bin/gcc /usr/bin/gcc-[0-9]* /usr/bin/cpp-* /usr/bin/*-gnu-cpp* || true
|
||||
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCCV} 50
|
||||
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCCV} 50
|
||||
sudo update-alternatives --install "/usr/bin/$(uname -m)-linux-gnu-cpp" cpp "/usr/bin/$(uname -m)-linux-gnu-cpp-${GCCV}" 50
|
||||
ls -l /usr/bin/g++ /usr/bin/g++-[0-9]* /usr/bin/gcc /usr/bin/gcc-[0-9]* /usr/bin/cpp-* /usr/bin/*-gnu-cpp* || true
|
||||
update-alternatives --list gcc || true
|
||||
update-alternatives --list g++ || true
|
||||
update-alternatives --list cpp || true
|
||||
hash -r
|
||||
gcc -v
|
||||
elif [ -n "$BUILD_CLANG_VERSION" ]
|
||||
then
|
||||
CLANGV=$BUILD_CLANG_VERSION
|
||||
# https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
|
||||
sudo apt-get install clang-${CLANGV} clang++-${CLANGV} #clang-cpp-${CLANGV}
|
||||
clang-${CLANGV} -v
|
||||
clang++-${CLANGV} -v
|
||||
clang-cpp-${CLANGV} -v < /dev/null
|
||||
ls -l /usr/bin/clang++ /usr/bin/clang++-[0-9]* /usr/bin/clang /usr/bin/clang-[0-9]* /usr/bin/clang-cpp-* /usr/bin/clang-cpp* || true
|
||||
update-alternatives --list clang || true
|
||||
update-alternatives --list clang++ || true
|
||||
update-alternatives --list clang-cpp || true
|
||||
update-alternatives --query clang || true
|
||||
update-alternatives --query clang++ || true
|
||||
update-alternatives --query clang-cpp || true
|
||||
ls -l /usr/bin/clang++ /usr/bin/clang++-[0-9]* /usr/bin/clang /usr/bin/clang-[0-9]* /usr/bin/clang-cpp-* /usr/bin/clang-cpp* || true
|
||||
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${CLANGV} 50
|
||||
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${CLANGV} 50
|
||||
sudo update-alternatives --install "/usr/bin/clang-cpp" clang-cpp "/usr/bin/clang-cpp-${CLANGV}" 50
|
||||
ls -l /usr/bin/clang++ /usr/bin/clang++-[0-9]* /usr/bin/clang /usr/bin/clang-[0-9]* /usr/bin/clang-cpp-* /usr/bin/clang-cpp* || true
|
||||
update-alternatives --list clang || true
|
||||
update-alternatives --list clang++ || true
|
||||
update-alternatives --list clang-cpp || true
|
||||
hash -r
|
||||
clang -v
|
||||
fi
|
||||
|
||||
- name: Get Dependencies
|
||||
run: |
|
||||
if [ -n "$PACKAGE_LIST" ]
|
||||
then
|
||||
sudo apt-get install -y ${PACKAGE_LIST}
|
||||
fi
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
if [ -n "$BUILD_CLANG_VERSION" ]
|
||||
then
|
||||
export CC="clang-${BUILD_CLANG_VERSION}"
|
||||
export CXX="clang++-${BUILD_CLANG_VERSION}"
|
||||
export CPP="clang-cpp-${BUILD_CLANG_VERSION}"
|
||||
fi
|
||||
|
||||
set -o pipefail # due to pipe inside CI
|
||||
./configure $CONFIGURE_ARGS 2>&1 | tee CONFIGURE.LOG
|
||||
|
||||
egrep "^(CPP|CXX|CC)\s" defs.mak
|
||||
|
||||
# Add -Wall for CI loggings
|
||||
sed -e 's# -Werror=# -Wall -Werror=#' -i defs.mak
|
||||
# Non security/reliability related warnings
|
||||
#sed -e 's# -Werror=# -Wno-unused-variable -Werror=#' -i defs.mak
|
||||
#sed -e 's# -Werror=# -Wno-unused-local-typedefs -Werror=#' -i defs.mak
|
||||
#sed -e 's# -Werror=# -Wno-unused-label -Werror=#' -i defs.mak
|
||||
#sed -e 's# -Werror=# -Wno-unused-but-set-variable -Werror=#' -i defs.mak
|
||||
make database/database.h
|
||||
make -j$(nproc) 2>&1 | tee MAKE.LOG
|
||||
|
||||
- name: Summary
|
||||
env:
|
||||
MATRIX_OS: ${{ matrix.os }}
|
||||
MATRIX_PKGS: ${{ matrix.pkgs }}
|
||||
run: |
|
||||
set +e
|
||||
grep "error:" MAKE.LOG > MAKE_error.LOG
|
||||
grep "warning:" MAKE.LOG > MAKE_warning.LOG
|
||||
|
||||
# Less important warnings relating to codesmell more than security (filter out of headline)
|
||||
grep -v "Wunused-variable" MAKE_warning.LOG |
|
||||
grep -v "Wunused-local-typedefs" |
|
||||
grep -v "Wunused-label" |
|
||||
grep -v "Wunused-but-set-variable" > MAKE_warning_filtered.LOG
|
||||
|
||||
ls -l
|
||||
wc -l *.LOG
|
||||
|
||||
error_count=$( grep -c "error:" MAKE_error.LOG)
|
||||
filtered_warning_count=$(grep -c "warning:" MAKE_warning_filtered.LOG)
|
||||
|
||||
title="### $(cat VERSION) ${MATRIX_OS} ${MATRIX_TC} ${MATRIX_PKGS} :: "
|
||||
if [ "$error_count" -gt 0 ]
|
||||
then
|
||||
title="$title $error_count error(s)"
|
||||
fi
|
||||
if [ "$filtered_warning_count" -gt 0 ]
|
||||
then
|
||||
title="$title $filtered_warning_count warning(s)"
|
||||
fi
|
||||
|
||||
(
|
||||
total_error_count=$( wc -l MAKE_error.LOG | cut -d' ' -f1)
|
||||
total_warning_count=$(wc -l MAKE_warning.LOG | cut -d' ' -f1)
|
||||
echo "$title"
|
||||
echo ""
|
||||
echo "PACKAGE_LIST=$PACKAGE_LIST"
|
||||
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS"
|
||||
echo ""
|
||||
if [ "$BUILD_CLANG_VERSION" ]
|
||||
then
|
||||
"clang-${BUILD_CLANG_VERSION}" --version | head -n1
|
||||
if ! update-alternatives --list clang
|
||||
then
|
||||
update-alternatives --list "clang-${BUILD_CLANG_VERSION}"
|
||||
fi
|
||||
else
|
||||
gcc --version | head -n1
|
||||
if ! update-alternatives --list gcc
|
||||
then
|
||||
update-alternatives --list "gcc-${BUILD_GCC_VERSION}"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
echo "total ${total_error_count} error(s) ${total_warning_count} warning(s) :"
|
||||
echo "|Count|Warning Group (-j build log inaccuracies)|"
|
||||
echo "|--:|:--|"
|
||||
# due to -j build the log lines might get corrupted, so missing/incorrect/bogus entries might be seen
|
||||
# so we add extra: egrep "\[\-W.*\]" (to try to remove that)
|
||||
sed -e 's#.*\(\[\-W\)#\1#' -e 's#\(\]\).*$#\1#' MAKE_warning.LOG | egrep "\[\-W.*\]" | sort | uniq -c | sort -n | tr -s ' ' | tr ' ' '|' | awk '{print $0"|"}'
|
||||
echo ""
|
||||
sed -e '0,/Configuration Summary/d' -e '/\---/,//d' CONFIGURE.LOG | egrep "^.*:"
|
||||
echo ""
|
||||
grep DCAD_DIR MAKE.LOG | tail -n1
|
||||
) >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: CI-aarch64
|
||||
|
||||
# Controls when the workflow will run
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
simple_build_linux_arm:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Get Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y tcl-dev tk-dev libcairo-dev
|
||||
- name: Build
|
||||
run: |
|
||||
./configure
|
||||
make database/database.h
|
||||
make -j$(nproc)
|
||||
simple_build_wasm_arm:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Get Dependencies
|
||||
run: |
|
||||
git clone https://github.com/emscripten-core/emsdk.git
|
||||
cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
- name: Build
|
||||
run: |
|
||||
source ./emsdk/emsdk_env.sh
|
||||
emconfigure ./configure --without-cairo --without-opengl --without-x --disable-readline --disable-compression --target=asmjs-unknown-emscripten
|
||||
echo "===== defs.mak ====="
|
||||
cat defs.mak
|
||||
echo "===== defs.mak ====="
|
||||
emmake make
|
||||
- name: archive wasm bundle
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: magic-wasm-bundle-arm
|
||||
path: |
|
||||
${{ github.workspace }}/magic/magic.wasm
|
||||
|
|
@ -0,0 +1,475 @@
|
|||
# This is a basic workflow to help you get started with Actions
|
||||
|
||||
name: CI-macos
|
||||
|
||||
# Controls when the workflow will run
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
simple_build_macos15:
|
||||
runs-on: macos-15-intel # only and last supported intel MacOS
|
||||
timeout-minutes: 45 # x86_64 seems non-SSD based (slower)
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get Dependencies
|
||||
shell: bash # default shell has unwanted broken pipe indication
|
||||
run: |
|
||||
brew install --cask xquartz
|
||||
PACKAGE_LIST="xquartz"
|
||||
brew install cairo tcl-tk@8 tcsh gnu-sed
|
||||
_package_list="cairo tcl-tk@8 tcsh gnu-sed"
|
||||
# These seem needed maybe they are being provided from somewhere else GHA runner
|
||||
# or brew transitive depend either way doesn't hurt to confirm they are installed.
|
||||
_package_list="$_package_list libglu freeglut"
|
||||
if [ -n "$PACKAGE_LIST" ]
|
||||
then
|
||||
brew install $PACKAGE_LIST
|
||||
fi
|
||||
PACKAGE_LIST="$PACKAGE_LIST $_package_list"
|
||||
echo "PACKAGE_LIST=$PACKAGE_LIST" >> $GITHUB_ENV
|
||||
echo "UNAME_M=$(uname -m)" >> $GITHUB_ENV
|
||||
set +e
|
||||
set +o pipefail # macosx this is on by default (turn it off)
|
||||
(
|
||||
echo "### $(uname -s) $(uname -m) $(uname -r)"
|
||||
echo ""
|
||||
set +e
|
||||
set +o pipefail # macosx this is on by default (turn it off)
|
||||
export HOMEBREW_NO_COLOR=true
|
||||
export HOMEBREW_NO_EMOKI=true
|
||||
# output to $TMPFILE first, then head, instead of using pipeline directly
|
||||
# this removes unwanted GHA SIGPIPE error/warning indicators from GHA logs
|
||||
# brew maybe a nodejs command which has a known issue in this area on macosx
|
||||
TMPFILE=/tmp/shell0$$.tmp
|
||||
brew info xquartz > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info cairo > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info libglu > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info freeglut > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info tcsh > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info gnu-sed > $TMPFILE && head -n1 $TMPFILE
|
||||
echo ""
|
||||
cc -v 2>&1
|
||||
echo ""
|
||||
xcodebuild -version
|
||||
echo ""
|
||||
xcodebuild -showsdks | grep macOS
|
||||
) >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Search
|
||||
run: |
|
||||
set +e
|
||||
( # designed to speed up this process in a single scan
|
||||
echo "#!/bin/sh"
|
||||
echo "echo \$*"
|
||||
echo "ls -ld -- \$*"
|
||||
echo "shasum -a 1 \$* </dev/null"
|
||||
echo "echo \"\""
|
||||
echo "exit 0"
|
||||
) > search.sh
|
||||
echo "=== search.sh"
|
||||
cat search.sh
|
||||
chmod a+x search.sh
|
||||
find /opt /usr $HOME \( -iname "libX11.*dylib" -or -iname "Xlib.h" -or -iname "libtcl*dylib" -or -iname "tcl.h" \) -exec ./search.sh {} \; 2>/dev/null
|
||||
#
|
||||
# Example symbols that were found missing from the tcl-tk X11 implementation
|
||||
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XCreateGC" {} \; 2>/dev/null || true
|
||||
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XGetVisualInfo" {} \; 2>/dev/null || true
|
||||
#for i in /usr/X11/include/X11/Xlib.h /opt/X11/include/X11/Xlib.h /usr/local/include/X11/Xlib.h;
|
||||
#do
|
||||
# echo "====== $i"
|
||||
# head -n 50 "$i"
|
||||
# echo "==="
|
||||
# tail -n 50 "$i"
|
||||
# echo "======"
|
||||
#done
|
||||
|
||||
# Different GHA platforms have different layouts (x86_64/arm64)
|
||||
echo "=== /opt"
|
||||
ls -l /opt
|
||||
if [ -d /opt/homebrew ]
|
||||
then
|
||||
echo "=== /opt/homebrew"
|
||||
ls -l /opt/homebrew
|
||||
fi
|
||||
echo "=== /usr/local/opt"
|
||||
ls -l /usr/local/opt
|
||||
echo "=== /usr/local/opt/runner"
|
||||
ls -l /usr/local/opt/runner
|
||||
|
||||
echo "Done"
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export PATH="/opt/X11/bin:$PATH"
|
||||
./scripts/configure_mac 2>&1 | tee CONFIGURE.LOG
|
||||
|
||||
config_log=""
|
||||
if [ -f scripts/config.log ]
|
||||
then
|
||||
config_log="scripts/config.log"
|
||||
elif [ -f build-magic/config.log ]
|
||||
then
|
||||
config_log="build-magic/config.log"
|
||||
fi
|
||||
if [ -n "$config_log" ]
|
||||
then
|
||||
CONFIGURE_ARGS=$(head -n 10 $config_log | egrep "./configure" | sed -e 's#^ *\$ ##' -e 's#./configure ##')
|
||||
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
echo "===== defs.mak ====="
|
||||
cat defs.mak
|
||||
echo "===== defs.mak ====="
|
||||
|
||||
make database/database.h
|
||||
make -j$(sysctl -n hw.ncpu) 2>&1 | tee MAKE.LOG
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
sudo make install
|
||||
|
||||
- name: Kick The Tyres
|
||||
run: |
|
||||
set +e
|
||||
echo "=== ls -l"
|
||||
ls -l
|
||||
find . -type f \( -name "*.dylib" -or -name "magic" -or -name "magicexec" -or -name "magicdnull" \)
|
||||
echo "=== find /usr/local/bin"
|
||||
find /usr/local/bin -mtime 0
|
||||
echo "=== find /usr/local/share"
|
||||
find /usr/local/share -mtime 0
|
||||
echo "=== find /usr/local/lib/magic"
|
||||
find /usr/local/lib/magic -mtime 0
|
||||
echo "=== otool -L magic/tclmagic.dylib"
|
||||
otool -L magic/tclmagic.dylib
|
||||
echo "=== otool -L tcltk/magicexec"
|
||||
otool -L tcltk/magicexec
|
||||
echo "=== otool -L tcltk/magicdnull"
|
||||
otool -L tcltk/magicdnull
|
||||
|
||||
set +o pipefail # macosx this is on by default (turn it off)
|
||||
|
||||
echo "=== magic --version"
|
||||
magic --version
|
||||
echo "=== magic -d help -noconsole"
|
||||
magic -d help -noconsole
|
||||
echo "=== magic -d null -noconsole -nowindow -T scmos"
|
||||
echo "version ; quit" | magic -d null -noconsole -nowindow -T scmos
|
||||
echo "=== magic -d null -noconsole -T scmos"
|
||||
echo "version ; quit" | magic -d null -noconsole -T scmos
|
||||
|
||||
- name: Summary
|
||||
if: always()
|
||||
run: |
|
||||
set +e
|
||||
|
||||
ls -l
|
||||
|
||||
touch MAKE.LOG # just in case it did not even build
|
||||
grep "error:" MAKE.LOG > MAKE_error.LOG
|
||||
grep "warning:" MAKE.LOG > MAKE_warning.LOG
|
||||
|
||||
# Less important warnings relating to codesmell more than security (filter out of headline)
|
||||
grep -v "Wunused-variable" MAKE_warning.LOG |
|
||||
grep -v "Wunused-local-typedefs" |
|
||||
grep -v "Wunused-label" |
|
||||
grep -v "Wunused-but-set-variable" > MAKE_warning_filtered.LOG
|
||||
|
||||
wc -l *.LOG
|
||||
|
||||
error_count=$( grep -c "error:" MAKE_error.LOG)
|
||||
filtered_warning_count=$(grep -c "warning:" MAKE_warning_filtered.LOG)
|
||||
|
||||
title="### $(cat VERSION) ${MATRIX_OS} ${MATRIX_TC} ${MATRIX_PKGS} :: "
|
||||
if [ "$error_count" -gt 0 ]
|
||||
then
|
||||
title="$title $error_count error(s)"
|
||||
fi
|
||||
if [ "$filtered_warning_count" -gt 0 ]
|
||||
then
|
||||
title="$title $filtered_warning_count warning(s)"
|
||||
fi
|
||||
|
||||
(
|
||||
total_error_count=$( wc -l MAKE_error.LOG | cut -d' ' -f1)
|
||||
total_warning_count=$(wc -l MAKE_warning.LOG | cut -d' ' -f1)
|
||||
echo "---"
|
||||
echo "$title"
|
||||
echo ""
|
||||
[ -f scripts/config.log ] && grep "./configure" scripts/config.log | head -n1
|
||||
echo ""
|
||||
echo "PACKAGE_LIST=$PACKAGE_LIST"
|
||||
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS"
|
||||
echo ""
|
||||
if [ -s MAKE.LOG ]
|
||||
then
|
||||
echo "total ${total_error_count} error(s) ${total_warning_count} warning(s) :"
|
||||
echo "|Count|Warning Group (-j build log inaccuracies)|"
|
||||
echo "|--:|:--|"
|
||||
# due to -j build the log lines might get corrupted, so missing/incorrect/bogus entries might be seen
|
||||
# so we add extra: egrep "\[\-W.*\]" (to try to remove that)
|
||||
sed -e 's#.*\(\[\-W\)#\1#' -e 's#\(\]\).*$#\1#' MAKE_warning.LOG | egrep "\[\-W.*\]" | sort | uniq -c | sort -n | tr -s ' ' | tr ' ' '|' | awk '{print $0"|"}'
|
||||
echo ""
|
||||
fi
|
||||
grep -A100 "Configuration Summary" CONFIGURE.LOG | grep -v "Configuration Summary" | egrep "^.*:" | sed -e '/\---/,//d'
|
||||
echo ""
|
||||
grep DCAD_DIR MAKE.LOG | tail -n1
|
||||
) >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Prepare archive
|
||||
run: |
|
||||
mkdir -p dist
|
||||
make install "DESTDIR=$(pwd)/dist"
|
||||
# Diagnostic details about this build
|
||||
mkdir -p dist/BUILD-INFO
|
||||
set +e
|
||||
cp */config.log dist/BUILD-INFO/
|
||||
cp *.mak dist/BUILD-INFO/
|
||||
cp *.LOG dist/BUILD-INFO/
|
||||
|
||||
- name: Upload archive magic-macos15
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: magic-macos15
|
||||
path: |
|
||||
${{ github.workspace }}/dist
|
||||
|
||||
simple_build_macos:
|
||||
runs-on: macos-latest
|
||||
timeout-minutes: 30 # arm64 seems SSD based (faster)
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get Dependencies
|
||||
shell: bash # default shell has unwanted broken pipe indication
|
||||
run: |
|
||||
brew install --cask xquartz
|
||||
PACKAGE_LIST="xquartz"
|
||||
brew install cairo tcl-tk@8 tcsh gnu-sed
|
||||
_package_list="cairo tcl-tk@8 tcsh gnu-sed"
|
||||
# These seem needed maybe they are being provided from somewhere else GHA runner
|
||||
# or brew transitive depend either way doesn't hurt to confirm they are installed.
|
||||
_package_list="$_package_list libglu freeglut"
|
||||
if [ -n "$PACKAGE_LIST" ]
|
||||
then
|
||||
brew install $PACKAGE_LIST
|
||||
fi
|
||||
PACKAGE_LIST="$PACKAGE_LIST $_package_list"
|
||||
echo "PACKAGE_LIST=$PACKAGE_LIST" >> $GITHUB_ENV
|
||||
echo "UNAME_M=$(uname -m)" >> $GITHUB_ENV
|
||||
set +e
|
||||
set +o pipefail # macosx this is on by default (turn it off)
|
||||
(
|
||||
echo "### $(uname -s) $(uname -m) $(uname -r)"
|
||||
echo ""
|
||||
set +e
|
||||
set +o pipefail # macosx this is on by default (turn it off)
|
||||
export HOMEBREW_NO_COLOR=true
|
||||
export HOMEBREW_NO_EMOKI=true
|
||||
# output to $TMPFILE first, then head, instead of using pipeline directly
|
||||
# this removes unwanted GHA SIGPIPE error/warning indicators from GHA logs
|
||||
# brew maybe a nodejs command which has a known issue in this area on macosx
|
||||
TMPFILE=/tmp/shell0$$.tmp
|
||||
brew info xquartz > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info cairo > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info libglu > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info freeglut > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info tcsh > $TMPFILE && head -n1 $TMPFILE
|
||||
brew info gnu-sed > $TMPFILE && head -n1 $TMPFILE
|
||||
echo ""
|
||||
cc -v 2>&1
|
||||
echo ""
|
||||
xcodebuild -version
|
||||
echo ""
|
||||
xcodebuild -showsdks | grep macOS
|
||||
) >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Search
|
||||
run: |
|
||||
set +e
|
||||
( # designed to speed up this process in a single scan
|
||||
echo "#!/bin/sh"
|
||||
echo "echo \$*"
|
||||
echo "ls -ld -- \$*"
|
||||
echo "shasum -a 1 \$* </dev/null"
|
||||
echo "echo \"\""
|
||||
echo "exit 0"
|
||||
) > search.sh
|
||||
echo "=== search.sh"
|
||||
cat search.sh
|
||||
chmod a+x search.sh
|
||||
find /opt /usr $HOME \( -iname "libX11.*dylib" -or -iname "Xlib.h" -or -iname "libtcl*dylib" -or -iname "tcl.h" \) -exec ./search.sh {} \; 2>/dev/null
|
||||
#
|
||||
# Example symbols that were found missing from the tcl-tk X11 implementation
|
||||
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XCreateGC" {} \; 2>/dev/null || true
|
||||
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XGetVisualInfo" {} \; 2>/dev/null || true
|
||||
#for i in /usr/X11/include/X11/Xlib.h /opt/X11/include/X11/Xlib.h /usr/local/include/X11/Xlib.h;
|
||||
#do
|
||||
# echo "====== $i"
|
||||
# head -n 50 "$i"
|
||||
# echo "==="
|
||||
# tail -n 50 "$i"
|
||||
# echo "======"
|
||||
#done
|
||||
|
||||
# Different GHA platforms have different layouts (x86_64/arm64)
|
||||
echo "=== /opt"
|
||||
ls -l /opt
|
||||
if [ -d /opt/homebrew ]
|
||||
then
|
||||
echo "=== /opt/homebrew"
|
||||
ls -l /opt/homebrew
|
||||
fi
|
||||
echo "=== /usr/local/opt"
|
||||
ls -l /usr/local/opt
|
||||
echo "=== /usr/local/opt/runner"
|
||||
ls -l /usr/local/opt/runner
|
||||
|
||||
echo "Done"
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
export PATH="/opt/X11/bin:$PATH"
|
||||
./scripts/configure_mac 2>&1 | tee CONFIGURE.LOG
|
||||
|
||||
config_log=""
|
||||
if [ -f scripts/config.log ]
|
||||
then
|
||||
config_log="scripts/config.log"
|
||||
elif [ -f build-magic/config.log ]
|
||||
then
|
||||
config_log="build-magic/config.log"
|
||||
fi
|
||||
if [ -n "$config_log" ]
|
||||
then
|
||||
CONFIGURE_ARGS=$(head -n 10 $config_log | egrep "./configure" | sed -e 's#^ *\$ ##' -e 's#./configure ##')
|
||||
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
echo "===== defs.mak ====="
|
||||
cat defs.mak
|
||||
echo "===== defs.mak ====="
|
||||
|
||||
make database/database.h
|
||||
make -j$(sysctl -n hw.ncpu) 2>&1 | tee MAKE.LOG
|
||||
|
||||
- name: Install
|
||||
run: |
|
||||
sudo make install
|
||||
|
||||
- name: Kick The Tyres
|
||||
run: |
|
||||
set +e
|
||||
echo "=== ls -l"
|
||||
ls -l
|
||||
find . -type f \( -name "*.dylib" -or -name "magic" -or -name "magicexec" -or -name "magicdnull" \)
|
||||
echo "=== find /usr/local/bin"
|
||||
find /usr/local/bin -mtime 0
|
||||
echo "=== find /usr/local/share"
|
||||
find /usr/local/share -mtime 0
|
||||
echo "=== find /usr/local/lib/magic"
|
||||
find /usr/local/lib/magic -mtime 0
|
||||
echo "=== otool -L magic/tclmagic.dylib"
|
||||
otool -L magic/tclmagic.dylib
|
||||
echo "=== otool -L tcltk/magicexec"
|
||||
otool -L tcltk/magicexec
|
||||
echo "=== otool -L tcltk/magicdnull"
|
||||
otool -L tcltk/magicdnull
|
||||
|
||||
set +o pipefail # macosx this is on by default (turn it off)
|
||||
|
||||
echo "=== magic --version"
|
||||
magic --version
|
||||
echo "=== magic -d help -noconsole"
|
||||
magic -d help -noconsole
|
||||
echo "=== magic -d null -noconsole -nowindow -T scmos"
|
||||
echo "version ; quit" | magic -d null -noconsole -nowindow -T scmos
|
||||
echo "=== magic -d null -noconsole -T scmos"
|
||||
echo "version ; quit" | magic -d null -noconsole -T scmos
|
||||
|
||||
- name: Summary
|
||||
if: always()
|
||||
run: |
|
||||
set +e
|
||||
|
||||
ls -l
|
||||
|
||||
touch MAKE.LOG # just in case it did not even build
|
||||
grep "error:" MAKE.LOG > MAKE_error.LOG
|
||||
grep "warning:" MAKE.LOG > MAKE_warning.LOG
|
||||
|
||||
# Less important warnings relating to codesmell more than security (filter out of headline)
|
||||
grep -v "Wunused-variable" MAKE_warning.LOG |
|
||||
grep -v "Wunused-local-typedefs" |
|
||||
grep -v "Wunused-label" |
|
||||
grep -v "Wunused-but-set-variable" > MAKE_warning_filtered.LOG
|
||||
|
||||
wc -l *.LOG
|
||||
|
||||
error_count=$( grep -c "error:" MAKE_error.LOG)
|
||||
filtered_warning_count=$(grep -c "warning:" MAKE_warning_filtered.LOG)
|
||||
|
||||
title="### $(cat VERSION) ${MATRIX_OS} ${MATRIX_TC} ${MATRIX_PKGS} :: "
|
||||
if [ "$error_count" -gt 0 ]
|
||||
then
|
||||
title="$title $error_count error(s)"
|
||||
fi
|
||||
if [ "$filtered_warning_count" -gt 0 ]
|
||||
then
|
||||
title="$title $filtered_warning_count warning(s)"
|
||||
fi
|
||||
|
||||
(
|
||||
total_error_count=$( wc -l MAKE_error.LOG | cut -d' ' -f1)
|
||||
total_warning_count=$(wc -l MAKE_warning.LOG | cut -d' ' -f1)
|
||||
echo "---"
|
||||
echo "$title"
|
||||
echo ""
|
||||
[ -f scripts/config.log ] && grep "./configure" scripts/config.log | head -n1
|
||||
echo ""
|
||||
echo "PACKAGE_LIST=$PACKAGE_LIST"
|
||||
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS"
|
||||
echo ""
|
||||
if [ -s MAKE.LOG ]
|
||||
then
|
||||
echo "total ${total_error_count} error(s) ${total_warning_count} warning(s) :"
|
||||
echo "|Count|Warning Group (-j build log inaccuracies)|"
|
||||
echo "|--:|:--|"
|
||||
# due to -j build the log lines might get corrupted, so missing/incorrect/bogus entries might be seen
|
||||
# so we add extra: egrep "\[\-W.*\]" (to try to remove that)
|
||||
sed -e 's#.*\(\[\-W\)#\1#' -e 's#\(\]\).*$#\1#' MAKE_warning.LOG | egrep "\[\-W.*\]" | sort | uniq -c | sort -n | tr -s ' ' | tr ' ' '|' | awk '{print $0"|"}'
|
||||
echo ""
|
||||
fi
|
||||
grep -A100 "Configuration Summary" CONFIGURE.LOG | grep -v "Configuration Summary" | egrep "^.*:" | sed -e '/\---/,//d'
|
||||
echo ""
|
||||
grep DCAD_DIR MAKE.LOG | tail -n1
|
||||
) >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
- name: Prepare archive
|
||||
run: |
|
||||
mkdir -p dist
|
||||
make install "DESTDIR=$(pwd)/dist"
|
||||
# Diagnostic details about this build
|
||||
mkdir -p dist/BUILD-INFO
|
||||
set +e
|
||||
cp */config.log dist/BUILD-INFO/
|
||||
cp *.mak dist/BUILD-INFO/
|
||||
cp *.LOG dist/BUILD-INFO/
|
||||
|
||||
- name: Upload archive magic-macos
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: magic-macos
|
||||
path: |
|
||||
${{ github.workspace }}/dist
|
||||
|
|
@ -17,35 +17,45 @@ jobs:
|
|||
steps:
|
||||
- name: Pulling the docker image
|
||||
run: docker pull vezzal/vezzal:v1
|
||||
|
||||
|
||||
- name: Start the container with the docker image
|
||||
run: docker run -id --name test_magic vezzal/vezzal:v1 bash | exit
|
||||
|
||||
|
||||
- name: Run the testing on the container and send the mail
|
||||
run: docker exec test_magic /vezzal/test_magic.sh "lankasaicharan123@gmail.com,tim@opencircuitdesign.com" ${{secrets.MAILING_KEY}}
|
||||
simple_build_linux:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
- name: Get Dependencies
|
||||
run: |
|
||||
sudo apt-get install -y tcl-dev tk-dev libcairo-dev csh
|
||||
sudo apt-get install -y tcl-dev tk-dev libcairo-dev
|
||||
- name: Build
|
||||
run: |
|
||||
./configure
|
||||
make database/database.h
|
||||
make -j$(nproc)
|
||||
# simple_build_mac:
|
||||
# runs-on: macos-11
|
||||
# steps:
|
||||
# - uses: actions/checkout@v2
|
||||
# - name: Get Dependencies
|
||||
# run: |
|
||||
# brew install --cask xquartz
|
||||
# brew install cairo tcl-tk tcsh
|
||||
# - name: Build
|
||||
# run: |
|
||||
# export PATH="/opt/X11/bin:$PATH"
|
||||
# ./scripts/configure_mac
|
||||
# make database/database.h
|
||||
# make -j$(sysctl -n hw.ncpu)
|
||||
simple_build_wasm:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Get Dependencies
|
||||
run: |
|
||||
git clone https://github.com/emscripten-core/emsdk.git
|
||||
cd emsdk
|
||||
./emsdk install latest
|
||||
./emsdk activate latest
|
||||
- name: Build
|
||||
run: |
|
||||
source ./emsdk/emsdk_env.sh
|
||||
emconfigure ./configure --without-cairo --without-opengl --without-x --disable-readline --disable-compression --target=asmjs-unknown-emscripten
|
||||
echo "===== defs.mak ====="
|
||||
cat defs.mak
|
||||
echo "===== defs.mak ====="
|
||||
emmake make
|
||||
- name: archive wasm bundle
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: magic-wasm-bundle
|
||||
path: |
|
||||
${{ github.workspace }}/magic/magic.wasm
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ database/database.h
|
|||
install.log
|
||||
magic/proto.magicrc
|
||||
make.log
|
||||
readline/readline
|
||||
scmos/gdsquery.tech
|
||||
scmos/minimum.tech
|
||||
scmos/scmos-sub.tech
|
||||
|
|
@ -32,3 +31,4 @@ magic/tclmagic.dylib
|
|||
tcltk/magicdnull.dSYM/
|
||||
tcltk/magicexec.dSYM/
|
||||
reconfigure.sh
|
||||
pfx/
|
||||
|
|
|
|||
6
INSTALL
6
INSTALL
|
|
@ -47,6 +47,12 @@ Autoconf Capsule Summary:
|
|||
Disable threaded X11 and OpenGL graphics.
|
||||
Normally enabled.
|
||||
|
||||
--disable-compression
|
||||
Disable reading and writing of compressed
|
||||
(gzipped) GDS files and reading of compressed
|
||||
.mag files. Normally enabled, if the zlib
|
||||
development package is installed.
|
||||
|
||||
Notes to Magic maintainers:
|
||||
--------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
Get [Homebrew](https://brew.sh).
|
||||
|
||||
```sh
|
||||
brew install cairo tcl-tk tcsh
|
||||
brew install cairo tcl-tk@8 python3 gnu-sed
|
||||
brew install --cask xquartz
|
||||
./scripts/configure_mac
|
||||
# If you have both TCL8 and TCL9 installed you may need to verify which was selected.
|
||||
make database/database.h
|
||||
make -j$(sysctl -n hw.ncpu)
|
||||
make install # may need sudo depending on your setup
|
||||
|
|
@ -22,6 +23,7 @@ We are following the instructions from xschem (https://github.com/StefanSchipper
|
|||
|
||||
We are using not `opt` but `opt2` so that this Tcl does not interfere with `tcl-tk` from HomeBrew.
|
||||
|
||||
Extract the Tcl sources and then go to the unix folder and execute the following commands::
|
||||
```
|
||||
./configure --prefix=/usr/local/opt2/tcl-tk
|
||||
make
|
||||
|
|
@ -32,6 +34,13 @@ make install
|
|||
|
||||
* Download Tk from https://prdownloads.sourceforge.net/tcl/tk8.6.10-src.tar.gz
|
||||
|
||||
Extract Tk source and then go to the unix folder:
|
||||
|
||||
NOTE: before running 'make' inspect the Makefile and ensure the LIB_RUNTIME_DIR is set as follows. Make the correction if not:
|
||||
```
|
||||
LIB_RUNTIME_DIR = $(libdir)
|
||||
```
|
||||
|
||||
```
|
||||
./configure --prefix=/usr/local/opt2/tcl-tk \
|
||||
--with-tcl=/usr/local/opt2/tcl-tk/lib --with-x \
|
||||
|
|
@ -53,3 +62,18 @@ CFLAGS=-Wno-error=implicit-function-declaration
|
|||
make
|
||||
make install
|
||||
```
|
||||
|
||||
## If facing issue with layout window not opening / XQuartz:
|
||||
Make sure that the output of the following command is ```:0```.
|
||||
```
|
||||
echo $DISPLAY
|
||||
```
|
||||
if the above command doesn't display ```:0``` then add the following line in ```.zshrc```.
|
||||
```
|
||||
export PATH="/opt/X11/bin:$PATH"
|
||||
```
|
||||
Close & reopen terminal to load the path. Then set display manually to ```0``` by using the following command.
|
||||
```
|
||||
export DISPLAY=:0
|
||||
```
|
||||
Now ```echo DISPLAY``` should give ```:0``` as output.
|
||||
104
Makefile
104
Makefile
|
|
@ -4,31 +4,33 @@
|
|||
|
||||
MAGICDIR = .
|
||||
PROGRAMS = magic
|
||||
TECH = scmos
|
||||
TECHS = scmos
|
||||
LIBRARIES = database utils extflat
|
||||
MODULES = bplane cmwind commands database dbwind debug drc extflat \
|
||||
extract graphics netmenu plow resis select sim textio tiles \
|
||||
utils windows wiring
|
||||
|
||||
# This was `cat VERSION`
|
||||
VERSION := $(shell cat ${MAGICDIR}/VERSION)
|
||||
|
||||
MAKEFLAGS =
|
||||
INSTALL_CAD_DIRS = windows doc ${TECH}
|
||||
INSTALL_CAD_DIRS = windows doc ${TECHS}
|
||||
|
||||
-include defs.mak
|
||||
|
||||
all: $(ALL_TARGET)
|
||||
all: $(ALL_TARGET) techs
|
||||
|
||||
standard:
|
||||
@echo --- errors and warnings logged in file make.log
|
||||
@${MAKE} mains
|
||||
standard: mains
|
||||
|
||||
tcl:
|
||||
@echo --- errors and warnings logged in file make.log
|
||||
@${MAKE} tcllibrary
|
||||
tcl: tcllibrary
|
||||
|
||||
force: clean all
|
||||
force:
|
||||
@${MAKE} clean
|
||||
@${MAKE} all
|
||||
|
||||
defs.mak:
|
||||
@echo No \"defs.mak\" file found. Run "configure" to make one.
|
||||
@exit 1
|
||||
|
||||
config:
|
||||
${MAGICDIR}/configure
|
||||
|
|
@ -43,25 +45,56 @@ mains: database/database.h modules libs
|
|||
for dir in ${PROGRAMS}; do \
|
||||
(cd $$dir && ${MAKE} main) || exit 1; done
|
||||
|
||||
database/database.h: database/database.h.in
|
||||
database/database.h: ${MAGICDIR}/database/database.h.in
|
||||
@echo --- making header file database/database.h
|
||||
${SCRIPTS}/makedbh database/database.h.in database/database.h
|
||||
${SCRIPTS}/makedbh ${MAGICDIR}/database/database.h.in database/database.h
|
||||
|
||||
modules: database/database.h depend
|
||||
@echo --- making modules
|
||||
for dir in ${MODULES} ${PROGRAMS}; do \
|
||||
(cd $$dir && ${MAKE} module) || exit 1; done
|
||||
# tiles xyz => tiles/libtiles.o xyz/libxyz.o
|
||||
MODULES_SUBDIR := $(shell for i in ${MODULES}; do echo "$${i}/lib$${i}.o"; done)
|
||||
# tiles xyz => tiles/libtiles.a xyz/libxyz.a
|
||||
LIBS_SUBDIR := $(shell for i in ${MODULES}; do echo "$${i}/lib$${i}.a"; done)
|
||||
|
||||
libs:
|
||||
@echo --- making libraries
|
||||
for dir in ${LIBRARIES}; do \
|
||||
(cd $$dir && ${MAKE} lib) || exit 1; done
|
||||
.PHONY: FORCE
|
||||
${MODULES_SUBDIR}: FORCE
|
||||
@${MAKE} -C $(dir $@) module
|
||||
|
||||
depend: database/database.h
|
||||
.PHONY: modules
|
||||
modules: database/database.h depend ${MODULES_SUBDIR}
|
||||
|
||||
${LIBS_SUBDIR}: FORCE
|
||||
@${MAKE} -C $(dir $@) lib
|
||||
|
||||
# Force the tiles/utils modules to exist first for libdatabase.a
|
||||
.PHONY: libs
|
||||
libs: database/database.h depend tiles/libtiles.o utils/libutils.o ${LIBS_SUBDIR}
|
||||
|
||||
#
|
||||
# extcheck - utility tool
|
||||
# net2ir - utility tool
|
||||
# oa - disabled (needs 'clean' target renaming)
|
||||
SUBDIRS = bplane cmwind commands database dbwind debug drc extflat extract graphics \
|
||||
magic netmenu plow resis select sim textio tiles utils windows wiring
|
||||
|
||||
BUNDLED_MODULES = readline lisp
|
||||
|
||||
# Unique list of all subdir that might have Depend file, we have to deduplicate otherwise
|
||||
# MAKE will warning loudly. This list is somewhat empty when defs.mak does not exist
|
||||
SUBDIRS_FILTERED := $(shell echo ${MODULES} ${PROGRAMS} ${SUBDIRS} | tr ' ' '\n' | sort | uniq)
|
||||
|
||||
SUBDIRS_DEPEND = $(addsuffix /Depend, ${SUBDIRS_FILTERED})
|
||||
|
||||
${SUBDIRS_DEPEND}: database/database.h
|
||||
@echo --- making dependencies
|
||||
${RM} */Depend
|
||||
for dir in ${MODULES} ${UNUSED_MODULES} ${PROGRAMS}; do \
|
||||
(cd $$dir && ${MAKE} depend) || exit 1; done
|
||||
${MAKE} -C $(dir $@) depend
|
||||
|
||||
.PHONY: depend
|
||||
depend: defs.mak ${SUBDIRS_DEPEND}
|
||||
|
||||
.PHONY: techs
|
||||
techs: depend
|
||||
@echo --- making techs
|
||||
for dir in ${TECHS}; do \
|
||||
(cd $$dir && ${MAKE} all) || exit 1; done
|
||||
|
||||
install: $(INSTALL_TARGET)
|
||||
|
||||
|
|
@ -96,7 +129,7 @@ install-tcl-real: install-tcl-dirs
|
|||
(cd $$dir && ${MAKE} install-tcl); done
|
||||
|
||||
clean:
|
||||
for dir in ${MODULES} ${PROGRAMS} ${TECH} ${UNUSED_MODULES}; do \
|
||||
for dir in ${SUBDIRS_FILTERED} ${TECHS} ${BUNDLED_MODULES}; do \
|
||||
(cd $$dir && ${MAKE} clean); done
|
||||
${RM} *.tmp */*.tmp *.sav */*.sav *.log TAGS tags
|
||||
|
||||
|
|
@ -106,18 +139,19 @@ distclean:
|
|||
${RM} defs.mak old.defs.mak ${MAGICDIR}/scripts/defs.mak
|
||||
${RM} ${MAGICDIR}/scripts/default.conf
|
||||
${RM} ${MAGICDIR}/scripts/config.log ${MAGICDIR}/scripts/config.status
|
||||
${RM} scripts/magic.spec magic-`cat VERSION` magic-`cat VERSION`.tgz
|
||||
${RM} *.log */Depend
|
||||
${RM} database/database.h
|
||||
${RM} scripts/magic.spec magic-${VERSION} magic-${VERSION}.tgz
|
||||
${RM} *.log
|
||||
|
||||
dist:
|
||||
${RM} scripts/magic.spec magic-`cat VERSION` magic-`cat VERSION`.tgz
|
||||
sed -e /@VERSION@/s%@VERSION@%`cat VERSION`% \
|
||||
${RM} scripts/magic.spec magic-${VERSION} magic-${VERSION}.tgz
|
||||
${SED} -e /@VERSION@/s%@VERSION@%${VERSION}% \
|
||||
scripts/magic.spec.in > scripts/magic.spec
|
||||
ln -nsf . magic-`cat VERSION`
|
||||
tar zchvf magic-`cat VERSION`.tgz --exclude CVS \
|
||||
--exclude magic-`cat VERSION`/magic-`cat VERSION` \
|
||||
--exclude magic-`cat VERSION`/magic-`cat VERSION`.tgz \
|
||||
magic-`cat VERSION`
|
||||
${LN} -nsf . magic-${VERSION}
|
||||
tar zchvf magic-${VERSION}.tgz --exclude CVS \
|
||||
--exclude magic-${VERSION}/magic-${VERSION} \
|
||||
--exclude magic-${VERSION}/magic-${VERSION}.tgz \
|
||||
magic-${VERSION}
|
||||
|
||||
clean-mains:
|
||||
for dir in ${PROGRAMS}; do \
|
||||
|
|
@ -134,6 +168,6 @@ TAGS:
|
|||
setup-git:
|
||||
git config --local include.path ../.gitconfig
|
||||
git stash save
|
||||
rm .git/index
|
||||
${RM} .git/index
|
||||
git checkout HEAD -- "$$(git rev-parse --show-toplevel)"
|
||||
git stash pop
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
FROM almalinux:10
|
||||
|
||||
USER root
|
||||
|
||||
# Build Dependencies (and dump version to logging)
|
||||
RUN dnf install -y python3 zlib-devel ncurses-devel readline-devel cairo-devel freeglut-devel \
|
||||
mesa-libGLU-devel mesa-libGL-devel libX11-devel libstdc++-devel gcc gcc-c++ make git tcsh \
|
||||
zip \
|
||||
&& echo "### rpm -qa:" \
|
||||
&& rpm -qa | sort \
|
||||
&& echo ""
|
||||
#RUN dnf group install -y "Development Tools"
|
||||
|
||||
# Tcl/Tk
|
||||
WORKDIR /tcl
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl9.0.1-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix \
|
||||
&& make \
|
||||
&& make install install-libraries install-msgs install-tzdata
|
||||
|
||||
WORKDIR /tk
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tk9.0.1-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib \
|
||||
&& make \
|
||||
&& make install install-libraries
|
||||
|
||||
WORKDIR /prefix/bin
|
||||
RUN cp ./wish9.0 ./wish
|
||||
RUN cp ./tclsh9.0 ./tclsh
|
||||
|
||||
# Magic
|
||||
WORKDIR /magic
|
||||
COPY . .
|
||||
|
||||
RUN ./configure \
|
||||
--prefix=/prefix \
|
||||
--with-tcl=/prefix/lib \
|
||||
--with-tk=/prefix/lib \
|
||||
&& make clean \
|
||||
&& make database/database.h \
|
||||
&& make -j$(nproc) \
|
||||
&& make install
|
||||
|
||||
# Produce summary of what was created and confirm their DSOs
|
||||
RUN echo "### filesystem:" \
|
||||
find /prefix -printf "%y/%M/%m %i/%n %l %u/%U %g/%G %s/%b %T+/%T@\t%p\n"; \
|
||||
ls -lR /prefix; \
|
||||
find /prefix -type f -perm /111 -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
for name in libgcc_s libstdc++ libpng liblzma libxml2 libz libcairo libGL libGLU; do \
|
||||
find /lib64 /usr/lib64 -maxdepth 2 -name "*.so" -name "${name}*" -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
done; \
|
||||
echo "###"
|
||||
|
||||
WORKDIR /
|
||||
RUN tar -czf /prefix.tar.gz -C ./prefix .
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
MAGIC_SRC_ROOT = ../..
|
||||
RESOURCES := $(shell find ../rsc/ -type f)
|
||||
ARCH := $(shell uname -m)
|
||||
APPIMAGE = Magic-$(ARCH).AppImage
|
||||
VERSION_MAGIC := $(shell cat $(MAGIC_SRC_ROOT)/VERSION)
|
||||
VERSION_TSTAMP := $(shell git show -s "--format=%cs" | tr -d '-')
|
||||
VERSION_HASH := $(shell git show -s "--format=%h")
|
||||
VERSION_NUM ?= $(VERSION_MAGIC)~$(VERSION_TSTAMP)~$(VERSION_HASH)
|
||||
VERSION := $(VERSION_NUM)
|
||||
|
||||
# Allow CI to override
|
||||
APPIMAGETOOL_DOWNLOAD_URL ?= https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
all: $(APPIMAGE)
|
||||
|
||||
.PHONY: prefix/bin/magic
|
||||
prefix/bin/magic: Dockerfile Makefile
|
||||
@echo "APPIMAGE=$(APPIMAGE)"
|
||||
@echo "VERSION=$(VERSION)"
|
||||
@echo "ARCH=$(ARCH)"
|
||||
@echo "RESOURCES=$(RESOURCES)"
|
||||
rm -rf prefix
|
||||
docker build -t magic_build -f ./Dockerfile $(MAGIC_SRC_ROOT)
|
||||
id=$$(docker create magic_build) ; \
|
||||
docker cp $$id:/prefix ./prefix ; \
|
||||
docker rm -v $$id
|
||||
mkdir -p prefix/lib/tcl9.0.1
|
||||
cp -r prefix/lib/tcl9.0 prefix/lib/tcl9.0.1/library
|
||||
|
||||
appimagetool:
|
||||
curl -L "$(APPIMAGETOOL_DOWNLOAD_URL)" > ./appimagetool
|
||||
chmod +x ./appimagetool
|
||||
|
||||
$(APPIMAGE): prefix/bin/magic appimagetool $(RESOURCES)
|
||||
cp $(RESOURCES) ./prefix/
|
||||
./appimagetool prefix
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
install:
|
||||
install $(APPIMAGE) $(PREFIX)/bin/magic
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.AppImage
|
||||
rm -f prefix.tar.gz
|
||||
rm -rf prefix
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
This is an AppImage that runs on all GNU/Linux platforms with:
|
||||
|
||||
* FUSE
|
||||
* This excludes non-privileged Docker containers unfortunately, unless pre-extracted.
|
||||
* GLIBC 2.38+
|
||||
* Cairo 1.18+
|
||||
* May require runtime CPU matching Linux ABI x86-64-v3 and newer (CPUs with SSE4.2/AVX2/BMI2/FMA via `lscpu`).
|
||||
|
||||
This AppImage build is based on EL10 (via AlmaLinux 10).
|
||||
|
||||
AlmaLinux 10 was first released on 27 May 2025.
|
||||
|
||||
# Version Info
|
||||
|
||||
See the AppImage main binary file naming, release tag information and AppInfo metadata
|
||||
for the exact magic version inside the archive. When starting AppImage by default the
|
||||
Tcl console banner can also provide version information, also using the `version` Tcl
|
||||
command.
|
||||
|
||||
# Build Info
|
||||
|
||||
* Based on AlmaLinux 10 (EL10)
|
||||
* Tcl/Tk 9.0.1
|
||||
* and Magic 8.x
|
||||
* all default modules enabled (including all Display drivers cairo/X11/OpenGL)
|
||||
|
||||
# FAQ: How to use
|
||||
|
||||
Download the *.AppImage file relevant to your platform and run:
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
./Magic-x86_64.AppImage
|
||||
```
|
||||
|
||||
Example startup with command line options:
|
||||
|
||||
```
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# FAQ: How to use (inside docker / podman)
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
|
||||
### Podman or Docker, use :Z when rootless with selinux enabled
|
||||
podman run --rm --device /dev/fuse --privileged \
|
||||
-v "$(pwd):/tmp/work:Z" -v "/tmp/.X11-unix/X0:/tmp/.X11-unix/X0:Z" \
|
||||
-e DISPLAY -ti almalinux:10
|
||||
|
||||
### Inside Docker:
|
||||
dnf update -y
|
||||
|
||||
dnf install -y fuse libX11 cairo libGL libGLU
|
||||
|
||||
cd /tmp/work
|
||||
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# Building Requirements
|
||||
|
||||
* A reasonably recent GNU/Linux host
|
||||
* GNU make
|
||||
* Docker 20+
|
||||
* Git
|
||||
* curl
|
||||
|
||||
The final build is then packaged into an AppImage using AppImageTool on the host machine.
|
||||
|
||||
# Build Instructions
|
||||
`make`
|
||||
|
||||
# Installation Instructions
|
||||
`make install`
|
||||
|
||||
# FAQ: Is my CPU supported ?
|
||||
|
||||
This is built with the standard x86_64 Linux ABI version for AlmaLinux 10.
|
||||
|
||||
Use the command `/lib64/ld-linux-x86-64.so.2 --help` to see which CPUs your
|
||||
Linux distribtion supports (and your CPU) look for the word "supported".
|
||||
|
||||
# FAQ: The DSO versioning link dependencies?
|
||||
|
||||
The information here provides an outline of what versions to expect from EL10
|
||||
of the major dependencies, to assist you in a compatibility check with your
|
||||
Linux distribution of choice.
|
||||
|
||||
The actual versions in our public releases can differ slightly inline with
|
||||
the EL10 support compatibility and ABI versioning policies for the support
|
||||
lifecycle of the distribution.
|
||||
|
||||
The most important items are the Direct Dependencies and the availabilty
|
||||
of a suitable graphics DSO as per your '-d' choice.
|
||||
|
||||
Direct Runtime Dependencies (from /prefix/**):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libc.so.6 | GLIBC_2.38 | glibc-2.39-37 |
|
||||
| libz.so.1 | ZLIB_1.2.2 | zlib-ng-2.2.3-1 |
|
||||
| | | zlib-ng-compat-2.2.3-1 |
|
||||
|
||||
Optional/Modular Runtime Dependencies (depending on graphics mode):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libcairo.so.2 | | |
|
||||
| libcairo.so.2.11802.0 | | cairo-1.18.2-2 |
|
||||
| libGL.so.1 | | libglvnd-glx-1:1.7.0-7 |
|
||||
| | | mesa-libGL-24.2.8-2 |
|
||||
| libGLU.so.1 | | mesa-libGLU-9.0.3-7 |
|
||||
|
||||
Transitive/Third-Party Runtime Dependencies (for information only):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libstdc++.so.6 | CXXABI_1.3.9 | gcc-c++-14.2.1-7 |
|
||||
| libstdc++.so.6 | GLIBCXX_3.4 | gcc-c++-14.2.1-7 |
|
||||
| libgcc_s.so.1 | GCC_4.2.0 | libgcc_s-14-20250110 |
|
||||
| libxml2.so.2 | LIBXML2_2.6.0 | libxml2-2.12.5-5 |
|
||||
| libpng16.so.16 | PNG16_0 | libpng-2:1.6.40-8 |
|
||||
| liblzma.so.5 | XZ_5.0 | xz-devel-1:5.6.2-4 |
|
||||
| libz.so.1 | ZLIB_1.2.9 | zlib-ng-2.2.3-1 |
|
||||
| | | zlib-ng-compat-2.2.3-1 |
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
FROM centos/python-38-centos7:20210726-fad62e9
|
||||
|
||||
USER root
|
||||
|
||||
# CentOS7 went EOL on June 30, 2024 this builds out of vault.centos.org
|
||||
RUN ls -l /etc/yum.repos.d/ \
|
||||
&& cp /etc/yum.repos.d/CentOS-Base.repo /tmp/CentOS-Base.repo.old \
|
||||
&& sed -e 's/mirror.centos.org/vault.centos.org/g' -i /etc/yum.repos.d/*.repo \
|
||||
&& sed -e 's/^#.*baseurl=http/baseurl=http/g' -i /etc/yum.repos.d/*.repo \
|
||||
&& sed -e 's/^mirrorlist=http/#mirrorlist=http/g' -i /etc/yum.repos.d/*.repo \
|
||||
&& diff -u /tmp/CentOS-Base.repo.old /etc/yum.repos.d/CentOS-Base.repo; \
|
||||
yum clean all \
|
||||
&& yum -y update \
|
||||
&& rm -f /tmp/CentOS-Base.repo.old
|
||||
|
||||
# Build Dependencies (and dump version to logging)
|
||||
RUN yum install -y cairo-devel freeglut-devel gcc make tcsh \
|
||||
&& echo "### rpm -qa:" \
|
||||
&& rpm -qa | sort \
|
||||
&& echo ""
|
||||
|
||||
# Tcl/Tk
|
||||
WORKDIR /tcl
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
WORKDIR /tk
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tk8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
WORKDIR /prefix/bin
|
||||
RUN cp ./wish8.6 ./wish
|
||||
RUN cp ./tclsh8.6 ./tclsh
|
||||
|
||||
# Magic
|
||||
WORKDIR /magic
|
||||
COPY . .
|
||||
|
||||
RUN ./configure \
|
||||
--prefix=/prefix \
|
||||
--with-tcl=/prefix/lib \
|
||||
--with-tk=/prefix/lib \
|
||||
--without-opengl \
|
||||
&& make clean \
|
||||
&& make database/database.h \
|
||||
&& make -j$(nproc) \
|
||||
&& make install
|
||||
|
||||
# Produce summary of what was created and confirm their DSOs
|
||||
RUN echo "### filesystem:" \
|
||||
find /prefix -printf "%y/%M/%m %i/%n %l %u/%U %g/%G %s/%b %T+/%T@\t%p\n"; \
|
||||
ls -lR /prefix; \
|
||||
find /prefix -type f -perm /111 -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
for name in libgcc_s libstdc++ libpng liblzma libxml2 libz libcairo libGL libGLU; do \
|
||||
find /lib64 /usr/lib64 -maxdepth 2 -name "*.so" -name "${name}*" -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
done; \
|
||||
echo "###"
|
||||
|
||||
WORKDIR /
|
||||
RUN tar -czf /prefix.tar.gz -C ./prefix .
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
MAGIC_SRC_ROOT = ../..
|
||||
RESOURCES := $(shell find ../rsc/ -type f)
|
||||
ARCH := $(shell uname -m)
|
||||
APPIMAGE = Magic-$(ARCH).AppImage
|
||||
VERSION_MAGIC := $(shell cat $(MAGIC_SRC_ROOT)/VERSION)
|
||||
VERSION_TSTAMP := $(shell git show -s "--format=%cs" | tr -d '-')
|
||||
VERSION_HASH := $(shell git show -s "--format=%h")
|
||||
VERSION_NUM ?= $(VERSION_MAGIC)~$(VERSION_TSTAMP)~$(VERSION_HASH)
|
||||
VERSION := $(VERSION_NUM)
|
||||
|
||||
# Allow CI to override
|
||||
APPIMAGETOOL_DOWNLOAD_URL ?= https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
all: $(APPIMAGE)
|
||||
|
||||
.PHONY: prefix/bin/magic
|
||||
prefix/bin/magic: Dockerfile Makefile
|
||||
@echo "APPIMAGE=$(APPIMAGE)"
|
||||
@echo "VERSION=$(VERSION)"
|
||||
@echo "ARCH=$(ARCH)"
|
||||
@echo "RESOURCES=$(RESOURCES)"
|
||||
rm -rf prefix
|
||||
docker build -t magic_build -f ./Dockerfile $(MAGIC_SRC_ROOT)
|
||||
id=$$(docker create magic_build) ; \
|
||||
docker cp $$id:/prefix ./prefix ; \
|
||||
docker rm -v $$id
|
||||
mkdir -p prefix/lib/tcl8.6.16
|
||||
cp -r prefix/lib/tcl8.6 prefix/lib/tcl8.6.16/library
|
||||
|
||||
appimagetool:
|
||||
curl -L "$(APPIMAGETOOL_DOWNLOAD_URL)" > ./appimagetool
|
||||
chmod +x ./appimagetool
|
||||
|
||||
$(APPIMAGE): prefix/bin/magic appimagetool $(RESOURCES)
|
||||
cp $(RESOURCES) ./prefix/
|
||||
./appimagetool prefix
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
install:
|
||||
install $(APPIMAGE) $(PREFIX)/bin/magic
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.AppImage
|
||||
rm -f prefix.tar.gz
|
||||
rm -rf prefix
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
This is an AppImage that runs on all GNU/Linux platforms with:
|
||||
|
||||
* FUSE
|
||||
* This excludes non-privileged Docker containers unfortunately, unless pre-extracted.
|
||||
* GLIBC 2.17+
|
||||
* Cairo 1.15+
|
||||
* Supports all Linux x86_64 CPUs
|
||||
|
||||
This AppImage build is based on EL7 (via CentOS 7)
|
||||
|
||||
CentOS 7 was first released on 07 July 2014 and went end-of-life on 30 June 2024.
|
||||
|
||||
# Version Info
|
||||
|
||||
See the AppImage main binary file naming, release tag information and AppInfo metadata
|
||||
for the exact magic version inside the archive. When starting AppImage by default the
|
||||
Tcl console banner can also provide version information, also using the `version` Tcl
|
||||
command.
|
||||
|
||||
# Build Info
|
||||
|
||||
* Based on CentOS 7 (EL7)
|
||||
* Tcl/Tk 8.6.16
|
||||
* and Magic 8.x
|
||||
* all default modules enabled, but without OpenGL (includes Display drivers cairo/X11)
|
||||
|
||||
# FAQ: How to use
|
||||
|
||||
Download the *.AppImage file relevant to your platform and run:
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
./Magic-x86_64.AppImage
|
||||
```
|
||||
|
||||
Example startup with command line options:
|
||||
|
||||
```
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# FAQ: How to use (inside docker / podman)
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
|
||||
### Podman or Docker, use :Z when rootless with selinux enabled
|
||||
podman run --rm --device /dev/fuse --privileged \
|
||||
-v "$(pwd):/tmp/work:Z" -v "/tmp/.X11-unix/X0:/tmp/.X11-unix/X0:Z" \
|
||||
-e DISPLAY -ti centos:7
|
||||
|
||||
### Inside Docker:
|
||||
echo "FIXUP yum from vault and update" \
|
||||
&& ls -l /etc/yum.repos.d/ \
|
||||
&& cp /etc/yum.repos.d/CentOS-Base.repo /tmp/CentOS-Base.repo.old \
|
||||
&& sed -e 's/mirror.centos.org/vault.centos.org/g' -i /etc/yum.repos.d/*.repo \
|
||||
&& sed -e 's/^#.*baseurl=http/baseurl=http/g' -i /etc/yum.repos.d/*.repo \
|
||||
&& sed -e 's/^mirrorlist=http/#mirrorlist=http/g' -i /etc/yum.repos.d/*.repo \
|
||||
&& diff -u /tmp/CentOS-Base.repo.old /etc/yum.repos.d/CentOS-Base.repo; \
|
||||
yum clean all \
|
||||
&& yum -y update \
|
||||
&& rm -f /tmp/CentOS-Base.repo.old
|
||||
|
||||
yum install -y fuse libX11 cairo
|
||||
|
||||
cd /tmp/work
|
||||
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# Building Requirements
|
||||
|
||||
* A reasonably recent GNU/Linux host
|
||||
* GNU make
|
||||
* Docker 20+
|
||||
* Git
|
||||
* curl
|
||||
|
||||
The final build is then packaged into an AppImage using AppImageTool on the host machine.
|
||||
|
||||
# Build Instructions
|
||||
`make`
|
||||
|
||||
# Installation Instructions
|
||||
`make install`
|
||||
|
||||
# FAQ: Is my CPU supported ?
|
||||
|
||||
Supports all x86_64 CPUs. The Linux ABI in use is the original x86-64 ABI (v1).
|
||||
|
||||
Use the command `/lib64/ld-linux-x86-64.so.2 --help` to see which CPUs your
|
||||
Linux distribtion supports (and your CPU) look for the word "supported".
|
||||
|
||||
# FAQ: The DSO versioning link dependencies?
|
||||
|
||||
The information here provides an outline of what versions to expect from EL7
|
||||
of the major dependencies, to assist you in a compatibility check with your
|
||||
Linux distribution of choice.
|
||||
|
||||
The actual versions in our public releases can differ slightly inline with
|
||||
the EL7 support compatibility and ABI versioning policies for the support
|
||||
lifecycle of the distribution.
|
||||
|
||||
The most important items are the Direct Dependencies and the availabilty
|
||||
of a suitable graphics DSO as per your '-d' choice.
|
||||
|
||||
Direct Runtime Dependencies (from /prefix/**):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libc.so.6 | GLIBC_2.14 | glibc-2.17-326 |
|
||||
| libz.so.1 | ZLIB_1.2.2 | zlib-1.2.7-21 |
|
||||
|
||||
Optional/Modular Runtime Dependencies (depending on graphics mode):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libcairo.so.2 | | |
|
||||
| libcairo.so.2.11512.0 | | cairo-1.15.12-4 |
|
||||
| libGL.so.1 | | |
|
||||
| libglvnd-glx-1:1.0.1-0 | | mesa-libGL-18.3.4-12 |
|
||||
| libGLU.so.1 | | mesa-libGLU-9.0.0-4 |
|
||||
|
||||
Transitive/Third-Party Runtime Dependencies (for information only):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libc.so.6 | GLIBC_2.35 | glibc-2.17-326 |
|
||||
| libstdc++.so.6 | GLIBCXX_3.4 | gcc-4.8.5-44 |
|
||||
| libstdc++.so.6 | CXXABI_1.3.9 | gcc-4.8.5-44 |
|
||||
| libgcc_s.so.1 | | |
|
||||
| libgcc_s-4.8.5-20150702.so.1 | GCC_4.2.0 | libgcc-4.8.5-44 |
|
||||
| libxml2.so.2 | LIBXML2_2.6.0 | libxml2-2.9.1-6 |
|
||||
| libpng15.so.15 | | |
|
||||
| libpng15.so.15.13.0 | PNG16_0 | libpng-1:1.5.13-8 |
|
||||
| liblzma.so.5 | XZ_5.0 | xz-libs-5.2.2-2 |
|
||||
| libz.so.1 | ZLIB_1.2.9 | zlib-1.2.7-21 |
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
FROM almalinux:8
|
||||
|
||||
USER root
|
||||
|
||||
# Build Dependencies (and dump version to logging)
|
||||
RUN dnf install -y python311 zlib-devel ncurses-devel readline-devel cairo-devel freeglut-devel \
|
||||
mesa-libGLU-devel mesa-libGL-devel libX11-devel libstdc++-devel gcc gcc-c++ make git tcsh \
|
||||
&& echo "### rpm -qa:" \
|
||||
&& rpm -qa | sort \
|
||||
&& echo ""
|
||||
#RUN dnf group install -y "Development Tools"
|
||||
|
||||
# Tcl/Tk
|
||||
WORKDIR /tcl
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
WORKDIR /tk
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tk8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
WORKDIR /prefix/bin
|
||||
RUN cp ./wish8.6 ./wish
|
||||
RUN cp ./tclsh8.6 ./tclsh
|
||||
|
||||
# Magic
|
||||
WORKDIR /magic
|
||||
COPY . .
|
||||
|
||||
RUN ./configure \
|
||||
--prefix=/prefix \
|
||||
--with-tcl=/prefix/lib \
|
||||
--with-tk=/prefix/lib \
|
||||
&& make clean \
|
||||
&& make database/database.h \
|
||||
&& make -j$(nproc) \
|
||||
&& make install
|
||||
|
||||
# Produce summary of what was created and confirm their DSOs
|
||||
RUN echo "### filesystem:" \
|
||||
find /prefix -printf "%y/%M/%m %i/%n %l %u/%U %g/%G %s/%b %T+/%T@\t%p\n"; \
|
||||
ls -lR /prefix; \
|
||||
find /prefix -type f -perm /111 -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
for name in libgcc_s libstdc++ libpng liblzma libxml2 libz libcairo libGL libGLU; do \
|
||||
find /lib64 /usr/lib64 -maxdepth 2 -name "*.so" -name "${name}*" -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
done; \
|
||||
echo "###"
|
||||
|
||||
WORKDIR /
|
||||
RUN tar -czf /prefix.tar.gz -C ./prefix .
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
MAGIC_SRC_ROOT = ../..
|
||||
RESOURCES := $(shell find ../rsc/ -type f)
|
||||
ARCH := $(shell uname -m)
|
||||
APPIMAGE = Magic-$(ARCH).AppImage
|
||||
VERSION_MAGIC := $(shell cat $(MAGIC_SRC_ROOT)/VERSION)
|
||||
VERSION_TSTAMP := $(shell git show -s "--format=%cs" | tr -d '-')
|
||||
VERSION_HASH := $(shell git show -s "--format=%h")
|
||||
VERSION_NUM ?= $(VERSION_MAGIC)~$(VERSION_TSTAMP)~$(VERSION_HASH)
|
||||
VERSION := $(VERSION_NUM)
|
||||
|
||||
# Allow CI to override
|
||||
APPIMAGETOOL_DOWNLOAD_URL ?= https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
all: $(APPIMAGE)
|
||||
|
||||
.PHONY: prefix/bin/magic
|
||||
prefix/bin/magic: Dockerfile Makefile
|
||||
@echo "APPIMAGE=$(APPIMAGE)"
|
||||
@echo "VERSION=$(VERSION)"
|
||||
@echo "ARCH=$(ARCH)"
|
||||
@echo "RESOURCES=$(RESOURCES)"
|
||||
rm -rf prefix
|
||||
docker build -t magic_build -f ./Dockerfile $(MAGIC_SRC_ROOT)
|
||||
id=$$(docker create magic_build) ; \
|
||||
docker cp $$id:/prefix ./prefix ; \
|
||||
docker rm -v $$id
|
||||
mkdir -p prefix/lib/tcl8.6.16
|
||||
cp -r prefix/lib/tcl8.6 prefix/lib/tcl8.6.16/library
|
||||
|
||||
appimagetool:
|
||||
curl -L "$(APPIMAGETOOL_DOWNLOAD_URL)" > ./appimagetool
|
||||
chmod +x ./appimagetool
|
||||
|
||||
$(APPIMAGE): prefix/bin/magic appimagetool $(RESOURCES)
|
||||
cp $(RESOURCES) ./prefix/
|
||||
./appimagetool prefix
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
install:
|
||||
install $(APPIMAGE) $(PREFIX)/bin/magic
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.AppImage
|
||||
rm -f prefix.tar.gz
|
||||
rm -rf prefix
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
This is an AppImage that runs on all GNU/Linux platforms with:
|
||||
|
||||
* FUSE
|
||||
* This excludes non-privileged Docker containers unfortunately, unless pre-extracted.
|
||||
* GLIBC 2.28+
|
||||
* Cairo 1.15+
|
||||
* Supports all Linux x86_64 CPUs
|
||||
|
||||
This AppImage build is based on EL8 (via AlmaLinux 8)
|
||||
|
||||
AlmaLinux 8 was first released on 20 March 2021, active support ends 31 May 2024,
|
||||
security support ends 31 May 2029 (please see AlmaLinux bulletins for
|
||||
up-to-date information).
|
||||
|
||||
# Version Info
|
||||
|
||||
See the AppImage main binary file naming, release tag information and AppInfo metadata
|
||||
for the exact magic version inside the archive. When starting AppImage by default the
|
||||
Tcl console banner can also provide version information, also using the `version` Tcl
|
||||
command.
|
||||
|
||||
* Based on AlmaLinux 8 (EL8)
|
||||
* Tcl/Tk 8.6.16
|
||||
* and Magic 8.x
|
||||
* all default modules enabled (including all Display drivers cairo/X11/OpenGL)
|
||||
|
||||
# FAQ: How to use
|
||||
|
||||
Download the *.AppImage file relevant to your platform and run:
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
./Magic-x86_64.AppImage
|
||||
```
|
||||
|
||||
Example startup with command line options:
|
||||
|
||||
```
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# FAQ: How to use (inside docker / podman)
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
|
||||
### Podman or Docker, use :Z when rootless with selinux enabled
|
||||
podman run --rm --device /dev/fuse --privileged \
|
||||
-v "$(pwd):/tmp/work:Z" -v "/tmp/.X11-unix/X0:/tmp/.X11-unix/X0:Z" \
|
||||
-e DISPLAY -ti almalinux:8
|
||||
|
||||
### Inside Docker:
|
||||
dnf update -y
|
||||
|
||||
dnf install -y fuse libX11 cairo libGL libGLU
|
||||
|
||||
cd /tmp/work
|
||||
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# Building Requirements
|
||||
|
||||
* A reasonably recent GNU/Linux host
|
||||
* GNU make
|
||||
* Docker
|
||||
* Git
|
||||
* curl
|
||||
|
||||
The final build is then packaged into an AppImage using AppImageTool on the host machine.
|
||||
|
||||
# Build Instructions
|
||||
`make`
|
||||
|
||||
# Installation Instructions
|
||||
`make install`
|
||||
|
||||
# FAQ: Is my CPU supported ?
|
||||
|
||||
Supports all x86_64 CPUs. The Linux ABI in use is the original x86-64 ABI (v1).
|
||||
|
||||
Use the command `/lib64/ld-linux-x86-64.so.2 --help` to see which CPUs your
|
||||
Linux distribtion supports (and your CPU) look for the word "supported".
|
||||
|
||||
# FAQ: The DSO versioning link dependencies?
|
||||
|
||||
The information here provides an outline of what versions to expect from EL8
|
||||
of the major dependencies, to assist you with a compatibility check with your
|
||||
Linux distribution of choice.
|
||||
|
||||
The actual versions in our public releases can differ slightly inline with
|
||||
the EL8 support compatibility and ABI versioning policies for the support
|
||||
lifecycle of the distribution.
|
||||
|
||||
The most important items are the Direct Dependencies and the availabilty
|
||||
of a suitable graphics DSO as per your '-d' choice.
|
||||
|
||||
Direct Runtime Dependencies (from /prefix/**):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libc.so.6 | GLIBC_2.14 | glibc-2.28-251 |
|
||||
| libz.so.1 | ZLIB_1.2.2 | zlib-1.2.11-25 |
|
||||
|
||||
Optional/Modular Runtime Dependencies (depending on graphics mode):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libcairo.so.2 | | |
|
||||
| libcairo.so.2.11512.0 | | cairo-1.15.12-6 |
|
||||
| libGL.so.1 | | libglvnd-glx-1:1.3.4-2 |
|
||||
| | | mesa-libGL-23.1.4-4 |
|
||||
| libGLU.so.1 | | mesa-libGLU-9.0.0-15 |
|
||||
|
||||
Transitive/Third-Party Runtime Dependencies (for information only):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libc.so.6 | GLIBC_2.35 | glibc-2.28-251 |
|
||||
| libstdc++.so.6 | GLIBCXX_3.4 | gcc-c++-8.5.0 |
|
||||
| libstdc++.so.6 | CXXABI_1.3.9 | gcc-c++-8.5.0 |
|
||||
| libgcc_s.so.1 | GCC_4.2.0 | libgcc-8.5.0-26 |
|
||||
| libxml2.so.2 | | libxml2-2.9.7-19 |
|
||||
| libpng16.so.16 | PNG16_0 | libpng-2:1.6.34-5 |
|
||||
| liblzma.so.5 | | xz-libs-5.2.4-4 |
|
||||
| libz.so.1 | ZLIB_1.2.9 | zlib-1.2.11-25 |
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
FROM almalinux:9
|
||||
|
||||
USER root
|
||||
|
||||
# Build Dependencies (and dump version to logging)
|
||||
RUN dnf install -y python311 zlib-devel ncurses-devel readline-devel cairo-devel freeglut-devel \
|
||||
mesa-libGLU-devel mesa-libGL-devel libX11-devel libstdc++-devel gcc gcc-c++ make git tcsh \
|
||||
zip \
|
||||
&& echo "### rpm -qa:" \
|
||||
&& rpm -qa | sort \
|
||||
&& echo ""
|
||||
#RUN dnf group install -y "Development Tools"
|
||||
|
||||
# Tcl/Tk
|
||||
WORKDIR /tcl
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl9.0.1-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix \
|
||||
&& make \
|
||||
&& make install install-libraries install-msgs install-tzdata
|
||||
|
||||
WORKDIR /tk
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tk9.0.1-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib \
|
||||
&& make \
|
||||
&& make install install-libraries
|
||||
|
||||
WORKDIR /prefix/bin
|
||||
RUN cp ./wish9.0 ./wish
|
||||
RUN cp ./tclsh9.0 ./tclsh
|
||||
|
||||
# Magic
|
||||
WORKDIR /magic
|
||||
COPY . .
|
||||
|
||||
RUN ./configure \
|
||||
--prefix=/prefix \
|
||||
--with-tcl=/prefix/lib \
|
||||
--with-tk=/prefix/lib \
|
||||
&& make clean \
|
||||
&& make database/database.h \
|
||||
&& make -j$(nproc) \
|
||||
&& make install
|
||||
|
||||
# Produce summary of what was created and confirm their DSOs
|
||||
RUN echo "### filesystem:" \
|
||||
find /prefix -printf "%y/%M/%m %i/%n %l %u/%U %g/%G %s/%b %T+/%T@\t%p\n"; \
|
||||
ls -lR /prefix; \
|
||||
find /prefix -type f -perm /111 -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
for name in libgcc_s libstdc++ libpng liblzma libxml2 libz libcairo libGL libGLU; do \
|
||||
find /lib64 /usr/lib64 -maxdepth 2 -name "*.so" -name "${name}*" -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
|
||||
done; \
|
||||
echo "###"
|
||||
|
||||
WORKDIR /
|
||||
RUN tar -czf /prefix.tar.gz -C ./prefix .
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
MAGIC_SRC_ROOT = ../..
|
||||
RESOURCES := $(shell find ../rsc/ -type f)
|
||||
ARCH := $(shell uname -m)
|
||||
APPIMAGE = Magic-$(ARCH).AppImage
|
||||
VERSION_MAGIC := $(shell cat $(MAGIC_SRC_ROOT)/VERSION)
|
||||
VERSION_TSTAMP := $(shell git show -s "--format=%cs" | tr -d '-')
|
||||
VERSION_HASH := $(shell git show -s "--format=%h")
|
||||
VERSION_NUM ?= $(VERSION_MAGIC)~$(VERSION_TSTAMP)~$(VERSION_HASH)
|
||||
VERSION := $(VERSION_NUM)
|
||||
|
||||
# Allow CI to override
|
||||
APPIMAGETOOL_DOWNLOAD_URL ?= https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
|
||||
all: $(APPIMAGE)
|
||||
|
||||
.PHONY: prefix/bin/magic
|
||||
prefix/bin/magic: Dockerfile Makefile
|
||||
@echo "APPIMAGE=$(APPIMAGE)"
|
||||
@echo "VERSION=$(VERSION)"
|
||||
@echo "ARCH=$(ARCH)"
|
||||
@echo "RESOURCES=$(RESOURCES)"
|
||||
rm -rf prefix
|
||||
docker build -t magic_build -f ./Dockerfile $(MAGIC_SRC_ROOT)
|
||||
id=$$(docker create magic_build) ; \
|
||||
docker cp $$id:/prefix ./prefix ; \
|
||||
docker rm -v $$id
|
||||
mkdir -p prefix/lib/tcl9.0.1
|
||||
cp -r prefix/lib/tcl9.0 prefix/lib/tcl9.0.1/library
|
||||
|
||||
appimagetool:
|
||||
curl -L "$(APPIMAGETOOL_DOWNLOAD_URL)" > ./appimagetool
|
||||
chmod +x ./appimagetool
|
||||
|
||||
$(APPIMAGE): prefix/bin/magic appimagetool $(RESOURCES)
|
||||
cp $(RESOURCES) ./prefix/
|
||||
./appimagetool prefix
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
install:
|
||||
install $(APPIMAGE) $(PREFIX)/bin/magic
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.AppImage
|
||||
rm -f prefix.tar.gz
|
||||
rm -rf prefix
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
This is an AppImage that runs on all GNU/Linux platforms with:
|
||||
|
||||
* FUSE
|
||||
* This excludes non-privileged Docker containers unfortunately, unless pre-extracted.
|
||||
* GLIBC 2.34+
|
||||
* Cairo 1.17+
|
||||
* May require runtime CPU matching Linux ABI x86-64-v2 and newer (CPUs with SSE4.2/CX16 via `lscpu`).
|
||||
|
||||
This AppImage build is based on EL9 (via AlmaLinux 9)
|
||||
|
||||
AlmaLinux 9 was first released on 26 May 2022, full support ends 31 May 2027,
|
||||
maintenance support ends 31 May 2032 (please see AlmaLinux bulletins for
|
||||
up-to-date information).
|
||||
|
||||
# Version Info
|
||||
|
||||
See the AppImage main binary file naming, release tag information and AppInfo metadata
|
||||
for the exact magic version inside the archive. When starting AppImage by default the
|
||||
Tcl console banner can also provide version information, also using the `version` Tcl
|
||||
command.
|
||||
|
||||
# Build Info
|
||||
|
||||
* Based on AlmaLinux 9 (EL9)
|
||||
* Tcl/Tk 9.0.1
|
||||
* and Magic 8.x
|
||||
* all default modules enabled (including all Display drivers cairo/X11/OpenGL)
|
||||
|
||||
# FAQ: How to use
|
||||
|
||||
Download the *.AppImage file relevant to your platform and run:
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
./Magic-x86_64.AppImage
|
||||
```
|
||||
|
||||
Example startup with command line options:
|
||||
|
||||
```
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# FAQ: How to use (inside docker / podman)
|
||||
|
||||
```
|
||||
chmod +x Magic-x86_64.AppImage
|
||||
|
||||
### Podman or Docker, use :Z when rootless with selinux enabled
|
||||
podman run --rm --device /dev/fuse --privileged \
|
||||
-v "$(pwd):/tmp/work:Z" -v "/tmp/.X11-unix/X0:/tmp/.X11-unix/X0:Z" \
|
||||
-e DISPLAY -ti almalinux:9
|
||||
|
||||
### Inside Docker:
|
||||
dnf update -y
|
||||
|
||||
dnf install -y fuse libX11 cairo libGL libGLU
|
||||
|
||||
cd /tmp/work
|
||||
|
||||
./Magic-x86_64.AppImage -d XR -T scmos
|
||||
```
|
||||
|
||||
# Building Requirements
|
||||
|
||||
* A reasonably recent GNU/Linux host
|
||||
* GNU make
|
||||
* Docker
|
||||
* Git
|
||||
* curl
|
||||
|
||||
The final build is then packaged into an AppImage using AppImageTool on the host machine.
|
||||
|
||||
# Build Instructions
|
||||
`make`
|
||||
|
||||
# Installation Instructions
|
||||
`make install`
|
||||
|
||||
# FAQ: Is my CPU supported ?
|
||||
|
||||
This is built with the standard x86_64 Linux ABI version for AlmaLinux 9.
|
||||
|
||||
Use the command `/lib64/ld-linux-x86-64.so.2 --help` to see which CPUs your
|
||||
Linux distribtion supports (and your CPU) look for the word "supported".
|
||||
|
||||
# FAQ: The DSO versioning link dependencies?
|
||||
|
||||
The information here provides an outline of what versions to expect from EL9
|
||||
of the major dependencies, to assist you in a compatibility check with your
|
||||
Linux distribution of choice.
|
||||
|
||||
The actual versions in our public releases can differ slightly inline with
|
||||
the EL9 support compatibility and ABI versioning policies for the support
|
||||
lifecycle of the distribution.
|
||||
|
||||
The most important items are the Direct Dependencies and the availabilty
|
||||
of a suitable graphics DSO as per your '-d' choice.
|
||||
|
||||
Direct Runtime Dependencies (from /prefix/**):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libc.so.6 | GLIBC_2.34 | glibc-2.34-168 |
|
||||
| libz.so.1 | ZLIB_1.2.2 | zlib-1.2.11-40 |
|
||||
|
||||
Optional/Modular Runtime Dependencies (depending on graphics mode):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libcairo.so.2 | | |
|
||||
| libcairo.so.2.11704.0 | | cairo-1.17.4-7 |
|
||||
| libGL.so.1 | | libglvnd-glx-1:1.3.4 |
|
||||
| | | mesa-libGL-24.2.8-2 |
|
||||
| libGLU.so.1 | | mesa-libGLU-9.0.1 |
|
||||
|
||||
Transitive/Third-Party Runtime Dependencies (for information only):
|
||||
|
||||
| DSO Filename | DSO Symbol Version | Related Packages |
|
||||
| :--------------------- | :------------------ | :------------------- |
|
||||
| libc.so.6 | GLIBC_2.35 | glibc-2.34-168 |
|
||||
| libstdc++.so.6 | CXXABI_1.3.9 | gcc-c++-11.5.0-5 |
|
||||
| libstdc++.so.6 | GLIBCXX_3.4 | gcc-c++-11.5.0-5 |
|
||||
| libgcc_s.so.1 | GCC_4.2.0 | libgcc-11.5.0-2 |
|
||||
| libxml2.so.2 | LIBXML2_2.6.0 | libxml2-2.9.13-9 |
|
||||
| libpng16.so.16 | PNG16_0 | ibpng-2:1.6.37-12 |
|
||||
| liblzma.so.5 | XZ_5.0 | xz-libs-5.2.5-8 |
|
||||
| libz.so.1 | ZLIB_1.2.9 | zlib-1.2.11-40 |
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
FROM centos/python-38-centos7:20210726-fad62e9
|
||||
|
||||
USER root
|
||||
|
||||
# Build Dependencies
|
||||
RUN yum install -y cairo-devel freeglut-devel gcc make tcsh
|
||||
|
||||
# Tcl/Tk
|
||||
WORKDIR /tcl
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl8.6.12-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
WORKDIR /tk
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tk8.6.12-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
&& cd unix \
|
||||
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib\
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
WORKDIR /prefix/bin
|
||||
RUN cp ./wish8.6 ./wish
|
||||
RUN cp ./tclsh8.6 ./tclsh
|
||||
|
||||
# Magic
|
||||
WORKDIR /magic
|
||||
COPY . .
|
||||
|
||||
RUN ./configure \
|
||||
--prefix=/prefix \
|
||||
--with-tcl=/prefix/lib \
|
||||
--with-tk=/prefix/lib \
|
||||
--without-opengl \
|
||||
&& make clean \
|
||||
&& make database/database.h \
|
||||
&& make -j$(nproc) \
|
||||
&& make install
|
||||
|
||||
WORKDIR /
|
||||
RUN tar -czf /prefix.tar.gz -C ./prefix .
|
||||
|
||||
CMD ["/bin/bash"]
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
RESOURCES = $(shell find rsc/ -type f)
|
||||
ARCH = $(shell uname -m)
|
||||
APPIMAGE = Magic-$(ARCH).AppImage
|
||||
|
||||
all: $(APPIMAGE)
|
||||
|
||||
.PHONY: prefix/bin/magic
|
||||
prefix/bin/magic: Dockerfile Makefile
|
||||
rm -rf prefix
|
||||
docker build -t magic_build -f ./Dockerfile ..
|
||||
id=$$(docker create magic_build) ; \
|
||||
docker cp $$id:/prefix ./prefix ; \
|
||||
docker rm -v $$id
|
||||
mkdir -p prefix/lib/tcl8.6.12
|
||||
cp -r prefix/lib/tcl8.6 prefix/lib/tcl8.6.12/library
|
||||
|
||||
appimagetool:
|
||||
curl -L https://github.com/AppImage/AppImageKit/releases/download/13/appimagetool-x86_64.AppImage > ./appimagetool
|
||||
chmod +x ./appimagetool
|
||||
|
||||
$(APPIMAGE): prefix/bin/magic appimagetool $(RESOURCES)
|
||||
cp $(RESOURCES) ./prefix
|
||||
./appimagetool prefix
|
||||
|
||||
PREFIX ?= /usr/local
|
||||
install:
|
||||
install $(APPIMAGE) $(PREFIX)/bin/magic
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f *.AppImage
|
||||
rm -f prefix.tar.gz
|
||||
rm -rf prefix
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
This is an AppImage that runs on all GNU/Linux platforms with:
|
||||
|
||||
* FUSE
|
||||
* This excludes non-privileged Docker containers unfortunately, unless pre-extracted.
|
||||
* GLIBC 2.17+
|
||||
* Cairo 1.8+
|
||||
|
||||
That's most Linux distributions released in 2016 or later.
|
||||
|
||||
# Build Info
|
||||
A Dockerfile on CentOS 7 (needed for older glibc) image builds Tcl, Tk and Magic.
|
||||
|
||||
The final build is then packaged into an AppImage using AppImageTool on the host machine.
|
||||
|
||||
# Building Requirements
|
||||
* A reasonably recent GNU/Linux host
|
||||
* Docker 20+
|
||||
* curl
|
||||
|
||||
# Build Instructions
|
||||
`make`
|
||||
|
||||
# Installation Instructions
|
||||
`make install`
|
||||
|
|
@ -1,7 +1,39 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
export CURDIR=$(dirname $(readlink -f "${0}"))
|
||||
|
||||
export PATH="${CURDIR}/bin":$PATH
|
||||
export LD_LIBRARY_PATH=${CURDIR}/lib:$LD_LIBRARY_PATH
|
||||
|
||||
export CAD_ROOT="${CURDIR}/lib"
|
||||
export MAGIC_WISH="${CURDIR}/bin/wish"
|
||||
exec "${CURDIR}/bin/magic" $@
|
||||
|
||||
function my_echo() {
|
||||
if [ "$MAGIC_VERBOSE" != "0" ]
|
||||
then
|
||||
echo -- $@
|
||||
fi
|
||||
}
|
||||
|
||||
# Attempt to set by default a valid 'ulimit -n' based on TCL version this
|
||||
# will automatically apply valid limit inside docker running processes.
|
||||
if [ "X${MAGIC_ULIMIT_NOFILE:+set}" = "X" ] # not set to something
|
||||
then
|
||||
if $MAGIC_WISH "${CURDIR}/version_check.tcl" | grep -q "=8\." # only needed for tcl8
|
||||
then
|
||||
if [ $(ulimit -Sn) -gt 1024 ] # only reduce >1024 to 1024
|
||||
then
|
||||
MAGIC_ULIMIT_NOFILE=1024
|
||||
my_echo "# ulimit -Sn reduced from $(ulimit -Sn) to $MAGIC_ULIMIT_NOFILE"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "X$MAGIC_ULIMIT_NOFILE" != "X" ] # non empty
|
||||
then
|
||||
# Inform user we did this and hint at how to customize
|
||||
my_echo "ulimit -Sn $MAGIC_ULIMIT_NOFILE # use \$MAGIC_ULIMIT_NOFILE to customize"
|
||||
ulimit -Sn $MAGIC_ULIMIT_NOFILE
|
||||
fi
|
||||
|
||||
my_echo "# Starting Magic"
|
||||
exec "${CURDIR}/bin/magic" "$@"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
# Usage: wish version_check.tcl
|
||||
puts "tcl_version=$tcl_version"
|
||||
puts "tk_version=$tk_version"
|
||||
exit 0
|
||||
|
|
@ -93,7 +93,7 @@ static BinArray *bpBinArrayNew(int dx, /* x diameter of bins */
|
|||
|
||||
/* allocate array */
|
||||
size = sizeof(BinArray) + numBins*(sizeof(void *));
|
||||
new = (BinArray *)callocMagic(size);
|
||||
new = (BinArray *)callocMagic(1, size);
|
||||
|
||||
/* initial */
|
||||
new->ba_bbox = *bbox;
|
||||
|
|
@ -567,6 +567,9 @@ BinArray *bpBinArrayBuild(Rect bbox,
|
|||
int numBins;
|
||||
int count;
|
||||
|
||||
/* Added by Tim, 2/19/2024 */
|
||||
/* This line is not supposed to be needed? */
|
||||
if ((!subbin) && ((pointertype)elements & BT_ARRAY)) return NULL;
|
||||
|
||||
if(BPD) DumpRect("#### bpBinArrayBuild, TOP bbox= ", &bbox);
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ void bpDumpRect(Rect *r)
|
|||
fprintf(stderr,"%d",
|
||||
r->r_ytop);
|
||||
}
|
||||
#ifdef CIF_MODULE
|
||||
else
|
||||
{
|
||||
float oscale;
|
||||
|
|
@ -93,6 +94,7 @@ void bpDumpRect(Rect *r)
|
|||
fprintf(stderr,"%f",
|
||||
oscale * (float)r->r_ytop);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -170,6 +172,7 @@ static void bpBinArrayDump(BinArray *ba, int indent)
|
|||
fprintf(stderr,"{dx %d} {dy %d} ",
|
||||
dx,dy);
|
||||
}
|
||||
#ifdef CIF_MODULE
|
||||
else
|
||||
{
|
||||
float oscale;
|
||||
|
|
@ -182,6 +185,7 @@ static void bpBinArrayDump(BinArray *ba, int indent)
|
|||
fprintf(stderr,"{dy %f} ",
|
||||
(float)dy * oscale);
|
||||
}
|
||||
#endif
|
||||
fprintf(stderr,"{dimX %d} {dimY %d} { bbox ",
|
||||
dimX,
|
||||
dimY);
|
||||
|
|
|
|||
|
|
@ -50,9 +50,9 @@
|
|||
*/
|
||||
void BPEnumInit(BPEnum *bpe, /* enum to initialize */
|
||||
BPlane *bp,
|
||||
Rect *area, /* search area */
|
||||
const Rect *area, /* search area */
|
||||
int match,
|
||||
char *id) /* for debugging */
|
||||
const char *id) /* for debugging */
|
||||
{
|
||||
bool inside = FALSE;
|
||||
bpe->bpe_plane = bp;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@
|
|||
//
|
||||
// ************************************************************************
|
||||
|
||||
#ifndef _BPENUM_H
|
||||
#define _BPENUM_H
|
||||
#ifndef _MAGIC__BPLANE__BPENUM_H
|
||||
#define _MAGIC__BPLANE__BPENUM_H
|
||||
|
||||
/* bpEnum.h --
|
||||
*
|
||||
|
|
@ -305,7 +305,7 @@ bpEnumNextBin(BPEnum *bpe, bool inside)
|
|||
{
|
||||
BPStack *bps = bpe->bpe_top;
|
||||
|
||||
#ifdef PARANOID
|
||||
#ifdef BPARANOID
|
||||
ASSERT(bps,"bpEnumNextBin");
|
||||
ASSERT(!bpe->bpe_nextElement,"bpEnumNextBin");
|
||||
#endif
|
||||
|
|
@ -506,23 +506,23 @@ static __inline__ void *BPEnumNext(BPEnum *bpe)
|
|||
switch (bpe->bpe_top->bps_state)
|
||||
{
|
||||
case BPS_BINS:
|
||||
if(e=bpEnumNextBINS(bpe, 0)) return e;
|
||||
if((e=bpEnumNextBINS(bpe, 0))) return e;
|
||||
break;
|
||||
|
||||
case BPS_BINS_INSIDE:
|
||||
if(e=bpEnumNextBINS(bpe, 1)) return e;
|
||||
if((e=bpEnumNextBINS(bpe, 1))) return e;
|
||||
break;
|
||||
|
||||
case BPS_INBOX:
|
||||
if(e=bpEnumNextINBOX(bpe, 0)) return e;
|
||||
if((e=bpEnumNextINBOX(bpe, 0))) return e;
|
||||
break;
|
||||
|
||||
case BPS_INBOX_INSIDE:
|
||||
if(e=bpEnumNextINBOX(bpe, 1)) return e;
|
||||
if((e=bpEnumNextINBOX(bpe, 1))) return e;
|
||||
break;
|
||||
|
||||
case BPS_HASH:
|
||||
if(e=bpEnumNextHASH(bpe)) return e;
|
||||
if((e=bpEnumNextHASH(bpe))) return e;
|
||||
break;
|
||||
|
||||
case BPS_DONE:
|
||||
|
|
@ -534,4 +534,4 @@ static __inline__ void *BPEnumNext(BPEnum *bpe)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* _BPENUM_H */
|
||||
#endif /* _MAGIC__BPLANE__BPENUM_H */
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include "utils/utils.h"
|
||||
#include "utils/malloc.h"
|
||||
#include "database/database.h"
|
||||
|
|
@ -68,8 +69,8 @@ BPlane *BPNew(void)
|
|||
|
||||
/* HASH TABLE */
|
||||
new->bp_hashTable = IHashInit(4, /* initial buckets */
|
||||
OFFSET(Element, e_rect), /* key */
|
||||
OFFSET(Element, e_hashLink),
|
||||
offsetof(Element, e_rect), /* key */
|
||||
offsetof(Element, e_hashLink),
|
||||
IHash4WordKeyHash,
|
||||
IHash4WordKeyEq);
|
||||
|
||||
|
|
@ -127,7 +128,7 @@ void BPAdd(BPlane *bp, void *element)
|
|||
"BPAdd, attempted during active enumerations");
|
||||
|
||||
/* element rect must be canonical! */
|
||||
#ifdef PARANOID
|
||||
#ifdef BPARANOID
|
||||
ASSERT(GeoIsCanonicalRect(r),"BPAdd, rect must be canonical.");
|
||||
#endif
|
||||
|
||||
|
|
@ -261,7 +262,7 @@ Rect BPBBox(BPlane *bp)
|
|||
e = BPEnumNext(&bpe);
|
||||
bp->bp_bbox = e->e_rect;
|
||||
|
||||
while(e = BPEnumNext(&bpe))
|
||||
while((e = BPEnumNext(&bpe)))
|
||||
{
|
||||
GeoIncludeRectInBBox(&e->e_rect, &bp->bp_bbox);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@
|
|||
|
||||
|
||||
|
||||
#ifndef _BPOPAQUE_H
|
||||
#define _BPOPAQUE_H
|
||||
#ifndef _MAGIC__BPLANE__BPOPAQUE_H
|
||||
#define _MAGIC__BPLANE__BPOPAQUE_H
|
||||
|
||||
#ifndef _IHASH_H
|
||||
#ifndef _MAGIC__UTILS__IHASH_H
|
||||
#include "utils/ihash.h"
|
||||
#endif /* _IHASH_H */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* bpOpaque.h --
|
||||
|
|
@ -106,7 +106,7 @@ static __inline__ bool bpBinType(BinArray *ba, int i)
|
|||
|
||||
static __inline__ Element *bpBinList(BinArray *ba, int i)
|
||||
{
|
||||
#ifdef PARANOID
|
||||
#ifdef BPARANOID
|
||||
ASSERT(bpBinType(ba,i)==BT_LIST,"bpBinList");
|
||||
#endif
|
||||
return (Element *) ba->ba_bins[i];
|
||||
|
|
@ -114,7 +114,7 @@ static __inline__ Element *bpBinList(BinArray *ba, int i)
|
|||
|
||||
static __inline__ Element **bpBinListHead(BinArray *ba, int i)
|
||||
{
|
||||
#ifdef PARANOID
|
||||
#ifdef BPARANOID
|
||||
ASSERT(bpBinType(ba,i)==BT_LIST,"bpBinList");
|
||||
#endif
|
||||
return (Element **) &ba->ba_bins[i];
|
||||
|
|
@ -122,7 +122,7 @@ static __inline__ Element **bpBinListHead(BinArray *ba, int i)
|
|||
|
||||
static __inline__ BinArray *bpSubArray(BinArray *ba, int i)
|
||||
{
|
||||
#ifdef PARANOID
|
||||
#ifdef BPARANOID
|
||||
ASSERT(bpBinType(ba,i)==BT_ARRAY,"bpSubArray");
|
||||
#endif
|
||||
return (BinArray *) ((pointertype) ba->ba_bins[i] & ~BT_TYPE_MASK);
|
||||
|
|
@ -182,7 +182,7 @@ typedef struct bpenum
|
|||
BPlane *bpe_plane; /* plane being searched */
|
||||
Rect bpe_srchArea; /* area being searched */
|
||||
int bpe_match; /* match criteria */
|
||||
char *bpe_id; /* for debug */
|
||||
const char *bpe_id; /* for debug */
|
||||
int bpe_subBinMinX;
|
||||
int bpe_subBinMinY; /* consider subbinning
|
||||
* for bins bigger than this.
|
||||
|
|
@ -192,4 +192,4 @@ typedef struct bpenum
|
|||
BPStack bpe_stack[10000]; /* stack for tree traversal during enum */
|
||||
} BPEnum;
|
||||
|
||||
#endif /* _BPOPAQUE_H */
|
||||
#endif /* _MAGIC__BPLANE__BPOPAQUE_H */
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
|
||||
|
||||
|
||||
#ifndef _BPLANE_H
|
||||
#define _BPLANE_H
|
||||
#ifndef _MAGIC__BPLANE__BPLANE_H
|
||||
#define _MAGIC__BPLANE__BPLANE_H
|
||||
|
||||
/*
|
||||
* bplane.h --
|
||||
|
|
@ -160,17 +160,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* offset of a structure member (used to gen offsets for ihash stuff) */
|
||||
#if _MSC_VER
|
||||
/* Microsoft compile complains about size of (void*), so must use (char*) */
|
||||
/* Could use (char*) in UNIX version too. */
|
||||
#define OFFSET(structure,member) \
|
||||
( ((char *) &(((structure *) 0))->member) - ((char *) 0) )
|
||||
#else
|
||||
#define OFFSET(structure,member) \
|
||||
( ((void *) &(((structure *) 0))->member) - ((void *) 0) )
|
||||
#endif
|
||||
|
||||
/* data-structures opaque to clients */
|
||||
#include "bplane/bpOpaque.h"
|
||||
|
||||
|
|
@ -196,9 +185,9 @@ extern void BPEnumInit(BPEnum *bpe, /* this procedure initializes this
|
|||
* enumeration.
|
||||
*/
|
||||
BPlane *bp, /* bplane to search */
|
||||
Rect *area, /* area to search */
|
||||
const Rect *area, /* area to search */
|
||||
int match, /* see below */
|
||||
char *id); /* for debugging */
|
||||
const char *id); /* for debugging */
|
||||
/* match values */
|
||||
|
||||
/* enum all elements in the bplane (area arg must be null) */
|
||||
|
|
@ -243,4 +232,4 @@ BPStat(BPlane *bp,
|
|||
int *totUnbinned, /* ret tot num of e's not binned */
|
||||
int *maxDepth); /* ret max bin array depth */
|
||||
|
||||
#endif /* _BPLANE_H */
|
||||
#endif /* _MAGIC__BPLANE__BPLANE_H */
|
||||
|
|
|
|||
|
|
@ -33,8 +33,8 @@
|
|||
* This file defines constants and datastructures used internally by the
|
||||
* bplane module, but not exported to the rest of the world.
|
||||
*/
|
||||
#ifndef _BPLANEINT_H
|
||||
#define _BPLANEINT_H
|
||||
#ifndef _MAGIC__BPLANE__BPLANEINT_H
|
||||
#define _MAGIC__BPLANE__BPLANEINT_H
|
||||
|
||||
/* Tcl linked Parameters */
|
||||
extern int bpMinBAPop; /* don't sub(bin) when count less than this
|
||||
|
|
@ -79,4 +79,4 @@ extern Plane *bpTestSnowTile(int size, bool trace);
|
|||
|
||||
extern int bpRand(int min, int max);
|
||||
|
||||
#endif /* _BPLANEINT_H */
|
||||
#endif /* _MAGIC__BPLANE__BPLANEINT_H */
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdcl.c,v 1.5 2010/06/25 13:59:24 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdcl.c,v 1.5 2010/06/25 13:59:24 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -56,11 +56,12 @@ bool CalmaRewound = FALSE;
|
|||
TileTypeBitMask *CalmaMaskHints = NULL;
|
||||
|
||||
extern HashTable calmaDefInitHash;
|
||||
extern int CalmaPolygonCount;
|
||||
|
||||
/* forward declarations */
|
||||
int calmaElementSref();
|
||||
bool calmaParseElement();
|
||||
void calmaUniqueCell();
|
||||
int calmaElementSref(char *filename);
|
||||
bool calmaParseElement(char *filename, int *pnsrefs, int *pnpaths);
|
||||
void calmaUniqueCell(char *sname);
|
||||
|
||||
/* Structure used when flattening the GDS hierarchy on read-in */
|
||||
|
||||
|
|
@ -95,8 +96,8 @@ typedef struct {
|
|||
*/
|
||||
|
||||
OFFTYPE
|
||||
calmaSetPosition(sname)
|
||||
char *sname;
|
||||
calmaSetPosition(
|
||||
char *sname)
|
||||
{
|
||||
OFFTYPE originalPos = 0, currentPos = 0;
|
||||
int nbytes, rtype;
|
||||
|
|
@ -187,7 +188,7 @@ calmaSetPosition(sname)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaNextCell()
|
||||
calmaNextCell(void)
|
||||
{
|
||||
int nbytes, rtype;
|
||||
|
||||
|
|
@ -239,12 +240,14 @@ calmaNextCell()
|
|||
*/
|
||||
|
||||
Plane **
|
||||
calmaExact()
|
||||
calmaExact(void)
|
||||
{
|
||||
int pNum;
|
||||
Plane *newplane;
|
||||
Plane **parray;
|
||||
int gdsCopyPaintFunc(); /* Forward reference */
|
||||
|
||||
/* Forward reference */
|
||||
int gdsCopyPaintFunc(Tile *tile, TileType dinfo, GDSCopyRec *gdsCopyRec);
|
||||
|
||||
parray = (Plane **)mallocMagic(MAXCIFRLAYERS * sizeof(Plane *));
|
||||
|
||||
|
|
@ -274,7 +277,56 @@ calmaExact()
|
|||
return parray;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* calmaFlattenPolygonFunc --
|
||||
*
|
||||
* Polygons have been dropped into subcells by default for
|
||||
* efficiency in reading. If the "subcell polygons" option
|
||||
* has not been selected, then flatten these cells into the
|
||||
* layout and delete the cells. This seems inefficient but
|
||||
* in fact can be much faster than reading the polygons
|
||||
* directly into the cell from GDS.
|
||||
*
|
||||
* Return value:
|
||||
* Return 0 to keep the search going
|
||||
*
|
||||
* Side effects:
|
||||
* Polygons are copied from use->cu_def to parent.
|
||||
* use->cu_def is deleted.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
calmaFlattenPolygonFunc(
|
||||
CellUse *use,
|
||||
CellDef *parent)
|
||||
{
|
||||
int i;
|
||||
CellUse dummy;
|
||||
SearchContext scx;
|
||||
HashEntry *he;
|
||||
|
||||
if (use->cu_def == NULL || use->cu_def->cd_name == NULL) return 0;
|
||||
if (strncmp(use->cu_def->cd_name, "polygon", 7)) return 0;
|
||||
|
||||
dummy.cu_transform = GeoIdentityTransform;
|
||||
dummy.cu_id = NULL;
|
||||
dummy.cu_def = parent;
|
||||
scx.scx_use = use;
|
||||
scx.scx_area = use->cu_bbox;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, 0, &dummy);
|
||||
DBDeleteCellNoModify(use);
|
||||
HashRemove(&CifCellTable, use->cu_def->cd_name);
|
||||
/* There should only be one use, so it can just be cleared */
|
||||
use->cu_def->cd_parents = (CellUse *)NULL;
|
||||
DBCellDeleteDef(use->cu_def);
|
||||
|
||||
return 0; /* Keep the search going */
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -297,22 +349,26 @@ calmaExact()
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaParseStructure(filename)
|
||||
char *filename; /* Name of the GDS file read */
|
||||
calmaParseStructure(
|
||||
char *filename) /* Name of the GDS file read */
|
||||
{
|
||||
static int structs[] = { CALMA_STRCLASS, CALMA_STRTYPE, -1 };
|
||||
int nbytes, rtype, nsrefs, osrefs, npaths;
|
||||
static const int structs[] = { CALMA_STRCLASS, CALMA_STRTYPE, -1 };
|
||||
int nbytes = -1, rtype = 0, nsrefs, osrefs, npaths;
|
||||
char *strname = NULL;
|
||||
HashEntry *he;
|
||||
int timestampval = 0;
|
||||
int suffix;
|
||||
int mfactor;
|
||||
int locPolygonCount;
|
||||
OFFTYPE filepos;
|
||||
bool was_called;
|
||||
bool was_called = FALSE;
|
||||
bool was_initialized;
|
||||
bool predefined;
|
||||
bool do_flatten;
|
||||
CellDef *def;
|
||||
Label *lab;
|
||||
|
||||
locPolygonCount = CalmaPolygonCount;
|
||||
|
||||
/* Make sure this is a structure; if not, let the caller know we're done */
|
||||
PEEKRH(nbytes, rtype);
|
||||
|
|
@ -333,6 +389,15 @@ calmaParseStructure(filename)
|
|||
he = HashFind(&calmaDefInitHash, strname);
|
||||
if ((def = (CellDef *)HashGetValue(he)) != NULL)
|
||||
{
|
||||
if (def->cd_flags & CDPRELOADED)
|
||||
{
|
||||
/* Cell definition was read ahead due to option "flatten" */
|
||||
/* or "flatglob". Do not complain about seeing it again. */
|
||||
def->cd_flags &= ~CDPRELOADED;
|
||||
calmaNextCell();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (def->cd_flags & CDPROCESSEDGDS)
|
||||
{
|
||||
/* If cell definition was marked as processed, then skip */
|
||||
|
|
@ -342,6 +407,7 @@ calmaParseStructure(filename)
|
|||
|
||||
if (!CalmaPostOrder && !CalmaRewound)
|
||||
{
|
||||
cifReadCellDef = def;
|
||||
CalmaReadError("Cell \"%s\" was already defined in this file.\n",
|
||||
strname);
|
||||
CalmaReadError("Ignoring duplicate definition\n");
|
||||
|
|
@ -353,6 +419,7 @@ calmaParseStructure(filename)
|
|||
{
|
||||
char *newname;
|
||||
|
||||
cifReadCellDef = def;
|
||||
CalmaReadError("Cell \"%s\" was already defined in this file.\n",
|
||||
strname);
|
||||
newname = (char *)mallocMagic(strlen(strname) + 20);
|
||||
|
|
@ -547,8 +614,21 @@ calmaParseStructure(filename)
|
|||
CIFPaintCurrent(FILE_CALMA);
|
||||
}
|
||||
|
||||
DBAdjustLabelsNew(cifReadCellDef, &TiPlaneRect,
|
||||
(cifCurReadStyle->crs_flags & CRF_NO_RECONNECT_LABELS) ? 1 : 0);
|
||||
/* Check for empty string labels that are caused by pin geometry that
|
||||
* did not get any corresponding text type, and remove them.
|
||||
*/
|
||||
DBEraseLabelsByContent(cifReadCellDef, NULL, -1, "");
|
||||
|
||||
if ((CalmaSubcellPolygons == CALMA_POLYGON_TEMP) &&
|
||||
(locPolygonCount < CalmaPolygonCount))
|
||||
DBCellEnum(cifReadCellDef, calmaFlattenPolygonFunc, (ClientData)cifReadCellDef);
|
||||
|
||||
/* Because the "label" statement can only match one GDS layer to one magic
|
||||
* layer, then all labels are subject to adjustment to attach them to
|
||||
* something meaningful in the layout. The "no-reconnect-labels" option
|
||||
* is not useful and has been deprecated.
|
||||
*/
|
||||
DBAdjustLabelsNew(cifReadCellDef, &TiPlaneRect);
|
||||
DBReComputeBbox(cifReadCellDef);
|
||||
|
||||
/* Don't bother to register with DRC if we're going to delete the */
|
||||
|
|
@ -608,11 +688,12 @@ syntaxerror:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaParseElement(filename, pnsrefs, pnpaths)
|
||||
char *filename;
|
||||
int *pnsrefs, *pnpaths;
|
||||
calmaParseElement(
|
||||
char *filename,
|
||||
int *pnsrefs,
|
||||
int *pnpaths)
|
||||
{
|
||||
static int node[] = { CALMA_ELFLAGS, CALMA_PLEX, CALMA_LAYER,
|
||||
static const int node[] = { CALMA_ELFLAGS, CALMA_PLEX, CALMA_LAYER,
|
||||
CALMA_NODETYPE, CALMA_XY, -1 };
|
||||
int nbytes, rtype, madeinst;
|
||||
|
||||
|
|
@ -670,9 +751,10 @@ calmaParseElement(filename, pnsrefs, pnpaths)
|
|||
*/
|
||||
|
||||
int
|
||||
calmaEnumFunc(tile, plane)
|
||||
Tile *tile;
|
||||
int *plane;
|
||||
calmaEnumFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
int *plane)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -697,24 +779,26 @@ calmaEnumFunc(tile, plane)
|
|||
*/
|
||||
|
||||
int
|
||||
calmaElementSref(filename)
|
||||
char *filename;
|
||||
calmaElementSref(
|
||||
char *filename)
|
||||
{
|
||||
int nbytes, rtype, cols, rows, nref, n, i, savescale;
|
||||
int xlo, ylo, xhi, yhi, xsep, ysep;
|
||||
bool madeinst = FALSE;
|
||||
char *sname = NULL;
|
||||
bool isArray = FALSE;
|
||||
bool dolookahead = FALSE;
|
||||
Transform trans, tinv;
|
||||
Point refarray[3], refunscaled[3], p;
|
||||
CellUse *use;
|
||||
CellDef *def;
|
||||
int gdsCopyPaintFunc(); /* Forward reference */
|
||||
int gdsHasUses(); /* Forward reference */
|
||||
/* Added by NP */
|
||||
char *useid = NULL, *arraystr = NULL;
|
||||
int propAttrType;
|
||||
|
||||
/* Forward reference */
|
||||
int gdsCopyPaintFunc(Tile *tile, TileType dinfo, GDSCopyRec *gdsCopyRec);
|
||||
int gdsHasUses(CellUse *use, ClientData clientdata);
|
||||
|
||||
/* Skip CALMA_ELFLAGS, CALMA_PLEX */
|
||||
calmaSkipSet(calmaElementIgnore);
|
||||
|
||||
|
|
@ -730,7 +814,38 @@ calmaElementSref(filename)
|
|||
*/
|
||||
|
||||
def = calmaLookCell(sname);
|
||||
if (!def && (CalmaPostOrder || CalmaFlattenUses || (CalmaFlattenUsesByName != NULL)))
|
||||
|
||||
/*
|
||||
* If the "flatten" option is set, then we always have to seek
|
||||
* ahead and read the structure in order to determine if it
|
||||
* meets the requirement of being flattened or not. If the
|
||||
* "flatglob" option is set, then we need to read ahead and
|
||||
* read the cell definition so that it can be flatten. This
|
||||
* requires pattern-matching the cell def.
|
||||
*/
|
||||
|
||||
dolookahead = (CalmaPostOrder || CalmaFlattenUses) ? TRUE : FALSE;
|
||||
if ((!dolookahead) && (CalmaFlattenUsesByName != NULL))
|
||||
{
|
||||
char *pattern;
|
||||
|
||||
i = 0;
|
||||
while (TRUE)
|
||||
{
|
||||
pattern = CalmaFlattenUsesByName[i];
|
||||
if (pattern == NULL) break;
|
||||
i++;
|
||||
|
||||
/* Check pattern against strname */
|
||||
if (Match(pattern, sname))
|
||||
{
|
||||
dolookahead = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!def && dolookahead)
|
||||
{
|
||||
/* Force the GDS parser to read the cell definition in
|
||||
* post-order. If cellname "sname" is not defined before
|
||||
|
|
@ -764,6 +879,7 @@ calmaElementSref(filename)
|
|||
FSEEK(calmaInputFile, originalFilePos, SEEK_SET);
|
||||
cifReadCellDef = calmaLookCell(currentSname);
|
||||
def = calmaLookCell(sname);
|
||||
def->cd_flags |= CDPRELOADED;
|
||||
cifCurReadPlanes = savePlanes;
|
||||
calmaLayerHash = OrigCalmaLayerHash;
|
||||
if (crsMultiplier != cifCurReadStyle->crs_multiplier)
|
||||
|
|
@ -1038,7 +1154,14 @@ calmaElementSref(filename)
|
|||
if (isArray)
|
||||
DBMakeArray(use, &GeoIdentityTransform, xlo, ylo, xhi, yhi, xsep, ysep);
|
||||
DBSetTrans(use, &trans);
|
||||
DBPlaceCell(use, cifReadCellDef);
|
||||
if (DBCellFindDup(use, cifReadCellDef) != NULL)
|
||||
{
|
||||
DBCellDeleteUse(use);
|
||||
CalmaReadError("Warning: cell \"%s\" placed on top of"
|
||||
" itself. Ignoring the extra one.\n", def->cd_name);
|
||||
}
|
||||
else
|
||||
DBPlaceCell(use, cifReadCellDef);
|
||||
|
||||
break; // No need to do 2nd loop
|
||||
}
|
||||
|
|
@ -1105,8 +1228,17 @@ calmaElementSref(filename)
|
|||
if (isArray)
|
||||
DBMakeArray(use, &GeoIdentityTransform, xlo, ylo, xhi, yhi, xsep, ysep);
|
||||
DBSetTrans(use, &trans);
|
||||
DBPlaceCell(use, cifReadCellDef);
|
||||
madeinst = TRUE;
|
||||
if (DBCellFindDup(use, cifReadCellDef) != NULL)
|
||||
{
|
||||
DBCellDeleteUse(use);
|
||||
CalmaReadError("Warning: cell \"%s\" placed on top of"
|
||||
" itself. Ignoring the extra one.\n", def->cd_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBPlaceCell(use, cifReadCellDef);
|
||||
madeinst = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1123,8 +1255,17 @@ calmaElementSref(filename)
|
|||
if (isArray)
|
||||
DBMakeArray(use, &GeoIdentityTransform, xlo, ylo, xhi, yhi, xsep, ysep);
|
||||
DBSetTrans(use, &trans);
|
||||
DBPlaceCell(use, cifReadCellDef);
|
||||
madeinst = TRUE;
|
||||
if (DBCellFindDup(use, cifReadCellDef) != NULL)
|
||||
{
|
||||
DBCellDeleteUse(use);
|
||||
CalmaReadError("Warning: cell \"%s\" placed on top of"
|
||||
" itself. Ignoring the extra one.\n", def->cd_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBPlaceCell(use, cifReadCellDef);
|
||||
madeinst = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1140,9 +1281,9 @@ calmaElementSref(filename)
|
|||
/* Callback function for determining if a cell has at least one subcell */
|
||||
|
||||
int
|
||||
gdsHasUses(use, clientdata)
|
||||
CellUse *use;
|
||||
ClientData clientdata;
|
||||
gdsHasUses(
|
||||
CellUse *use,
|
||||
ClientData clientdata)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -1150,29 +1291,30 @@ gdsHasUses(use, clientdata)
|
|||
/* Callback function for copying paint from one CIF cell into another */
|
||||
|
||||
int
|
||||
gdsCopyPaintFunc(tile, gdsCopyRec)
|
||||
Tile *tile;
|
||||
GDSCopyRec *gdsCopyRec;
|
||||
gdsCopyPaintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
GDSCopyRec *gdsCopyRec)
|
||||
{
|
||||
int pNum;
|
||||
TileType dinfo;
|
||||
TileType newdinfo;
|
||||
Rect sourceRect, targetRect;
|
||||
Transform *trans = gdsCopyRec->trans;
|
||||
Plane *plane = gdsCopyRec->plane;
|
||||
|
||||
dinfo = TiGetTypeExact(tile);
|
||||
newdinfo = TiGetTypeExact(tile) | dinfo;
|
||||
|
||||
if (trans)
|
||||
{
|
||||
TiToRect(tile, &sourceRect);
|
||||
GeoTransRect(trans, &sourceRect, &targetRect);
|
||||
if (IsSplit(tile))
|
||||
dinfo = DBTransformDiagonal(TiGetTypeExact(tile), trans);
|
||||
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, trans);
|
||||
}
|
||||
else
|
||||
TiToRect(tile, &targetRect);
|
||||
|
||||
DBNMPaintPlane(plane, dinfo, &targetRect, CIFPaintTable,
|
||||
DBNMPaintPlane(plane, newdinfo, &targetRect, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1197,8 +1339,8 @@ gdsCopyPaintFunc(tile, gdsCopyRec)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaUniqueCell(sname)
|
||||
char *sname;
|
||||
calmaUniqueCell(
|
||||
char *sname)
|
||||
{
|
||||
HashEntry *h;
|
||||
CellDef *def, *testdef;
|
||||
|
|
@ -1257,14 +1399,14 @@ calmaUniqueCell(sname)
|
|||
*/
|
||||
|
||||
CellDef *
|
||||
calmaFindCell(name, was_called, predefined)
|
||||
char *name; /* Name of desired cell */
|
||||
bool *was_called; /* If this cell is in the hash table, then it
|
||||
calmaFindCell(
|
||||
const char *name, /* Name of desired cell */
|
||||
bool *was_called, /* If this cell is in the hash table, then it
|
||||
* was instanced before it was defined. We
|
||||
* need to know this so as to avoid flattening
|
||||
* the cell if requested.
|
||||
*/
|
||||
bool *predefined; /* If this cell was in memory before the GDS
|
||||
bool *predefined) /* If this cell was in memory before the GDS
|
||||
* file was read, then this flag gets set.
|
||||
*/
|
||||
|
||||
|
|
@ -1286,20 +1428,26 @@ calmaFindCell(name, was_called, predefined)
|
|||
* if the cell is used in a parent before being defined
|
||||
* then it will cause a core dump.
|
||||
*/
|
||||
DBReComputeBbox(def);
|
||||
DBReComputeBbox(def);
|
||||
if (was_called) *was_called = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
TxPrintf("Warning: cell %s already existed before reading GDS!\n",
|
||||
name);
|
||||
if (CalmaNoDuplicates)
|
||||
{
|
||||
TxPrintf("Note: cell %s already existed before reading GDS.\n",
|
||||
name);
|
||||
if (predefined) *predefined = TRUE;
|
||||
TxPrintf("Using pre-existing cell definition\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
TxPrintf("Warning: cell %s already existed before reading GDS!\n",
|
||||
name);
|
||||
}
|
||||
if (was_called) *was_called = TRUE;
|
||||
}
|
||||
HashSetValue(h, def);
|
||||
if (was_called) *was_called = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1338,8 +1486,8 @@ calmaFindCell(name, was_called, predefined)
|
|||
*/
|
||||
|
||||
CellDef *
|
||||
calmaLookCell(name)
|
||||
char *name; /* Name of desired cell */
|
||||
calmaLookCell(
|
||||
char *name) /* Name of desired cell */
|
||||
{
|
||||
HashEntry *h;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdio.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdio.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -50,8 +50,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "calma/calma.h"
|
||||
|
||||
/* Forward declarations */
|
||||
bool calmaReadR8();
|
||||
bool calmaSkipBytes();
|
||||
bool calmaReadR8(double *pd);
|
||||
bool calmaSkipBytes(int nbytes);
|
||||
|
||||
|
||||
/*
|
||||
|
|
@ -73,9 +73,9 @@ bool calmaSkipBytes();
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaReadTransform(ptrans, name)
|
||||
Transform *ptrans; /* Fill in this transform */
|
||||
char *name; /* Name of subcell (for errors) */
|
||||
calmaReadTransform(
|
||||
Transform *ptrans, /* Fill in this transform */
|
||||
char *name) /* Name of subcell (for errors) */
|
||||
{
|
||||
int nbytes, rtype, flags, angle;
|
||||
double dangle;
|
||||
|
|
@ -205,9 +205,9 @@ calmaReadTransform(ptrans, name)
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaReadI2Record(type, pvalue)
|
||||
int type; /* Type of record expected */
|
||||
int *pvalue; /* Store value here */
|
||||
calmaReadI2Record(
|
||||
int type, /* Type of record expected */
|
||||
int *pvalue) /* Store value here */
|
||||
{
|
||||
int nbytes, rtype, n;
|
||||
|
||||
|
|
@ -250,9 +250,9 @@ eof:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaReadI4Record(type, pvalue)
|
||||
int type; /* Type of record expected */
|
||||
int *pvalue; /* Store value here */
|
||||
calmaReadI4Record(
|
||||
int type, /* Type of record expected */
|
||||
int *pvalue) /* Store value here */
|
||||
{
|
||||
int nbytes, rtype, n;
|
||||
|
||||
|
|
@ -298,9 +298,9 @@ eof:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaReadStampRecord(type, stampptr)
|
||||
int type;
|
||||
int *stampptr;
|
||||
calmaReadStampRecord(
|
||||
int type,
|
||||
int *stampptr)
|
||||
{
|
||||
int nbytes, rtype;
|
||||
struct tm gds_timestamp;
|
||||
|
|
@ -371,9 +371,9 @@ eof:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaReadStringRecord(type, str)
|
||||
int type;
|
||||
char **str;
|
||||
calmaReadStringRecord(
|
||||
int type,
|
||||
char **str)
|
||||
{
|
||||
int nbytes, rtype;
|
||||
|
||||
|
|
@ -389,7 +389,7 @@ calmaReadStringRecord(type, str)
|
|||
|
||||
nbytes -= CALMAHEADERLENGTH;
|
||||
*str = (char *) mallocMagic(nbytes + 1);
|
||||
if (FREAD(*str, sizeof (char), nbytes, calmaInputFile) != nbytes)
|
||||
if (magicFREAD(*str, sizeof (char), nbytes, calmaInputFile) != nbytes)
|
||||
goto eof;
|
||||
|
||||
*(*str + nbytes) = '\0';
|
||||
|
|
@ -420,21 +420,21 @@ eof:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaReadR8(pd)
|
||||
double *pd; /* Store result in *pd */
|
||||
calmaReadR8(
|
||||
double *pd) /* Store result in *pd */
|
||||
{
|
||||
int i, exponent;
|
||||
unsigned char dchars[8];
|
||||
double mantissa, d;
|
||||
bool isneg;
|
||||
|
||||
if (FREAD((char *) dchars, sizeof (char), sizeof dchars,
|
||||
if (magicFREAD((char *) dchars, sizeof (char), sizeof dchars,
|
||||
calmaInputFile) != sizeof dchars)
|
||||
return (FALSE);
|
||||
|
||||
/* Extract the sign and exponent */
|
||||
exponent = dchars[0];
|
||||
if (isneg = (exponent & 0x80))
|
||||
if ((isneg = (exponent & 0x80)))
|
||||
exponent &= ~0x80;
|
||||
exponent -= 64;
|
||||
|
||||
|
|
@ -489,10 +489,10 @@ calmaReadR8(pd)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaSkipSet(skipwhat)
|
||||
int *skipwhat;
|
||||
calmaSkipSet(
|
||||
const int *skipwhat)
|
||||
{
|
||||
int *skipp;
|
||||
const int *skipp;
|
||||
int nbytes, rtype;
|
||||
|
||||
for (;;)
|
||||
|
|
@ -533,8 +533,8 @@ skipit:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaSkipExact(type)
|
||||
int type;
|
||||
calmaSkipExact(
|
||||
int type)
|
||||
{
|
||||
int nbytes, rtype;
|
||||
|
||||
|
|
@ -579,8 +579,8 @@ eof:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaSkipTo(what)
|
||||
int what;
|
||||
calmaSkipTo(
|
||||
int what)
|
||||
{
|
||||
int nbytes, rtype;
|
||||
|
||||
|
|
@ -615,8 +615,8 @@ calmaSkipTo(what)
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaSkipBytes(nbytes)
|
||||
int nbytes; /* Skip this many bytes */
|
||||
calmaSkipBytes(
|
||||
int nbytes) /* Skip this many bytes */
|
||||
{
|
||||
while (nbytes-- > 0)
|
||||
if (FGETC(calmaInputFile) < 0)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdpt.c,v 1.7 2010/08/25 17:33:54 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdpt.c,v 1.7 2010/08/25 17:33:54 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -57,8 +57,8 @@ extern int CalmaPolygonCount;
|
|||
extern int CalmaPathCount;
|
||||
extern HashTable calmaDefInitHash;
|
||||
|
||||
extern void calmaLayerError();
|
||||
bool calmaReadPath();
|
||||
extern void calmaLayerError(char *mesg, int layer, int dt);
|
||||
CIFPath *calmaReadPath(int iscale);
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -82,8 +82,9 @@ bool calmaReadPath();
|
|||
*/
|
||||
|
||||
void
|
||||
calmaInputRescale(n, d)
|
||||
int n, d;
|
||||
calmaInputRescale(
|
||||
int n,
|
||||
int d)
|
||||
{
|
||||
HashEntry *h;
|
||||
HashSearch hs;
|
||||
|
|
@ -135,9 +136,9 @@ calmaInputRescale(n, d)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaReadPoint(p, iscale)
|
||||
Point *p;
|
||||
int iscale;
|
||||
calmaReadPoint(
|
||||
Point *p,
|
||||
int iscale)
|
||||
{
|
||||
int rescale;
|
||||
|
||||
|
|
@ -205,14 +206,14 @@ calmaReadPoint(p, iscale)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaElementBoundary()
|
||||
calmaElementBoundary(void)
|
||||
{
|
||||
int dt, layer, ciftype;
|
||||
CIFPath *pathheadp;
|
||||
LinkedRect *rp;
|
||||
Plane *plane;
|
||||
CellUse *use;
|
||||
CellDef *savedef, *newdef = NULL;
|
||||
CellDef *savedef = NULL, *newdef = NULL;
|
||||
|
||||
/* Skip CALMA_ELFLAGS, CALMA_PLEX */
|
||||
calmaSkipSet(calmaElementIgnore);
|
||||
|
|
@ -236,7 +237,8 @@ calmaElementBoundary()
|
|||
plane = cifCurReadPlanes[ciftype];
|
||||
|
||||
/* Read the path itself, building up a path structure */
|
||||
if (!calmaReadPath(&pathheadp, (plane == NULL) ? 0 : 1))
|
||||
pathheadp = calmaReadPath((plane == NULL) ? 0 : 1);
|
||||
if (pathheadp == NULL)
|
||||
{
|
||||
if (plane != NULL)
|
||||
CalmaReadError("Error while reading path for boundary/box; ignored.\n");
|
||||
|
|
@ -247,23 +249,27 @@ calmaElementBoundary()
|
|||
/* so we need to set it again. */
|
||||
if (ciftype >= 0) plane = cifCurReadPlanes[ciftype];
|
||||
|
||||
/* Convert the polygon to rectangles. */
|
||||
/* Save non-Manhattan polygons in their own subcells. */
|
||||
/* NOTE: CALMA_POLYGON_TEMP and CALMA_POLYGON_KEEP read in polygons much
|
||||
* faster, but that interferes with boolean processing. This method
|
||||
* needs to be reworked.
|
||||
*/
|
||||
|
||||
if (CalmaSubcellPolygons && (calmaNonManhattan > 0))
|
||||
if ((CalmaSubcellPolygons != CALMA_POLYGON_NONE) && (calmaNonManhattan > 0))
|
||||
{
|
||||
/* Place the polygon in its own subcell */
|
||||
char newname[] = "polygonXXXXX";
|
||||
char newname[20];
|
||||
HashEntry *he;
|
||||
|
||||
savedef = cifReadCellDef;
|
||||
|
||||
/* Make up name for cell */
|
||||
sprintf(newname + 7, "%05d", ++CalmaPolygonCount);
|
||||
snprintf(newname, sizeof(newname), "polygon%05d", ++CalmaPolygonCount);
|
||||
|
||||
he = HashFind(&calmaDefInitHash, newname);
|
||||
if (!HashGetValue(he))
|
||||
{
|
||||
newdef = calmaFindCell(newname, NULL);
|
||||
newdef = calmaFindCell(newname, NULL, NULL);
|
||||
cifReadCellDef = newdef;
|
||||
DBCellClearDef(cifReadCellDef);
|
||||
DBCellSetAvail(cifReadCellDef);
|
||||
|
|
@ -277,7 +283,9 @@ calmaElementBoundary()
|
|||
}
|
||||
}
|
||||
|
||||
rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||
/* Convert the polygon to rectangles. */
|
||||
|
||||
rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL, TRUE);
|
||||
CIFFreePath(pathheadp);
|
||||
|
||||
/* If the input layer is designated for ports by a "label" */
|
||||
|
|
@ -319,18 +327,47 @@ calmaElementBoundary()
|
|||
if (lab == NULL)
|
||||
{
|
||||
/* There was no label in the area. Create a placeholder label */
|
||||
DBPutLabel(cifReadCellDef, &rpc, GEO_CENTER, "", type, 0, 0);
|
||||
lab = DBPutLabel(cifReadCellDef, &rpc, GEO_CENTER, "", type, 0, 0);
|
||||
}
|
||||
if ((cifCurReadStyle->crs_labelSticky[ciftype] == LABEL_TYPE_PORT)
|
||||
&& ((lab->lab_flags & PORT_DIR_MASK) == 0))
|
||||
{
|
||||
/* Label was read previously as a text type, but the pin layer
|
||||
* causes it to be recast as a port, or corresponding label has
|
||||
* not yet been seen.
|
||||
*/
|
||||
int i, idx;
|
||||
Label *sl;
|
||||
|
||||
/* Order ports as encountered. */
|
||||
i = -1;
|
||||
for (sl = cifReadCellDef->cd_labels; sl != NULL; sl = sl->lab_next)
|
||||
{
|
||||
idx = sl->lab_port;
|
||||
if (idx > i) i = idx;
|
||||
if ((idx > 0) && (sl != lab) && !strcmp(sl->lab_text, lab->lab_text))
|
||||
{
|
||||
i = idx - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
lab->lab_port = i;
|
||||
lab->lab_flags |= PORT_DIR_NORTH | PORT_DIR_SOUTH |
|
||||
PORT_DIR_EAST | PORT_DIR_WEST;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Paint the rectangles (if any) */
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (; rp != NULL ; rp = rp->r_next)
|
||||
{
|
||||
if (plane)
|
||||
DBPaintPlane(plane, &rp->r_r, CIFPaintTable, (PaintUndoInfo *)NULL);
|
||||
freeMagic((char *) rp);
|
||||
freeMagic1(&mm1, (char *) rp);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
if (cifCurReadPlanes == cifEditCellPlanes)
|
||||
{
|
||||
|
|
@ -373,7 +410,7 @@ calmaElementBoundary()
|
|||
*/
|
||||
|
||||
void
|
||||
calmaElementBox()
|
||||
calmaElementBox(void)
|
||||
{
|
||||
int nbytes, rtype, npoints, savescale;
|
||||
int dt, layer, ciftype;
|
||||
|
|
@ -468,9 +505,9 @@ calmaElementBox()
|
|||
*/
|
||||
|
||||
void
|
||||
calmaElementPath()
|
||||
calmaElementPath(void)
|
||||
{
|
||||
int nbytes, rtype, extend1, extend2;
|
||||
int nbytes = -1, rtype = 0, extend1, extend2;
|
||||
int layer, dt, width, pathtype, ciftype, savescale;
|
||||
int xmin, ymin, xmax, ymax, temp;
|
||||
CIFPath *pathheadp, *pathp, *previousp;
|
||||
|
|
@ -478,7 +515,7 @@ calmaElementPath()
|
|||
Plane *plane;
|
||||
int first,last;
|
||||
CellUse *use;
|
||||
CellDef *savedef, *newdef = NULL;
|
||||
CellDef *savedef = NULL, *newdef = NULL;
|
||||
|
||||
/* Skip CALMA_ELFLAGS, CALMA_PLEX */
|
||||
calmaSkipSet(calmaElementIgnore);
|
||||
|
|
@ -561,7 +598,8 @@ calmaElementPath()
|
|||
|
||||
/* Read the points in the path */
|
||||
savescale = calmaReadScale1;
|
||||
if (!calmaReadPath(&pathheadp, 2))
|
||||
pathheadp = calmaReadPath(2);
|
||||
if (pathheadp == NULL)
|
||||
{
|
||||
CalmaReadError("Improper path; ignored.\n");
|
||||
return;
|
||||
|
|
@ -629,18 +667,18 @@ calmaElementPath()
|
|||
if (CalmaSubcellPaths)
|
||||
{
|
||||
/* Place the path in its own subcell */
|
||||
char newname[] = "pathXXXXX";
|
||||
char newname[16];
|
||||
HashEntry *he;
|
||||
|
||||
savedef = cifReadCellDef;
|
||||
|
||||
/* Make up name for cell */
|
||||
sprintf(newname + 4, "%05d", ++CalmaPathCount);
|
||||
snprintf(newname, sizeof(newname), "path%05d", ++CalmaPathCount);
|
||||
|
||||
he = HashFind(&calmaDefInitHash, newname);
|
||||
if (!HashGetValue(he))
|
||||
{
|
||||
newdef = calmaFindCell(newname, NULL);
|
||||
newdef = calmaFindCell(newname, NULL, NULL);
|
||||
cifReadCellDef = newdef;
|
||||
DBCellClearDef(cifReadCellDef);
|
||||
DBCellSetAvail(cifReadCellDef);
|
||||
|
|
@ -696,16 +734,16 @@ calmaElementPath()
|
|||
*/
|
||||
|
||||
void
|
||||
calmaElementText()
|
||||
calmaElementText(void)
|
||||
{
|
||||
static int ignore[] = { CALMA_PATHTYPE, CALMA_WIDTH, -1 };
|
||||
static const int ignore[] = { CALMA_PATHTYPE, CALMA_WIDTH, -1 };
|
||||
char *textbody = NULL;
|
||||
int nbytes, rtype;
|
||||
int nbytes = -1, rtype = 0;
|
||||
int layer, textt, cifnum, textpres;
|
||||
TileType type;
|
||||
Rect r;
|
||||
double dval;
|
||||
int size, angle, font, pos;
|
||||
int size, micron, angle, font, pos, portnum, idx;
|
||||
|
||||
/* Skip CALMA_ELFLAGS, CALMA_PLEX */
|
||||
calmaSkipSet(calmaElementIgnore);
|
||||
|
|
@ -727,10 +765,29 @@ calmaElementText()
|
|||
|
||||
font = -1;
|
||||
angle = 0;
|
||||
portnum = 0;
|
||||
|
||||
/* Default size is 1um */
|
||||
size = (int)((1000 * cifCurReadStyle->crs_multiplier)
|
||||
/* Use the minimum width of the layer on which the text is placed
|
||||
* as the default text size, or 1um, whichever is smaller. Account
|
||||
* for the 8/10 difference encoded in the rendered font height.
|
||||
*/
|
||||
size = 0;
|
||||
if (type > 0)
|
||||
{
|
||||
size = DRCGetDefaultLayerWidth(type);
|
||||
if (size > 0)
|
||||
{
|
||||
size *= (calmaReadScale2 * cifCurReadStyle->crs_multiplier * 8);
|
||||
size /= (calmaReadScale1 * cifCurReadStyle->crs_scaleFactor * 10);
|
||||
}
|
||||
}
|
||||
|
||||
/* Default or maximum size is 1um */
|
||||
micron = (int)((800 * cifCurReadStyle->crs_multiplier)
|
||||
/ cifCurReadStyle->crs_scaleFactor);
|
||||
if ((size == 0) || (size > micron))
|
||||
size = micron;
|
||||
|
||||
/* Default position is bottom-right (but what the spec calls "top-left"!) */
|
||||
pos = GEO_SOUTHEAST;
|
||||
|
||||
|
|
@ -820,8 +877,11 @@ calmaElementText()
|
|||
else
|
||||
/* Assume that MAG is the label size in microns */
|
||||
/* "size" is the label size in 10 * (database units) */
|
||||
size = (int)((dval * 1000 * cifCurReadStyle->crs_multiplier)
|
||||
/ cifCurReadStyle->crs_scaleFactor);
|
||||
/* The "calma magscale" option can be used to */
|
||||
/* reinterpret the size for any specific GDS file. */
|
||||
size = (int)(0.5 + ((dval * 1000 * CalmaMagScale
|
||||
* cifCurReadStyle->crs_multiplier)
|
||||
/ cifCurReadStyle->crs_scaleFactor));
|
||||
}
|
||||
else
|
||||
UNREADRH(nbytes, rtype);
|
||||
|
|
@ -947,8 +1007,6 @@ calmaElementText()
|
|||
flags = 0;
|
||||
else if (cifnum >= 0 && (cifCurReadStyle->crs_labelSticky[cifnum] != LABEL_TYPE_NONE))
|
||||
flags = LABEL_STICKY;
|
||||
else if (cifCurReadStyle->crs_flags & CRF_NO_RECONNECT_LABELS)
|
||||
flags = LABEL_STICKY;
|
||||
else
|
||||
flags = 0;
|
||||
|
||||
|
|
@ -970,6 +1028,26 @@ calmaElementText()
|
|||
sl->lab_next = lab->lab_next;
|
||||
if (cifReadCellDef->cd_lastLabel == lab)
|
||||
cifReadCellDef->cd_lastLabel = sl;
|
||||
|
||||
/* Port number from the placeholder is ignored; find
|
||||
* a new valid port number for the new label name.
|
||||
*/
|
||||
i = -1;
|
||||
for (sl = cifReadCellDef->cd_labels; sl != NULL; sl = sl->lab_next)
|
||||
{
|
||||
idx = sl->lab_port;
|
||||
if (idx > i) i = idx;
|
||||
if ((idx > 0) && (sl != lab) && !strcmp(sl->lab_text, textbody))
|
||||
{
|
||||
i = idx - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
portnum = i;
|
||||
flags |= PORT_DIR_NORTH | PORT_DIR_SOUTH |
|
||||
PORT_DIR_EAST | PORT_DIR_WEST;
|
||||
|
||||
freeMagic((char *)lab);
|
||||
break;
|
||||
}
|
||||
|
|
@ -978,16 +1056,14 @@ calmaElementText()
|
|||
}
|
||||
|
||||
if (font < 0)
|
||||
lab = DBPutLabel(cifReadCellDef, &r, pos, textbody, type, flags, 0);
|
||||
lab = DBPutLabel(cifReadCellDef, &r, pos, textbody, type, flags, portnum);
|
||||
else
|
||||
lab = DBPutFontLabel(cifReadCellDef, &r, font, size, angle,
|
||||
&GeoOrigin, pos, textbody, type, flags, 0);
|
||||
&GeoOrigin, pos, textbody, type, flags, portnum);
|
||||
|
||||
if ((lab != NULL) && (cifnum >= 0) &&
|
||||
(cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_PORT))
|
||||
{
|
||||
int idx;
|
||||
|
||||
/* No port information can be encoded in the GDS file, so */
|
||||
/* assume defaults, and assume that the port order is the */
|
||||
/* order in which labels arrive in the GDS stream. If */
|
||||
|
|
@ -1026,26 +1102,24 @@ calmaElementText()
|
|||
* centerline, to avoid roundoff errors.
|
||||
*
|
||||
* Results:
|
||||
* TRUE is returned if the path was parsed successfully,
|
||||
* FALSE otherwise.
|
||||
* non-NULL CIFPath* the caller takes ownership of
|
||||
* if the path was parsed successfully, otherwise NULL.
|
||||
*
|
||||
* Side effects:
|
||||
* Modifies the parameter pathheadpp to point to the path
|
||||
* that is constructed.
|
||||
* None
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool
|
||||
calmaReadPath(pathheadpp, iscale)
|
||||
CIFPath **pathheadpp;
|
||||
int iscale;
|
||||
CIFPath *
|
||||
calmaReadPath(
|
||||
int iscale)
|
||||
{
|
||||
CIFPath path, *pathtailp, *newpathp;
|
||||
CIFPath path, *pathheadp, *pathtailp, *newpathp;
|
||||
int nbytes, rtype, npoints, savescale;
|
||||
bool nonManhattan = FALSE;
|
||||
|
||||
*pathheadpp = (CIFPath *) NULL;
|
||||
pathheadp = (CIFPath *) NULL;
|
||||
pathtailp = (CIFPath *) NULL;
|
||||
path.cifp_next = (CIFPath *) NULL;
|
||||
|
||||
|
|
@ -1054,12 +1128,12 @@ calmaReadPath(pathheadpp, iscale)
|
|||
if (nbytes < 0)
|
||||
{
|
||||
CalmaReadError("EOF when reading path.\n");
|
||||
return (FALSE);
|
||||
return (NULL);
|
||||
}
|
||||
if (rtype != CALMA_XY)
|
||||
{
|
||||
calmaUnexpected(CALMA_XY, rtype);
|
||||
return (FALSE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Read this many points (pairs of four-byte integers) */
|
||||
|
|
@ -1070,7 +1144,7 @@ calmaReadPath(pathheadpp, iscale)
|
|||
calmaReadPoint(&path.cifp_point, iscale);
|
||||
if (savescale != calmaReadScale1)
|
||||
{
|
||||
CIFPath *phead = *pathheadpp;
|
||||
CIFPath *phead = pathheadp;
|
||||
int newscale = calmaReadScale1 / savescale;
|
||||
while (phead != NULL)
|
||||
{
|
||||
|
|
@ -1085,8 +1159,8 @@ calmaReadPath(pathheadpp, iscale)
|
|||
}
|
||||
if (FEOF(calmaInputFile))
|
||||
{
|
||||
CIFFreePath(*pathheadpp);
|
||||
return (FALSE);
|
||||
CIFFreePath(pathheadp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (iscale != 0)
|
||||
|
|
@ -1094,7 +1168,7 @@ calmaReadPath(pathheadpp, iscale)
|
|||
newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath)));
|
||||
*newpathp = path;
|
||||
|
||||
if (*pathheadpp)
|
||||
if (pathheadp)
|
||||
{
|
||||
/*
|
||||
* Check that this segment is Manhattan. If not, remember the
|
||||
|
|
@ -1115,11 +1189,11 @@ calmaReadPath(pathheadpp, iscale)
|
|||
}
|
||||
pathtailp->cifp_next = newpathp;
|
||||
}
|
||||
else *pathheadpp = newpathp;
|
||||
else pathheadp = newpathp;
|
||||
pathtailp = newpathp;
|
||||
}
|
||||
}
|
||||
return (*pathheadpp != NULL);
|
||||
return (pathheadp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1144,10 +1218,10 @@ calmaReadPath(pathheadpp, iscale)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaLayerError(mesg, layer, dt)
|
||||
char *mesg;
|
||||
int layer;
|
||||
int dt;
|
||||
calmaLayerError(
|
||||
char *mesg,
|
||||
int layer,
|
||||
int dt)
|
||||
{
|
||||
CalmaLayerType clt;
|
||||
HashEntry *he;
|
||||
|
|
|
|||
|
|
@ -17,9 +17,10 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRead.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRead.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -27,6 +28,12 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
#include <netinet/in.h>
|
||||
|
||||
/*
|
||||
* C99 compat
|
||||
* Mind: tcltk/tclmagic.h must be included prior to all the other headers
|
||||
*/
|
||||
#include "tcltk/tclmagic.h"
|
||||
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
#include "tiles/tile.h"
|
||||
|
|
@ -55,9 +62,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
/* Globals for Calma reading */
|
||||
FILETYPE calmaInputFile = NULL; /* Read from this stream */
|
||||
FILE *calmaErrorFile = NULL; /* Write error output here */
|
||||
bool CalmaSubcellPolygons = FALSE; /* Put non-Manhattan polygons
|
||||
* in their own subcells.
|
||||
*/
|
||||
unsigned char CalmaSubcellPolygons = CALMA_POLYGON_NONE;
|
||||
/* Read non-Manhattan polygons as-is */
|
||||
int CalmaPolygonCount;
|
||||
bool CalmaSubcellPaths = FALSE; /* Put paths in their own subcells. */
|
||||
int CalmaPathCount;
|
||||
|
|
@ -76,6 +82,12 @@ bool CalmaReadOnly = FALSE; /* Set files to read-only and
|
|||
* retain file position information
|
||||
* so cells can be written verbatim.
|
||||
*/
|
||||
float CalmaMagScale = 1.0; /* Scale by which to interpret the MAG
|
||||
* record in GDS text records. The
|
||||
* default is to treat the value as
|
||||
* the text height in microns. This
|
||||
* value reinterprets the scale.
|
||||
*/
|
||||
bool CalmaNoDRCCheck = FALSE; /* If TRUE, don't mark cells as needing
|
||||
* a DRC check; they will be assumed
|
||||
* DRC clean.
|
||||
|
|
@ -99,10 +111,8 @@ bool CalmaUnique = FALSE; /* If TRUE, then if a cell exists in
|
|||
*/
|
||||
extern bool CalmaDoLibrary; /* Also used by GDS write */
|
||||
|
||||
extern void calmaUnexpected();
|
||||
extern int calmaWriteInitFunc();
|
||||
|
||||
bool calmaParseUnits();
|
||||
extern void calmaUnexpected(int wanted, int got);
|
||||
extern int calmaWriteInitFunc(CellDef *def);
|
||||
|
||||
/*
|
||||
* Scaling.
|
||||
|
|
@ -137,7 +147,7 @@ HashTable calmaLayerHash;
|
|||
HashTable calmaDefInitHash;
|
||||
|
||||
/* Common stuff to ignore */
|
||||
int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 };
|
||||
const int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 };
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -157,18 +167,18 @@ int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 };
|
|||
*/
|
||||
|
||||
void
|
||||
CalmaReadFile(file, filename)
|
||||
FILETYPE file; /* File from which to read Calma */
|
||||
char *filename; /* The real name of the file read */
|
||||
CalmaReadFile(
|
||||
FILETYPE file, /* File from which to read Calma */
|
||||
char *filename) /* The real name of the file read */
|
||||
{
|
||||
int k, version;
|
||||
char *libname = NULL, *libnameptr;
|
||||
char *libname = NULL, *libnameptr = NULL;
|
||||
MagWindow *mw;
|
||||
static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS,
|
||||
CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE,
|
||||
CALMA_STYPTABLE, CALMA_GENERATIONS, -1 };
|
||||
static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME,
|
||||
CALMA_LIBSECUR, -1 };
|
||||
static const int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS,
|
||||
CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE,
|
||||
CALMA_STYPTABLE, CALMA_GENERATIONS, -1 };
|
||||
static const int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME,
|
||||
CALMA_LIBSECUR, -1 };
|
||||
|
||||
if (EditCellUse == (CellUse *)NULL)
|
||||
{
|
||||
|
|
@ -289,7 +299,7 @@ done:
|
|||
windCheckOnlyWindow(&mw, DBWclientID);
|
||||
if (mw != NULL)
|
||||
{
|
||||
if (calmaLookCell(libnameptr, NULL) != (CellDef *)NULL)
|
||||
if (calmaLookCell(libnameptr) != (CellDef *)NULL)
|
||||
DBWloadWindow(mw, libnameptr, 0);
|
||||
}
|
||||
freeMagic(libname);
|
||||
|
|
@ -299,7 +309,11 @@ done:
|
|||
HashKill(&calmaDefInitHash);
|
||||
UndoEnable();
|
||||
|
||||
if (calmaErrorFile != NULL) fclose(calmaErrorFile);
|
||||
if (calmaErrorFile != NULL)
|
||||
{
|
||||
fclose(calmaErrorFile);
|
||||
calmaErrorFile = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -333,12 +347,13 @@ done:
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaParseUnits()
|
||||
calmaParseUnits(void)
|
||||
{
|
||||
int nbytes, rtype;
|
||||
int nbytes, rtype = 0;
|
||||
double metersPerDBUnit;
|
||||
double userUnitsPerDBUnit;
|
||||
double cuPerDBUnit;
|
||||
bool compatible;
|
||||
|
||||
READRH(nbytes, rtype);
|
||||
#ifdef lint
|
||||
|
|
@ -357,6 +372,39 @@ calmaParseUnits()
|
|||
/* Read meters per database unit */
|
||||
if (!calmaReadR8(&metersPerDBUnit)) return (FALSE);
|
||||
|
||||
/* Important! When CalmaReadOnly is TRUE, then this file will have its
|
||||
* contents output verbatim. But if the database units don't match,
|
||||
* then it will get output at the wrong scale. Setting a magnification
|
||||
* factor on the instance when generating output might (?) work. For
|
||||
* now, prohibiting a GDS read in read-only mode when the database units
|
||||
* don't match. This forces the user either to reconsider the read-only
|
||||
* status or to rewrite the GDS at a compatible scalefactor.
|
||||
*/
|
||||
compatible = TRUE;
|
||||
if (CalmaReadOnly == TRUE)
|
||||
{
|
||||
if (CIFCurStyle->cs_flags & CWF_ANGSTROMS)
|
||||
{
|
||||
if ((int)(0.5 + metersPerDBUnit * 1e12) != 100)
|
||||
{
|
||||
CalmaReadError("Incompatible scale factor of %g, must be 1e-10.\n",
|
||||
metersPerDBUnit);
|
||||
TxError("Cannot read this file in read-only mode.\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)(0.5 + metersPerDBUnit * 1e11) != 100)
|
||||
{
|
||||
CalmaReadError("Incompatible scale factor of %g, must be 1e-9.\n",
|
||||
metersPerDBUnit);
|
||||
TxError("Cannot read this file in read-only mode.\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
TxPrintf("1 database unit equals %e user units\n", userUnitsPerDBUnit);
|
||||
TxPrintf("1 database unit equals %e meters\n", metersPerDBUnit);
|
||||
|
|
@ -411,11 +459,9 @@ calmaParseUnits()
|
|||
*/
|
||||
|
||||
void
|
||||
/*VARARGS1*/
|
||||
CalmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
|
||||
char *format;
|
||||
char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9, *a10;
|
||||
CalmaReadError(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
OFFTYPE filepos;
|
||||
|
||||
calmaTotalErrors++;
|
||||
|
|
@ -433,15 +479,18 @@ CalmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
|
|||
cifReadCellDef->cd_name);
|
||||
fprintf(calmaErrorFile, "(byte position %"DLONG_PREFIX"d): ",
|
||||
(dlong)filepos);
|
||||
fprintf(calmaErrorFile, format, a1, a2, a3, a4, a5, a6, a7,
|
||||
a8, a9, a10);
|
||||
va_start(args, format);
|
||||
Vfprintf(calmaErrorFile, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TxError("Error while reading cell \"%s\" ", cifReadCellDef->cd_name);
|
||||
TxError("(byte position %"DLONG_PREFIX"d): ", (dlong)filepos);
|
||||
TxError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
|
||||
va_start(args, format);
|
||||
TxErrorV(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
else if ((calmaTotalErrors == 100) && (CIFWarningLevel == CIF_WARN_LIMIT))
|
||||
|
|
@ -467,9 +516,9 @@ CalmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaUnexpected(wanted, got)
|
||||
int wanted; /* Type of record we wanted */
|
||||
int got; /* Type of record we got */
|
||||
calmaUnexpected(
|
||||
int wanted, /* Type of record we wanted */
|
||||
int got) /* Type of record we got */
|
||||
{
|
||||
CalmaReadError("Unexpected record type in input: \n");
|
||||
|
||||
|
|
@ -509,12 +558,12 @@ calmaUnexpected(wanted, got)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
calmaRecordName(rtype)
|
||||
int rtype;
|
||||
const char *
|
||||
calmaRecordName(
|
||||
int rtype)
|
||||
{
|
||||
static char numeric[10];
|
||||
static char *calmaRecordNames[] =
|
||||
static const char * const calmaRecordNames[] =
|
||||
{
|
||||
"HEADER", "BGNLIB", "LIBNAME", "UNITS",
|
||||
"ENDLIB", "BGNSTR", "STRNAME", "ENDSTR",
|
||||
|
|
@ -559,8 +608,28 @@ calmaRecordName(rtype)
|
|||
*/
|
||||
|
||||
void
|
||||
CalmaTechInit()
|
||||
CalmaTechInit(void)
|
||||
{
|
||||
ASSERT(sizeof(FourByteInt)==4, "definition in calmaInt.h");
|
||||
ASSERT(sizeof(TwoByteInt)==2, "definition in calmaInt.h");
|
||||
|
||||
/* NOTE: Add "$$*$$" to the default "flatglob" value */
|
||||
/* when CalmaContactArrays behaves like the non-arrayed */
|
||||
/* function and can be enabled by default. */
|
||||
|
||||
/* Initialize CalmaFlattenByName to have one entry for */
|
||||
/* "*_CDNS_*" to match the name style used by many foundry */
|
||||
/* cells and which corresponds to pcells that often split */
|
||||
/* layers between cells in ways that magic can't cope with; */
|
||||
/* and whose original parameterized functions cannot be */
|
||||
/* recovered by magic anyway. When necessary, this default */
|
||||
/* can be overridden by the "gds flatglob none" command */
|
||||
/* option. */
|
||||
|
||||
if (CalmaFlattenUsesByName == (char **)NULL)
|
||||
{
|
||||
CalmaFlattenUsesByName = (char **)mallocMagic(2 * sizeof(char *));
|
||||
*CalmaFlattenUsesByName = StrDup((char **)NULL, "*_CDNS_*");
|
||||
*(CalmaFlattenUsesByName + 1) = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/calma/CalmaWrite.c,v 1.8 2010/12/22 16:29:06 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/calma/CalmaWrite.c,v 1.8 2010/12/22 16:29:06 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
|
|
@ -34,13 +34,19 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h> /* for random() */
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h> /* for htons() */
|
||||
#ifdef SYSV
|
||||
#include <time.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "utils/magic.h"
|
||||
|
|
@ -48,6 +54,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
|
|||
#include "utils/geometry.h"
|
||||
#include "tiles/tile.h"
|
||||
#include "utils/utils.h"
|
||||
#include "utils/magic_zlib.h"
|
||||
#include "utils/hash.h"
|
||||
#include "database/database.h"
|
||||
#include "database/databaseInt.h"
|
||||
|
|
@ -60,6 +67,7 @@ static char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic-8.0/c
|
|||
#include "utils/styles.h"
|
||||
#include "textio/textio.h"
|
||||
#include "calma/calmaInt.h"
|
||||
#include "extract/extractInt.h" /* for LabelList */
|
||||
#include "utils/main.h" /* for Path and CellLibPath */
|
||||
#include "utils/stack.h"
|
||||
|
||||
|
|
@ -88,32 +96,31 @@ extern int calmaPaintLayerNumber;
|
|||
extern int calmaPaintLayerType;
|
||||
|
||||
/* External functions from CalmaWrite.c */
|
||||
extern int calmaWriteInitFunc();
|
||||
extern int calmaWriteMarkFunc();
|
||||
|
||||
/* Forward declarations */
|
||||
extern int calmaWritePaintFuncZ();
|
||||
extern int calmaMergePaintFuncZ();
|
||||
extern int calmaWriteUseFuncZ();
|
||||
extern int calmaPaintLabelFuncZ();
|
||||
extern void calmaWriteContactsZ();
|
||||
extern void calmaOutFuncZ();
|
||||
extern void calmaOutStructNameZ();
|
||||
extern void calmaWriteLabelFuncZ();
|
||||
extern void calmaOutHeaderZ();
|
||||
extern void calmaOutDateZ();
|
||||
extern void calmaOutStringRecordZ();
|
||||
extern void calmaOut8Z();
|
||||
extern void calmaOutR8Z();
|
||||
extern int calmaWriteInitFunc(CellDef *def);
|
||||
|
||||
/* Structure used by calmaWritePaintFuncZ() and others */
|
||||
|
||||
typedef struct {
|
||||
gzFile f; /* Compressed file stream for output */
|
||||
Rect *area; /* Clipping area, in GDS coordinates */
|
||||
const Rect *area; /* Clipping area, in GDS coordinates */
|
||||
int type; /* Layer index */
|
||||
} calmaOutputStructZ;
|
||||
|
||||
/* Forward declarations */
|
||||
extern int calmaWritePaintFuncZ(Tile *tile, TileType dinfo, calmaOutputStructZ *cos);
|
||||
extern int calmaMergePaintFuncZ(Tile *tile, TileType dinfo, calmaOutputStructZ *cos);
|
||||
extern int calmaWriteUseFuncZ(CellUse *use, gzFile f);
|
||||
extern int calmaPaintLabelFuncZ(Tile *tile, TileType dinfo, calmaOutputStructZ *cos);
|
||||
extern void calmaWriteContactsZ(gzFile f);
|
||||
extern void calmaOutFuncZ(CellDef *def, gzFile f, const Rect *cliprect);
|
||||
extern void calmaOutStructNameZ(int type, CellDef *def, gzFile f);
|
||||
extern void calmaWriteLabelFuncZ(Label *lab, int ltype, int type, gzFile f);
|
||||
extern void calmaOutHeaderZ(CellDef *rootDef, gzFile f);
|
||||
extern void calmaOutDateZ(time_t t, gzFile f);
|
||||
extern void calmaOutStringRecordZ(int type, char *str, gzFile f);
|
||||
extern void calmaOut8Z(const char *str, gzFile f);
|
||||
extern void calmaOutR8Z(double d, gzFile f);
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Structures used by the tile merging algorithm */
|
||||
/*--------------------------------------------------------------*/
|
||||
|
|
@ -122,28 +129,12 @@ typedef struct {
|
|||
#define GDS_UNPROCESSED CLIENTDEFAULT
|
||||
#define GDS_PROCESSED 1
|
||||
|
||||
#define PUSHTILE(tp) \
|
||||
if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \
|
||||
(tp)->ti_client = (ClientData) GDS_PENDING; \
|
||||
#define PUSHTILEZ(tp) \
|
||||
if (TiGetClient(tp) == GDS_UNPROCESSED) { \
|
||||
TiSetClientINT(tp, GDS_PENDING); \
|
||||
STACKPUSH((ClientData) (tp), SegStack); \
|
||||
}
|
||||
|
||||
#define LB_EXTERNAL 0 /* Polygon external edge */
|
||||
#define LB_INTERNAL 1 /* Polygon internal edge */
|
||||
#define LB_INIT 2 /* Data not yet valid */
|
||||
|
||||
typedef struct LB1 {
|
||||
char lb_type; /* Boundary Type (external or internal) */
|
||||
Point lb_start; /* Start point */
|
||||
struct LB1 *lb_next; /* Next point record */
|
||||
} LinkedBoundary;
|
||||
|
||||
typedef struct BT1 {
|
||||
LinkedBoundary *bt_first; /* Polygon list */
|
||||
int bt_points; /* Number of points in this list */
|
||||
struct BT1 *bt_next; /* Next polygon record */
|
||||
} BoundaryTop;
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
|
|
@ -195,7 +186,7 @@ typedef struct BT1 {
|
|||
(void) gzputc(f, u.u_c[3]); \
|
||||
}
|
||||
|
||||
static char calmaMapTableStrict[] =
|
||||
static const char calmaMapTableStrict[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* NUL - BEL */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* BS - SI */
|
||||
|
|
@ -215,7 +206,7 @@ static char calmaMapTableStrict[] =
|
|||
'x', 'y', 'z', '_', '_', '_', '_', 0, /* x - DEL */
|
||||
};
|
||||
|
||||
static char calmaMapTablePermissive[] =
|
||||
static const char calmaMapTablePermissive[] =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* NUL - BEL */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, /* BS - SI */
|
||||
|
|
@ -270,12 +261,13 @@ static char calmaMapTablePermissive[] =
|
|||
*/
|
||||
|
||||
bool
|
||||
CalmaWriteZ(rootDef, f)
|
||||
CellDef *rootDef; /* Pointer to CellDef to be written */
|
||||
gzFile f; /* Open compressed output file */
|
||||
CalmaWriteZ(
|
||||
CellDef *rootDef, /* Pointer to CellDef to be written */
|
||||
gzFile f) /* Open compressed output file */
|
||||
{
|
||||
int oldCount = DBWFeedbackCount, problems, nerr;
|
||||
bool good;
|
||||
CellDef *err_def;
|
||||
CellUse dummy;
|
||||
HashEntry *he;
|
||||
HashSearch hs;
|
||||
|
|
@ -301,9 +293,11 @@ CalmaWriteZ(rootDef, f)
|
|||
*/
|
||||
|
||||
dummy.cu_def = rootDef;
|
||||
if (DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined))
|
||||
err_def = DBCellReadArea(&dummy, &rootDef->cd_bbox, !CalmaAllowUndefined);
|
||||
if (err_def != NULL)
|
||||
{
|
||||
TxError("Failure to read entire subtree of the cell.\n");
|
||||
TxError("Failed on cell %s.\n", err_def->cd_name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -365,7 +359,7 @@ CalmaWriteZ(rootDef, f)
|
|||
good = (nerr == 0) ? TRUE : FALSE;
|
||||
|
||||
/* See if any problems occurred */
|
||||
if (problems = (DBWFeedbackCount - oldCount))
|
||||
if ((problems = (DBWFeedbackCount - oldCount)))
|
||||
TxPrintf("%d problems occurred. See feedback entries.\n", problems);
|
||||
|
||||
/*
|
||||
|
|
@ -395,13 +389,13 @@ CalmaWriteZ(rootDef, f)
|
|||
*/
|
||||
|
||||
bool
|
||||
calmaDumpStructureZ(def, outf, calmaDefHash, filename)
|
||||
CellDef *def;
|
||||
gzFile outf;
|
||||
HashTable *calmaDefHash;
|
||||
char *filename;
|
||||
calmaDumpStructureZ(
|
||||
CellDef *def,
|
||||
gzFile outf,
|
||||
HashTable *calmaDefHash,
|
||||
char *filename)
|
||||
{
|
||||
int nbytes, rtype;
|
||||
int nbytes = -1, rtype = 0;
|
||||
char *strname = NULL, *newnameptr;
|
||||
HashEntry *he, *he2;
|
||||
CellDef *edef;
|
||||
|
|
@ -665,11 +659,11 @@ syntaxerror:
|
|||
*/
|
||||
|
||||
void
|
||||
calmaFullDumpZ(def, fi, outf, filename)
|
||||
CellDef *def;
|
||||
gzFile fi;
|
||||
gzFile outf;
|
||||
char *filename;
|
||||
calmaFullDumpZ(
|
||||
CellDef *def,
|
||||
gzFile fi,
|
||||
gzFile outf,
|
||||
char *filename)
|
||||
{
|
||||
int version, rval;
|
||||
char *libname = NULL, *testlib, uniqlibname[4];
|
||||
|
|
@ -679,10 +673,10 @@ calmaFullDumpZ(def, fi, outf, filename)
|
|||
HashSearch hs;
|
||||
HashEntry *he, *he2;
|
||||
|
||||
static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS,
|
||||
static const int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS,
|
||||
CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE,
|
||||
CALMA_STYPTABLE, CALMA_GENERATIONS, CALMA_UNITS, -1 };
|
||||
static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME,
|
||||
CALMA_STYPTABLE, CALMA_GENERATIONS, -1 };
|
||||
static const int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME,
|
||||
CALMA_LIBSECUR, -1 };
|
||||
|
||||
HashInit(&calmaDefHash, 32, 0);
|
||||
|
|
@ -697,10 +691,14 @@ calmaFullDumpZ(def, fi, outf, filename)
|
|||
calmaSkipSet(skipBeforeLib);
|
||||
if (!calmaReadStringRecord(CALMA_LIBNAME, &libname)) goto done;
|
||||
|
||||
// NOTE: CALMA_UNITS needs to be parsed to determine if units in
|
||||
// the input file are compatible with units being used in the output
|
||||
// CALMA_UNITS needs to be parsed to determine if units in the
|
||||
// input file are compatible with units being used in the output
|
||||
// file.
|
||||
calmaSkipSet(hdrSkip);
|
||||
if (calmaParseUnits() == FALSE)
|
||||
{
|
||||
TxError("Error: Library %s has incompatible database units!\n", libname);
|
||||
return;
|
||||
}
|
||||
|
||||
// Record the GDS library so it will not be processed again.
|
||||
he = HashFind(&calmaLibHash, filename);
|
||||
|
|
@ -809,42 +807,40 @@ done:
|
|||
*/
|
||||
|
||||
int
|
||||
calmaProcessUseZ(use, outf)
|
||||
CellUse *use; /* Process use->cu_def */
|
||||
gzFile outf; /* Stream file */
|
||||
calmaProcessUseZ(
|
||||
CellUse *use, /* Process use->cu_def */
|
||||
gzFile outf) /* Stream file */
|
||||
{
|
||||
return (calmaProcessDefZ(use->cu_def, outf, FALSE));
|
||||
}
|
||||
|
||||
int
|
||||
calmaProcessDefZ(def, outf, do_library)
|
||||
CellDef *def; /* Output this def's children, then the def itself */
|
||||
gzFile outf; /* Stream file */
|
||||
bool do_library; /* If TRUE, output only children of def, but not def */
|
||||
calmaProcessDefZ(
|
||||
CellDef *def, /* Output this def's children, then the def itself */
|
||||
gzFile outf, /* Stream file */
|
||||
bool do_library) /* If TRUE, output only children of def, but not def */
|
||||
{
|
||||
char *filename;
|
||||
int polyidx;
|
||||
bool isReadOnly, oldStyle, hasContent, isAbstract, hasGDSEnd;
|
||||
bool isReadOnly, oldStyle, hasContent, isAbstract, hasGDSEnd, needHier;
|
||||
bool hierWrite, arrayWrite;
|
||||
HashEntry *he;
|
||||
|
||||
/* Skip if already output */
|
||||
if ((int) def->cd_client > 0)
|
||||
if ((int) CD2INT(def->cd_client) > 0)
|
||||
return (0);
|
||||
|
||||
/* Assign it a (negative) number if it doesn't have one yet */
|
||||
if ((int) def->cd_client == 0)
|
||||
def->cd_client = (ClientData) calmaCellNum--;
|
||||
if ((int) CD2INT(def->cd_client) == 0)
|
||||
def->cd_client = INT2CD(calmaCellNum--);
|
||||
|
||||
/* Mark this cell */
|
||||
def->cd_client = (ClientData) (- (int) def->cd_client);
|
||||
def->cd_client = INT2CD(- (int) CD2INT(def->cd_client));
|
||||
|
||||
/* Read the cell in if it is not already available. */
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL))
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flag an error if attempting to write the default (UNNAMED) cell
|
||||
|
|
@ -873,6 +869,7 @@ calmaProcessDefZ(def, outf, do_library)
|
|||
DBPropGet(def, "LEFview", &isAbstract);
|
||||
DBPropGet(def, "GDS_START", &hasContent);
|
||||
DBPropGet(def, "GDS_END", &hasGDSEnd);
|
||||
DBPropGet(def, "CIFhier", &needHier);
|
||||
filename = (char *)DBPropGet(def, "GDS_FILE", &isReadOnly);
|
||||
|
||||
/* When used with "calma addendum true", don't output the read-only */
|
||||
|
|
@ -902,8 +899,29 @@ calmaProcessDefZ(def, outf, do_library)
|
|||
* as they are expected to be in the referenced GDS file.
|
||||
*/
|
||||
if (!hasContent || hasGDSEnd)
|
||||
if (DBCellEnum(def, calmaProcessUseZ, (ClientData) outf) != 0)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (needHier)
|
||||
{
|
||||
hierWrite = CIFHierWriteDisable;
|
||||
arrayWrite = CIFArrayWriteDisable;
|
||||
|
||||
CIFHierWriteDisable = FALSE;
|
||||
CIFArrayWriteDisable = FALSE;
|
||||
}
|
||||
|
||||
result = DBCellEnum(def, calmaProcessUseZ, (ClientData) outf);
|
||||
|
||||
if (needHier)
|
||||
{
|
||||
CIFHierWriteDisable = hierWrite;
|
||||
CIFArrayWriteDisable = arrayWrite;
|
||||
}
|
||||
|
||||
if (result != 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Give some feedback to the user */
|
||||
TxPrintf(" Generating output for cell %s\n", def->cd_name);
|
||||
|
|
@ -921,6 +939,11 @@ calmaProcessDefZ(def, outf, do_library)
|
|||
/* searched to find the .mag file that indicated this GDS file. */
|
||||
|
||||
fi = PaZOpen(filename, "r", "", Path, CellLibPath, &retfilename);
|
||||
|
||||
/* Check if file may have been compressed */
|
||||
if (fi == NULL)
|
||||
fi = PaZOpen(filename, "r", ".gz", Path, CellLibPath, &retfilename);
|
||||
|
||||
if (fi == NULL)
|
||||
{
|
||||
/* This is a rare error, but if the subcell is inside */
|
||||
|
|
@ -1026,6 +1049,7 @@ calmaProcessDefZ(def, outf, do_library)
|
|||
" Using magic's internal definition\n");
|
||||
isReadOnly = FALSE;
|
||||
}
|
||||
freeMagic(buffer);
|
||||
|
||||
if (cellend < cellstart) /* Sanity check */
|
||||
{
|
||||
|
|
@ -1106,8 +1130,25 @@ calmaProcessDefZ(def, outf, do_library)
|
|||
/* Output this cell definition from the Magic database */
|
||||
if (!isReadOnly)
|
||||
if (!do_library)
|
||||
{
|
||||
if (needHier)
|
||||
{
|
||||
hierWrite = CIFHierWriteDisable;
|
||||
arrayWrite = CIFArrayWriteDisable;
|
||||
|
||||
CIFHierWriteDisable = FALSE;
|
||||
CIFArrayWriteDisable = FALSE;
|
||||
}
|
||||
|
||||
calmaOutFuncZ(def, outf, &TiPlaneRect);
|
||||
|
||||
if (needHier)
|
||||
{
|
||||
CIFHierWriteDisable = hierWrite;
|
||||
CIFArrayWriteDisable = arrayWrite;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1131,10 +1172,10 @@ calmaProcessDefZ(def, outf, do_library)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaOutFuncZ(def, f, cliprect)
|
||||
CellDef *def; /* Pointer to cell def to be written */
|
||||
gzFile f; /* Open output file */
|
||||
Rect *cliprect; /* Area to clip to (used for contact cells),
|
||||
calmaOutFuncZ(
|
||||
CellDef *def, /* Pointer to cell def to be written */
|
||||
gzFile f, /* Open output file */
|
||||
const Rect *cliprect)/* Area to clip to (used for contact cells),
|
||||
* in CIF/GDS coordinates.
|
||||
*/
|
||||
{
|
||||
|
|
@ -1144,6 +1185,9 @@ calmaOutFuncZ(def, f, cliprect)
|
|||
int type;
|
||||
int dbunits;
|
||||
calmaOutputStructZ cos;
|
||||
bool propfound;
|
||||
char *propvalue;
|
||||
extern int compport(const void *one, const void *two); /* Forward declaration */
|
||||
|
||||
cos.f = f;
|
||||
cos.area = (cliprect == &TiPlaneRect) ? NULL : cliprect;
|
||||
|
|
@ -1200,13 +1244,27 @@ calmaOutFuncZ(def, f, cliprect)
|
|||
|
||||
/* Output all the tiles associated with this cell; skip temporary layers */
|
||||
GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea);
|
||||
|
||||
/* Include any fixed bounding box as part of the area to process, */
|
||||
/* in case the fixed bounding box is larger than the geometry. */
|
||||
propvalue = (char *)DBPropGet(def, "FIXED_BBOX", &propfound);
|
||||
if (propfound)
|
||||
{
|
||||
Rect bbox;
|
||||
|
||||
if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
|
||||
&bbox.r_xtop, &bbox.r_ytop) == 4)
|
||||
GeoInclude(&bbox, &bigArea);
|
||||
}
|
||||
|
||||
CIFErrorDef = def;
|
||||
CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE,
|
||||
(ClientData)f);
|
||||
|
||||
if (!CIFHierWriteDisable)
|
||||
CIFGenSubcells(def, &bigArea, CIFPlanes);
|
||||
CIFGenSubcells(def, &bigArea, CIFPlanes);
|
||||
if (!CIFArrayWriteDisable)
|
||||
CIFGenArrays(def, &bigArea, CIFPlanes);
|
||||
CIFGenArrays(def, &bigArea, CIFPlanes);
|
||||
|
||||
for (type = 0; type < CIFCurStyle->cs_nLayers; type++)
|
||||
{
|
||||
|
|
@ -1234,33 +1292,57 @@ calmaOutFuncZ(def, f, cliprect)
|
|||
|
||||
if (CalmaDoLabels)
|
||||
{
|
||||
int i, maxport = -1;
|
||||
int i, ltype, numports = 0;
|
||||
LabelList *ll = NULL, *newll;
|
||||
|
||||
for (lab = def->cd_labels; lab; lab = lab->lab_next)
|
||||
{
|
||||
type = CIFCurStyle->cs_labelLayer[lab->lab_type];
|
||||
if ((type >= 0) && (lab->lab_flags & PORT_DIR_MASK) == 0)
|
||||
if ((lab->lab_flags & PORT_DIR_MASK) == 0)
|
||||
{
|
||||
calmaWriteLabelFuncZ(lab, type, f);
|
||||
ltype = CIFCurStyle->cs_labelLayer[lab->lab_type];
|
||||
type = ltype;
|
||||
calmaWriteLabelFuncZ(lab, ltype, type, f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((int)lab->lab_port > maxport)
|
||||
maxport = (int)lab->lab_port;
|
||||
newll = (LabelList *)mallocMagic(sizeof(LabelList));
|
||||
newll->ll_label = lab;
|
||||
newll->ll_attr = (unsigned int)lab->lab_port;
|
||||
newll->ll_next = ll;
|
||||
ll = newll;
|
||||
numports++;
|
||||
}
|
||||
}
|
||||
if (maxport >= 0)
|
||||
for (i = 0; i <= maxport; i++)
|
||||
for (lab = def->cd_labels; lab; lab = lab->lab_next)
|
||||
{
|
||||
type = CIFCurStyle->cs_portLayer[lab->lab_type];
|
||||
if ((type >= 0) && ((lab->lab_flags & PORT_DIR_MASK) != 0) &&
|
||||
(lab->lab_port == i))
|
||||
{
|
||||
calmaWriteLabelFuncZ(lab, type, f);
|
||||
/* break; */ /* Do not limit to unique labels! */
|
||||
}
|
||||
}
|
||||
if (newll != NULL)
|
||||
{
|
||||
/* Turn linked list into an array, then run qsort on it */
|
||||
/* to sort by port number. */
|
||||
|
||||
PortLabel *pllist = (PortLabel *)mallocMagic(numports * sizeof(PortLabel));
|
||||
i = 0;
|
||||
while (ll != NULL)
|
||||
{
|
||||
pllist[i].pl_label = ll->ll_label;
|
||||
pllist[i].pl_port = (unsigned int)ll->ll_attr;
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, ll);
|
||||
ll = ll->ll_next;
|
||||
freeMagic1_end(&mm1);
|
||||
i++;
|
||||
}
|
||||
|
||||
qsort(pllist, numports, sizeof(PortLabel), compport);
|
||||
|
||||
for (i = 0; i < numports; i++)
|
||||
{
|
||||
lab = pllist[i].pl_label;
|
||||
ltype = CIFCurStyle->cs_portText[lab->lab_type];
|
||||
type = CIFCurStyle->cs_portLayer[lab->lab_type];
|
||||
if (type >= 0)
|
||||
calmaWriteLabelFuncZ(lab, ltype, type, f);
|
||||
}
|
||||
freeMagic(pllist);
|
||||
}
|
||||
}
|
||||
|
||||
/* End of structure */
|
||||
|
|
@ -1287,9 +1369,9 @@ calmaOutFuncZ(def, f, cliprect)
|
|||
*/
|
||||
|
||||
int
|
||||
calmaWriteUseFuncZ(use, f)
|
||||
CellUse *use;
|
||||
gzFile f;
|
||||
calmaWriteUseFuncZ(
|
||||
CellUse *use,
|
||||
gzFile f)
|
||||
{
|
||||
/*
|
||||
* r90, r180, and r270 are Calma 8-byte real representations
|
||||
|
|
@ -1297,10 +1379,10 @@ calmaWriteUseFuncZ(use, f)
|
|||
* only 4 possible values, it is faster to have them pre-computed
|
||||
* than to format with calmaOutR8Z().
|
||||
*/
|
||||
static unsigned char r90[] = { 0x42, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static unsigned char r180[] = { 0x42, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static unsigned char r270[] = { 0x43, 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
unsigned char *whichangle;
|
||||
static const unsigned char r90[] = { 0x42, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const unsigned char r180[] = { 0x42, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const unsigned char r270[] = { 0x43, 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
const unsigned char *whichangle;
|
||||
int x, y, topx, topy, rows, cols, xxlate, yxlate, hdrsize;
|
||||
int rectype, stransflags;
|
||||
Transform *t;
|
||||
|
|
@ -1374,7 +1456,7 @@ calmaWriteUseFuncZ(use, f)
|
|||
if (whichangle)
|
||||
{
|
||||
calmaOutRHZ(12, CALMA_ANGLE, CALMA_R8, f);
|
||||
calmaOut8Z(whichangle, f);
|
||||
calmaOut8Z((char *)whichangle, f);
|
||||
}
|
||||
|
||||
/* Translation */
|
||||
|
|
@ -1411,7 +1493,7 @@ calmaWriteUseFuncZ(use, f)
|
|||
if (whichangle)
|
||||
{
|
||||
calmaOutRHZ(12, CALMA_ANGLE, CALMA_R8, f);
|
||||
calmaOut8Z(whichangle, f);
|
||||
calmaOut8Z((char *)whichangle, f);
|
||||
}
|
||||
|
||||
/* If array, number of columns and rows in the array */
|
||||
|
|
@ -1457,13 +1539,11 @@ calmaWriteUseFuncZ(use, f)
|
|||
/* By NP */
|
||||
/* Property attributes/value pairs. */
|
||||
/* Add a CellUse ID property, if the CellUse has a non-default name */
|
||||
/* (Modified 11/11/2022: Do this always, not just the non-default case) */
|
||||
|
||||
if (!calmaIsUseNameDefault(use->cu_def->cd_name, use->cu_id))
|
||||
{
|
||||
calmaOutRHZ(6, CALMA_PROPATTR, CALMA_I2, f);
|
||||
calmaOutI2Z(CALMA_PROP_USENAME_STD, f);
|
||||
calmaOutStringRecordZ(CALMA_PROPVALUE, use->cu_id, f);
|
||||
}
|
||||
calmaOutRHZ(6, CALMA_PROPATTR, CALMA_I2, f);
|
||||
calmaOutI2Z(CALMA_PROP_USENAME_STD, f);
|
||||
calmaOutStringRecordZ(CALMA_PROPVALUE, use->cu_id, f);
|
||||
|
||||
/* Add an array limits property, if the CellUse is an array and */
|
||||
/* limits of the array (xlo, ylo) are not zero (the default). */
|
||||
|
|
@ -1504,16 +1584,16 @@ calmaWriteUseFuncZ(use, f)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaOutStructNameZ(type, def, f)
|
||||
int type;
|
||||
CellDef *def;
|
||||
gzFile f;
|
||||
calmaOutStructNameZ(
|
||||
int type,
|
||||
CellDef *def,
|
||||
gzFile f)
|
||||
{
|
||||
char *defname;
|
||||
unsigned char c;
|
||||
char *cp;
|
||||
int calmanum;
|
||||
char *table;
|
||||
const char *table;
|
||||
|
||||
if (CIFCurStyle->cs_flags & CWF_PERMISSIVE_LABELS)
|
||||
{
|
||||
|
|
@ -1523,7 +1603,7 @@ calmaOutStructNameZ(type, def, f)
|
|||
}
|
||||
|
||||
/* Is the def name a legal Calma name? */
|
||||
for (cp = def->cd_name; c = (unsigned char) *cp; cp++)
|
||||
for (cp = def->cd_name; (c = (unsigned char) *cp); cp++)
|
||||
{
|
||||
if ((c > 127) || (table[c] == 0))
|
||||
goto bad;
|
||||
|
|
@ -1544,7 +1624,7 @@ calmaOutStructNameZ(type, def, f)
|
|||
{
|
||||
/* Bad name: use XXXXXcalmaNum */
|
||||
bad:
|
||||
calmanum = (int) def->cd_client;
|
||||
calmanum = (int) CD2INT(def->cd_client);
|
||||
if (calmanum < 0) calmanum = -calmanum;
|
||||
defname = (char *)mallocMagic(32);
|
||||
(void) sprintf(defname, "XXXXX%d", calmanum);
|
||||
|
|
@ -1559,7 +1639,7 @@ bad:
|
|||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* CalmaGenerateArray --
|
||||
* CalmaGenerateArrayZ --
|
||||
*
|
||||
* This routine
|
||||
*
|
||||
|
|
@ -1573,14 +1653,16 @@ bad:
|
|||
*/
|
||||
|
||||
bool
|
||||
CalmaGenerateArrayZ(f, type, llx, lly, pitch, cols, rows)
|
||||
gzFile f; /* GDS output file */
|
||||
TileType type; /* Magic tile type of contact */
|
||||
int llx, lly; /* Lower-left hand coordinate of the array
|
||||
CalmaGenerateArrayZ(
|
||||
gzFile f, /* GDS output file */
|
||||
TileType type, /* Magic tile type of contact */
|
||||
int llx,
|
||||
int lly, /* Lower-left hand coordinate of the array
|
||||
* (centered on contact cut)
|
||||
*/
|
||||
int pitch; /* Pitch of the array elements */
|
||||
int cols, rows; /* Number of array elements in X and Y */
|
||||
int pitch, /* Pitch of the array elements */
|
||||
int cols,
|
||||
int rows) /* Number of array elements in X and Y */
|
||||
{
|
||||
CellDef *child; /* Cell definition of the contact cell */
|
||||
int xxlate, yxlate;
|
||||
|
|
@ -1641,8 +1723,8 @@ CalmaGenerateArrayZ(f, type, llx, lly, pitch, cols, rows)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaWriteContactsZ(f)
|
||||
gzFile f;
|
||||
calmaWriteContactsZ(
|
||||
gzFile f)
|
||||
{
|
||||
TileType type;
|
||||
TileTypeBitMask tMask, *rMask;
|
||||
|
|
@ -1681,7 +1763,7 @@ calmaWriteContactsZ(f)
|
|||
/* Get clip bounds, so that residue surround is */
|
||||
/* minimum. Note that these values are in CIF/GDS */
|
||||
/* units, and the clipping rectangle passed to */
|
||||
/* calmaOutFunc is also in CIF/GDS units. */
|
||||
/* calmaOutFuncZ is also in CIF/GDS units. */
|
||||
|
||||
halfsize = CIFGetContactSize(type, NULL, NULL, NULL) >> 1;
|
||||
|
||||
|
|
@ -1724,9 +1806,9 @@ calmaWriteContactsZ(f)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaProcessBoundaryZ(blist, cos)
|
||||
BoundaryTop *blist;
|
||||
calmaOutputStructZ *cos;
|
||||
calmaProcessBoundaryZ(
|
||||
BoundaryTop *blist,
|
||||
calmaOutputStructZ *cos)
|
||||
{
|
||||
gzFile f = cos->f;
|
||||
LinkedBoundary *listtop, *lbref, *lbstop, *lbfree;
|
||||
|
|
@ -1762,8 +1844,11 @@ calmaProcessBoundaryZ(blist, cos)
|
|||
calmaOutI4Z(lbref->lb_start.p_y * calmaPaintScale, f);
|
||||
chkcount++;
|
||||
}
|
||||
calmaOutI4Z(listtop->lb_start.p_x * calmaPaintScale, f);
|
||||
calmaOutI4Z(listtop->lb_start.p_y * calmaPaintScale, f);
|
||||
if (listtop != NULL)
|
||||
{
|
||||
calmaOutI4Z(listtop->lb_start.p_x * calmaPaintScale, f);
|
||||
calmaOutI4Z(listtop->lb_start.p_y * calmaPaintScale, f);
|
||||
}
|
||||
|
||||
if (chkcount != bounds->bt_points)
|
||||
TxError("Points recorded=%d; Points written=%d\n",
|
||||
|
|
@ -1774,19 +1859,27 @@ calmaProcessBoundaryZ(blist, cos)
|
|||
|
||||
/* Free the LinkedBoundary list */
|
||||
|
||||
lbref = listtop;
|
||||
while (lbref->lb_next != listtop)
|
||||
{
|
||||
freeMagic(lbref);
|
||||
lbref = lbref->lb_next;
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
lbref = listtop;
|
||||
while (lbref->lb_next != listtop)
|
||||
{
|
||||
freeMagic1(&mm1, lbref);
|
||||
lbref = lbref->lb_next;
|
||||
}
|
||||
freeMagic1(&mm1, lbref);
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
freeMagic(lbref);
|
||||
}
|
||||
|
||||
/* Free the BoundaryTop list */
|
||||
|
||||
for (bounds = blist; bounds != NULL; bounds = bounds->bt_next)
|
||||
freeMagic(bounds);
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (bounds = blist; bounds != NULL; bounds = bounds->bt_next)
|
||||
freeMagic1(&mm1, bounds);
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1804,12 +1897,13 @@ calmaProcessBoundaryZ(blist, cos)
|
|||
*/
|
||||
|
||||
int
|
||||
calmaMergePaintFuncZ(tile, cos)
|
||||
Tile *tile; /* Tile to be written out. */
|
||||
calmaOutputStructZ *cos; /* Information needed by algorithm */
|
||||
calmaMergePaintFuncZ(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
calmaOutputStructZ *cos) /* Information needed by algorithm */
|
||||
{
|
||||
gzFile f = cos->f;
|
||||
Rect *clipArea = cos->area;
|
||||
const Rect *clipArea = cos->area;
|
||||
Tile *t, *tp;
|
||||
TileType ttype;
|
||||
int i, llx, lly, urx, ury, intedges, num_points, split_type;
|
||||
|
|
@ -1821,26 +1915,25 @@ calmaMergePaintFuncZ(tile, cos)
|
|||
BoundaryTop *bounds = NULL;
|
||||
|
||||
/* Quick check for tiles that have already been processed */
|
||||
if (tile->ti_client == (ClientData)GDS_PROCESSED) return 0;
|
||||
if (TiGetClientINT(tile) == GDS_PROCESSED) return 0;
|
||||
|
||||
if (SegStack == (Stack *)NULL)
|
||||
SegStack = StackNew(64);
|
||||
|
||||
PUSHTILE(tile);
|
||||
PUSHTILEZ(tile);
|
||||
while (!StackEmpty(SegStack))
|
||||
{
|
||||
t = (Tile *) STACKPOP(SegStack);
|
||||
if (t->ti_client != (ClientData)GDS_PENDING) continue;
|
||||
t->ti_client = (ClientData)GDS_PROCESSED;
|
||||
if (TiGetClientINT(t) != GDS_PENDING) continue;
|
||||
TiSetClientINT(t, GDS_PROCESSED);
|
||||
|
||||
split_type = -1;
|
||||
if (IsSplit(t))
|
||||
{
|
||||
/* If we use SplitSide, then we need to set it when the */
|
||||
/* If we use TT_SIDE, then we need to set it when the */
|
||||
/* tile is pushed. Since these are one-or-zero mask layers */
|
||||
/* I assume it is okay to just check which side is TT_SPACE */
|
||||
|
||||
/* split_type = (SplitSide(t) << 1) | SplitDirection(t); */
|
||||
split_type = SplitDirection(t);
|
||||
if (TiGetLeftType(t) == TT_SPACE) split_type |= 2;
|
||||
num_points = 2;
|
||||
|
|
@ -1852,8 +1945,10 @@ calmaMergePaintFuncZ(tile, cos)
|
|||
lb = edge;
|
||||
while (lb->lb_next != edge) lb = lb->lb_next;
|
||||
lb->lb_next = edge->lb_next;
|
||||
freeMagic(edge);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, edge);
|
||||
edge = edge->lb_next;
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -1994,7 +2089,7 @@ calmaMergePaintFuncZ(tile, cos)
|
|||
intedges += calmaAddSegment(&lb, is_ext,
|
||||
MIN(RIGHT(t), RIGHT(tp)), TOP(t),
|
||||
MAX(LEFT(t), LEFT(tp)), TOP(t));
|
||||
if (!is_ext) PUSHTILE(tp);
|
||||
if (!is_ext) PUSHTILEZ(tp);
|
||||
}
|
||||
|
||||
if (split_type == 0x3)
|
||||
|
|
@ -2014,7 +2109,7 @@ left_search:
|
|||
intedges += calmaAddSegment(&lb, is_ext,
|
||||
LEFT(t), MIN(TOP(t), TOP(tp)),
|
||||
LEFT(t), MAX(BOTTOM(t), BOTTOM(tp)));
|
||||
if (!is_ext) PUSHTILE(tp);
|
||||
if (!is_ext) PUSHTILEZ(tp);
|
||||
}
|
||||
|
||||
if (split_type == 0x0)
|
||||
|
|
@ -2034,7 +2129,7 @@ bottom_search:
|
|||
intedges += calmaAddSegment(&lb, is_ext,
|
||||
MAX(LEFT(t), LEFT(tp)), BOTTOM(t),
|
||||
MIN(RIGHT(t), RIGHT(tp)), BOTTOM(t));
|
||||
if (!is_ext) PUSHTILE(tp);
|
||||
if (!is_ext) PUSHTILEZ(tp);
|
||||
}
|
||||
|
||||
if (split_type == 0x1)
|
||||
|
|
@ -2053,7 +2148,7 @@ right_search:
|
|||
intedges += calmaAddSegment(&lb, is_ext,
|
||||
RIGHT(t), MAX(BOTTOM(t), BOTTOM(tp)),
|
||||
RIGHT(t), MIN(TOP(t), TOP(tp)));
|
||||
if (!is_ext) PUSHTILE(tp);
|
||||
if (!is_ext) PUSHTILEZ(tp);
|
||||
}
|
||||
|
||||
/* If tile is isolated, process it now and we're done */
|
||||
|
|
@ -2061,7 +2156,9 @@ right_search:
|
|||
done_searches:
|
||||
if (intedges == 0)
|
||||
{
|
||||
calmaWritePaintFuncZ(t, cos);
|
||||
calmaWritePaintFuncZ(t,
|
||||
(split_type & 2) ? (TileType)TT_SIDE : (TileType)0,
|
||||
cos);
|
||||
|
||||
/* Although calmaWritePaintFunc is called only on isolated */
|
||||
/* tiles, we may have expanded it. This could use a LOT of */
|
||||
|
|
@ -2072,11 +2169,13 @@ done_searches:
|
|||
|
||||
if (num_points != 4)
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (i = 0; i < num_points; i++)
|
||||
{
|
||||
freeMagic(edge);
|
||||
freeMagic1(&mm1, edge);
|
||||
edge = edge->lb_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
edge = NULL;
|
||||
}
|
||||
if (!StackEmpty(SegStack))
|
||||
|
|
@ -2127,12 +2226,13 @@ done_searches:
|
|||
*/
|
||||
|
||||
int
|
||||
calmaWritePaintFuncZ(tile, cos)
|
||||
Tile *tile; /* Tile to be written out. */
|
||||
calmaOutputStructZ *cos; /* File for output and clipping area */
|
||||
calmaWritePaintFuncZ(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
calmaOutputStructZ *cos) /* File for output and clipping area */
|
||||
{
|
||||
gzFile f = cos->f;
|
||||
Rect *clipArea = cos->area;
|
||||
const Rect *clipArea = cos->area;
|
||||
Rect r, r2;
|
||||
|
||||
TiToRect(tile, &r);
|
||||
|
|
@ -2164,7 +2264,7 @@ calmaWritePaintFuncZ(tile, cos)
|
|||
/* Coordinates */
|
||||
calmaOutRHZ(36, CALMA_XY, CALMA_I4, f);
|
||||
|
||||
switch ((SplitSide(tile) << 1) | SplitDirection(tile))
|
||||
switch (((dinfo & TT_SIDE) ? 2 : 0) | SplitDirection(tile))
|
||||
{
|
||||
case 0x0:
|
||||
calmaOutI4Z(r.r_xbot, f); calmaOutI4Z(r.r_ybot, f);
|
||||
|
|
@ -2232,18 +2332,21 @@ calmaWritePaintFuncZ(tile, cos)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaWriteLabelFuncZ(lab, type, f)
|
||||
Label *lab; /* Label to output */
|
||||
int type; /* CIF layer number, or -1 if not attached to a layer */
|
||||
gzFile f; /* Stream file */
|
||||
calmaWriteLabelFuncZ(
|
||||
Label *lab, /* Label to output */
|
||||
int ltype, /* CIF layer number to use for TEXT record */
|
||||
int type, /* CIF layer number to use for BOUNDARY record,
|
||||
* or -1 if not attached to a layer
|
||||
*/
|
||||
gzFile f) /* Stream file */
|
||||
{
|
||||
Point p;
|
||||
int calmanum, calmatype;
|
||||
|
||||
if (type < 0)
|
||||
if (ltype < 0)
|
||||
return;
|
||||
|
||||
calmanum = CIFCurStyle->cs_layers[type]->cl_calmanum;
|
||||
calmanum = CIFCurStyle->cs_layers[ltype]->cl_calmanum;
|
||||
if (!CalmaIsValidLayer(calmanum))
|
||||
return;
|
||||
|
||||
|
|
@ -2252,7 +2355,7 @@ calmaWriteLabelFuncZ(lab, type, f)
|
|||
calmaOutRHZ(6, CALMA_LAYER, CALMA_I2, f);
|
||||
calmaOutI2Z(calmanum, f);
|
||||
|
||||
calmatype = CIFCurStyle->cs_layers[type]->cl_calmatype;
|
||||
calmatype = CIFCurStyle->cs_layers[ltype]->cl_calmatype;
|
||||
calmaOutRHZ(6, CALMA_TEXTTYPE, CALMA_I2, f);
|
||||
calmaOutI2Z(calmatype, f);
|
||||
|
||||
|
|
@ -2334,6 +2437,15 @@ calmaWriteLabelFuncZ(lab, type, f)
|
|||
/* and the label rectangle is not degenerate, then output the label */
|
||||
/* rectangle as a boundary with the label's layer:purpose pair. */
|
||||
|
||||
if (type < 0)
|
||||
return;
|
||||
|
||||
calmanum = CIFCurStyle->cs_layers[type]->cl_calmanum;
|
||||
if (!CalmaIsValidLayer(calmanum))
|
||||
return;
|
||||
|
||||
calmatype = CIFCurStyle->cs_layers[type]->cl_calmatype;
|
||||
|
||||
/* Note that the check for whether the CIF_LABEL_NOPORT flag has */
|
||||
/* been set is done outside of this routine. */
|
||||
|
||||
|
|
@ -2391,12 +2503,13 @@ calmaWriteLabelFuncZ(lab, type, f)
|
|||
*/
|
||||
|
||||
int
|
||||
calmaPaintLabelFuncZ(tile, cos)
|
||||
Tile *tile; /* Tile contains area for label. */
|
||||
calmaOutputStructZ *cos; /* File for output and clipping area */
|
||||
calmaPaintLabelFuncZ(
|
||||
Tile *tile, /* Tile contains area for label. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
calmaOutputStructZ *cos) /* File for output and clipping area */
|
||||
{
|
||||
gzFile f = cos->f;
|
||||
Rect *clipArea = cos->area;
|
||||
const Rect *clipArea = cos->area;
|
||||
Rect r, r2;
|
||||
Point p;
|
||||
int len;
|
||||
|
|
@ -2452,9 +2565,9 @@ calmaPaintLabelFuncZ(tile, cos)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaOutHeaderZ(rootDef, f)
|
||||
CellDef *rootDef;
|
||||
gzFile f;
|
||||
calmaOutHeaderZ(
|
||||
CellDef *rootDef,
|
||||
gzFile f)
|
||||
{
|
||||
static double useru = 0.001;
|
||||
static double mum = 1.0e-9;
|
||||
|
|
@ -2513,9 +2626,9 @@ calmaOutHeaderZ(rootDef, f)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaOutDateZ(t, f)
|
||||
time_t t; /* Time (UNIX format) to be output */
|
||||
gzFile f; /* Stream file */
|
||||
calmaOutDateZ(
|
||||
time_t t, /* Time (UNIX format) to be output */
|
||||
gzFile f) /* Stream file */
|
||||
{
|
||||
struct tm *datep = localtime(&t);
|
||||
|
||||
|
|
@ -2548,14 +2661,15 @@ calmaOutDateZ(t, f)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaOutStringRecordZ(type, str, f)
|
||||
int type; /* Type of this record (data type is ASCII string) */
|
||||
char *str; /* String to be output */
|
||||
gzFile f; /* Compressed stream file */
|
||||
calmaOutStringRecordZ(
|
||||
int type, /* Type of this record (data type is ASCII string) */
|
||||
char *str, /* String to be output */
|
||||
gzFile f) /* Compressed stream file */
|
||||
{
|
||||
int len;
|
||||
unsigned char c;
|
||||
char *table, *locstr, *origstr = NULL;
|
||||
const char *table;
|
||||
char *locstr, *origstr = NULL;
|
||||
char *locstrprv;
|
||||
|
||||
if(CIFCurStyle->cs_flags & CWF_PERMISSIVE_LABELS)
|
||||
|
|
@ -2649,9 +2763,9 @@ calmaOutStringRecordZ(type, str, f)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaOutR8Z(d, f)
|
||||
double d; /* Double value to write to output */
|
||||
gzFile f; /* Stream file */
|
||||
calmaOutR8Z(
|
||||
double d, /* Double value to write to output */
|
||||
gzFile f) /* Stream file */
|
||||
{
|
||||
int c, i, sign, expon;
|
||||
|
||||
|
|
@ -2724,9 +2838,9 @@ calmaOutR8Z(d, f)
|
|||
*/
|
||||
|
||||
void
|
||||
calmaOut8Z(str, f)
|
||||
char *str; /* 8-byte string to be output */
|
||||
gzFile f; /* Compressed stream file */
|
||||
calmaOut8Z(
|
||||
const char *str, /* 8-byte string to be output */
|
||||
gzFile f) /* Compressed stream file */
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/calma/calma.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CALMA_H
|
||||
#define _CALMA_H
|
||||
#ifndef _MAGIC__CALMA__CALMA_H
|
||||
#define _MAGIC__CALMA__CALMA_H
|
||||
|
||||
#include "utils/magic.h"
|
||||
|
||||
/* Externally visible variables */
|
||||
extern bool CalmaSubcellPolygons;
|
||||
extern unsigned char CalmaSubcellPolygons;
|
||||
extern bool CalmaSubcellPaths;
|
||||
extern bool CalmaDoLabels;
|
||||
extern bool CalmaDoLibrary;
|
||||
|
|
@ -39,6 +39,8 @@ extern bool CalmaMergeTiles;
|
|||
extern bool CalmaFlattenArrays;
|
||||
extern bool CalmaNoDRCCheck;
|
||||
extern bool CalmaFlattenUses;
|
||||
extern int CalmaFlattenLimit;
|
||||
extern float CalmaMagScale;
|
||||
extern char **CalmaFlattenUsesByName;
|
||||
extern bool CalmaReadOnly;
|
||||
extern bool CalmaContactArrays;
|
||||
|
|
@ -49,43 +51,50 @@ extern bool CalmaPostOrder;
|
|||
extern bool CalmaAllowUndefined;
|
||||
extern bool CalmaAllowAbstract;
|
||||
|
||||
/* Definitions used by the return value for CalmaSubcellPolygons */
|
||||
/* CALMA_POLYGON_NONE: Process polygons immediately */
|
||||
/* CALMA_POLYGON_TEMP: Create temporary polygon subcells */
|
||||
/* CALMA_POLYGON_KEEP: Keep polygons in subcells */
|
||||
|
||||
#define CALMA_POLYGON_NONE 0
|
||||
#define CALMA_POLYGON_TEMP 1
|
||||
#define CALMA_POLYGON_KEEP 2
|
||||
|
||||
/* Externally-visible procedures: */
|
||||
extern bool CalmaWrite();
|
||||
extern void CalmaReadFile();
|
||||
extern void CalmaTechInit();
|
||||
extern bool CalmaGenerateArray();
|
||||
extern void CalmaReadError();
|
||||
extern bool CalmaWrite(CellDef *rootDef, FILE *f);
|
||||
extern void CalmaReadFile(FILETYPE file, char *filename);
|
||||
extern void CalmaTechInit(void);
|
||||
extern bool CalmaGenerateArray(FILE *f, TileType type, int llx, int lly, int pitch, int cols, int rows);
|
||||
extern void CalmaReadError(const char *format, ...) ATTR_FORMAT_PRINTF_1;
|
||||
|
||||
/* C99 compat */
|
||||
extern void CalmaReadError();
|
||||
extern int calmaAddSegment();
|
||||
extern void calmaDelContacts();
|
||||
extern void calmaElementBoundary();
|
||||
extern void calmaElementBox();
|
||||
extern void calmaElementPath();
|
||||
extern void calmaElementText();
|
||||
extern bool calmaIsUseNameDefault();
|
||||
extern bool calmaParseStructure();
|
||||
extern int calmaProcessDef();
|
||||
extern int calmaProcessDefZ();
|
||||
extern bool calmaReadI2Record();
|
||||
extern bool calmaReadI4Record();
|
||||
extern void calmaReadPoint();
|
||||
extern bool calmaReadR8();
|
||||
extern bool calmaReadStampRecord();
|
||||
extern bool calmaReadStringRecord();
|
||||
extern bool calmaReadStringRecord();
|
||||
extern bool calmaReadTransform();
|
||||
extern bool calmaSkipBytes();
|
||||
extern bool calmaSkipExact();
|
||||
extern bool calmaSkipTo();
|
||||
extern void calmaUnexpected();
|
||||
extern void calmaMergeSegments();
|
||||
extern void calmaRemoveDegenerate();
|
||||
extern void calmaRemoveColinear();
|
||||
extern void calmaDelContacts(void);
|
||||
extern void calmaElementBoundary(void);
|
||||
extern void calmaElementBox(void);
|
||||
extern void calmaElementPath(void);
|
||||
extern void calmaElementText(void);
|
||||
extern bool calmaIsUseNameDefault(char *defName, char *useName);
|
||||
extern bool calmaParseStructure(char *filename);
|
||||
extern int calmaProcessDef(CellDef *def, FILE *outf, bool do_library);
|
||||
#ifdef HAVE_ZLIB
|
||||
extern int calmaProcessDefZ(CellDef *def, gzFile outf, bool do_library);
|
||||
#endif
|
||||
extern bool calmaReadI2Record(int type, int *pvalue);
|
||||
extern bool calmaReadI4Record(int type, int *pvalue);
|
||||
extern void calmaReadPoint(Point *p, int iscale);
|
||||
extern bool calmaReadR8(double *pd);
|
||||
extern bool calmaReadStampRecord(int type, int *stampptr);
|
||||
extern bool calmaReadStringRecord(int type, char **str);
|
||||
extern bool calmaReadStringRecord(int type, char **str);
|
||||
extern bool calmaReadTransform(Transform *ptrans, char *name);
|
||||
extern bool calmaSkipBytes(int nbytes);
|
||||
extern bool calmaSkipExact(int type);
|
||||
extern bool calmaSkipTo(int what);
|
||||
extern void calmaUnexpected(int wanted, int got);
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
extern bool CalmaWriteZ();
|
||||
extern bool CalmaWriteZ(CellDef *rootDef, gzFile f);
|
||||
extern bool CalmaGenerateArrayZ(gzFile f, TileType type, int llx, int lly, int pitch, int cols, int rows);
|
||||
#endif
|
||||
|
||||
#endif /* _CALMA_H */
|
||||
#endif /* _MAGIC__CALMA__CALMA_H */
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/calma/calmaInt.h,v 1.2 2010/06/24 12:37:15 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CALMAINT_H
|
||||
#define _CALMAINT_H
|
||||
#ifndef _MAGIC__CALMA__CALMAINT_H
|
||||
#define _MAGIC__CALMA__CALMAINT_H
|
||||
|
||||
#include "utils/magic.h"
|
||||
#include "database/database.h"
|
||||
|
|
@ -131,8 +131,11 @@ typedef struct
|
|||
/* Length of record header */
|
||||
#define CALMAHEADERLENGTH 4
|
||||
|
||||
/* Label types */
|
||||
typedef enum { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT, LABEL_TYPE_CELLID } labelType;
|
||||
/* Label types
|
||||
* The intention is all the values can be stored/converted with unsigned char type,
|
||||
* C23 allows us to be explicit with the type but C99 does not, so a comment for now.
|
||||
*/
|
||||
typedef enum /* : unsigned char */ { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT, LABEL_TYPE_CELLID } labelType;
|
||||
|
||||
/* ------------------------- Input macros ----------------------------- */
|
||||
|
||||
|
|
@ -216,19 +219,52 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
|
|||
UNREADRH(nb, rt); \
|
||||
}
|
||||
|
||||
/* Structure used for sorting ports by number */
|
||||
|
||||
typedef struct portlabel
|
||||
{
|
||||
Label *pl_label;
|
||||
unsigned int pl_port;
|
||||
} PortLabel;
|
||||
|
||||
/* Other commonly used globals */
|
||||
extern HashTable calmaLayerHash;
|
||||
extern int calmaElementIgnore[];
|
||||
extern CellDef *calmaFindCell();
|
||||
extern const int calmaElementIgnore[];
|
||||
extern CellDef *calmaFindCell(const char *name, bool *was_called, bool *predefined);
|
||||
|
||||
/* (Added by Nishit, 8/18/2004--8/24/2004) */
|
||||
extern CellDef *calmaLookCell();
|
||||
extern void calmaWriteContact();
|
||||
extern CellDef *calmaGetContactCell();
|
||||
extern CellDef *calmaLookCell(char *name);
|
||||
extern void calmaWriteContacts(FILE *f);
|
||||
extern CellDef *calmaGetContactCell(TileType type, bool lookOnly);
|
||||
extern bool calmaIsContactCell;
|
||||
|
||||
extern char *calmaRecordName();
|
||||
extern void calmaSkipSet();
|
||||
extern const char *calmaRecordName(int rtype);
|
||||
extern void calmaSkipSet(const int *skipwhat);
|
||||
extern bool calmaParseUnits(void);
|
||||
|
||||
extern int compport(const void *one, const void *two);
|
||||
|
||||
|
||||
#define LB_EXTERNAL 0 /* Polygon external edge */
|
||||
#define LB_INTERNAL 1 /* Polygon internal edge */
|
||||
#define LB_INIT 2 /* Data not yet valid */
|
||||
|
||||
typedef struct LB1 {
|
||||
char lb_type; /* Boundary Type (external or internal) */
|
||||
Point lb_start; /* Start point */
|
||||
struct LB1 *lb_next; /* Next point record */
|
||||
} LinkedBoundary;
|
||||
|
||||
typedef struct BT1 {
|
||||
LinkedBoundary *bt_first; /* Polygon list */
|
||||
int bt_points; /* Number of points in this list */
|
||||
struct BT1 *bt_next; /* Next polygon record */
|
||||
} BoundaryTop;
|
||||
|
||||
extern int calmaAddSegment(LinkedBoundary **lbptr, bool poly_edge, int p1x, int p1y, int p2x, int p2y);
|
||||
extern void calmaMergeSegments(LinkedBoundary *edge, BoundaryTop **blist, int num_points);
|
||||
extern void calmaRemoveDegenerate(BoundaryTop *blist);
|
||||
extern void calmaRemoveColinear(BoundaryTop *blist);
|
||||
|
||||
/* ------------------- Imports from CIF reading ----------------------- */
|
||||
|
||||
|
|
@ -238,4 +274,4 @@ extern Plane **cifCurReadPlanes;
|
|||
extern HashTable CifCellTable;
|
||||
extern Plane *cifEditCellPlanes[];
|
||||
|
||||
#endif /* _CALMAINT_H */
|
||||
#endif /* _MAGIC__CALMA__CALMAINT_H */
|
||||
|
|
|
|||
1265
cif/CIFgen.c
1265
cif/CIFgen.c
File diff suppressed because it is too large
Load Diff
193
cif/CIFhier.c
193
cif/CIFhier.c
|
|
@ -22,7 +22,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFhier.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFhier.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -107,7 +107,7 @@ static CIFLayer *CurCifLayer;
|
|||
*/
|
||||
|
||||
void
|
||||
CIFInitCells()
|
||||
CIFInitCells(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -172,7 +172,7 @@ CIFInitCells()
|
|||
*/
|
||||
|
||||
void
|
||||
cifHierCleanup()
|
||||
cifHierCleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -232,10 +232,10 @@ typedef struct _maskHintsData
|
|||
|
||||
/* DEPRECATED */
|
||||
int
|
||||
cifMaskHints(name, value, targetDef)
|
||||
char *name;
|
||||
char *value;
|
||||
CellDef *targetDef;
|
||||
cifMaskHints(
|
||||
char *name,
|
||||
char *value,
|
||||
CellDef *targetDef)
|
||||
{
|
||||
char *propvalue, *newval;
|
||||
bool propfound;
|
||||
|
|
@ -277,15 +277,15 @@ cifMaskHints(name, value, targetDef)
|
|||
*/
|
||||
|
||||
int
|
||||
cifFlatMaskHints(name, value, mhd)
|
||||
char *name;
|
||||
char *value;
|
||||
MaskHintsData *mhd;
|
||||
cifFlatMaskHints(
|
||||
char *name,
|
||||
char *value,
|
||||
MaskHintsData *mhd)
|
||||
{
|
||||
Rect r, newr;
|
||||
char *vptr, *newval, *lastval, *propvalue;
|
||||
bool propfound;
|
||||
int lastlen;
|
||||
int lastlen, numvals;
|
||||
|
||||
if (!strncmp(name, "MASKHINTS_", 10))
|
||||
{
|
||||
|
|
@ -293,8 +293,9 @@ cifFlatMaskHints(name, value, mhd)
|
|||
vptr = value;
|
||||
while (*vptr != '\0')
|
||||
{
|
||||
if (sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop) == 4)
|
||||
numvals = sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop);
|
||||
if (numvals == 4)
|
||||
{
|
||||
/* Transform rectangle to top level coordinates */
|
||||
GeoTransRect(mhd->mh_trans, &r, &newr);
|
||||
|
|
@ -320,6 +321,12 @@ cifFlatMaskHints(name, value, mhd)
|
|||
while (*vptr && !isspace(*vptr)) vptr++;
|
||||
while (*vptr && isspace(*vptr)) vptr++;
|
||||
}
|
||||
else
|
||||
{
|
||||
TxError("MASKHINTS_%s: Expected 4 values, found only %d\n",
|
||||
name + 10, numvals);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if name exists already in the flattened cell */
|
||||
|
|
@ -354,9 +361,9 @@ cifFlatMaskHints(name, value, mhd)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFCopyMaskHints(scx, targetDef)
|
||||
SearchContext *scx;
|
||||
CellDef *targetDef;
|
||||
CIFCopyMaskHints(
|
||||
SearchContext *scx,
|
||||
CellDef *targetDef)
|
||||
{
|
||||
MaskHintsData mhd;
|
||||
|
||||
|
|
@ -385,9 +392,9 @@ CIFCopyMaskHints(scx, targetDef)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierCopyMaskHints(scx, clientData)
|
||||
SearchContext *scx;
|
||||
ClientData clientData;
|
||||
cifHierCopyMaskHints(
|
||||
SearchContext *scx,
|
||||
ClientData clientData)
|
||||
{
|
||||
MaskHintsData mhd;
|
||||
|
||||
|
|
@ -424,17 +431,18 @@ cifHierCopyMaskHints(scx, clientData)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierCopyFunc(tile, cxp)
|
||||
Tile *tile; /* Pointer to tile to copy. */
|
||||
TreeContext *cxp; /* Describes context of search, including
|
||||
cifHierCopyFunc(
|
||||
Tile *tile, /* Pointer to tile to copy. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
TreeContext *cxp) /* Describes context of search, including
|
||||
* transform and client data.
|
||||
*/
|
||||
{
|
||||
TileType type = TiGetTypeExact(tile);
|
||||
TileType type = TiGetTypeExact(tile) | dinfo;
|
||||
Rect sourceRect, targetRect;
|
||||
int pNum;
|
||||
CellDef *def = (CellDef *) cxp->tc_filter->tf_arg;
|
||||
int dinfo = 0;
|
||||
TileType newdinfo = 0;
|
||||
|
||||
/* Ignore tiles in vendor GDS, unless this is specifically */
|
||||
/* overridden by the "see-vendor" option. */
|
||||
|
|
@ -450,8 +458,8 @@ cifHierCopyFunc(tile, cxp)
|
|||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
dinfo = DBTransformDiagonal(type, &cxp->tc_scx->scx_trans);
|
||||
type = (SplitSide(tile)) ? SplitRightType(tile) :
|
||||
newdinfo = DBTransformDiagonal(type, &cxp->tc_scx->scx_trans);
|
||||
type = (dinfo & TT_SIDE) ? SplitRightType(tile) :
|
||||
SplitLeftType(tile);
|
||||
}
|
||||
|
||||
|
|
@ -466,7 +474,7 @@ cifHierCopyFunc(tile, cxp)
|
|||
{
|
||||
if (DBPaintOnPlane(type, pNum))
|
||||
{
|
||||
DBNMPaintPlane(def->cd_planes[pNum], dinfo, &targetRect,
|
||||
DBNMPaintPlane(def->cd_planes[pNum], newdinfo, &targetRect,
|
||||
DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -493,8 +501,8 @@ cifHierCopyFunc(tile, cxp)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierCellFunc(scx)
|
||||
SearchContext *scx; /* Describes cell and area in cell. */
|
||||
cifHierCellFunc(
|
||||
SearchContext *scx) /* Describes cell and area in cell. */
|
||||
{
|
||||
SearchContext newscx;
|
||||
Rect rootArea;
|
||||
|
|
@ -553,11 +561,13 @@ cifHierCellFunc(scx)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierErrorFunc(tile, checkArea)
|
||||
Tile *tile; /* Tile that covers area it shouldn't. */
|
||||
Rect *checkArea; /* Intersection of this and tile is error. */
|
||||
cifHierErrorFunc(
|
||||
Tile *tile, /* Tile that covers area it shouldn't. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
Rect *checkArea) /* Intersection of this and tile is error. */
|
||||
{
|
||||
Rect area;
|
||||
bool side = (dinfo & TT_SIDE) ? TRUE : FALSE;
|
||||
|
||||
TiToRect(tile, &area);
|
||||
|
||||
|
|
@ -565,8 +575,8 @@ cifHierErrorFunc(tile, checkArea)
|
|||
* space bounds the checkArea.
|
||||
*/
|
||||
if (IsSplit(tile))
|
||||
if (((area.r_xbot == checkArea->r_xbot) && !SplitSide(tile)) ||
|
||||
((area.r_xtop == checkArea->r_xtop) && SplitSide(tile)))
|
||||
if (((area.r_xbot == checkArea->r_xbot) && !side) ||
|
||||
((area.r_xtop == checkArea->r_xtop) && side))
|
||||
return 0;
|
||||
|
||||
GeoClip(&area, checkArea);
|
||||
|
|
@ -595,9 +605,10 @@ cifHierErrorFunc(tile, checkArea)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierCheckFunc(tile, plane)
|
||||
Tile *tile; /* Tile containing CIF. */
|
||||
Plane *plane; /* Plane to check against and modify. */
|
||||
cifHierCheckFunc(
|
||||
Tile *tile, /* Tile containing CIF. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
Plane *plane) /* Plane to check against and modify. */
|
||||
{
|
||||
Rect area;
|
||||
|
||||
|
|
@ -605,10 +616,10 @@ cifHierCheckFunc(tile, plane)
|
|||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
DBSrPaintNMArea((Tile *)NULL, plane, TiGetTypeExact(tile),
|
||||
DBSrPaintNMArea((Tile *)NULL, plane, TiGetTypeExact(tile) | dinfo,
|
||||
&area, &DBSpaceBits, cifHierErrorFunc, (ClientData) &area);
|
||||
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable,
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFEraseTable,
|
||||
(PaintUndoInfo *) NULL);
|
||||
}
|
||||
else
|
||||
|
|
@ -642,16 +653,17 @@ cifHierCheckFunc(tile, plane)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierTempCheckFunc(tile, plane)
|
||||
Tile *tile; /* Tile containing CIF. */
|
||||
Plane *plane; /* Plane to check against and modify. */
|
||||
cifHierTempCheckFunc(
|
||||
Tile *tile, /* Tile containing CIF. */
|
||||
TileType dinfo, /* Information about split tiles */
|
||||
Plane *plane) /* Plane to check against and modify. */
|
||||
{
|
||||
Rect area;
|
||||
|
||||
TiToRect(tile, &area);
|
||||
|
||||
if (IsSplit(tile))
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable,
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFEraseTable,
|
||||
(PaintUndoInfo *) NULL);
|
||||
else
|
||||
DBPaintPlane(plane, &area, CIFEraseTable, (PaintUndoInfo *) NULL);
|
||||
|
|
@ -677,18 +689,19 @@ cifHierTempCheckFunc(tile, plane)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierPaintFunc(tile, plane)
|
||||
Tile *tile;
|
||||
Plane *plane; /* Plane in which to paint CIF over tile's
|
||||
cifHierPaintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* Information about split tiles */
|
||||
Plane *plane) /* Plane in which to paint CIF over tile's
|
||||
* area.
|
||||
*/
|
||||
{
|
||||
Rect area;
|
||||
|
||||
TiToRect(tile, &area);
|
||||
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area);
|
||||
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, dinfo, &area);
|
||||
if (IsSplit(tile))
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFPaintTable,
|
||||
DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFPaintTable,
|
||||
(PaintUndoInfo *) NULL);
|
||||
else
|
||||
DBPaintPlane(plane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||
|
|
@ -718,8 +731,8 @@ cifHierPaintFunc(tile, plane)
|
|||
*/
|
||||
|
||||
void
|
||||
cifCheckAndErase(style)
|
||||
CIFStyle *style; /* Describes how to make CIF. */
|
||||
cifCheckAndErase(
|
||||
CIFStyle *style) /* Describes how to make CIF. */
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -759,10 +772,10 @@ cifCheckAndErase(style)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFGenSubcells(def, area, output)
|
||||
CellDef *def; /* Parent cell for which CIF is computed. */
|
||||
Rect *area; /* All CIF in this area is interesting. */
|
||||
Plane **output; /* Array of pointers to planes into which
|
||||
CIFGenSubcells(
|
||||
CellDef *def, /* Parent cell for which CIF is computed. */
|
||||
Rect *area, /* All CIF in this area is interesting. */
|
||||
Plane **output) /* Array of pointers to planes into which
|
||||
* the CIF output will be OR'ed (real CIF
|
||||
* only).
|
||||
*/
|
||||
|
|
@ -927,13 +940,14 @@ CIFGenSubcells(def, area, output)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierElementFuncLow(use, transform, x, y, checkArea)
|
||||
CellUse *use; /* CellUse being array-checked. */
|
||||
Transform *transform; /* Transform from this instance to
|
||||
cifHierElementFuncLow(
|
||||
CellUse *use, /* CellUse being array-checked. */
|
||||
Transform *transform, /* Transform from this instance to
|
||||
* the parent.
|
||||
*/
|
||||
int x, y; /* Indices of this instance. */
|
||||
Rect *checkArea; /* Area (in parent coords) to be
|
||||
int x,
|
||||
int y, /* Indices of this instance. */
|
||||
Rect *checkArea) /* Area (in parent coords) to be
|
||||
* CIF-generated.
|
||||
*/
|
||||
{
|
||||
|
|
@ -950,13 +964,14 @@ cifHierElementFuncLow(use, transform, x, y, checkArea)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierElementFuncHigh(use, transform, x, y, checkArea)
|
||||
CellUse *use; /* CellUse being array-checked. */
|
||||
Transform *transform; /* Transform from this instance to
|
||||
cifHierElementFuncHigh(
|
||||
CellUse *use, /* CellUse being array-checked. */
|
||||
Transform *transform, /* Transform from this instance to
|
||||
* the parent.
|
||||
*/
|
||||
int x, y; /* Indices of this instance. */
|
||||
Rect *checkArea; /* Area (in parent coords) to be
|
||||
int x,
|
||||
int y, /* Indices of this instance. */
|
||||
Rect *checkArea) /* Area (in parent coords) to be
|
||||
* CIF-generated.
|
||||
*/
|
||||
{
|
||||
|
|
@ -991,13 +1006,14 @@ cifHierElementFuncHigh(use, transform, x, y, checkArea)
|
|||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cifHierElementFunc(use, transform, x, y, checkArea)
|
||||
CellUse *use; /* CellUse being array-checked. */
|
||||
Transform *transform; /* Transform from this instance to
|
||||
cifHierElementFunc(
|
||||
CellUse *use, /* CellUse being array-checked. */
|
||||
Transform *transform, /* Transform from this instance to
|
||||
* the parent.
|
||||
*/
|
||||
int x, y; /* Indices of this instance. */
|
||||
Rect *checkArea; /* Area (in parent coords) to be
|
||||
int x,
|
||||
int y, /* Indices of this instance. */
|
||||
Rect *checkArea) /* Area (in parent coords) to be
|
||||
* CIF-generated.
|
||||
*/
|
||||
{
|
||||
|
|
@ -1055,9 +1071,10 @@ cifHierElementFunc(use, transform, x, y, checkArea)
|
|||
*/
|
||||
|
||||
int
|
||||
cifGrowSliver(tile, area)
|
||||
Tile *tile;
|
||||
Rect *area;
|
||||
cifGrowSliver(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* Split tile information, needs to be handled */
|
||||
Rect *area)
|
||||
{
|
||||
int height, width, expand_up, expand_side;
|
||||
|
||||
|
|
@ -1116,23 +1133,25 @@ cifGrowSliver(tile, area)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierPaintArrayFunc(tile)
|
||||
Tile *tile;
|
||||
cifHierPaintArrayFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
Rect area;
|
||||
int i, j, xbot, xtop;
|
||||
|
||||
TiToRect(tile, &area);
|
||||
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area);
|
||||
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, dinfo, &area);
|
||||
xbot = area.r_xbot;
|
||||
xtop = area.r_xtop;
|
||||
for (i=0; i<cifHierYCount; i++)
|
||||
{
|
||||
for (j=0; j<cifHierXCount; j++)
|
||||
for (j = 0; j < cifHierXCount; j++)
|
||||
{
|
||||
DBPaintPlane(cifHierCurPlane, &area, CIFPaintTable,
|
||||
(PaintUndoInfo *) NULL);
|
||||
CIFTileOps += 1;
|
||||
DBNMPaintPlane(cifHierCurPlane, TiGetTypeExact(tile) | dinfo,
|
||||
&area, CIFPaintTable, (PaintUndoInfo *) NULL);
|
||||
CIFTileOps++;
|
||||
area.r_xbot += cifHierXSpacing;
|
||||
area.r_xtop += cifHierXSpacing;
|
||||
}
|
||||
|
|
@ -1187,9 +1206,9 @@ cifHierPaintArrayFunc(tile)
|
|||
*/
|
||||
|
||||
int
|
||||
cifHierArrayFunc(scx, output)
|
||||
SearchContext *scx; /* Information about the search. */
|
||||
Plane **output; /* Array of planes to hold results. */
|
||||
cifHierArrayFunc(
|
||||
SearchContext *scx, /* Information about the search. */
|
||||
Plane **output) /* Array of planes to hold results. */
|
||||
{
|
||||
Rect childArea, parentArea, A, B, C, D, expandedArea;
|
||||
CellUse *use;
|
||||
|
|
@ -1533,10 +1552,10 @@ cifHierArrayFunc(scx, output)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFGenArrays(def, area, output)
|
||||
CellDef *def; /* Parent cell for which CIF is computed. */
|
||||
Rect *area; /* All CIF in this area is interesting. */
|
||||
Plane **output; /* Array of pointers to planes into which
|
||||
CIFGenArrays(
|
||||
CellDef *def, /* Parent cell for which CIF is computed. */
|
||||
Rect *area, /* All CIF in this area is interesting. */
|
||||
Plane **output) /* Array of pointers to planes into which
|
||||
* the CIF output will be OR'ed (real CIF
|
||||
* only, temp layers won't appear). If
|
||||
* output is NULL, then CIF is stored in
|
||||
|
|
|
|||
97
cif/CIFint.h
97
cif/CIFint.h
|
|
@ -19,8 +19,8 @@
|
|||
* rcsid "$Header: /usr/cvsroot/magic-8.0/cif/CIFint.h,v 1.3 2008/12/04 17:10:29 tim Exp $"
|
||||
*/
|
||||
|
||||
#ifndef _CIFINT_H
|
||||
#define _CIFINT_H
|
||||
#ifndef _MAGIC__CIF__CIFINT_H
|
||||
#define _MAGIC__CIF__CIFINT_H
|
||||
|
||||
#include "database/database.h"
|
||||
|
||||
|
|
@ -134,12 +134,14 @@ typedef struct cifop
|
|||
* box coordinates into CIF layer geometry.
|
||||
* CIFOP_NET - Added 11/3/08---pull an entire electrical net into
|
||||
* the CIF layer, selectively picking layers.
|
||||
* CIFOP_MAXRECT - Reduce all areas to the largest internal fitting
|
||||
* CIFOP_MAXRECT - Reduce all disjoint regions to the largest internal fitting
|
||||
* rectangle.
|
||||
* CIFOP_INTERACT - Select all disjoint regions which overlap a given set of types
|
||||
* CIFOP_COPYUP - Added 5/5/16---make and keep a copy the resulting layer,
|
||||
* which will be painted into parent cells instead of the
|
||||
* current cell. This replaces the "fault" method.
|
||||
* CIFOP_CLOSE - Added 11/25/19---close up areas smaller than indicated
|
||||
* CIFOP_MANHATTAN - Added 3/27/25---remove or fill nonmanhattan areas
|
||||
* CIFOP_BRIDGE - Added 6/11/20---Bridge across catecorner gaps
|
||||
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
|
||||
* CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any.
|
||||
|
|
@ -163,12 +165,17 @@ typedef struct cifop
|
|||
#define CIFOP_BOUNDARY 16
|
||||
#define CIFOP_NET 17
|
||||
#define CIFOP_MAXRECT 18
|
||||
#define CIFOP_COPYUP 19
|
||||
#define CIFOP_CLOSE 20
|
||||
#define CIFOP_BRIDGE 21
|
||||
#define CIFOP_BRIDGELIM 22
|
||||
#define CIFOP_MASKHINTS 23
|
||||
#define CIFOP_INTERACT 19
|
||||
#define CIFOP_COPYUP 20
|
||||
#define CIFOP_CLOSE 21
|
||||
#define CIFOP_MANHATTAN 22
|
||||
#define CIFOP_BRIDGE 23
|
||||
#define CIFOP_BRIDGELIM 24
|
||||
#define CIFOP_MASKHINTS 25
|
||||
|
||||
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
|
||||
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
|
||||
#define CIFOP_INT_TOUCHING 0x2 /* Include both touching and overlapping */
|
||||
|
||||
/* Added by Tim 10/21/2004 */
|
||||
/* The following structure is used to pass information on how to draw
|
||||
|
|
@ -294,9 +301,12 @@ typedef struct cifstyle
|
|||
* layer.
|
||||
*/
|
||||
int cs_portLayer[TT_MAXTYPES];
|
||||
/* Similar to cs_labelLayer, to distinguish
|
||||
* between output types used for "normal"
|
||||
* text and those used specifically for ports.
|
||||
/* Similar to cs_labelLayer, to use as
|
||||
* a type for geometry attached to port labels.
|
||||
*/
|
||||
int cs_portText[TT_MAXTYPES];
|
||||
/* Similar to cs_labelLayer, to use as
|
||||
* a text type for port labels
|
||||
*/
|
||||
CIFLayer *cs_layers[MAXCIFLAYERS];
|
||||
/* Describes how to generate each layer.*/
|
||||
|
|
@ -312,40 +322,38 @@ typedef struct cifstyle
|
|||
#define CWF_SEE_NO_VENDOR 0x10 /* Hide magic's GDS from vendor cells */
|
||||
#define CWF_NO_ERRORS 0x20 /* Do not generate error msgs and fdbk */
|
||||
#define CWF_STRING_LIMIT 0x40 /* Use older Calma format character limit */
|
||||
#define CWF_MINIMUM_GRID 0x80 /* Force minimum grid scaling */
|
||||
|
||||
/* procedures */
|
||||
|
||||
extern bool CIFNameToMask();
|
||||
extern void CIFGenSubcells();
|
||||
extern void CIFGenArrays();
|
||||
extern void CIFGen();
|
||||
extern void CIFClearPlanes();
|
||||
extern Plane *CIFGenLayer();
|
||||
extern void CIFInitCells();
|
||||
extern int cifHierCopyFunc();
|
||||
extern int cifHierCopyMaskHints();
|
||||
extern void CIFLoadStyle();
|
||||
extern void CIFCopyMaskHints();
|
||||
extern bool CIFNameToMask(char *name, TileTypeBitMask *result, TileTypeBitMask *depend);
|
||||
extern void CIFGenSubcells(CellDef *def, Rect *area, Plane **output);
|
||||
extern void CIFGenArrays(CellDef *def, Rect *area, Plane **output);
|
||||
extern void CIFGen(CellDef *cellDef, CellDef *origDef, const Rect *area, Plane **planes, TileTypeBitMask *layers,
|
||||
bool replace, bool genAllPlanes, bool hier, ClientData clientdata);
|
||||
extern void CIFClearPlanes(Plane **planes);
|
||||
extern Plane *CIFGenLayer(CIFOp *op, const Rect *area, CellDef *cellDef, CellDef *origDef, Plane *temps[],
|
||||
bool hier, ClientData clientdata);
|
||||
extern void CIFInitCells(void);
|
||||
extern int cifHierCopyFunc(Tile *tile, TileType dinfo, TreeContext *cxp);
|
||||
extern int cifHierCopyMaskHints(SearchContext *scx, ClientData clientData);
|
||||
extern void CIFLoadStyle(char *stylename);
|
||||
extern void CIFCopyMaskHints(SearchContext *scx, CellDef *targetDef);
|
||||
|
||||
/* C99 compat */
|
||||
extern void CIFCoverageLayer();
|
||||
extern bool CIFWriteFlat();
|
||||
extern void CIFScalePlanes();
|
||||
extern void CIFInputRescale();
|
||||
extern int CIFCalmaLayerToCifLayer();
|
||||
extern int CIFScaleCoord();
|
||||
extern void CIFPropRecordPath();
|
||||
extern void CIFPaintWirePath();
|
||||
extern void CIFMakeManhattanPath();
|
||||
extern int cifGrowSliver();
|
||||
extern int cifHierElementFunc();
|
||||
extern int cifSquareFunc();
|
||||
extern int cifSquareGridFunc();
|
||||
extern int cifSlotFunc();
|
||||
extern int CIFParseScale();
|
||||
extern int cifParseCalmaNums();
|
||||
extern int CIFEdgeDirection();
|
||||
extern bool CIFReadTechLimitScale();
|
||||
extern void CIFCoverageLayer(CellDef *rootDef, Rect *area, char *layer, bool dolist);
|
||||
extern bool CIFWriteFlat(CellDef *rootDef, FILE *f);
|
||||
extern void CIFScalePlanes(int scalen, int scaled, Plane **planearray);
|
||||
extern void CIFInputRescale(int n, int d);
|
||||
extern int CIFScaleCoord(int cifCoord, int snap_type);
|
||||
extern int cifGrowSliver(Tile *tile, TileType dinfo, Rect *area);
|
||||
extern int cifHierElementFunc(CellUse *use, Transform *transform, int x, int y, Rect *checkArea);
|
||||
extern int cifSquareFunc(Rect *area, CIFOp *op, int *rows, int *columns, Rect *cut);
|
||||
extern int cifSquareGridFunc(Rect *area, CIFOp *op, int *rows, int *columns, Rect *cut);
|
||||
extern int cifSlotFunc(Rect *area, CIFOp *op, int *numY, int *numX, Rect *cut, bool vertical);
|
||||
extern int CIFParseScale(char *true_scale, int *expander);
|
||||
extern int cifParseCalmaNums(char *str, int *numArray, int numNums);
|
||||
extern bool CIFReadTechLimitScale(int ns, int ds);
|
||||
|
||||
/* Shared variables and structures: */
|
||||
|
||||
|
|
@ -359,6 +367,9 @@ extern CellUse *CIFDummyUse; /* Used to dummy up a CellUse for a
|
|||
* def.
|
||||
*/
|
||||
|
||||
extern Plane *CIFTotalPlanes[]; /* Exported for diagnostics */
|
||||
extern Plane *CIFComponentPlanes[]; /* Exported for diagnostics */
|
||||
|
||||
/* Valid values of CIFWarningLevel (see cif.h) */
|
||||
|
||||
typedef enum {CIF_WARN_DEFAULT, CIF_WARN_NONE, CIF_WARN_ALIGN,
|
||||
|
|
@ -373,13 +384,13 @@ extern int CIFHierRects;
|
|||
|
||||
/* Tables used for painting and erasing CIF. */
|
||||
|
||||
extern PaintResultType CIFPaintTable[], CIFEraseTable[];
|
||||
extern const PaintResultType CIFPaintTable[], CIFEraseTable[];
|
||||
|
||||
/* Procedures and variables for reporting errors. */
|
||||
|
||||
extern int CIFErrorLayer;
|
||||
extern CellDef *CIFErrorDef;
|
||||
extern void CIFError();
|
||||
extern void CIFError(Rect *area, char *message);
|
||||
|
||||
/* The following determines the tile type used to hold the CIF
|
||||
* information on its paint plane.
|
||||
|
|
@ -388,4 +399,4 @@ extern void CIFError();
|
|||
#define CIF_SOLIDTYPE 1
|
||||
extern TileTypeBitMask CIFSolidBits;
|
||||
|
||||
#endif /* _CIFINT_H */
|
||||
#endif /* _MAGIC__CIF__CIFINT_H */
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFmain.c,v 1.3 2009/01/15 15:44:34 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFmain.c,v 1.3 2009/01/15 15:44:34 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -95,7 +95,7 @@ global int CIFErrorLayer; /* Index of CIF layer associated with errors.*/
|
|||
*/
|
||||
|
||||
void
|
||||
CIFPrintStats()
|
||||
CIFPrintStats(void)
|
||||
{
|
||||
TxPrintf("CIF statistics (recent/total):\n");
|
||||
cifTotalTileOps += CIFTileOps;
|
||||
|
|
@ -136,8 +136,8 @@ CIFPrintStats()
|
|||
*/
|
||||
|
||||
float
|
||||
CIFGetOutputScale(convert)
|
||||
int convert;
|
||||
CIFGetOutputScale(
|
||||
int convert)
|
||||
{
|
||||
if (CIFCurStyle == NULL) return 1.0;
|
||||
|
||||
|
|
@ -159,8 +159,8 @@ CIFGetOutputScale(convert)
|
|||
*/
|
||||
|
||||
float
|
||||
CIFGetScale(convert)
|
||||
int convert;
|
||||
CIFGetScale(
|
||||
int convert)
|
||||
{
|
||||
if (CIFCurStyle == NULL) return 1.0;
|
||||
|
||||
|
|
@ -185,10 +185,10 @@ CIFGetScale(convert)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFPrintStyle(dolist, doforall, docurrent)
|
||||
bool dolist; /* Return as a list if true */
|
||||
bool doforall; /* Print all known styles if true */
|
||||
bool docurrent; /* Print current style if true */
|
||||
CIFPrintStyle(
|
||||
bool dolist, /* Return as a list if true */
|
||||
bool doforall, /* Print all known styles if true */
|
||||
bool docurrent) /* Print current style if true */
|
||||
{
|
||||
CIFKeep *style;
|
||||
|
||||
|
|
@ -254,8 +254,8 @@ CIFPrintStyle(dolist, doforall, docurrent)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSetStyle(name)
|
||||
char *name; /* Name of the new style. If NULL, just
|
||||
CIFSetStyle(
|
||||
char *name) /* Name of the new style. If NULL, just
|
||||
* print out the valid styles.
|
||||
*/
|
||||
{
|
||||
|
|
@ -320,10 +320,10 @@ CIFSetStyle(name)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFNameToMask(name, result, depend)
|
||||
char *name;
|
||||
TileTypeBitMask *result;
|
||||
TileTypeBitMask *depend;
|
||||
CIFNameToMask(
|
||||
char *name,
|
||||
TileTypeBitMask *result,
|
||||
TileTypeBitMask *depend)
|
||||
{
|
||||
int i, j;
|
||||
CIFOp *op;
|
||||
|
|
@ -414,11 +414,11 @@ CIFNameToMask(name, result, depend)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFError(area, message)
|
||||
Rect *area; /* Place in CIFErrorDef where there was a
|
||||
CIFError(
|
||||
Rect *area, /* Place in CIFErrorDef where there was a
|
||||
* problem in generating CIFErrorLayer.
|
||||
*/
|
||||
char *message; /* Short note about what went wrong. */
|
||||
char *message) /* Short note about what went wrong. */
|
||||
{
|
||||
char msg[200];
|
||||
|
||||
|
|
@ -452,7 +452,7 @@ CIFError(area, message)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFOutputScaleFactor()
|
||||
CIFOutputScaleFactor(void)
|
||||
{
|
||||
if (CIFCurStyle == NULL) return 1;
|
||||
return CIFCurStyle->cs_scaleFactor;
|
||||
|
|
|
|||
128
cif/CIFrdcl.c
128
cif/CIFrdcl.c
|
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdcl.c,v 1.5 2010/08/25 17:33:55 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdcl.c,v 1.5 2010/08/25 17:33:55 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -126,8 +126,8 @@ char *cifSubcellId = NULL;
|
|||
*/
|
||||
|
||||
void
|
||||
CIFReadCellInit(ptrkeys)
|
||||
int ptrkeys;
|
||||
CIFReadCellInit(
|
||||
int ptrkeys)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -162,8 +162,8 @@ CIFReadCellInit(ptrkeys)
|
|||
*/
|
||||
|
||||
bool
|
||||
cifForgetCell(cifNum)
|
||||
int cifNum;
|
||||
cifForgetCell(
|
||||
int cifNum)
|
||||
{
|
||||
HashEntry *h;
|
||||
|
||||
|
|
@ -196,8 +196,8 @@ cifForgetCell(cifNum)
|
|||
*/
|
||||
|
||||
void
|
||||
cifUniqueCell(cifNum)
|
||||
int cifNum;
|
||||
cifUniqueCell(
|
||||
int cifNum)
|
||||
{
|
||||
HashEntry *h;
|
||||
CellDef *def, *testdef;
|
||||
|
|
@ -256,8 +256,8 @@ cifUniqueCell(cifNum)
|
|||
*/
|
||||
|
||||
CellDef *
|
||||
cifFindCell(cifNum)
|
||||
int cifNum; /* The CIF number of the desired cell. */
|
||||
cifFindCell(
|
||||
int cifNum) /* The CIF number of the desired cell. */
|
||||
{
|
||||
HashEntry *h;
|
||||
CellDef *def, *testdef;
|
||||
|
|
@ -299,10 +299,10 @@ cifFindCell(cifNum)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFScalePlanes(scalen, scaled, planearray)
|
||||
int scalen;
|
||||
int scaled;
|
||||
Plane **planearray;
|
||||
CIFScalePlanes(
|
||||
int scalen,
|
||||
int scaled,
|
||||
Plane **planearray)
|
||||
{
|
||||
int pNum;
|
||||
Plane *newplane;
|
||||
|
|
@ -348,8 +348,9 @@ CIFScalePlanes(scalen, scaled, planearray)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFInputRescale(n, d)
|
||||
int n, d;
|
||||
CIFInputRescale(
|
||||
int n,
|
||||
int d)
|
||||
{
|
||||
CIFReadStyle *istyle = cifCurReadStyle;
|
||||
CIFReadLayer *cl;
|
||||
|
|
@ -389,7 +390,7 @@ CIFInputRescale(n, d)
|
|||
CIFScalePlanes(n, d, cifCurReadPlanes);
|
||||
if (cifCurReadPlanes != cifEditCellPlanes)
|
||||
CIFScalePlanes(n, d, cifEditCellPlanes);
|
||||
if (cifEditCellPlanes != cifSubcellPlanes && cifCurReadPlanes != cifSubcellPlanes)
|
||||
if ((const Plane*)cifEditCellPlanes != (const Plane*)cifSubcellPlanes && cifCurReadPlanes != cifSubcellPlanes)
|
||||
CIFScalePlanes(n, d, cifSubcellPlanes);
|
||||
|
||||
CIFReadWarning("CIF style %s: units rescaled by factor of %d / %d\n",
|
||||
|
|
@ -417,7 +418,7 @@ CIFInputRescale(n, d)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseStart()
|
||||
CIFParseStart(void)
|
||||
{
|
||||
int number;
|
||||
|
||||
|
|
@ -502,9 +503,10 @@ CIFParseStart()
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int cifCheckPaintFunc(tile, clientData)
|
||||
Tile *tile;
|
||||
ClientData clientData;
|
||||
int cifCheckPaintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData clientData)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -512,29 +514,30 @@ int cifCheckPaintFunc(tile, clientData)
|
|||
/* Callback function for copying paint from one CIF cell into another */
|
||||
|
||||
int
|
||||
cifCopyPaintFunc(tile, cifCopyRec)
|
||||
Tile *tile;
|
||||
CIFCopyRec *cifCopyRec;
|
||||
cifCopyPaintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
CIFCopyRec *cifCopyRec)
|
||||
{
|
||||
int pNum;
|
||||
TileType dinfo;
|
||||
TileType newdinfo;
|
||||
Rect sourceRect, targetRect;
|
||||
Transform *trans = cifCopyRec->trans;
|
||||
Plane *plane = cifCopyRec->plane;
|
||||
|
||||
dinfo = TiGetTypeExact(tile);
|
||||
newdinfo = TiGetTypeExact(tile) | dinfo;
|
||||
|
||||
if (trans)
|
||||
{
|
||||
TiToRect(tile, &sourceRect);
|
||||
GeoTransRect(trans, &sourceRect, &targetRect);
|
||||
if (IsSplit(tile))
|
||||
dinfo = DBTransformDiagonal(TiGetTypeExact(tile), trans);
|
||||
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, trans);
|
||||
}
|
||||
else
|
||||
TiToRect(tile, &targetRect);
|
||||
|
||||
DBNMPaintPlane(plane, dinfo, &targetRect, CIFPaintTable,
|
||||
DBNMPaintPlane(plane, newdinfo, &targetRect, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
return 0;
|
||||
|
|
@ -558,9 +561,10 @@ cifCopyPaintFunc(tile, cifCopyRec)
|
|||
*/
|
||||
|
||||
int
|
||||
cifMaskHintFunc(tile, lrecp)
|
||||
Tile *tile;
|
||||
LinkedRect **lrecp;
|
||||
cifMaskHintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* Unused, do not support non-manhattan hints */
|
||||
LinkedRect **lrecp)
|
||||
{
|
||||
Rect r;
|
||||
LinkedRect *newlr;
|
||||
|
|
@ -593,11 +597,12 @@ cifMaskHintFunc(tile, lrecp)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFPaintCurrent(filetype)
|
||||
bool filetype;
|
||||
CIFPaintCurrent(
|
||||
int filetype)
|
||||
{
|
||||
extern int cifMakeBoundaryFunc(); /* Forward declaration. */
|
||||
extern int cifPaintCurrentFunc(); /* Forward declaration. */
|
||||
/* Forward declarations. */
|
||||
extern int cifMakeBoundaryFunc(Tile *tile, TileType dinfo, ClientData clientdata);
|
||||
extern int cifPaintCurrentFunc(Tile *tile, TileType dinfo, TileType type);
|
||||
|
||||
Plane *plane, *swapplane;
|
||||
int i;
|
||||
|
|
@ -696,7 +701,7 @@ CIFPaintCurrent(filetype)
|
|||
&DBAllButSpaceBits, cifCheckPaintFunc,
|
||||
(ClientData)NULL) == 1))
|
||||
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifMakeBoundaryFunc, (ClientData)filetype);
|
||||
&CIFSolidBits, cifMakeBoundaryFunc, INT2CD(filetype));
|
||||
}
|
||||
|
||||
/* Swap planes */
|
||||
|
|
@ -708,7 +713,7 @@ CIFPaintCurrent(filetype)
|
|||
{
|
||||
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
|
||||
&CIFSolidBits, cifPaintCurrentFunc,
|
||||
(ClientData)type);
|
||||
INT2CD(type));
|
||||
}
|
||||
|
||||
/* Recycle the plane, which was dynamically allocated. */
|
||||
|
|
@ -759,7 +764,8 @@ CIFPaintCurrent(filetype)
|
|||
}
|
||||
|
||||
/* Multiply input planes to the same scale as the generated output */
|
||||
CIFScalePlanes(CIFCurStyle->cs_scaleFactor, 1, cifCurReadPlanes);
|
||||
CIFScalePlanes(CIFCurStyle->cs_scaleFactor, cifCurReadStyle->crs_scaleFactor,
|
||||
cifCurReadPlanes);
|
||||
|
||||
/* Generate the output for these layers from the cell contents */
|
||||
CIFClearPlanes(CIFPlanes);
|
||||
|
|
@ -849,9 +855,11 @@ CIFPaintCurrent(filetype)
|
|||
freeMagic(propstr);
|
||||
}
|
||||
propstr = newstr;
|
||||
freeMagic(lrec);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, lrec);
|
||||
lrec = lrec->r_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
/* NOTE: propstr is transferred to the CellDef and should
|
||||
* not be free'd here.
|
||||
*/
|
||||
|
|
@ -885,9 +893,10 @@ CIFPaintCurrent(filetype)
|
|||
/* Use CIF layer geometry to define a fixed bounding box for the current cell */
|
||||
|
||||
int
|
||||
cifMakeBoundaryFunc(tile, clientdata)
|
||||
Tile *tile; /* Tile of CIF information. */
|
||||
ClientData clientdata; /* Pass the file type (CIF or CALMA) */
|
||||
cifMakeBoundaryFunc(
|
||||
Tile *tile, /* Tile of CIF information. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
ClientData clientdata) /* Pass the file type (CIF or CALMA) */
|
||||
{
|
||||
/* It is assumed that there is one rectangle for the boundary. */
|
||||
/* If there are multiple rectangles defined with the boundary */
|
||||
|
|
@ -896,7 +905,7 @@ cifMakeBoundaryFunc(tile, clientdata)
|
|||
Rect area;
|
||||
char propertyvalue[128], *storedvalue;
|
||||
int savescale;
|
||||
bool filetype = (bool)clientdata;
|
||||
int filetype = (int)CD2INT(clientdata);
|
||||
|
||||
TiToRect(tile, &area);
|
||||
area.r_xtop = CIFScaleCoord(area.r_xtop, COORD_EXACT);
|
||||
|
|
@ -964,9 +973,10 @@ cifMakeBoundaryFunc(tile, clientdata)
|
|||
/* Paint CIF layer geometry into the current cell def as magic layer "type" */
|
||||
|
||||
int
|
||||
cifPaintCurrentFunc(tile, type)
|
||||
Tile *tile; /* Tile of CIF information. */
|
||||
TileType type; /* Magic type to be painted. */
|
||||
cifPaintCurrentFunc(
|
||||
Tile *tile, /* Tile of CIF information. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
TileType type) /* Magic type to be painted. */
|
||||
{
|
||||
Rect area;
|
||||
int pNum;
|
||||
|
|
@ -1015,7 +1025,7 @@ cifPaintCurrentFunc(tile, type)
|
|||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
if (DBPaintOnPlane(type, pNum))
|
||||
{
|
||||
DBNMPaintPlane(cifReadCellDef->cd_planes[pNum], TiGetTypeExact(tile),
|
||||
DBNMPaintPlane(cifReadCellDef->cd_planes[pNum], TiGetTypeExact(tile) | dinfo,
|
||||
&area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL);
|
||||
}
|
||||
|
||||
|
|
@ -1041,7 +1051,7 @@ cifPaintCurrentFunc(tile, type)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseFinish()
|
||||
CIFParseFinish(void)
|
||||
{
|
||||
if (!cifSubcellBeingRead)
|
||||
{
|
||||
|
|
@ -1096,7 +1106,7 @@ CIFParseFinish()
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseDelete()
|
||||
CIFParseDelete(void)
|
||||
{
|
||||
int number;
|
||||
|
||||
|
|
@ -1138,7 +1148,7 @@ CIFParseDelete()
|
|||
*/
|
||||
|
||||
char *
|
||||
cifParseName()
|
||||
cifParseName(void)
|
||||
{
|
||||
char ch;
|
||||
char *bufferp;
|
||||
|
|
@ -1180,7 +1190,7 @@ cifParseName()
|
|||
*/
|
||||
|
||||
bool
|
||||
cifParseUser9()
|
||||
cifParseUser9(void)
|
||||
{
|
||||
char *name;
|
||||
|
||||
|
|
@ -1212,7 +1222,7 @@ cifParseUser9()
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseCall()
|
||||
CIFParseCall(void)
|
||||
{
|
||||
int called;
|
||||
Transform transform;
|
||||
|
|
@ -1279,7 +1289,7 @@ CIFParseCall()
|
|||
*/
|
||||
|
||||
bool
|
||||
cifParseUser91()
|
||||
cifParseUser91(void)
|
||||
{
|
||||
if (cifSubcellId != NULL)
|
||||
{
|
||||
|
|
@ -1310,7 +1320,7 @@ cifParseUser91()
|
|||
*/
|
||||
|
||||
bool
|
||||
cifParseUser94()
|
||||
cifParseUser94(void)
|
||||
{
|
||||
Rect rectangle;
|
||||
char *name = NULL;
|
||||
|
|
@ -1400,7 +1410,7 @@ cifParseUser94()
|
|||
*/
|
||||
|
||||
bool
|
||||
cifParseUser95()
|
||||
cifParseUser95(void)
|
||||
{
|
||||
/* Modified by BIM 1/8/2018 */
|
||||
Rect rectangle;
|
||||
|
|
@ -1560,7 +1570,7 @@ cifParseUser95()
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
bool
|
||||
CIFParseUser()
|
||||
CIFParseUser(void)
|
||||
{
|
||||
char ch;
|
||||
|
||||
|
|
@ -1612,8 +1622,8 @@ CIFParseUser()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFReadCellCleanup(filetype)
|
||||
bool filetype;
|
||||
CIFReadCellCleanup(
|
||||
int filetype)
|
||||
{
|
||||
HashEntry *h;
|
||||
HashSearch hs;
|
||||
|
|
@ -1656,7 +1666,7 @@ CIFReadCellCleanup(filetype)
|
|||
def->cd_flags &= ~CDPROCESSEDGDS;
|
||||
|
||||
if ((filetype == FILE_CIF && CIFNoDRCCheck == FALSE) ||
|
||||
(filetype == 1 && CalmaNoDRCCheck == FALSE))
|
||||
(filetype == FILE_CALMA && CalmaNoDRCCheck == FALSE))
|
||||
DRCCheckThis(def, TT_CHECKPAINT, &def->cd_bbox);
|
||||
DBWAreaChanged(def, &def->cd_bbox, DBW_ALLWINDOWS, &DBAllButSpaceBits);
|
||||
DBCellSetModified(def, TRUE);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpoly.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpoly.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -29,6 +29,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "database/database.h"
|
||||
#include "cif/CIFint.h"
|
||||
#include "cif/CIFread.h"
|
||||
#include "calma/calma.h"
|
||||
#include "utils/malloc.h"
|
||||
|
||||
#define HEDGE 0 /* Horizontal edge */
|
||||
|
|
@ -54,10 +55,14 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
*/
|
||||
|
||||
int
|
||||
cifLowX(a, b)
|
||||
CIFPath **a, **b;
|
||||
cifLowX(
|
||||
const void *aa,
|
||||
const void *bb)
|
||||
{
|
||||
Point *p, *q;
|
||||
const CIFPath **a = (const CIFPath **)aa;
|
||||
const CIFPath **b = (const CIFPath **)bb;
|
||||
|
||||
const Point *p, *q;
|
||||
|
||||
p = &(*a)->cifp_point;
|
||||
q = &(*b)->cifp_point;
|
||||
|
|
@ -87,9 +92,12 @@ cifLowX(a, b)
|
|||
*/
|
||||
|
||||
int
|
||||
cifLowY(a, b)
|
||||
Point **a, **b;
|
||||
cifLowY(
|
||||
const void *aa,
|
||||
const void *bb)
|
||||
{
|
||||
const Point **a = (const Point **)aa;
|
||||
const Point **b = (const Point **)bb;
|
||||
if ((*a)->p_y < (*b)->p_y)
|
||||
return (-1);
|
||||
if ((*a)->p_y > (*b)->p_y)
|
||||
|
|
@ -118,10 +126,10 @@ cifLowY(a, b)
|
|||
*/
|
||||
|
||||
bool
|
||||
cifOrient(edges, nedges, dir)
|
||||
CIFPath *edges[]; /* Array of edges to be categorized. */
|
||||
int dir[]; /* Array to hold directions. */
|
||||
int nedges; /* Size of arrays. */
|
||||
cifOrient(
|
||||
CIFPath *edges[], /* Array of edges to be categorized. */
|
||||
int nedges, /* Size of arrays. */
|
||||
int dir[]) /* Array to hold directions. */
|
||||
{
|
||||
Point *p, *q;
|
||||
int n;
|
||||
|
|
@ -178,10 +186,11 @@ cifOrient(edges, nedges, dir)
|
|||
*/
|
||||
|
||||
bool
|
||||
cifCross(edge, dir, ybot, ytop)
|
||||
CIFPath *edge; /* Pointer to first of 2 path points in edge */
|
||||
int dir; /* Direction of edge */
|
||||
int ybot, ytop; /* Range of interest */
|
||||
cifCross(
|
||||
CIFPath *edge, /* Pointer to first of 2 path points in edge */
|
||||
int dir, /* Direction of edge */
|
||||
int ybot,
|
||||
int ytop) /* Range of interest */
|
||||
{
|
||||
int ebot, etop;
|
||||
|
||||
|
|
@ -222,11 +231,12 @@ cifCross(edge, dir, ybot, ytop)
|
|||
*/
|
||||
|
||||
LinkedRect *
|
||||
CIFPolyToRects(path, plane, resultTbl, ui)
|
||||
CIFPath *path; /* Path describing a polygon. */
|
||||
Plane *plane; /* Plane to draw on */
|
||||
PaintResultType *resultTbl;
|
||||
PaintUndoInfo *ui;
|
||||
CIFPolyToRects(
|
||||
CIFPath *path, /* Path describing a polygon. */
|
||||
Plane *plane, /* Plane to draw on */
|
||||
const PaintResultType *resultTbl,
|
||||
PaintUndoInfo *ui,
|
||||
bool isCalma) /* TRUE for Calma, FALSE for CIF */
|
||||
{
|
||||
int npts = 0, n, *dir, curr, wrapno;
|
||||
int xbot, xtop, ybot, ytop;
|
||||
|
|
@ -240,6 +250,9 @@ CIFPolyToRects(path, plane, resultTbl, ui)
|
|||
|
||||
if ((tail->cifp_x != path->cifp_x) || (tail->cifp_y != path->cifp_y))
|
||||
{
|
||||
if (isCalma)
|
||||
CalmaReadError("Boundary is not closed.\n" );
|
||||
|
||||
p = (CIFPath *) mallocMagic ((unsigned) sizeof (CIFPath));
|
||||
p->cifp_x = path->cifp_x;
|
||||
p->cifp_y = path->cifp_y;
|
||||
|
|
|
|||
102
cif/CIFrdpt.c
102
cif/CIFrdpt.c
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpt.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpt.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -65,7 +65,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseBox()
|
||||
CIFParseBox(void)
|
||||
{
|
||||
Point center;
|
||||
Point direction;
|
||||
|
|
@ -176,7 +176,7 @@ CIFParseBox()
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseFlash()
|
||||
CIFParseFlash(void)
|
||||
{
|
||||
int diameter;
|
||||
int savescale;
|
||||
|
|
@ -236,13 +236,13 @@ CIFParseFlash()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFPropRecordPath(def, pathheadp, iswire, propname)
|
||||
CellDef *def;
|
||||
CIFPath *pathheadp;
|
||||
bool iswire;
|
||||
char *propname;
|
||||
CIFPropRecordPath(
|
||||
CellDef *def,
|
||||
CIFPath *pathheadp,
|
||||
bool iswire,
|
||||
char *propname)
|
||||
{
|
||||
extern float CIFGetOutputScale();
|
||||
extern float CIFGetOutputScale(int convert);
|
||||
CIFPath *pathp;
|
||||
char *pathstr, *sptr;
|
||||
int components;
|
||||
|
|
@ -316,13 +316,13 @@ CIFPropRecordPath(def, pathheadp, iswire, propname)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
|
||||
CIFPath *pathheadp;
|
||||
int width;
|
||||
bool endcap;
|
||||
Plane *plane;
|
||||
PaintResultType *ptable;
|
||||
PaintUndoInfo *ui;
|
||||
CIFPaintWirePath(
|
||||
CIFPath *pathheadp,
|
||||
int width,
|
||||
bool endcap,
|
||||
Plane *plane,
|
||||
const PaintResultType *ptable,
|
||||
PaintUndoInfo *ui)
|
||||
{
|
||||
CIFPath *pathp, *previousp, *nextp, *polypath;
|
||||
CIFPath *returnpath, *newpath, *savepath;
|
||||
|
|
@ -338,18 +338,20 @@ CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
|
|||
pathp = pathheadp->cifp_next;
|
||||
if (pathp != NULL)
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (pathp->cifp_next != NULL)
|
||||
{
|
||||
if (pathp->cifp_next->cifp_x == pathp->cifp_x &&
|
||||
pathp->cifp_next->cifp_y == pathp->cifp_y)
|
||||
{
|
||||
previousp->cifp_next = pathp->cifp_next;
|
||||
freeMagic(pathp);
|
||||
freeMagic1(&mm1, pathp);
|
||||
}
|
||||
else
|
||||
previousp = pathp;
|
||||
pathp = pathp->cifp_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
previousp = pathheadp;
|
||||
|
|
@ -439,7 +441,8 @@ CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
|
|||
/* Wire reverses direction. Break wire here, */
|
||||
/* draw, and start new polygon. */
|
||||
|
||||
TxError("Warning: direction reversal in path.\n");
|
||||
TxError("Warning: direction reversal in path at (%d, %d).\n",
|
||||
pathp->cifp_x, pathp->cifp_y);
|
||||
|
||||
phi = theta;
|
||||
if (endcap)
|
||||
|
|
@ -451,7 +454,8 @@ CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
|
|||
firstpoint = TRUE;
|
||||
}
|
||||
else {
|
||||
TxError("Error: mitre limit exceeded at wire junction.\n");
|
||||
TxError("Error: mitre limit exceeded at wire junction at (%d, %d).\n",
|
||||
pathp->cifp_x, pathp->cifp_y);
|
||||
TxError("Route has been truncated.\n");
|
||||
break;
|
||||
}
|
||||
|
|
@ -481,14 +485,16 @@ CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
|
|||
/* Slow draw for non-Manhattan paths: */
|
||||
/* Break the area up into triangles and rectangles */
|
||||
|
||||
rectp = CIFPolyToRects(polypath, plane, ptable, ui);
|
||||
rectp = CIFPolyToRects(polypath, plane, ptable, ui, FALSE);
|
||||
CIFFreePath(polypath);
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (; rectp != NULL ; rectp = rectp->r_next)
|
||||
{
|
||||
DBPaintPlane(plane, &rectp->r_r, ptable, ui);
|
||||
freeMagic((char *) rectp);
|
||||
freeMagic1(&mm1, (char *) rectp);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
polypath = NULL;
|
||||
}
|
||||
else
|
||||
|
|
@ -562,13 +568,13 @@ CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
|
|||
*/
|
||||
|
||||
LinkedRect *
|
||||
PaintPolygon(pointlist, number, plane, ptable, ui, keep)
|
||||
Point *pointlist; /* Array of Point structures */
|
||||
int number; /* total number of points */
|
||||
Plane *plane; /* Plane structure to paint into */
|
||||
PaintResultType *ptable; /* Paint result table */
|
||||
PaintUndoInfo *ui; /* Undo record */
|
||||
bool keep; /* Return list of rects if true */
|
||||
PaintPolygon(
|
||||
Point *pointlist, /* Array of Point structures */
|
||||
int number, /* total number of points */
|
||||
Plane *plane, /* Plane structure to paint into */
|
||||
PaintResultType *ptable, /* Paint result table */
|
||||
PaintUndoInfo *ui, /* Undo record */
|
||||
bool keep) /* Return list of rects if true */
|
||||
{
|
||||
LinkedRect *rectp, *rectlist;
|
||||
CIFPath *newpath, *cifpath = (CIFPath *)NULL;
|
||||
|
|
@ -583,14 +589,16 @@ PaintPolygon(pointlist, number, plane, ptable, ui, keep)
|
|||
cifpath = newpath;
|
||||
}
|
||||
|
||||
rectlist = CIFPolyToRects(cifpath, plane, ptable, ui);
|
||||
rectlist = CIFPolyToRects(cifpath, plane, ptable, ui, FALSE);
|
||||
CIFFreePath(cifpath);
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (rectp = rectlist; rectp != NULL ; rectp = rectp->r_next)
|
||||
{
|
||||
DBPaintPlane(plane, &rectp->r_r, ptable, ui);
|
||||
if (!keep) freeMagic((char *) rectp);
|
||||
if (!keep) freeMagic1(&mm1, (char *) rectp);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
return (keep) ? rectlist : (LinkedRect *)NULL;
|
||||
}
|
||||
|
||||
|
|
@ -617,14 +625,14 @@ PaintPolygon(pointlist, number, plane, ptable, ui, keep)
|
|||
*/
|
||||
|
||||
void
|
||||
PaintWireList(pointlist, number, width, endcap, plane, ptable, ui)
|
||||
Point *pointlist; /* Array of Point structures */
|
||||
int number; /* total number of points */
|
||||
int width; /* Route width of path */
|
||||
bool endcap; /* Whether or not to add 1/2 width endcaps */
|
||||
Plane *plane; /* Plane structure to paint into */
|
||||
PaintResultType *ptable; /* Paint result table */
|
||||
PaintUndoInfo *ui; /* Undo record */
|
||||
PaintWireList(
|
||||
Point *pointlist, /* Array of Point structures */
|
||||
int number, /* total number of points */
|
||||
int width, /* Route width of path */
|
||||
bool endcap, /* Whether or not to add 1/2 width endcaps */
|
||||
Plane *plane, /* Plane structure to paint into */
|
||||
PaintResultType *ptable, /* Paint result table */
|
||||
PaintUndoInfo *ui) /* Undo record */
|
||||
{
|
||||
CIFPath *newpath, *cifpath = (CIFPath *)NULL;
|
||||
int i;
|
||||
|
|
@ -661,7 +669,7 @@ PaintWireList(pointlist, number, width, endcap, plane, ptable, ui)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseWire()
|
||||
CIFParseWire(void)
|
||||
{
|
||||
int width;
|
||||
CIFPath *pathheadp, *polypath;
|
||||
|
|
@ -687,7 +695,8 @@ CIFParseWire()
|
|||
|
||||
width /= cifReadScale2;
|
||||
savescale = cifReadScale1;
|
||||
if (!CIFParsePath(&pathheadp, 2))
|
||||
pathheadp = CIFParsePath(2);
|
||||
if (pathheadp == NULL)
|
||||
{
|
||||
CIFReadError("wire, but improper path; ignored.\n");
|
||||
CIFSkipToSemi();
|
||||
|
|
@ -721,7 +730,7 @@ CIFParseWire()
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseLayer()
|
||||
CIFParseLayer(void)
|
||||
{
|
||||
#define MAXCHARS 4
|
||||
char name[MAXCHARS+1];
|
||||
|
|
@ -784,7 +793,7 @@ CIFParseLayer()
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParsePoly()
|
||||
CIFParsePoly(void)
|
||||
{
|
||||
CIFPath *pathheadp;
|
||||
LinkedRect *rectp;
|
||||
|
|
@ -797,7 +806,8 @@ CIFParsePoly()
|
|||
CIFSkipToSemi();
|
||||
return FALSE;
|
||||
}
|
||||
if (!CIFParsePath(&pathheadp, 1))
|
||||
pathheadp = CIFParsePath(1);
|
||||
if (pathheadp == NULL)
|
||||
{
|
||||
CIFReadError("polygon, but improper path; ignored.\n");
|
||||
CIFSkipToSemi();
|
||||
|
|
@ -807,7 +817,7 @@ CIFParsePoly()
|
|||
/* Convert the polygon to rectangles. */
|
||||
|
||||
rectp = CIFPolyToRects(pathheadp, cifReadPlane, CIFPaintTable,
|
||||
(PaintUndoInfo *)NULL);
|
||||
(PaintUndoInfo *)NULL, FALSE);
|
||||
CIFFreePath(pathheadp);
|
||||
if (rectp == NULL)
|
||||
{
|
||||
|
|
@ -817,11 +827,13 @@ CIFParsePoly()
|
|||
CIFSkipToSemi();
|
||||
return FALSE;
|
||||
}
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (; rectp != NULL ; rectp = rectp->r_next)
|
||||
{
|
||||
DBPaintPlane(cifReadPlane, &rectp->r_r, CIFPaintTable,
|
||||
(PaintUndoInfo *) NULL);
|
||||
freeMagic((char *) rectp);
|
||||
freeMagic1(&mm1, (char *) rectp);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
148
cif/CIFrdtech.c
148
cif/CIFrdtech.c
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdtech.c,v 1.4 2010/09/15 15:45:30 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdtech.c,v 1.4 2010/09/15 15:45:30 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -62,8 +62,8 @@ CIFReadLayer *cifCurReadLayer; /* Current layer being processed. */
|
|||
CIFOp *cifCurReadOp; /* Last geometric operation seen. */
|
||||
|
||||
/* Forward declarations */
|
||||
void cifReadStyleInit();
|
||||
void CIFReadLoadStyle();
|
||||
void cifReadStyleInit(void);
|
||||
void CIFReadLoadStyle(char *stylename);
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -90,8 +90,9 @@ void CIFReadLoadStyle();
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFReadTechLimitScale(ns, ds)
|
||||
int ns, ds;
|
||||
CIFReadTechLimitScale(
|
||||
int ns,
|
||||
int ds)
|
||||
{
|
||||
int gridup, scaledown;
|
||||
int scale, limit, mult;
|
||||
|
|
@ -131,9 +132,9 @@ CIFReadTechLimitScale(ns, ds)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFReadNameToType(name, newOK)
|
||||
char *name; /* Name of a CIF layer. */
|
||||
bool newOK; /* TRUE means OK to create a new layer if this
|
||||
CIFReadNameToType(
|
||||
char *name, /* Name of a CIF layer. */
|
||||
bool newOK) /* TRUE means OK to create a new layer if this
|
||||
* name is one we haven't seen before.
|
||||
*/
|
||||
{
|
||||
|
|
@ -196,34 +197,34 @@ CIFReadNameToType(name, newOK)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFCalmaLayerToCifLayer(layer, datatype, calmaStyle)
|
||||
int layer; /* Calma layer number */
|
||||
int datatype; /* Calma datatype */
|
||||
CIFReadStyle *calmaStyle;
|
||||
CIFCalmaLayerToCifLayer(
|
||||
int layer, /* Calma layer number */
|
||||
int datatype, /* Calma datatype */
|
||||
CIFReadStyle *calmaStyle)
|
||||
{
|
||||
CalmaLayerType clt;
|
||||
HashEntry *he;
|
||||
|
||||
clt.clt_layer = layer;
|
||||
clt.clt_type = datatype;
|
||||
if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
|
||||
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt)))
|
||||
return ((spointertype) HashGetValue(he));
|
||||
|
||||
/* Try wildcarding the datatype */
|
||||
clt.clt_type = -1;
|
||||
if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
|
||||
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt)))
|
||||
return ((spointertype) HashGetValue(he));
|
||||
|
||||
/* Try wildcarding the layer */
|
||||
clt.clt_layer = -1;
|
||||
clt.clt_type = datatype;
|
||||
if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
|
||||
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt)))
|
||||
return ((spointertype) HashGetValue(he));
|
||||
|
||||
/* Try wildcarding them both, for a default value */
|
||||
clt.clt_layer = -1;
|
||||
clt.clt_type = -1;
|
||||
if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
|
||||
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt)))
|
||||
return ((spointertype) HashGetValue(he));
|
||||
|
||||
/* No luck */
|
||||
|
|
@ -251,10 +252,10 @@ CIFCalmaLayerToCifLayer(layer, datatype, calmaStyle)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFParseReadLayers(string, mask, newok)
|
||||
char *string; /* Comma-separated list of CIF layers. */
|
||||
TileTypeBitMask *mask; /* Where to store bit mask. */
|
||||
bool newok; /* If TRUE, create new layers if they don't exist */
|
||||
CIFParseReadLayers(
|
||||
char *string, /* Comma-separated list of CIF layers. */
|
||||
TileTypeBitMask *mask, /* Where to store bit mask. */
|
||||
bool newok) /* If TRUE, create new layers if they don't exist */
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
|
|
@ -313,7 +314,7 @@ CIFParseReadLayers(string, mask, newok)
|
|||
*/
|
||||
|
||||
void
|
||||
cifNewReadStyle()
|
||||
cifNewReadStyle(void)
|
||||
{
|
||||
int i;
|
||||
CIFOp *op;
|
||||
|
|
@ -328,8 +329,10 @@ cifNewReadStyle()
|
|||
layer = cifCurReadStyle->crs_layers[i];
|
||||
if (layer != NULL)
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (op = layer->crl_ops; op != NULL; op = op->co_next)
|
||||
freeMagic((char *)op);
|
||||
freeMagic1(&mm1, (char *)op);
|
||||
freeMagic1_end(&mm1);
|
||||
freeMagic((char *)layer);
|
||||
}
|
||||
}
|
||||
|
|
@ -353,7 +356,7 @@ cifNewReadStyle()
|
|||
*/
|
||||
|
||||
void
|
||||
cifReadStyleInit()
|
||||
cifReadStyleInit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -395,7 +398,7 @@ cifReadStyleInit()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFReadTechInit()
|
||||
CIFReadTechInit(void)
|
||||
{
|
||||
CIFReadKeep *style;
|
||||
|
||||
|
|
@ -407,11 +410,13 @@ CIFReadTechInit()
|
|||
|
||||
/* forget the list of styles */
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (style = cifReadStyleList; style != NULL; style = style->crs_next)
|
||||
{
|
||||
freeMagic(style->crs_name);
|
||||
freeMagic(style);
|
||||
freeMagic1(&mm1, style);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
cifReadStyleList = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -433,7 +438,7 @@ CIFReadTechInit()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFReadTechStyleInit()
|
||||
CIFReadTechStyleInit(void)
|
||||
{
|
||||
cifNReadLayers = 0;
|
||||
cifCurReadLayer = NULL;
|
||||
|
|
@ -460,10 +465,10 @@ CIFReadTechStyleInit()
|
|||
*/
|
||||
/* ARGSUSED */
|
||||
bool
|
||||
CIFReadTechLine(sectionName, argc, argv)
|
||||
char *sectionName; /* Name of this section ("cifinput"). */
|
||||
int argc; /* Number of fields on line. */
|
||||
char *argv[]; /* Values of fields. */
|
||||
CIFReadTechLine(
|
||||
char *sectionName, /* Name of this section ("cifinput"). */
|
||||
int argc, /* Number of fields on line. */
|
||||
char *argv[]) /* Values of fields. */
|
||||
{
|
||||
CIFOp *newOp = NULL;
|
||||
CIFReadKeep *newStyle, *p;
|
||||
|
|
@ -872,10 +877,33 @@ CIFReadTechLine(sectionName, argc, argv)
|
|||
goto wrongNumArgs;
|
||||
}
|
||||
CIFParseReadLayers(argv[1], &mask, TRUE);
|
||||
for (i=0; i<MAXCIFRLAYERS; i+=1)
|
||||
for (i = 0; i < MAXCIFRLAYERS; i++)
|
||||
{
|
||||
if (TTMaskHasType(&mask,i))
|
||||
if (TTMaskHasType(&mask, i))
|
||||
{
|
||||
/* Only one magic type can be assigned to a GDS layer, so
|
||||
* multiple assignments should be flagged as errors. BUT,
|
||||
* this is a common historic error. Since reattachments
|
||||
* should be handled rationally (by code added 10/17/2023
|
||||
* to DBlabel.c), there is no urgent need to flag an issue
|
||||
* unless the new layer does not exist on the same plane
|
||||
* as the old one.
|
||||
*/
|
||||
if (cifCurReadStyle->crs_labelLayer[i] != TT_SPACE)
|
||||
{
|
||||
int p1, p2;
|
||||
p1 = DBPlane(cifCurReadLayer->crl_magicType);
|
||||
p2 = DBPlane(cifCurReadStyle->crs_labelLayer[i]);
|
||||
|
||||
if (!DBTypeOnPlane(cifCurReadLayer->crl_magicType, p2) &&
|
||||
!DBTypeOnPlane(cifCurReadStyle->crs_labelLayer[i], p1))
|
||||
TechError("Labels on layer \"%s\" attached to \"%s\" "
|
||||
"supersedes prior attachment to \"%s\".\n",
|
||||
cifReadLayers[i],
|
||||
DBTypeLongNameTbl[cifCurReadLayer->crl_magicType],
|
||||
DBTypeLongNameTbl[cifCurReadStyle->crs_labelLayer[i]]);
|
||||
}
|
||||
|
||||
cifCurReadStyle->crs_labelLayer[i]
|
||||
= cifCurReadLayer->crl_magicType;
|
||||
if (argc == 3)
|
||||
|
|
@ -899,8 +927,8 @@ CIFReadTechLine(sectionName, argc, argv)
|
|||
if (argc != 2) goto wrongNumArgs;
|
||||
CIFParseReadLayers(argv[1], &mask, TRUE);
|
||||
/* trash the value in crs_labelLayer so that any labels on this
|
||||
layer get junked, also. dcs 4/11/90
|
||||
*/
|
||||
* layer get junked, also. dcs 4/11/90
|
||||
*/
|
||||
for (i=0; i < cifNReadLayers; i++)
|
||||
{
|
||||
if (TTMaskHasType(&mask,i))
|
||||
|
|
@ -916,14 +944,15 @@ CIFReadTechLine(sectionName, argc, argv)
|
|||
|
||||
/* miscellaneous cif-reading boolean options */
|
||||
|
||||
if(strcmp(argv[0], "options") == 0) {
|
||||
if (strcmp(argv[0], "options") == 0) {
|
||||
int i;
|
||||
if (argc < 2) goto wrongNumArgs;
|
||||
for(i = 1; i < argc; i++) {
|
||||
if(strcmp(argv[i], "ignore-unknown-layer-labels") == 0)
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "ignore-unknown-layer-labels") == 0)
|
||||
cifCurReadStyle->crs_flags |= CRF_IGNORE_UNKNOWNLAYER_LABELS;
|
||||
if(strcmp(argv[i], "no-reconnect-labels") == 0)
|
||||
cifCurReadStyle->crs_flags |= CRF_NO_RECONNECT_LABELS;
|
||||
/* Allow "no-reconnect-labels", although it has been deprecated */
|
||||
else if (strcmp(argv[i], "no-reconnect-labels") != 0)
|
||||
TechError("Unknown cifinput option \"%s\".\n", argv[i]);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1027,7 +1056,7 @@ CIFReadTechLine(sectionName, argc, argv)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFReadTechFinal()
|
||||
CIFReadTechFinal(void)
|
||||
{
|
||||
/* Reduce the scale by the multiplier, as much as possible while */
|
||||
/* keeping all CIF input ops in integer units. */
|
||||
|
|
@ -1071,8 +1100,8 @@ CIFReadTechFinal()
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
CIFReadLoadStyle(stylename)
|
||||
char *stylename;
|
||||
CIFReadLoadStyle(
|
||||
char *stylename)
|
||||
{
|
||||
SectionID invcifr;
|
||||
|
||||
|
|
@ -1114,8 +1143,8 @@ CIFReadLoadStyle(stylename)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFReadGetGrowSize(type)
|
||||
TileType type;
|
||||
CIFReadGetGrowSize(
|
||||
TileType type)
|
||||
{
|
||||
CIFReadStyle *istyle = cifCurReadStyle;
|
||||
CIFOp *op;
|
||||
|
|
@ -1169,8 +1198,8 @@ CIFReadGetGrowSize(type)
|
|||
*/
|
||||
|
||||
float
|
||||
CIFGetInputScale(convert)
|
||||
int convert;
|
||||
CIFGetInputScale(
|
||||
int convert)
|
||||
{
|
||||
/* Avoid divide-by-0 error if there is no cif input style */
|
||||
/* in the tech file. */
|
||||
|
|
@ -1202,10 +1231,10 @@ CIFGetInputScale(convert)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFPrintReadStyle(dolist, doforall, docurrent)
|
||||
bool dolist; /* Return as a list if true */
|
||||
bool doforall; /* Return list of all styles if true */
|
||||
bool docurrent; /* Return current style if true */
|
||||
CIFPrintReadStyle(
|
||||
bool dolist, /* Return as a list if true */
|
||||
bool doforall, /* Return list of all styles if true */
|
||||
bool docurrent) /* Return current style if true */
|
||||
{
|
||||
CIFReadKeep *style;
|
||||
|
||||
|
|
@ -1273,8 +1302,8 @@ CIFPrintReadStyle(dolist, doforall, docurrent)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSetReadStyle(name)
|
||||
char *name; /* Name of the new style. If NULL,
|
||||
CIFSetReadStyle(
|
||||
char *name) /* Name of the new style. If NULL,
|
||||
* just print the name of the current
|
||||
* style.
|
||||
*/
|
||||
|
|
@ -1334,10 +1363,10 @@ CIFSetReadStyle(name)
|
|||
*/
|
||||
|
||||
int
|
||||
cifParseCalmaNums(str, numArray, numNums)
|
||||
char *str; /* String to parse */
|
||||
int *numArray; /* Array to fill in */
|
||||
int numNums; /* Maximum number of entries in numArray */
|
||||
cifParseCalmaNums(
|
||||
char *str, /* String to parse */
|
||||
int *numArray, /* Array to fill in */
|
||||
int numNums) /* Maximum number of entries in numArray */
|
||||
{
|
||||
int numFilled, num;
|
||||
|
||||
|
|
@ -1397,9 +1426,10 @@ cifParseCalmaNums(str, numArray, numNums)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFTechInputScale(n, d, opt)
|
||||
int n, d;
|
||||
bool opt;
|
||||
CIFTechInputScale(
|
||||
int n,
|
||||
int d,
|
||||
bool opt)
|
||||
{
|
||||
CIFReadStyle *istyle = cifCurReadStyle;
|
||||
CIFReadLayer *cl;
|
||||
|
|
|
|||
151
cif/CIFrdutils.c
151
cif/CIFrdutils.c
|
|
@ -19,7 +19,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdutils.c,v 1.4 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdutils.c,v 1.4 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -129,7 +129,7 @@ Plane *cifReadPlane; /* Plane into which to paint material
|
|||
|
||||
/* VARARGS1 */
|
||||
void
|
||||
CIFReadError(char *format, ...)
|
||||
CIFReadError(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
|
|
@ -140,7 +140,7 @@ CIFReadError(char *format, ...)
|
|||
if (cifLineNumber > 0)
|
||||
TxError("Error at line %d of CIF file: ", cifLineNumber);
|
||||
else
|
||||
TxError("CIF file read error: ", cifLineNumber);
|
||||
TxError("CIF file read error: ");
|
||||
va_start(args, format);
|
||||
Vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
|
|
@ -153,7 +153,7 @@ CIFReadError(char *format, ...)
|
|||
|
||||
|
||||
void
|
||||
CIFReadWarning(char *format, ...)
|
||||
CIFReadWarning(const char *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
|
|
@ -205,9 +205,9 @@ CIFReadWarning(char *format, ...)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFScaleCoord(cifCoord, snap_type)
|
||||
int cifCoord; /* A coordinate in CIF units. */
|
||||
int snap_type; /* How to deal with fractional results */
|
||||
CIFScaleCoord(
|
||||
int cifCoord, /* A coordinate in CIF units. */
|
||||
int snap_type) /* How to deal with fractional results */
|
||||
{
|
||||
int result, scale, remain, denom;
|
||||
int mult, mfactor;
|
||||
|
|
@ -276,8 +276,10 @@ CIFScaleCoord(cifCoord, snap_type)
|
|||
PlowAfterTech();
|
||||
ExtTechScale(1, denom);
|
||||
WireTechScale(1, denom);
|
||||
#ifdef ROUTE_MODULE
|
||||
MZAfterTech();
|
||||
IRAfterTech();
|
||||
#endif
|
||||
#ifdef LEF_MODULE
|
||||
LefTechScale(1, denom);
|
||||
#endif
|
||||
|
|
@ -343,8 +345,8 @@ CIFScaleCoord(cifCoord, snap_type)
|
|||
*/
|
||||
|
||||
bool
|
||||
cifIsBlank(ch)
|
||||
int ch;
|
||||
cifIsBlank(
|
||||
int ch)
|
||||
{
|
||||
|
||||
if ( isdigit(ch) || isupper(ch)
|
||||
|
|
@ -376,7 +378,7 @@ cifIsBlank(ch)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSkipBlanks()
|
||||
CIFSkipBlanks(void)
|
||||
{
|
||||
|
||||
while (cifIsBlank(PEEK())) {
|
||||
|
|
@ -405,7 +407,7 @@ CIFSkipBlanks()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSkipSep()
|
||||
CIFSkipSep(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
|
|
@ -435,7 +437,7 @@ CIFSkipSep()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSkipToSemi()
|
||||
CIFSkipToSemi(void)
|
||||
{
|
||||
int ch;
|
||||
|
||||
|
|
@ -464,7 +466,7 @@ CIFSkipToSemi()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSkipSemi()
|
||||
CIFSkipSemi(void)
|
||||
{
|
||||
|
||||
CIFSkipBlanks();
|
||||
|
|
@ -495,8 +497,8 @@ CIFSkipSemi()
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseSInteger(valuep)
|
||||
int *valuep;
|
||||
CIFParseSInteger(
|
||||
int *valuep)
|
||||
{
|
||||
bool is_signed;
|
||||
char buffer[ BUFSIZ ];
|
||||
|
|
@ -540,8 +542,8 @@ CIFParseSInteger(valuep)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseInteger(valuep)
|
||||
int *valuep;
|
||||
CIFParseInteger(
|
||||
int *valuep)
|
||||
{
|
||||
|
||||
if (!CIFParseSInteger(valuep))
|
||||
|
|
@ -581,9 +583,9 @@ CIFParseInteger(valuep)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParsePoint(pointp, iscale)
|
||||
Point *pointp;
|
||||
int iscale;
|
||||
CIFParsePoint(
|
||||
Point *pointp,
|
||||
int iscale)
|
||||
{
|
||||
int rescale;
|
||||
|
||||
|
|
@ -649,12 +651,11 @@ CIFParsePoint(pointp, iscale)
|
|||
* one or more points.
|
||||
*
|
||||
* Results:
|
||||
* TRUE is returned if the path was parsed successfully,
|
||||
* FALSE otherwise.
|
||||
* non-NULL CIFPath* the caller takes ownership of
|
||||
* if the path was parsed successfully, otherwise NULL.
|
||||
*
|
||||
* Side effects:
|
||||
* Modifies the parameter pathheadpp to point to the path
|
||||
* that is constructed.
|
||||
* None
|
||||
*
|
||||
* Corrections:
|
||||
* CIF coordinates are multiplied by 2 to cover the case where
|
||||
|
|
@ -666,17 +667,16 @@ CIFParsePoint(pointp, iscale)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool
|
||||
CIFParsePath(pathheadpp, iscale)
|
||||
CIFPath **pathheadpp;
|
||||
int iscale;
|
||||
CIFPath *
|
||||
CIFParsePath(
|
||||
int iscale)
|
||||
{
|
||||
CIFPath *pathtailp, *newpathp;
|
||||
CIFPath *pathheadp, *pathtailp, *newpathp;
|
||||
bool nonManhattan = FALSE; /* diagnostic only */
|
||||
CIFPath path;
|
||||
int savescale;
|
||||
|
||||
*pathheadpp = NULL;
|
||||
pathheadp = NULL;
|
||||
pathtailp = NULL;
|
||||
path.cifp_next = NULL;
|
||||
while (TRUE)
|
||||
|
|
@ -688,12 +688,12 @@ CIFParsePath(pathheadpp, iscale)
|
|||
savescale = cifReadScale1;
|
||||
if (!CIFParsePoint(&path.cifp_point, iscale))
|
||||
{
|
||||
CIFFreePath(*pathheadpp);
|
||||
return FALSE;
|
||||
CIFFreePath(pathheadp);
|
||||
return NULL;
|
||||
}
|
||||
if (savescale != cifReadScale1)
|
||||
{
|
||||
CIFPath *phead = *pathheadpp;
|
||||
CIFPath *phead = pathheadp;
|
||||
int newscale = cifReadScale1 / savescale;
|
||||
while (phead != NULL)
|
||||
{
|
||||
|
|
@ -704,7 +704,7 @@ CIFParsePath(pathheadpp, iscale)
|
|||
}
|
||||
newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath)));
|
||||
*newpathp = path;
|
||||
if (*pathheadpp)
|
||||
if (pathheadp)
|
||||
{
|
||||
/*
|
||||
* Check that this segment is Manhattan. If not, remember the
|
||||
|
|
@ -721,10 +721,10 @@ CIFParsePath(pathheadpp, iscale)
|
|||
}
|
||||
pathtailp->cifp_next = newpathp;
|
||||
}
|
||||
else *pathheadpp = newpathp;
|
||||
else pathheadp = newpathp;
|
||||
pathtailp = newpathp;
|
||||
}
|
||||
return (*pathheadpp != NULL);
|
||||
return pathheadp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -744,9 +744,9 @@ CIFParsePath(pathheadpp, iscale)
|
|||
*/
|
||||
|
||||
bool
|
||||
test_insideness(start, tpoint)
|
||||
CIFPath *start;
|
||||
Point *tpoint;
|
||||
test_insideness(
|
||||
CIFPath *start,
|
||||
Point *tpoint)
|
||||
{
|
||||
Rect tmprect, irect;
|
||||
|
||||
|
|
@ -782,10 +782,11 @@ test_insideness(start, tpoint)
|
|||
*/
|
||||
|
||||
bool
|
||||
seg_intersect(tstart, bf, bs, respt)
|
||||
CIFPath *tstart;
|
||||
Point *bf, *bs;
|
||||
Point *respt;
|
||||
seg_intersect(
|
||||
CIFPath *tstart,
|
||||
Point *bf,
|
||||
Point *bs,
|
||||
Point *respt)
|
||||
{
|
||||
int afx = tstart->cifp_x;
|
||||
int afy = tstart->cifp_y;
|
||||
|
|
@ -848,9 +849,10 @@ seg_intersect(tstart, bf, bs, respt)
|
|||
*/
|
||||
|
||||
bool
|
||||
path_intersect(pathHead, start, respt)
|
||||
CIFPath *pathHead, *start;
|
||||
Point *respt;
|
||||
path_intersect(
|
||||
CIFPath *pathHead,
|
||||
CIFPath *start,
|
||||
Point *respt)
|
||||
{
|
||||
CIFPath *path, *segcrossed, *new;
|
||||
Point tmppt;
|
||||
|
|
@ -953,8 +955,8 @@ path_intersect(pathHead, start, respt)
|
|||
*/
|
||||
|
||||
bool
|
||||
is_clockwise(pathHead)
|
||||
CIFPath *pathHead;
|
||||
is_clockwise(
|
||||
CIFPath *pathHead)
|
||||
{
|
||||
CIFPath *path, *midx = NULL, *last;
|
||||
Point *p1, *p2, *p3;
|
||||
|
|
@ -1047,11 +1049,11 @@ is_clockwise(pathHead)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFMakeManhattanPath(pathHead, plane, resultTbl, ui)
|
||||
CIFPath *pathHead;
|
||||
Plane *plane;
|
||||
PaintResultType *resultTbl;
|
||||
PaintUndoInfo *ui;
|
||||
CIFMakeManhattanPath(
|
||||
CIFPath *pathHead,
|
||||
Plane *plane,
|
||||
const PaintResultType *resultTbl,
|
||||
PaintUndoInfo *ui)
|
||||
{
|
||||
CIFPath *new, *new2, *next, *path;
|
||||
int xinit, xdiff, xincr, xlast, x;
|
||||
|
|
@ -1154,7 +1156,11 @@ CIFMakeManhattanPath(pathHead, plane, resultTbl, ui)
|
|||
/* Final check---ensure that rectangle is not degenerate */
|
||||
|
||||
if (plane && (tr.r_xtop - tr.r_xbot > 0) && (tr.r_ytop - tr.r_ybot > 0))
|
||||
{
|
||||
DBNMPaintPlane(plane, type, &tr, resultTbl, ui);
|
||||
GEO_EXPAND(&tr, 1, &tr);
|
||||
DBMergeNMTiles(plane, &tr, ui);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1181,8 +1187,9 @@ CIFMakeManhattanPath(pathHead, plane, resultTbl, ui)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFEdgeDirection(first, last)
|
||||
CIFPath *first, *last; /* Edge to be categorized. */
|
||||
CIFEdgeDirection(
|
||||
CIFPath *first,
|
||||
CIFPath *last) /* Edge to be categorized. */
|
||||
{
|
||||
|
||||
if (first->cifp_x < last->cifp_x)
|
||||
|
|
@ -1229,8 +1236,8 @@ CIFEdgeDirection(first, last)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFCleanPath(pathHead)
|
||||
CIFPath *pathHead;
|
||||
CIFCleanPath(
|
||||
CIFPath *pathHead)
|
||||
{
|
||||
CIFPath *next, *path, *prev, *last;
|
||||
int dir1, dir2;
|
||||
|
|
@ -1249,7 +1256,7 @@ CIFCleanPath(pathHead)
|
|||
if (!path) return;
|
||||
}
|
||||
|
||||
while (next = path->cifp_next)
|
||||
while ((next = path->cifp_next))
|
||||
{
|
||||
if ((dir2 = CIFEdgeDirection(path, next)) == CIF_ZERO)
|
||||
{
|
||||
|
|
@ -1328,14 +1335,16 @@ path_inc:
|
|||
*/
|
||||
|
||||
void
|
||||
CIFFreePath(path)
|
||||
CIFPath *path; /* Path to be freed. */
|
||||
CIFFreePath(
|
||||
CIFPath *path) /* Path to be freed. */
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (path != NULL)
|
||||
{
|
||||
freeMagic((char *) path);
|
||||
freeMagic1(&mm1, (char *) path);
|
||||
path = path->cifp_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1357,7 +1366,7 @@ CIFFreePath(path)
|
|||
*/
|
||||
|
||||
void
|
||||
cifCommandError()
|
||||
cifCommandError(void)
|
||||
{
|
||||
CIFReadError("unknown command `%c'; ignored.\n" , PEEK());
|
||||
CIFSkipToSemi();
|
||||
|
|
@ -1382,7 +1391,7 @@ cifCommandError()
|
|||
*/
|
||||
|
||||
bool
|
||||
cifParseEnd()
|
||||
cifParseEnd(void)
|
||||
{
|
||||
TAKE();
|
||||
CIFSkipBlanks();
|
||||
|
|
@ -1411,7 +1420,7 @@ cifParseEnd()
|
|||
*/
|
||||
|
||||
bool
|
||||
cifParseComment()
|
||||
cifParseComment(void)
|
||||
{
|
||||
int opens;
|
||||
int ch;
|
||||
|
|
@ -1462,9 +1471,9 @@ cifParseComment()
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Transform *
|
||||
CIFDirectionToTrans(point)
|
||||
Point *point; /* Direction vector from origin. */
|
||||
const Transform *
|
||||
CIFDirectionToTrans(
|
||||
const Point *point) /* Direction vector from origin. */
|
||||
{
|
||||
if ((point->p_x != 0) && (point->p_y == 0))
|
||||
{
|
||||
|
|
@ -1503,8 +1512,8 @@ CIFDirectionToTrans(point)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFParseTransform(transformp)
|
||||
Transform *transformp;
|
||||
CIFParseTransform(
|
||||
Transform *transformp)
|
||||
{
|
||||
char ch;
|
||||
Point point;
|
||||
|
|
@ -1597,8 +1606,8 @@ CIFParseTransform(transformp)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFReadFile(file)
|
||||
FILE *file; /* File from which to read CIF. */
|
||||
CIFReadFile(
|
||||
FILE *file) /* File from which to read CIF. */
|
||||
{
|
||||
/* We will use 1-word CIF numbers as keys in this hash table */
|
||||
CIFReadCellInit(1);
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
* rcsid "$Header: /usr/cvsroot/magic-8.0/cif/CIFread.h,v 1.3 2010/08/25 17:33:55 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CIFREAD_H
|
||||
#define _CIFREAD_H
|
||||
#ifndef _MAGIC__CIF__CIFREAD_H
|
||||
#define _MAGIC__CIF__CIFREAD_H
|
||||
|
||||
#include "cif/CIFint.h"
|
||||
|
||||
|
|
@ -104,8 +104,10 @@ typedef struct cifrstyle
|
|||
/* Gives the Magic layer to use for labels
|
||||
* on each possible CIF layer.
|
||||
*/
|
||||
bool crs_labelSticky[MAXCIFRLAYERS];
|
||||
/* Marker if label layer makes sticky labels */
|
||||
/* enum labelType */ unsigned char crs_labelSticky[MAXCIFRLAYERS];
|
||||
/* Marker if label layer makes sticky labels
|
||||
* enum labelType LABEL_TYPE_xxxxxx
|
||||
*/
|
||||
CIFReadLayer *crs_layers[MAXCIFRLAYERS];
|
||||
HashTable cifCalmaToCif; /* Table mapping from Calma layer numbers to
|
||||
* CIF layers
|
||||
|
|
@ -115,7 +117,6 @@ typedef struct cifrstyle
|
|||
|
||||
/* option bitmasks used in crs_flags */
|
||||
#define CRF_IGNORE_UNKNOWNLAYER_LABELS 1
|
||||
#define CRF_NO_RECONNECT_LABELS 2
|
||||
|
||||
/* Methods to deal with fractional results of conversion from CIF to magic */
|
||||
/* units (see routine CIFScaleCoord() for details). */
|
||||
|
|
@ -153,22 +154,45 @@ typedef struct cifpath
|
|||
|
||||
/* Procedures */
|
||||
|
||||
extern bool CIFParseBox(), CIFParseWire(), CIFParsePoly();
|
||||
extern bool CIFParseFlash(), CIFParseLayer(), CIFParseStart();
|
||||
extern bool CIFParseFinish(), CIFParseDelete(), CIFParseUser();
|
||||
extern bool CIFParseCall(), CIFParseTransform(), CIFParseInteger();
|
||||
extern bool CIFParsePath(), CIFParsePoint(), CIFParseSInteger();
|
||||
extern void CIFSkipToSemi(), CIFSkipSep(), CIFSkipBlanks();
|
||||
extern void CIFFreePath(), CIFCleanPath();
|
||||
extern void CIFReadCellInit(), CIFReadCellCleanup();
|
||||
extern LinkedRect *CIFPolyToRects();
|
||||
extern Transform *CIFDirectionToTrans();
|
||||
extern int CIFReadNameToType();
|
||||
extern bool CIFParseBox(void);
|
||||
extern bool CIFParseWire(void);
|
||||
extern bool CIFParsePoly(void);
|
||||
extern bool CIFParseFlash(void);
|
||||
extern bool CIFParseLayer(void);
|
||||
extern bool CIFParseStart(void);
|
||||
extern bool CIFParseFinish(void);
|
||||
extern bool CIFParseDelete(void);
|
||||
extern bool CIFParseUser(void);
|
||||
extern bool CIFParseCall(void);
|
||||
extern bool CIFParseTransform(Transform *transformp);
|
||||
extern bool CIFParseInteger(int *valuep);
|
||||
extern CIFPath *CIFParsePath(int iscale);
|
||||
extern bool CIFParsePoint(Point *pointp, int iscale);
|
||||
extern bool CIFParseSInteger(int *valuep);
|
||||
extern void CIFSkipToSemi(void);
|
||||
extern void CIFSkipSep(void);
|
||||
extern void CIFSkipBlanks(void);
|
||||
extern void CIFFreePath(CIFPath *path);
|
||||
extern void CIFCleanPath(CIFPath *pathHead);
|
||||
extern void CIFReadCellInit(int ptrkeys);
|
||||
extern void CIFReadCellCleanup(int filetype);
|
||||
extern LinkedRect *CIFPolyToRects(CIFPath *path, Plane *plane, const PaintResultType *resultTbl,
|
||||
PaintUndoInfo *ui, bool isCalma);
|
||||
extern const Transform *CIFDirectionToTrans(const Point *point);
|
||||
extern int CIFReadNameToType(char *name, bool newOK);
|
||||
|
||||
extern int CIFCalmaLayerToCifLayer(int layer, int datatype, CIFReadStyle *calmaStyle);
|
||||
extern void CIFPropRecordPath(CellDef *def, CIFPath *pathheadp, bool iswire, char *propname);
|
||||
extern void CIFPaintWirePath(CIFPath *pathheadp, int width, bool endcap, Plane *plane,
|
||||
const PaintResultType *ptable, PaintUndoInfo *ui);
|
||||
extern void CIFMakeManhattanPath(CIFPath *pathHead, Plane *plane, const PaintResultType *resultTbl, PaintUndoInfo *ui);
|
||||
|
||||
extern int CIFEdgeDirection(CIFPath *first, CIFPath *last);
|
||||
|
||||
/* Variable argument procedures require complete prototype */
|
||||
|
||||
extern void CIFReadError(char *format, ...);
|
||||
extern void CIFReadWarning(char *format, ...);
|
||||
extern void CIFReadError(const char *format, ...) ATTR_FORMAT_PRINTF_1;
|
||||
extern void CIFReadWarning(const char *format, ...) ATTR_FORMAT_PRINTF_1;
|
||||
|
||||
/* Variables shared by the CIF-reading modules, see CIFreadutils.c
|
||||
* for more details:
|
||||
|
|
@ -197,4 +221,4 @@ extern int cifParseLaChar;
|
|||
? (cifParseLaAvail = FALSE, cifParseLaChar) \
|
||||
: (cifParseLaChar = getc(cifInputFile)))
|
||||
|
||||
#endif /* _CIFREAD_H */
|
||||
#endif /* _MAGIC__CIF__CIFREAD_H */
|
||||
|
|
|
|||
77
cif/CIFsee.c
77
cif/CIFsee.c
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFsee.c,v 1.5 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFsee.c,v 1.5 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -76,9 +76,10 @@ typedef struct {
|
|||
*/
|
||||
|
||||
int
|
||||
cifPaintDBFunc(tile, pld)
|
||||
Tile *tile; /* Tile of CIF information. */
|
||||
PaintLayerData *pld;
|
||||
cifPaintDBFunc(
|
||||
Tile *tile, /* Tile of CIF information. */
|
||||
TileType dinfo,
|
||||
PaintLayerData *pld)
|
||||
{
|
||||
Rect area;
|
||||
int pNum;
|
||||
|
|
@ -106,7 +107,7 @@ cifPaintDBFunc(tile, pld)
|
|||
if (DBPaintOnPlane(type, pNum))
|
||||
{
|
||||
ui.pu_pNum = pNum;
|
||||
DBNMPaintPlane(paintDef->cd_planes[pNum], TiGetTypeExact(tile),
|
||||
DBNMPaintPlane(paintDef->cd_planes[pNum], TiGetTypeExact(tile) | dinfo,
|
||||
&area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) &ui);
|
||||
}
|
||||
|
||||
|
|
@ -132,14 +133,14 @@ cifPaintDBFunc(tile, pld)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef)
|
||||
CellDef *rootDef; /* Cell for which to generate CIF. Must be
|
||||
CIFPaintLayer(
|
||||
CellDef *rootDef, /* Cell for which to generate CIF. Must be
|
||||
* the rootDef of a window.
|
||||
*/
|
||||
Rect *area; /* Area in which to generate CIF. */
|
||||
char *cifLayer; /* CIF layer to highlight on the screen. */
|
||||
int magicLayer; /* Magic layer to paint with the result */
|
||||
CellDef *paintDef; /* CellDef to paint into (may be NULL) */
|
||||
Rect *area, /* Area in which to generate CIF. */
|
||||
char *cifLayer, /* CIF layer to highlight on the screen. */
|
||||
int magicLayer, /* Magic layer to paint with the result */
|
||||
CellDef *paintDef) /* CellDef to paint into (may be NULL) */
|
||||
{
|
||||
int oldCount, i;
|
||||
char msg[100];
|
||||
|
|
@ -217,9 +218,10 @@ CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef)
|
|||
*/
|
||||
|
||||
int
|
||||
cifSeeFunc(tile, sld)
|
||||
Tile *tile; /* Tile to be entered as feedback. */
|
||||
SeeLayerData *sld; /* Layer and explanation for the feedback. */
|
||||
cifSeeFunc(
|
||||
Tile *tile, /* Tile to be entered as feedback. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
SeeLayerData *sld) /* Layer and explanation for the feedback. */
|
||||
{
|
||||
Rect area;
|
||||
|
||||
|
|
@ -233,10 +235,10 @@ cifSeeFunc(tile, sld)
|
|||
(float)area.r_ybot / (float)CIFCurStyle->cs_scaleFactor);
|
||||
}
|
||||
|
||||
/* (NOTE: Preserve information about the geometry of a diagonal tile) */
|
||||
DBWFeedbackAdd(&area, sld->text, cifSeeDef, CIFCurStyle->cs_scaleFactor,
|
||||
sld->style |
|
||||
(TiGetTypeExact(tile) & (TT_DIAGONAL | TT_DIRECTION | TT_SIDE)));
|
||||
/* (preserve information about the geometry of a diagonal tile) */
|
||||
sld->style | ((TiGetTypeExact(tile) | dinfo) &
|
||||
(TT_DIAGONAL | TT_DIRECTION | TT_SIDE)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -258,12 +260,12 @@ cifSeeFunc(tile, sld)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSeeLayer(rootDef, area, layer)
|
||||
CellDef *rootDef; /* Cell for which to generate CIF. Must be
|
||||
CIFSeeLayer(
|
||||
CellDef *rootDef, /* Cell for which to generate CIF. Must be
|
||||
* the rootDef of a window.
|
||||
*/
|
||||
Rect *area; /* Area in which to generate CIF. */
|
||||
char *layer; /* CIF layer to highlight on the screen. */
|
||||
Rect *area, /* Area in which to generate CIF. */
|
||||
char *layer) /* CIF layer to highlight on the screen. */
|
||||
{
|
||||
int oldCount, i;
|
||||
char msg[100];
|
||||
|
|
@ -348,14 +350,14 @@ CIFSeeLayer(rootDef, area, layer)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFSeeHierLayer(rootDef, area, layer, arrays, subcells)
|
||||
CellDef *rootDef; /* Def in which to compute CIF. Must be
|
||||
CIFSeeHierLayer(
|
||||
CellDef *rootDef, /* Def in which to compute CIF. Must be
|
||||
* the root definition of a window.
|
||||
*/
|
||||
Rect *area; /* Area in which to generate CIF. */
|
||||
char *layer; /* CIF layer to be highlighted. */
|
||||
bool arrays; /* TRUE means show array interactions. */
|
||||
bool subcells; /* TRUE means show subcell interactions. */
|
||||
Rect *area, /* Area in which to generate CIF. */
|
||||
char *layer, /* CIF layer to be highlighted. */
|
||||
bool arrays, /* TRUE means show array interactions. */
|
||||
bool subcells) /* TRUE means show subcell interactions. */
|
||||
{
|
||||
int i, oldCount;
|
||||
SeeLayerData sld;
|
||||
|
|
@ -426,11 +428,11 @@ typedef struct {
|
|||
} coverstats;
|
||||
|
||||
void
|
||||
CIFCoverageLayer(rootDef, area, layer, dolist)
|
||||
CellDef *rootDef; /* Def in which to compute CIF coverage */
|
||||
Rect *area; /* Area in which to compute coverage */
|
||||
char *layer; /* CIF layer for coverage computation. */
|
||||
bool dolist; /* If TRUE, report only the value, in decimal */
|
||||
CIFCoverageLayer(
|
||||
CellDef *rootDef, /* Def in which to compute CIF coverage */
|
||||
Rect *area, /* Area in which to compute coverage */
|
||||
char *layer, /* CIF layer for coverage computation. */
|
||||
bool dolist) /* If TRUE, report only the value, in decimal */
|
||||
{
|
||||
coverstats cstats;
|
||||
int i, scale;
|
||||
|
|
@ -438,9 +440,11 @@ CIFCoverageLayer(rootDef, area, layer, dolist)
|
|||
SearchContext scx;
|
||||
TileTypeBitMask mask, depend;
|
||||
float fcover;
|
||||
int cifCoverageFunc();
|
||||
bool doBox = (area != &rootDef->cd_bbox) ? TRUE : FALSE;
|
||||
|
||||
/* Forward declaration */
|
||||
int cifCoverageFunc(Tile *tile, TileType dinfo, ClientData *arg);
|
||||
|
||||
/* Check out the CIF layer name. */
|
||||
|
||||
if (!CIFNameToMask(layer, &mask, &depend)) return;
|
||||
|
|
@ -510,9 +514,10 @@ CIFCoverageLayer(rootDef, area, layer, dolist)
|
|||
}
|
||||
|
||||
int
|
||||
cifCoverageFunc(tile, arg)
|
||||
Tile *tile;
|
||||
ClientData *arg;
|
||||
cifCoverageFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData *arg)
|
||||
{
|
||||
coverstats *cstats = (coverstats *)arg;
|
||||
Rect r;
|
||||
|
|
|
|||
234
cif/CIFtech.c
234
cif/CIFtech.c
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFtech.c,v 1.7 2010/10/20 20:34:19 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFtech.c,v 1.7 2010/10/20 20:34:19 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -64,8 +64,8 @@ TileTypeBitMask CIFSolidBits;
|
|||
|
||||
/* Forward Declarations */
|
||||
|
||||
void cifTechStyleInit();
|
||||
bool cifCheckCalmaNum();
|
||||
void cifTechStyleInit(void);
|
||||
bool cifCheckCalmaNum(char *str);
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -85,7 +85,7 @@ bool cifCheckCalmaNum();
|
|||
*/
|
||||
|
||||
void
|
||||
cifTechFreeStyle()
|
||||
cifTechFreeStyle(void)
|
||||
{
|
||||
int i;
|
||||
CIFOp *op;
|
||||
|
|
@ -100,6 +100,7 @@ cifTechFreeStyle()
|
|||
layer = CIFCurStyle->cs_layers[i];
|
||||
if (layer != NULL)
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (op = layer->cl_ops; op != NULL; op = op->co_next)
|
||||
{
|
||||
if (op->co_client != (ClientData)NULL)
|
||||
|
|
@ -110,6 +111,8 @@ cifTechFreeStyle()
|
|||
case CIFOP_BBOX:
|
||||
case CIFOP_MAXRECT:
|
||||
case CIFOP_BOUNDARY:
|
||||
case CIFOP_INTERACT:
|
||||
case CIFOP_MANHATTAN:
|
||||
/* These options use co_client to hold a single */
|
||||
/* integer value, so it is not allocated. */
|
||||
break;
|
||||
|
|
@ -118,8 +121,9 @@ cifTechFreeStyle()
|
|||
break;
|
||||
}
|
||||
}
|
||||
freeMagic((char *)op);
|
||||
freeMagic1(&mm1, (char *)op);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
freeMagic((char *)layer);
|
||||
}
|
||||
}
|
||||
|
|
@ -148,7 +152,7 @@ cifTechFreeStyle()
|
|||
*/
|
||||
|
||||
void
|
||||
cifTechNewStyle()
|
||||
cifTechNewStyle(void)
|
||||
{
|
||||
cifTechFreeStyle();
|
||||
cifTechStyleInit();
|
||||
|
|
@ -165,7 +169,7 @@ cifTechNewStyle()
|
|||
*/
|
||||
|
||||
void
|
||||
cifTechStyleInit()
|
||||
cifTechStyleInit(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -188,6 +192,7 @@ cifTechStyleInit()
|
|||
{
|
||||
CIFCurStyle->cs_labelLayer[i] = -1;
|
||||
CIFCurStyle->cs_portLayer[i] = -1;
|
||||
CIFCurStyle->cs_portText[i] = -1;
|
||||
}
|
||||
for (i = 0; i < MAXCIFLAYERS; i++)
|
||||
CIFCurStyle->cs_layers[i] = NULL;
|
||||
|
|
@ -215,23 +220,23 @@ cifTechStyleInit()
|
|||
*/
|
||||
|
||||
void
|
||||
cifParseLayers(string, style, paintMask, cifMask, spaceOK)
|
||||
char *string; /* List of layers. */
|
||||
CIFStyle *style; /* Gives CIF style for parsing string.*/
|
||||
TileTypeBitMask *paintMask; /* Place to store mask of paint layers. If
|
||||
cifParseLayers(
|
||||
char *string, /* List of layers. */
|
||||
CIFStyle *style, /* Gives CIF style for parsing string.*/
|
||||
TileTypeBitMask *paintMask, /* Place to store mask of paint layers. If
|
||||
* NULL, then only CIF layer names are
|
||||
* considered.
|
||||
*/
|
||||
TileTypeBitMask *cifMask; /* Place to store mask of CIF layers. If
|
||||
TileTypeBitMask *cifMask, /* Place to store mask of CIF layers. If
|
||||
* NULL, then only paint layer names are
|
||||
* considered.
|
||||
*/
|
||||
int spaceOK; /* are space layers permissible in this cif
|
||||
int spaceOK) /* are space layers permissible in this cif
|
||||
layer?
|
||||
*/
|
||||
{
|
||||
TileTypeBitMask curCifMask, curPaintMask;
|
||||
char curLayer[40], *p, *cp;
|
||||
char curLayer[512], *p, *cp;
|
||||
TileType paintType;
|
||||
int i;
|
||||
bool allResidues;
|
||||
|
|
@ -243,6 +248,10 @@ cifParseLayers(string, style, paintMask, cifMask, spaceOK)
|
|||
{
|
||||
p = curLayer;
|
||||
|
||||
if (*string == '(')
|
||||
while ((*string != ')') && (*string != 0))
|
||||
*p++ = *string++;
|
||||
|
||||
if (*string == '*')
|
||||
{
|
||||
allResidues = TRUE;
|
||||
|
|
@ -260,7 +269,22 @@ cifParseLayers(string, style, paintMask, cifMask, spaceOK)
|
|||
|
||||
if (paintMask != NULL)
|
||||
{
|
||||
paintType = DBTechNameTypes(curLayer, &curPaintMask);
|
||||
if (*curLayer == '(')
|
||||
{
|
||||
TileType t;
|
||||
|
||||
/* Layer groups with parentheses can only be paint types,
|
||||
* and will be parsed accordingly. Residues will be
|
||||
* handled within the group. Set paintType to -3, which
|
||||
* is flagged and handled below.
|
||||
*/
|
||||
DBTechNoisyNameMask(curLayer, &curPaintMask);
|
||||
paintType = -3;
|
||||
allResidues = FALSE;
|
||||
}
|
||||
else
|
||||
paintType = DBTechNameTypes(curLayer, &curPaintMask);
|
||||
|
||||
if (paintType >= 0) goto okpaint;
|
||||
}
|
||||
else paintType = -2;
|
||||
|
|
@ -296,7 +320,7 @@ okpaint:
|
|||
TechError("Ambiguous layer (type) \"%s\".\n", curLayer);
|
||||
continue;
|
||||
}
|
||||
if (paintType >= 0)
|
||||
if ((paintType >= 0) || (paintType == -3))
|
||||
{
|
||||
if (paintType == TT_SPACE && spaceOK ==0)
|
||||
TechError("\"Space\" layer not permitted in CIF rules.\n");
|
||||
|
|
@ -356,7 +380,7 @@ okpaint:
|
|||
*/
|
||||
|
||||
void
|
||||
CIFTechInit()
|
||||
CIFTechInit(void)
|
||||
{
|
||||
CIFKeep *style;
|
||||
|
||||
|
|
@ -366,11 +390,13 @@ CIFTechInit()
|
|||
|
||||
/* forget the list of styles */
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (style = CIFStyleList; style != NULL; style = style->cs_next)
|
||||
{
|
||||
freeMagic(style->cs_name);
|
||||
freeMagic(style);
|
||||
freeMagic1(&mm1, style);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
CIFStyleList = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -392,7 +418,7 @@ CIFTechInit()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFTechStyleInit()
|
||||
CIFTechStyleInit(void)
|
||||
{
|
||||
CalmaTechInit();
|
||||
|
||||
|
|
@ -433,8 +459,9 @@ CIFTechStyleInit()
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFTechLimitScale(ns, ds)
|
||||
int ns, ds;
|
||||
CIFTechLimitScale(
|
||||
int ns,
|
||||
int ds)
|
||||
{
|
||||
int gridup, scaledown;
|
||||
int scale, limit, expand;
|
||||
|
|
@ -473,9 +500,9 @@ CIFTechLimitScale(ns, ds)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFParseScale(true_scale, expander)
|
||||
char *true_scale;
|
||||
int *expander;
|
||||
CIFParseScale(
|
||||
char *true_scale,
|
||||
int *expander)
|
||||
{
|
||||
char *decimal;
|
||||
short places;
|
||||
|
|
@ -524,10 +551,10 @@ CIFParseScale(true_scale, expander)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFTechLine(sectionName, argc, argv)
|
||||
char *sectionName; /* The name of this section. */
|
||||
int argc; /* Number of fields on line. */
|
||||
char *argv[]; /* Values of fields. */
|
||||
CIFTechLine(
|
||||
char *sectionName, /* The name of this section. */
|
||||
int argc, /* Number of fields on line. */
|
||||
char *argv[]) /* Values of fields. */
|
||||
{
|
||||
TileTypeBitMask mask, tempMask, cifMask, bloatLayers;
|
||||
int i, j, l, distance;
|
||||
|
|
@ -790,7 +817,7 @@ CIFTechLine(sectionName, argc, argv)
|
|||
else
|
||||
{
|
||||
l = strlen(CIFCurStyle->cs_name) - strlen(tptr);
|
||||
if (!strcmp(tptr, CIFCurStyle->cs_name + l))
|
||||
if ((l > 0) && !strcmp(tptr, CIFCurStyle->cs_name + l))
|
||||
{
|
||||
CIFCurStyle->cs_status = TECH_PENDING;
|
||||
return TRUE;
|
||||
|
|
@ -871,7 +898,7 @@ CIFTechLine(sectionName, argc, argv)
|
|||
|
||||
if (strcmp(argv[0], "labels") == 0)
|
||||
{
|
||||
bool portOnly = FALSE, noPort = FALSE;
|
||||
bool portOnly = FALSE, noPort = FALSE, textOnly = FALSE;
|
||||
|
||||
if (cifCurLayer == NULL)
|
||||
{
|
||||
|
|
@ -886,6 +913,8 @@ CIFTechLine(sectionName, argc, argv)
|
|||
portOnly = TRUE;
|
||||
else if (!strncmp(argv[2], "noport", 6))
|
||||
noPort = TRUE;
|
||||
else if (!strncmp(argv[2], "text", 6))
|
||||
textOnly = TRUE;
|
||||
else
|
||||
{
|
||||
TechError("Unknown option %s for labels statement.\n", argv[2]);
|
||||
|
|
@ -898,10 +927,28 @@ CIFTechLine(sectionName, argc, argv)
|
|||
{
|
||||
if (TTMaskHasType(&mask, i))
|
||||
{
|
||||
if (portOnly != TRUE)
|
||||
CIFCurStyle->cs_labelLayer[i] = CIFCurStyle->cs_nLayers-1;
|
||||
if (noPort != TRUE)
|
||||
if (portOnly == TRUE)
|
||||
{
|
||||
/* With "port", use layer for port geometry.
|
||||
* If the port text type has not been set, set it to
|
||||
* this layer.
|
||||
*/
|
||||
CIFCurStyle->cs_portLayer[i] = CIFCurStyle->cs_nLayers-1;
|
||||
if (CIFCurStyle->cs_portText[i] == -1)
|
||||
CIFCurStyle->cs_portText[i] = CIFCurStyle->cs_nLayers-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For "noport" or no argument, the label text and data
|
||||
* are set to this layer. If no argument, then set the
|
||||
* port text type to this type. If a later "port" statement
|
||||
* applies to the same layer, then the data type will be
|
||||
* separate from the text type.
|
||||
*/
|
||||
CIFCurStyle->cs_labelLayer[i] = CIFCurStyle->cs_nLayers-1;
|
||||
if (noPort == FALSE)
|
||||
CIFCurStyle->cs_portText[i] = CIFCurStyle->cs_nLayers-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
cifGotLabels = TRUE;
|
||||
|
|
@ -997,6 +1044,8 @@ CIFTechLine(sectionName, argc, argv)
|
|||
{
|
||||
if (strcmp(argv[i], "calma-permissive-labels") == 0)
|
||||
CIFCurStyle->cs_flags |= CWF_PERMISSIVE_LABELS;
|
||||
else if (strcmp(argv[i], "set-minimum-grid") == 0)
|
||||
CIFCurStyle->cs_flags |= CWF_MINIMUM_GRID;
|
||||
else if (strcmp(argv[i], "grow-euclidean") == 0)
|
||||
CIFCurStyle->cs_flags |= CWF_GROW_EUCLIDEAN;
|
||||
else if (strcmp(argv[i], "see-no-vendor") == 0)
|
||||
|
|
@ -1066,10 +1115,29 @@ CIFTechLine(sectionName, argc, argv)
|
|||
newOp->co_opcode = CIFOP_MASKHINTS;
|
||||
else if (strcmp(argv[0], "close") == 0)
|
||||
newOp->co_opcode = CIFOP_CLOSE;
|
||||
else if (strcmp(argv[0], "orthogonal") == 0)
|
||||
newOp->co_opcode = CIFOP_MANHATTAN;
|
||||
else if (strcmp(argv[0], "bridge") == 0)
|
||||
newOp->co_opcode = CIFOP_BRIDGE;
|
||||
else if (strcmp(argv[0], "bridge-lim") == 0)
|
||||
newOp->co_opcode = CIFOP_BRIDGELIM;
|
||||
else if (strcmp(argv[0], "overlapping") == 0)
|
||||
newOp->co_opcode = CIFOP_INTERACT;
|
||||
else if (strcmp(argv[0], "nonoverlapping") == 0)
|
||||
{
|
||||
newOp->co_opcode = CIFOP_INTERACT;
|
||||
newOp->co_client = (ClientData)CIFOP_INT_NOT;
|
||||
}
|
||||
else if (strcmp(argv[0], "interacting") == 0)
|
||||
{
|
||||
newOp->co_opcode = CIFOP_INTERACT;
|
||||
newOp->co_client = (ClientData)CIFOP_INT_TOUCHING;
|
||||
}
|
||||
else if (strcmp(argv[0], "noninteracting") == 0)
|
||||
{
|
||||
newOp->co_opcode = CIFOP_INTERACT;
|
||||
newOp->co_client = (ClientData)(CIFOP_INT_TOUCHING | CIFOP_INT_NOT);
|
||||
}
|
||||
else
|
||||
{
|
||||
TechError("Unknown statement \"%s\".\n", argv[0]);
|
||||
|
|
@ -1081,6 +1149,7 @@ CIFTechLine(sectionName, argc, argv)
|
|||
case CIFOP_AND:
|
||||
case CIFOP_ANDNOT:
|
||||
case CIFOP_OR:
|
||||
case CIFOP_INTERACT:
|
||||
if (argc != 2) goto wrongNumArgs;
|
||||
cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
|
||||
&newOp->co_cifMask,FALSE);
|
||||
|
|
@ -1090,7 +1159,6 @@ CIFTechLine(sectionName, argc, argv)
|
|||
case CIFOP_GROWMIN:
|
||||
case CIFOP_GROW_G:
|
||||
case CIFOP_SHRINK:
|
||||
case CIFOP_CLOSE:
|
||||
if (argc != 2) goto wrongNumArgs;
|
||||
newOp->co_distance = atoi(argv[1]);
|
||||
if (newOp->co_distance <= 0)
|
||||
|
|
@ -1100,6 +1168,26 @@ CIFTechLine(sectionName, argc, argv)
|
|||
}
|
||||
break;
|
||||
|
||||
case CIFOP_CLOSE:
|
||||
/* "close" is like "grow" and "shrink" except that it can have
|
||||
* no argument, in which case any closed shape of any size
|
||||
* will be closed (useful for finding enclosed areas).
|
||||
*/
|
||||
if (argc == 1)
|
||||
newOp->co_distance = 0;
|
||||
else if (argc != 2)
|
||||
goto wrongNumArgs;
|
||||
else
|
||||
{
|
||||
newOp->co_distance = atoi(argv[1]);
|
||||
if (newOp->co_distance <= 0)
|
||||
{
|
||||
TechError("Grow/shrink distance must be greater than zero.\n");
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CIFOP_BRIDGE:
|
||||
if (argc != 3) goto wrongNumArgs;
|
||||
newOp->co_distance = atoi(argv[1]);
|
||||
|
|
@ -1140,7 +1228,7 @@ CIFTechLine(sectionName, argc, argv)
|
|||
break;
|
||||
|
||||
case CIFOP_BLOATALL:
|
||||
if (argc != 3) goto wrongNumArgs;
|
||||
if (argc != 3 && argc != 4) goto wrongNumArgs;
|
||||
cifParseLayers(argv[1], CIFCurStyle, &newOp->co_paintMask,
|
||||
&newOp->co_cifMask, FALSE);
|
||||
bloats = (BloatData *)mallocMagic(sizeof(BloatData));
|
||||
|
|
@ -1156,6 +1244,21 @@ CIFTechLine(sectionName, argc, argv)
|
|||
if (!TTMaskIsZero(&mask) && !TTMaskIsZero(&cifMask))
|
||||
TechError("Can't mix CIF and magic layers in bloat statement.\n");
|
||||
|
||||
if (argc == 4)
|
||||
{
|
||||
/* 12/23/2024: Allow an additional argument, which is a
|
||||
* maximum halo distance to bloat (i.e., clip mask)
|
||||
*/
|
||||
newOp->co_distance = atoi(argv[3]);
|
||||
if (newOp->co_distance <= 0)
|
||||
{
|
||||
TechError("Bloat distance must be greater than zero.\n");
|
||||
goto errorReturn;
|
||||
}
|
||||
}
|
||||
else
|
||||
newOp->co_distance = 0;
|
||||
|
||||
/* 10/15/2019: Lifting restriction that the types that */
|
||||
/* trigger the bloating must be in the same plane as the */
|
||||
/* types that are bloated into. */
|
||||
|
|
@ -1276,6 +1379,19 @@ bloatCheck:
|
|||
goto wrongNumArgs;
|
||||
break;
|
||||
|
||||
case CIFOP_MANHATTAN:
|
||||
if (argc == 2)
|
||||
{
|
||||
if (!strcmp(argv[1], "fill"))
|
||||
newOp->co_client = (ClientData)1;
|
||||
else if (strcmp(argv[1], "remove"))
|
||||
TechError("Orthogonal takes only one optional argument "
|
||||
"\"fill\" or \"remove\" (default).\n");
|
||||
}
|
||||
else if (argc != 1)
|
||||
goto wrongNumArgs;
|
||||
break;
|
||||
|
||||
case CIFOP_BBOX:
|
||||
if (argc == 2)
|
||||
{
|
||||
|
|
@ -1502,8 +1618,8 @@ bloatCheck:
|
|||
*/
|
||||
|
||||
bool
|
||||
cifCheckCalmaNum(str)
|
||||
char *str;
|
||||
cifCheckCalmaNum(
|
||||
char *str)
|
||||
{
|
||||
int n = atoi(str);
|
||||
|
||||
|
|
@ -1539,9 +1655,9 @@ cifCheckCalmaNum(str)
|
|||
*/
|
||||
|
||||
void
|
||||
cifComputeRadii(layer, des)
|
||||
CIFLayer *layer; /* Layer for which to compute distances. */
|
||||
CIFStyle *des; /* CIF style (used to find temp layer
|
||||
cifComputeRadii(
|
||||
CIFLayer *layer, /* Layer for which to compute distances. */
|
||||
CIFStyle *des) /* CIF style (used to find temp layer
|
||||
* distances.
|
||||
*/
|
||||
{
|
||||
|
|
@ -1586,6 +1702,7 @@ cifComputeRadii(layer, des)
|
|||
case CIFOP_AND:
|
||||
case CIFOP_ANDNOT:
|
||||
case CIFOP_OR:
|
||||
case CIFOP_INTERACT:
|
||||
case CIFOP_MASKHINTS:
|
||||
break;
|
||||
|
||||
|
|
@ -1647,8 +1764,8 @@ cifComputeRadii(layer, des)
|
|||
*/
|
||||
|
||||
void
|
||||
cifComputeHalo(style)
|
||||
CIFStyle *style;
|
||||
cifComputeHalo(
|
||||
CIFStyle *style)
|
||||
{
|
||||
int maxGrow, maxShrink, i;
|
||||
|
||||
|
|
@ -1664,7 +1781,8 @@ cifComputeHalo(style)
|
|||
if (maxGrow > maxShrink)
|
||||
style->cs_radius = 2*maxGrow;
|
||||
else style->cs_radius = 2*maxShrink;
|
||||
style->cs_radius /= style->cs_scaleFactor;
|
||||
if (style->cs_scaleFactor > 0)
|
||||
style->cs_radius /= style->cs_scaleFactor;
|
||||
style->cs_radius++;
|
||||
|
||||
/* TxPrintf("Radius for %s CIF is %d.\n",
|
||||
|
|
@ -1717,7 +1835,7 @@ cifComputeHalo(style)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFTechFinal()
|
||||
CIFTechFinal(void)
|
||||
{
|
||||
CIFStyle *style = CIFCurStyle;
|
||||
CIFOp *op;
|
||||
|
|
@ -1866,7 +1984,7 @@ CIFTechFinal()
|
|||
}
|
||||
}
|
||||
/* Presence of op->co_opcode in CIFOP_OR indicates a copy */
|
||||
/* of the SquaresData pointer from a following operator */
|
||||
/* of the SquaresData pointer from a following operator. */
|
||||
/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
|
||||
/* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
|
||||
/* uses it for a string. */
|
||||
|
|
@ -1879,6 +1997,7 @@ CIFTechFinal()
|
|||
case CIFOP_MASKHINTS:
|
||||
case CIFOP_BOUNDARY:
|
||||
case CIFOP_MAXRECT:
|
||||
case CIFOP_MANHATTAN:
|
||||
case CIFOP_NET:
|
||||
break;
|
||||
case CIFOP_BRIDGELIM:
|
||||
|
|
@ -1977,6 +2096,7 @@ CIFTechFinal()
|
|||
|
||||
case CIFOP_AND:
|
||||
case CIFOP_ANDNOT:
|
||||
case CIFOP_INTERACT:
|
||||
case CIFOP_SHRINK:
|
||||
case CIFOP_CLOSE:
|
||||
case CIFOP_BRIDGELIM:
|
||||
|
|
@ -2049,7 +2169,8 @@ CIFTechFinal()
|
|||
for (op = style->cs_layers[i]->cl_ops; (op != NULL) &&
|
||||
(op->co_opcode == CIFOP_OR) &&
|
||||
(TTMaskIsZero(&op->co_cifMask)); op = op->co_next);
|
||||
if (op && (op->co_opcode == CIFOP_SQUARES) && (op->co_next == NULL))
|
||||
if (op && ((op->co_opcode == CIFOP_SQUARES) ||
|
||||
(op->co_opcode == CIFOP_SQUARES_G)) && (op->co_next == NULL))
|
||||
{
|
||||
clientdata = op->co_client;
|
||||
for (op = style->cs_layers[i]->cl_ops; op->co_opcode == CIFOP_OR;
|
||||
|
|
@ -2100,8 +2221,8 @@ CIFTechFinal()
|
|||
*/
|
||||
|
||||
void
|
||||
CIFLoadStyle(stylename)
|
||||
char *stylename;
|
||||
CIFLoadStyle(
|
||||
char *stylename)
|
||||
{
|
||||
SectionID invcif;
|
||||
|
||||
|
|
@ -2149,11 +2270,11 @@ CIFLoadStyle(stylename)
|
|||
*/
|
||||
|
||||
int
|
||||
CIFGetContactSize(type, edge, spacing, border)
|
||||
TileType type;
|
||||
int *edge;
|
||||
int *border;
|
||||
int *spacing;
|
||||
CIFGetContactSize(
|
||||
TileType type,
|
||||
int *edge,
|
||||
int *spacing,
|
||||
int *border)
|
||||
{
|
||||
CIFStyle *style = CIFCurStyle;
|
||||
CIFOp *op, *sop;
|
||||
|
|
@ -2246,8 +2367,9 @@ CIFGetContactSize(type, edge, spacing, border)
|
|||
*/
|
||||
|
||||
void
|
||||
CIFTechOutputScale(n, d)
|
||||
int n, d;
|
||||
CIFTechOutputScale(
|
||||
int n,
|
||||
int d)
|
||||
{
|
||||
int i, j, lgcf, lexpand;
|
||||
CIFStyle *ostyle = CIFCurStyle;
|
||||
|
|
@ -2410,7 +2532,9 @@ CIFTechOutputScale(n, d)
|
|||
case CIFOP_BOUNDARY:
|
||||
case CIFOP_MASKHINTS:
|
||||
case CIFOP_MAXRECT:
|
||||
case CIFOP_MANHATTAN:
|
||||
case CIFOP_NET:
|
||||
case CIFOP_INTERACT:
|
||||
break;
|
||||
case CIFOP_BRIDGELIM:
|
||||
case CIFOP_BRIDGE:
|
||||
|
|
|
|||
114
cif/CIFwrite.c
114
cif/CIFwrite.c
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFwrite.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFwrite.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
|
@ -44,15 +44,15 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "textio/textio.h"
|
||||
|
||||
/* Forward declarations */
|
||||
extern int cifWriteInitFunc();
|
||||
extern int cifWriteMarkFunc();
|
||||
extern int cifWritePaintFunc();
|
||||
extern int cifWriteLabelFunc();
|
||||
extern int cifWriteUseFunc();
|
||||
extern void cifOutPreamble();
|
||||
extern void cifOut();
|
||||
extern void cifOutFunc();
|
||||
extern int GrClipTriangle();
|
||||
extern int cifWriteInitFunc(CellDef *def);
|
||||
extern int cifWriteMarkFunc(CellUse *use);
|
||||
extern int cifWritePaintFunc(Tile *tile, TileType dinfo, FILE *f);
|
||||
extern int cifWriteLabelFunc(Tile *tile, TileType dinfo, FILE *f);
|
||||
extern int cifWriteUseFunc(CellUse *use, FILE *f);
|
||||
extern void cifOutPreamble(FILE *outf, CellDef *cell);
|
||||
extern void cifOut(FILE *outf);
|
||||
extern void cifOutFunc(CellDef *def, FILE *f);
|
||||
extern void GrClipTriangle(Rect *r, Rect *c, int clipped, TileType dinfo, Point *points, int *np);
|
||||
|
||||
/* Current cell number in CIF numbering scheme */
|
||||
|
||||
|
|
@ -118,12 +118,13 @@ bool CIFArrayWriteDisable = FALSE;
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFWrite(rootDef, f)
|
||||
CellDef *rootDef; /* Pointer to CellDef to be written */
|
||||
FILE *f; /* Open output file */
|
||||
CIFWrite(
|
||||
CellDef *rootDef, /* Pointer to CellDef to be written */
|
||||
FILE *f) /* Open output file */
|
||||
{
|
||||
bool good;
|
||||
int oldCount = DBWFeedbackCount;
|
||||
CellDef *err_def;
|
||||
CellUse dummy;
|
||||
|
||||
/*
|
||||
|
|
@ -133,9 +134,11 @@ CIFWrite(rootDef, f)
|
|||
*/
|
||||
|
||||
dummy.cu_def = rootDef;
|
||||
if (DBCellReadArea(&dummy, &rootDef->cd_bbox, TRUE))
|
||||
err_def = DBCellReadArea(&dummy, &rootDef->cd_bbox, TRUE);
|
||||
if (err_def != NULL)
|
||||
{
|
||||
TxError("Failure to read in entire subtree of the cell.\n");
|
||||
TxError("Failed on cell %s.\n", err_def->cd_name);
|
||||
return (FALSE);
|
||||
}
|
||||
DBFixMismatch();
|
||||
|
|
@ -164,8 +167,8 @@ CIFWrite(rootDef, f)
|
|||
cifOutPreamble(f, rootDef);
|
||||
cifOut(f);
|
||||
StackFree(cifStack);
|
||||
if ((int) rootDef->cd_client < 0)
|
||||
rootDef->cd_client = (ClientData) (- (int) rootDef->cd_client);
|
||||
if ((int) CD2INT(rootDef->cd_client) < 0)
|
||||
rootDef->cd_client = INT2CD(- (int) CD2INT(rootDef->cd_client));
|
||||
|
||||
/* See if any problems occurred. */
|
||||
|
||||
|
|
@ -179,7 +182,7 @@ CIFWrite(rootDef, f)
|
|||
* Now we are almost done.
|
||||
* Just output a call on the root cell
|
||||
*/
|
||||
fprintf(f, "C %d;\nEnd\n", (int) rootDef->cd_client);
|
||||
fprintf(f, "C %d;\nEnd\n", (int) CD2INT(rootDef->cd_client));
|
||||
good = !ferror(f);
|
||||
return (good);
|
||||
}
|
||||
|
|
@ -202,8 +205,8 @@ CIFWrite(rootDef, f)
|
|||
*/
|
||||
|
||||
int
|
||||
cifWriteInitFunc(def)
|
||||
CellDef *def;
|
||||
cifWriteInitFunc(
|
||||
CellDef *def)
|
||||
{
|
||||
def->cd_client = (ClientData) 0;
|
||||
return (0);
|
||||
|
|
@ -226,11 +229,11 @@ cifWriteInitFunc(def)
|
|||
*/
|
||||
|
||||
int
|
||||
cifWriteMarkFunc(use)
|
||||
CellUse *use;
|
||||
cifWriteMarkFunc(
|
||||
CellUse *use)
|
||||
{
|
||||
if (use->cu_def->cd_client != (ClientData) 0) return 0;
|
||||
use->cu_def->cd_client = (ClientData) cifCellNum;
|
||||
use->cu_def->cd_client = INT2CD(cifCellNum);
|
||||
cifCellNum -= 1;
|
||||
StackPush((ClientData) use->cu_def, cifStack);
|
||||
return (0);
|
||||
|
|
@ -252,9 +255,9 @@ cifWriteMarkFunc(use)
|
|||
*/
|
||||
|
||||
void
|
||||
cifOutPreamble(outf, cell)
|
||||
FILE *outf;
|
||||
CellDef *cell;
|
||||
cifOutPreamble(
|
||||
FILE *outf,
|
||||
CellDef *cell)
|
||||
{
|
||||
extern char *MagicVersion;
|
||||
extern char *MagicCompileTime;
|
||||
|
|
@ -301,25 +304,24 @@ cifOutPreamble(outf, cell)
|
|||
*/
|
||||
|
||||
void
|
||||
cifOut(outf)
|
||||
FILE *outf;
|
||||
cifOut(
|
||||
FILE *outf)
|
||||
{
|
||||
CellDef *def;
|
||||
bool needHier;
|
||||
|
||||
while (!StackEmpty(cifStack))
|
||||
{
|
||||
def = (CellDef *) StackPop(cifStack);
|
||||
if ((int) def->cd_client >= 0) continue; /* Already output */
|
||||
if ((int) CD2INT(def->cd_client) >= 0) continue; /* Already output */
|
||||
if (SigInterruptPending) continue;
|
||||
|
||||
def->cd_client = (ClientData) (- (int) def->cd_client);
|
||||
def->cd_client = INT2CD(- (int) CD2INT(def->cd_client));
|
||||
|
||||
/* Read the cell in if it is not already available. */
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) continue;
|
||||
}
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
continue;
|
||||
|
||||
/* Add any subcells to the stack. This must be done before
|
||||
* outputting CIF to make sure that the subcells all have
|
||||
|
|
@ -351,16 +353,16 @@ cifOut(outf)
|
|||
*/
|
||||
|
||||
void
|
||||
cifOutFunc(def, f)
|
||||
CellDef *def; /* Pointer to cell def to be written */
|
||||
FILE *f; /* Open output file */
|
||||
cifOutFunc(
|
||||
CellDef *def, /* Pointer to cell def to be written */
|
||||
FILE *f) /* Open output file */
|
||||
{
|
||||
Rect bigArea;
|
||||
Label *lab;
|
||||
int type;
|
||||
CIFLayer *layer;
|
||||
|
||||
fprintf(f, "DS %d %d %d;\n", (int) def->cd_client,
|
||||
fprintf(f, "DS %d %d %d;\n", (int) CD2INT(def->cd_client),
|
||||
CIFCurStyle->cs_reducer, 2 * CIFCurStyle->cs_expander);
|
||||
|
||||
if (def->cd_name != (char *) NULL)
|
||||
|
|
@ -385,10 +387,12 @@ cifOutFunc(def, f)
|
|||
CIFErrorDef = def;
|
||||
CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE,
|
||||
(ClientData)NULL);
|
||||
|
||||
if (!CIFHierWriteDisable)
|
||||
CIFGenSubcells(def, &bigArea, CIFPlanes);
|
||||
CIFGenSubcells(def, &bigArea, CIFPlanes);
|
||||
if (!CIFArrayWriteDisable)
|
||||
CIFGenArrays(def, &bigArea, CIFPlanes);
|
||||
CIFGenArrays(def, &bigArea, CIFPlanes);
|
||||
|
||||
for (type = 0; type < CIFCurStyle->cs_nLayers; type++)
|
||||
{
|
||||
layer = CIFCurStyle->cs_layers[type];
|
||||
|
|
@ -480,16 +484,16 @@ cifOutFunc(def, f)
|
|||
*/
|
||||
|
||||
int
|
||||
cifWriteUseFunc(use, f)
|
||||
CellUse *use;
|
||||
FILE *f;
|
||||
cifWriteUseFunc(
|
||||
CellUse *use,
|
||||
FILE *f)
|
||||
{
|
||||
int x, y, topx, topy;
|
||||
int realx, realy;
|
||||
Transform *t;
|
||||
int cifnum;
|
||||
|
||||
cifnum = (int) use->cu_def->cd_client;
|
||||
cifnum = (int) CD2INT(use->cu_def->cd_client);
|
||||
if (cifnum < 0) cifnum = (-cifnum);
|
||||
topx = use->cu_xhi - use->cu_xlo;
|
||||
if (topx < 0) topx = -topx;
|
||||
|
|
@ -578,9 +582,10 @@ cifWriteUseFunc(use, f)
|
|||
*/
|
||||
|
||||
int
|
||||
cifWriteLabelFunc(tile, f)
|
||||
Tile *tile; /* Tile to be written out. */
|
||||
FILE *f; /* File in which to write. */
|
||||
cifWriteLabelFunc(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
FILE *f) /* File in which to write. */
|
||||
{
|
||||
Rect r;
|
||||
int type;
|
||||
|
|
@ -637,9 +642,10 @@ cifWriteLabelFunc(tile, f)
|
|||
*/
|
||||
|
||||
int
|
||||
cifWritePaintFunc(tile, f)
|
||||
Tile *tile; /* Tile to be written out. */
|
||||
FILE *f; /* File in which to write. */
|
||||
cifWritePaintFunc(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
FILE *f) /* File in which to write. */
|
||||
{
|
||||
Rect r;
|
||||
|
||||
|
|
@ -658,7 +664,7 @@ cifWritePaintFunc(tile, f)
|
|||
Point points[5];
|
||||
int i, np;
|
||||
|
||||
GrClipTriangle(&r, NULL, FALSE, TiGetTypeExact(tile), points, &np);
|
||||
GrClipTriangle(&r, NULL, FALSE, TiGetTypeExact(tile) | dinfo, points, &np);
|
||||
|
||||
/* Write triangle as a CIF polygon */
|
||||
|
||||
|
|
@ -718,9 +724,9 @@ cifWritePaintFunc(tile, f)
|
|||
*/
|
||||
|
||||
bool
|
||||
CIFWriteFlat(rootDef, f)
|
||||
CellDef *rootDef; /* Pointer to CellDef to be written */
|
||||
FILE *f; /* Open output file */
|
||||
CIFWriteFlat(
|
||||
CellDef *rootDef, /* Pointer to CellDef to be written */
|
||||
FILE *f) /* Open output file */
|
||||
{
|
||||
bool good;
|
||||
int oldCount = DBWFeedbackCount;
|
||||
|
|
@ -769,7 +775,7 @@ CIFWriteFlat(rootDef, f)
|
|||
* Just output a call on the root cell
|
||||
*/
|
||||
|
||||
fprintf(f, "C %d;\nEnd\n", (int) CIFComponentDef->cd_client);
|
||||
fprintf(f, "C %d;\nEnd\n", (int) CD2INT(CIFComponentDef->cd_client));
|
||||
DBCellClearDef(CIFComponentDef);
|
||||
good = !ferror(f);
|
||||
|
||||
|
|
|
|||
69
cif/cif.h
69
cif/cif.h
|
|
@ -20,8 +20,8 @@
|
|||
* rcsid "$Header: /usr/cvsroot/magic-8.0/cif/cif.h,v 1.4 2010/06/24 12:37:15 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CIF_H
|
||||
#define _CIF_H
|
||||
#ifndef _MAGIC__CIF__CIF_H
|
||||
#define _MAGIC__CIF__CIF_H
|
||||
|
||||
#include "database/database.h"
|
||||
|
||||
|
|
@ -51,47 +51,48 @@ extern bool CIFUnfracture;
|
|||
|
||||
/* Procedures that parse the cif sections of a technology file. */
|
||||
|
||||
extern void CIFTechStyleInit();
|
||||
extern void CIFTechInit();
|
||||
extern bool CIFTechLine();
|
||||
extern void CIFTechFinal();
|
||||
extern void CIFTechOutputScale();
|
||||
extern int CIFTechInputScale();
|
||||
extern bool CIFTechLimitScale();
|
||||
extern void CIFReadTechStyleInit();
|
||||
extern void CIFReadTechInit();
|
||||
extern bool CIFReadTechLine();
|
||||
extern void CIFReadTechFinal();
|
||||
extern void CIFParseReadLayers();
|
||||
extern void CIFTechStyleInit(void);
|
||||
extern void CIFTechInit(void);
|
||||
extern bool CIFTechLine(char *sectionName, int argc, char *argv[]);
|
||||
extern void CIFTechFinal(void);
|
||||
extern void CIFTechOutputScale(int n, int d);
|
||||
extern int CIFTechInputScale(int n, int d, bool opt);
|
||||
extern bool CIFTechLimitScale(int ns, int ds);
|
||||
extern void CIFReadTechStyleInit(void);
|
||||
extern void CIFReadTechInit(void);
|
||||
extern bool CIFReadTechLine(char *sectionName, int argc, char *argv[]);
|
||||
extern void CIFReadTechFinal(void);
|
||||
extern void CIFParseReadLayers(char *string, TileTypeBitMask *mask, bool newok);
|
||||
|
||||
/* Externally-visible procedures: */
|
||||
|
||||
extern float CIFGetOutputScale();
|
||||
extern float CIFGetScale();
|
||||
extern float CIFGetInputScale();
|
||||
extern int CIFGetDefaultContactSize();
|
||||
extern float CIFGetOutputScale(int convert);
|
||||
extern float CIFGetScale(int convert);
|
||||
extern float CIFGetInputScale(int convert);
|
||||
|
||||
extern int CIFPaintCurrent();
|
||||
extern void CIFSeeLayer();
|
||||
extern void CIFPaintLayer();
|
||||
extern void CIFSeeHierLayer();
|
||||
extern void CIFPrintStats();
|
||||
extern int CIFPaintCurrent(int filetype);
|
||||
extern void CIFSeeLayer(CellDef *rootDef, Rect *area, char *layer);
|
||||
extern void CIFPaintLayer(CellDef *rootDef, Rect *area, char *cifLayer, int magicLayer, CellDef *paintDef);
|
||||
extern void CIFSeeHierLayer(CellDef *rootDef, Rect *area, char *layer, int arrays, int subcells);
|
||||
extern void CIFPrintStats(void);
|
||||
|
||||
extern bool CIFWrite();
|
||||
extern void CIFReadFile();
|
||||
extern bool CIFWrite(CellDef *rootDef, FILE *f);
|
||||
extern void CIFReadFile(FILE *file);
|
||||
|
||||
extern void CIFSetStyle();
|
||||
extern void CIFSetReadStyle();
|
||||
extern void CIFSetStyle(char *name);
|
||||
extern void CIFSetReadStyle(char *name);
|
||||
|
||||
extern void CIFPrintStyle();
|
||||
extern void CIFPrintReadStyle();
|
||||
extern void CIFPrintStyle(bool dolist, bool doforall, bool docurrent);
|
||||
extern void CIFPrintReadStyle(bool dolist, bool doforall, bool docurrent);
|
||||
|
||||
extern int CIFOutputScaleFactor();
|
||||
extern int CIFOutputScaleFactor(void);
|
||||
|
||||
extern void PaintWireList();
|
||||
extern LinkedRect *PaintPolygon();
|
||||
extern void PaintWireList(Point *pointlist, int number, int width, int endcap, Plane *plane,
|
||||
PaintResultType *ptable, PaintUndoInfo *ui);
|
||||
extern LinkedRect *PaintPolygon(Point *pointlist, int number, Plane *plane, PaintResultType *ptable,
|
||||
PaintUndoInfo *ui, int keep);
|
||||
|
||||
/* C99 compat */
|
||||
extern int CIFGetContactSize();
|
||||
extern int CIFGetContactSize(TileType type, int *edge, int *spacing, int *border);
|
||||
|
||||
#endif /* _CIF_H */
|
||||
#endif /* _MAGIC__CIF__CIF_H */
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWcmmnds.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWcmmnds.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -43,10 +43,11 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
/* Forward declarations: */
|
||||
|
||||
extern void cmwButtonUp(), cmwButtonDown();
|
||||
extern void cbUpdate();
|
||||
extern void RGBxHSV();
|
||||
extern void HSVxRGB();
|
||||
extern void cmwButtonUp(MagWindow *w, Point *p, int button);
|
||||
extern void cmwButtonDown(MagWindow *w, Point *p, int button);
|
||||
extern void cbUpdate(MagWindow *w, int code, double x, int replace);
|
||||
extern bool RGBxHSV(double r, double g, double b, double *h, double *s, double *v);
|
||||
extern void HSVxRGB(double h, double s, double v, double *r, double *g, double *b);
|
||||
|
||||
/* If a button is pressed over the top box in the window, which
|
||||
* displays the current color, we must save the window in which
|
||||
|
|
@ -84,9 +85,9 @@ bool cmwModified = FALSE;
|
|||
*/
|
||||
|
||||
void
|
||||
CMWcommand(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CMWcommand(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
switch (cmd->tx_button)
|
||||
{
|
||||
|
|
@ -137,13 +138,13 @@ CMWcommand(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwButtonDown(w, p, button)
|
||||
MagWindow *w; /* Window where the button was pressed. */
|
||||
Point *p;
|
||||
int button;
|
||||
cmwButtonDown(
|
||||
MagWindow *w, /* Window where the button was pressed. */
|
||||
Point *p,
|
||||
int button)
|
||||
{
|
||||
ColorBar *cb;
|
||||
ColorPump *cp;
|
||||
const ColorBar *cb;
|
||||
const ColorPump *cp;
|
||||
Point surfacePoint;
|
||||
int x;
|
||||
double dx;
|
||||
|
|
@ -224,14 +225,14 @@ cmwButtonDown(w, p, button)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwButtonUp(w, p, button)
|
||||
MagWindow *w; /* Window where the button was released */
|
||||
Point *p; /* Point where button was released, in window coords.*/
|
||||
int button; /* Button that was released. */
|
||||
cmwButtonUp(
|
||||
MagWindow *w, /* Window where the button was released */
|
||||
Point *p, /* Point where button was released, in window coords.*/
|
||||
int button) /* Button that was released. */
|
||||
{
|
||||
CMWclientRec *crec;
|
||||
int r, g, b, color, oldR, oldG, oldB;
|
||||
extern int cmwRedisplayFunc();
|
||||
extern int cmwRedisplayFunc(MagWindow *w, int color);
|
||||
|
||||
/* If the button wasn't depressed over the top box in the window
|
||||
* (the one displaying the current color), then we ignore the
|
||||
|
|
@ -296,12 +297,12 @@ cmwButtonUp(w, p, button)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwPushbutton(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
cmwPushbutton(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int button;
|
||||
static char *cmwButton[] = {"left", "middle", "right", NULL};
|
||||
static const char * const cmwButton[] = {"left", "middle", "right", NULL};
|
||||
|
||||
if (cmd->tx_argc != 2)
|
||||
{
|
||||
|
|
@ -355,9 +356,9 @@ cmwPushbutton(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwColor(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
cmwColor(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int color, r, g, b;
|
||||
CMWclientRec *crec;
|
||||
|
|
@ -372,7 +373,7 @@ cmwColor(w, cmd)
|
|||
}
|
||||
else if (cmd->tx_argc == 2)
|
||||
{
|
||||
if (sscanf(cmd->tx_argv[1], "%i", &color) == 0)
|
||||
if (sscanf(cmd->tx_argv[1], "%i", &color) != 1)
|
||||
{
|
||||
/* Invalid color---allow keywords "next" and "last" */
|
||||
crec = (CMWclientRec *) w->w_clientData;
|
||||
|
|
@ -450,9 +451,9 @@ cmwColor(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwSave(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
cmwSave(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
bool ok;
|
||||
if ((cmd->tx_argc != 1) && (cmd->tx_argc != 4))
|
||||
|
|
@ -495,9 +496,9 @@ cmwSave(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwLoad(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
cmwLoad(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
if ((cmd->tx_argc != 1) && (cmd->tx_argc != 4))
|
||||
{
|
||||
|
|
@ -537,18 +538,18 @@ cmwLoad(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
cbUpdate(w, code, x, replace)
|
||||
MagWindow *w; /* Window whose color is to be changed. */
|
||||
int code; /* Indicates which color component to change. */
|
||||
double x; /* Gives increment or new value for color. */
|
||||
int replace; /* TRUE means replace component with x, FALSE
|
||||
cbUpdate(
|
||||
MagWindow *w, /* Window whose color is to be changed. */
|
||||
int code, /* Indicates which color component to change. */
|
||||
double x, /* Gives increment or new value for color. */
|
||||
int replace) /* TRUE means replace component with x, FALSE
|
||||
* means increment component by x.
|
||||
*/
|
||||
{
|
||||
CMWclientRec *cr = (CMWclientRec *) w->w_clientData;
|
||||
double values[6];
|
||||
int r, g, b, nr, ng, nb;
|
||||
extern int cmwRedisplayFunc();
|
||||
extern int cmwRedisplayFunc(MagWindow *w, int color);
|
||||
|
||||
/* Get current color map values */
|
||||
(void) GrGetColor(cr->cmw_color, &r, &g, &b);
|
||||
|
|
@ -591,14 +592,14 @@ cbUpdate(w, code, x, replace)
|
|||
}
|
||||
|
||||
int
|
||||
cmwRedisplayFunc(w, color)
|
||||
MagWindow *w; /* Window that may have to be redisplayed. */
|
||||
int color; /* If this color is in window, redisplay the
|
||||
cmwRedisplayFunc(
|
||||
MagWindow *w, /* Window that may have to be redisplayed. */
|
||||
int color) /* If this color is in window, redisplay the
|
||||
* color bars in the window.
|
||||
*/
|
||||
{
|
||||
ColorBar *cb;
|
||||
ColorPump *cp;
|
||||
const ColorBar *cb;
|
||||
const ColorPump *cp;
|
||||
Rect screenR;
|
||||
CMWclientRec *cr = (CMWclientRec *) w->w_clientData;
|
||||
|
||||
|
|
@ -644,11 +645,11 @@ cmwRedisplayFunc(w, color)
|
|||
*/
|
||||
|
||||
bool
|
||||
CMWCheckWritten()
|
||||
CMWCheckWritten(void)
|
||||
{
|
||||
bool indx;
|
||||
char *prompt;
|
||||
static char *(yesno[]) = {"no", "yes", NULL};
|
||||
static const char * const yesno[] = {"no", "yes", NULL};
|
||||
|
||||
if (!cmwModified) return TRUE;
|
||||
prompt = TxPrintString("The color map has been modified.\n"
|
||||
|
|
|
|||
120
cmwind/CMWmain.c
120
cmwind/CMWmain.c
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWmain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWmain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -44,12 +44,12 @@ global WindClient CMWclientID;
|
|||
|
||||
/* Forward and external declarations */
|
||||
|
||||
extern void cmwColor();
|
||||
extern void cmwSave();
|
||||
extern void cmwLoad();
|
||||
extern void cmwPushbutton();
|
||||
extern void RGBxHSV();
|
||||
extern void CMWundoInit();
|
||||
extern void cmwColor(MagWindow *w, TxCommand *cmd);
|
||||
extern void cmwSave(MagWindow *w, TxCommand *cmd);
|
||||
extern void cmwLoad(MagWindow *w, TxCommand *cmd);
|
||||
extern void cmwPushbutton(MagWindow *w, TxCommand *cmd);
|
||||
extern bool RGBxHSV(double r, double g, double b, double *h, double *s, double *v);
|
||||
extern void CMWundoInit(void);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
|
|
@ -89,47 +89,47 @@ extern void CMWundoInit();
|
|||
* which pump is hit and which mouse button is used to hit it.
|
||||
*/
|
||||
|
||||
ColorBar colorBars[] =
|
||||
const ColorBar colorBars[] =
|
||||
{
|
||||
"Red", CB_RED, STYLE_RED, {2000, 8000, 10000, 9000},
|
||||
{2000, 9500, 10000, 10500},
|
||||
"Green", CB_GREEN, STYLE_GREEN, {2000, 5000, 10000, 6000},
|
||||
{2000, 6500, 10000, 7500},
|
||||
"Blue", CB_BLUE, STYLE_BLUE, {2000, 2000, 10000, 3000},
|
||||
{2000, 3500, 10000, 4500},
|
||||
"Hue", CB_HUE, STYLE_YELLOW, {14000, 8000, 22000, 9000},
|
||||
{14000, 9500, 22000, 10500},
|
||||
"Saturation", CB_SAT, STYLE_GRAY, {14000, 5000, 22000, 6000},
|
||||
{14000, 6500, 22000, 7500},
|
||||
"Value", CB_VALUE, STYLE_BROWN1, {14000, 2000, 22000, 3000},
|
||||
{14000, 3500, 22000, 4500},
|
||||
0
|
||||
{"Red", CB_RED, STYLE_RED, {{ 2000, 8000}, {10000, 9000}},
|
||||
{{ 2000, 9500}, {10000, 10500}}},
|
||||
{"Green", CB_GREEN, STYLE_GREEN, {{ 2000, 5000}, {10000, 6000}},
|
||||
{{ 2000, 6500}, {10000, 7500}}},
|
||||
{"Blue", CB_BLUE, STYLE_BLUE, {{ 2000, 2000}, {10000, 3000}},
|
||||
{{ 2000, 3500}, {10000, 4500}}},
|
||||
{"Hue", CB_HUE, STYLE_YELLOW, {{14000, 8000}, {22000, 9000}},
|
||||
{{14000, 9500}, {22000, 10500}}},
|
||||
{"Saturation", CB_SAT, STYLE_GRAY, {{14000, 5000}, {22000, 6000}},
|
||||
{{14000, 6500}, {22000, 7500}}},
|
||||
{"Value", CB_VALUE, STYLE_BROWN1, {{14000, 2000}, {22000, 3000}},
|
||||
{{14000, 3500}, {22000, 4500}}},
|
||||
{0}
|
||||
};
|
||||
|
||||
ColorPump colorPumps[] =
|
||||
const ColorPump colorPumps[] =
|
||||
{
|
||||
CB_RED, -.0078, {500, 8000, 1500, 9000},
|
||||
CB_RED, .0078, {10500, 8000, 11500, 9000},
|
||||
CB_GREEN, -.0078, {500, 5000, 1500, 6000},
|
||||
CB_GREEN, .0078, {10500, 5000, 11500, 6000},
|
||||
CB_BLUE, -.0078, {500, 2000, 1500, 3000},
|
||||
CB_BLUE, .0078, {10500, 2000, 11500, 3000},
|
||||
CB_HUE, -.01, {12500, 8000, 13500, 9000},
|
||||
CB_HUE, .01, {22500, 8000, 23500, 9000},
|
||||
CB_SAT, -.01, {12500, 5000, 13500, 6000},
|
||||
CB_SAT, .01, {22500, 5000, 23500, 6000},
|
||||
CB_VALUE, -.01, {12500, 2000, 13500, 3000},
|
||||
CB_VALUE, .01, {22500, 2000, 23500, 3000},
|
||||
-1
|
||||
{CB_RED, -.0078, {{ 500, 8000}, { 1500, 9000}}},
|
||||
{CB_RED, .0078, {{10500, 8000}, {11500, 9000}}},
|
||||
{CB_GREEN, -.0078, {{ 500, 5000}, { 1500, 6000}}},
|
||||
{CB_GREEN, .0078, {{10500, 5000}, {11500, 6000}}},
|
||||
{CB_BLUE, -.0078, {{ 500, 2000}, { 1500, 3000}}},
|
||||
{CB_BLUE, .0078, {{10500, 2000}, {11500, 3000}}},
|
||||
{CB_HUE, -.01, {{12500, 8000}, {13500, 9000}}},
|
||||
{CB_HUE, .01, {{22500, 8000}, {23500, 9000}}},
|
||||
{CB_SAT, -.01, {{12500, 5000}, {13500, 6000}}},
|
||||
{CB_SAT, .01, {{22500, 5000}, {23500, 6000}}},
|
||||
{CB_VALUE, -.01, {{12500, 2000}, {13500, 3000}}},
|
||||
{CB_VALUE, .01, {{22500, 2000}, {23500, 3000}}},
|
||||
{-1}
|
||||
};
|
||||
|
||||
Rect cmwCurrentColorArea = {{6000, 12000}, {18000, 15000}};
|
||||
Rect cmwCurrentColorTextBox = {{6000, 15500}, {18000, 16500}};
|
||||
char *cmwCurrentColorText = "Color Being Edited";
|
||||
const Rect cmwCurrentColorArea = {{6000, 12000}, {18000, 15000}};
|
||||
const Rect cmwCurrentColorTextBox = {{6000, 15500}, {18000, 16500}};
|
||||
const char * const cmwCurrentColorText = "Color Being Edited";
|
||||
|
||||
/* Bounding rectangle for entire window */
|
||||
|
||||
Rect colorWindowRect = {{0, 1500}, {24000, 17000}};
|
||||
const Rect colorWindowRect = {{0, 1500}, {24000, 17000}};
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -149,13 +149,13 @@ Rect colorWindowRect = {{0, 1500}, {24000, 17000}};
|
|||
*/
|
||||
|
||||
bool
|
||||
CMWcreate(window, argc, argv)
|
||||
MagWindow *window;
|
||||
int argc;
|
||||
char *argv[];
|
||||
CMWcreate(
|
||||
MagWindow *window,
|
||||
int argc,
|
||||
char *argv[])
|
||||
{
|
||||
CMWclientRec *crec;
|
||||
int color;
|
||||
unsigned int color;
|
||||
|
||||
crec = (CMWclientRec *) mallocMagic(sizeof(CMWclientRec));
|
||||
window->w_clientData = (ClientData) crec;
|
||||
|
|
@ -189,8 +189,8 @@ CMWcreate(window, argc, argv)
|
|||
*/
|
||||
|
||||
bool
|
||||
CMWdelete(window)
|
||||
MagWindow *window;
|
||||
CMWdelete(
|
||||
MagWindow *window)
|
||||
{
|
||||
CMWclientRec *cr;
|
||||
|
||||
|
|
@ -218,10 +218,10 @@ CMWdelete(window)
|
|||
*/
|
||||
|
||||
void
|
||||
CMWreposition(window, newScreenArea, final)
|
||||
MagWindow *window;
|
||||
Rect *newScreenArea;
|
||||
bool final;
|
||||
CMWreposition(
|
||||
MagWindow *window,
|
||||
Rect *newScreenArea,
|
||||
bool final)
|
||||
{
|
||||
if (final)
|
||||
WindMove(window, &colorWindowRect);
|
||||
|
|
@ -244,14 +244,14 @@ CMWreposition(window, newScreenArea, final)
|
|||
*/
|
||||
|
||||
void
|
||||
CMWredisplay(w, rootArea, clipArea)
|
||||
MagWindow *w; /* The window containing the area. */
|
||||
Rect *rootArea; /* Redisplay area in surface coordinates. */
|
||||
Rect *clipArea; /* An area on the screen to clip to. */
|
||||
CMWredisplay(
|
||||
MagWindow *w, /* The window containing the area. */
|
||||
Rect *rootArea, /* Redisplay area in surface coordinates. */
|
||||
Rect *clipArea) /* An area on the screen to clip to. */
|
||||
{
|
||||
CMWclientRec *cr;
|
||||
ColorBar *cb;
|
||||
ColorPump *cp;
|
||||
const ColorBar *cb;
|
||||
const ColorPump *cp;
|
||||
Rect rect, screenR;
|
||||
Point screenP;
|
||||
double values[6], x;
|
||||
|
|
@ -372,9 +372,9 @@ CMWredisplay(w, rootArea, clipArea)
|
|||
*/
|
||||
|
||||
void
|
||||
CMWloadWindow(w, color)
|
||||
MagWindow *w; /* Identifies window to which color is to be bound */
|
||||
int color; /* New color to be bound to this window. */
|
||||
CMWloadWindow(
|
||||
MagWindow *w, /* Identifies window to which color is to be bound */
|
||||
int color) /* New color to be bound to this window. */
|
||||
{
|
||||
CMWclientRec *cr = (CMWclientRec *) w->w_clientData;
|
||||
char caption[40];
|
||||
|
|
@ -407,7 +407,7 @@ CMWloadWindow(w, color)
|
|||
*/
|
||||
|
||||
void
|
||||
CMWinit()
|
||||
CMWinit(void)
|
||||
{
|
||||
CMWclientID = WindAddClient("color", CMWcreate, CMWdelete,
|
||||
CMWredisplay, CMWcommand,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWrgbhsv.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWrgbhsv.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -45,9 +45,13 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
*/
|
||||
|
||||
bool
|
||||
RGBxHSV( r, g, b, h, s, v)
|
||||
double r, g, b;
|
||||
double *h, *s, *v;
|
||||
RGBxHSV(
|
||||
double r,
|
||||
double g,
|
||||
double b,
|
||||
double *h,
|
||||
double *s,
|
||||
double *v)
|
||||
{
|
||||
double max, delta;
|
||||
double mr,mg,mb;
|
||||
|
|
@ -90,10 +94,14 @@ RGBxHSV( r, g, b, h, s, v)
|
|||
#define SETRGB(rr,gg,bb) *r=rr;*g=gg;*b=bb
|
||||
|
||||
void
|
||||
HSVxRGB( h,s,v,r,g,b)
|
||||
double h,s,v;
|
||||
double *r,*g,*b;
|
||||
{
|
||||
HSVxRGB(
|
||||
double h,
|
||||
double s,
|
||||
double v,
|
||||
double *r,
|
||||
double *g,
|
||||
double *b)
|
||||
{
|
||||
double f,m,n,k;
|
||||
int i;
|
||||
double vs,vsf;
|
||||
|
|
@ -125,9 +133,13 @@ double *r,*g,*b;
|
|||
*/
|
||||
|
||||
bool
|
||||
RGBxHSL( r, g, b, h, s, l )
|
||||
double r, g, b;
|
||||
double *h, *s, *l;
|
||||
RGBxHSL(
|
||||
double r,
|
||||
double g,
|
||||
double b,
|
||||
double *h,
|
||||
double *s,
|
||||
double *l)
|
||||
{
|
||||
double min, max;
|
||||
double delta, mr, mg, mb;
|
||||
|
|
@ -184,9 +196,13 @@ RGBxHSL( r, g, b, h, s, l )
|
|||
*/
|
||||
|
||||
void
|
||||
HSLxRGB( h, s, l, r, g, b )
|
||||
double h, s, l;
|
||||
double *r, *g, *b;
|
||||
HSLxRGB(
|
||||
double h,
|
||||
double s,
|
||||
double l,
|
||||
double *r,
|
||||
double *g,
|
||||
double *b)
|
||||
{
|
||||
double min;
|
||||
double v;
|
||||
|
|
@ -235,9 +251,11 @@ HSLxRGB( h, s, l, r, g, b )
|
|||
*/
|
||||
|
||||
void
|
||||
Correct_chromaticity(x, y, wx, wy)
|
||||
double *x,*y;
|
||||
double wx,wy;
|
||||
Correct_chromaticity(
|
||||
double *x,
|
||||
double *y,
|
||||
double wx,
|
||||
double wy)
|
||||
{
|
||||
double oldx,oldy;
|
||||
double slope;
|
||||
|
|
@ -261,9 +279,13 @@ Correct_chromaticity(x, y, wx, wy)
|
|||
*/
|
||||
|
||||
void
|
||||
xyz_to_mrgb(x, y, z, mr, mg, mb)
|
||||
double x, y, z;
|
||||
double *mr, *mg, *mb;
|
||||
xyz_to_mrgb(
|
||||
double x,
|
||||
double y,
|
||||
double z,
|
||||
double *mr,
|
||||
double *mg,
|
||||
double *mb)
|
||||
{
|
||||
*mr = 2.4513*x - 1.2249*y - 0.3237*z;
|
||||
*mg = -1.4746*x + 2.5052*y + 0.0596*z;
|
||||
|
|
@ -281,8 +303,10 @@ xyz_to_mrgb(x, y, z, mr, mg, mb)
|
|||
*/
|
||||
|
||||
void
|
||||
Make_mRGB_Nice(mR,mG,mB)
|
||||
double *mR,*mG,*mB;
|
||||
Make_mRGB_Nice(
|
||||
double *mR,
|
||||
double *mG,
|
||||
double *mB)
|
||||
{
|
||||
double min,max;
|
||||
double mr, mg, mb;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWundo.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWundo.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -35,12 +35,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
*/
|
||||
UndoType cmwUndoClientID;
|
||||
|
||||
/*
|
||||
* Functions to play events forward/backward.
|
||||
*/
|
||||
void cmwUndoForw(), cmwUndoBack();
|
||||
void cmwUndoStart(), cmwUndoDone();
|
||||
|
||||
/*
|
||||
* A single undo event for the
|
||||
* color map module.
|
||||
|
|
@ -58,6 +52,14 @@ void cmwUndoStart(), cmwUndoDone();
|
|||
*/
|
||||
bool cmwColorsChanged[256];
|
||||
|
||||
/*
|
||||
* Functions to play events forward/backward.
|
||||
*/
|
||||
void cmwUndoForw(colorUE *up);
|
||||
void cmwUndoBack(colorUE *up);
|
||||
void cmwUndoStart(void);
|
||||
void cmwUndoDone(void);
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -77,7 +79,7 @@ bool cmwColorsChanged[256];
|
|||
*/
|
||||
|
||||
void
|
||||
CMWundoInit()
|
||||
CMWundoInit(void)
|
||||
{
|
||||
cmwUndoClientID = UndoAddClient(cmwUndoStart, cmwUndoDone, NULL, NULL,
|
||||
cmwUndoForw, cmwUndoBack, "color map");
|
||||
|
|
@ -102,16 +104,16 @@ CMWundoInit()
|
|||
*/
|
||||
|
||||
void
|
||||
cmwUndoForw(up)
|
||||
colorUE *up;
|
||||
cmwUndoForw(
|
||||
colorUE *up)
|
||||
{
|
||||
(void) GrPutColor(up->cue_color, up->new_r, up->new_g, up->new_b);
|
||||
cmwColorsChanged[up->cue_color] = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
cmwUndoBack(up)
|
||||
colorUE *up;
|
||||
cmwUndoBack(
|
||||
colorUE *up)
|
||||
{
|
||||
(void) GrPutColor(up->cue_color, up->old_r, up->old_g, up->old_b);
|
||||
cmwColorsChanged[up->cue_color] = TRUE;
|
||||
|
|
@ -134,10 +136,14 @@ cmwUndoBack(up)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwUndoColor(color, oldr, oldg, oldb, newr, newg, newb)
|
||||
int color;
|
||||
int oldr, oldg, oldb;
|
||||
int newr, newg, newb;
|
||||
cmwUndoColor(
|
||||
int color,
|
||||
int oldr,
|
||||
int oldg,
|
||||
int oldb,
|
||||
int newr,
|
||||
int newg,
|
||||
int newb)
|
||||
{
|
||||
colorUE *up;
|
||||
|
||||
|
|
@ -171,7 +177,7 @@ cmwUndoColor(color, oldr, oldg, oldb, newr, newg, newb)
|
|||
*/
|
||||
|
||||
void
|
||||
cmwUndoStart()
|
||||
cmwUndoStart(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -198,13 +204,13 @@ cmwUndoStart()
|
|||
*/
|
||||
|
||||
void
|
||||
cmwUndoDone()
|
||||
cmwUndoDone(void)
|
||||
{
|
||||
int i;
|
||||
extern int cmwRedisplayFunc();
|
||||
extern int cmwRedisplayFunc(MagWindow *w, int color);
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
if (cmwColorsChanged[i])
|
||||
(void) WindSearch(CMWclientID, (ClientData) NULL, (Rect *) NULL,
|
||||
cmwRedisplayFunc, (ClientData) i);
|
||||
cmwRedisplayFunc, INT2CD(i));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/cmwind/cmwind.h,v 1.2 2009/09/10 20:32:51 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _CMWIND_H
|
||||
#define _CMWIND_H
|
||||
#ifndef _MAGIC__CMWIND__CMWIND_H
|
||||
#define _MAGIC__CMWIND__CMWIND_H
|
||||
|
||||
#include "windows/windows.h"
|
||||
#include "textio/txcommands.h"
|
||||
|
|
@ -69,16 +69,16 @@ typedef struct
|
|||
extern void CMWloadWindow(MagWindow *, int);
|
||||
extern void CMWcommand(MagWindow *, TxCommand *);
|
||||
|
||||
extern Rect colorWindowRect;
|
||||
extern const Rect colorWindowRect;
|
||||
extern WindClient CMWclientID;
|
||||
extern ColorBar colorBars[];
|
||||
extern ColorPump colorPumps[];
|
||||
extern Rect cmwCurrentColorArea;
|
||||
extern const ColorBar colorBars[];
|
||||
extern const ColorPump colorPumps[];
|
||||
extern const Rect cmwCurrentColorArea;
|
||||
extern void cmwUndoColor(int, int, int, int, int, int, int);
|
||||
extern bool CMWCheckWritten(void);
|
||||
|
||||
/* C99 compat */
|
||||
extern void CMWinit();
|
||||
extern void CMWinit(void);
|
||||
|
||||
|
||||
#endif /* _CMWIND_H */
|
||||
#endif /* _MAGIC__CMWIND__CMWIND_H */
|
||||
|
|
|
|||
127
commands/CmdAB.c
127
commands/CmdAB.c
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdAB.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdAB.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -50,7 +50,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
* CmdAddPath --
|
||||
*
|
||||
* Implement the "addpath" command: append to the global cell search path.
|
||||
* (Usage superceded by extended "path" command; retained for compatibility)
|
||||
* (Usage superseded by extended "path" command; retained for compatibility)
|
||||
*
|
||||
* Usage:
|
||||
* addpath path
|
||||
|
|
@ -70,9 +70,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
/*ARGSUSED*/
|
||||
|
||||
void
|
||||
CmdAddPath( w, cmd )
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdAddPath(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
if (cmd->tx_argc != 2) {
|
||||
TxError("Usage: %s appended_search_path\n", cmd->tx_argv[0]);
|
||||
|
|
@ -81,6 +81,70 @@ CmdAddPath( w, cmd )
|
|||
PaAppend(&Path, cmd->tx_argv[1]);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* CmdArchive --
|
||||
*
|
||||
* Save an entire database to a "crash recovery"-type archive file, or
|
||||
* load a database from a "crash recovery"-type archive file. Option
|
||||
* "writeall" writes everything, including read-only PDK cells, while
|
||||
* "readref" does not dereference and will prefer files found in the
|
||||
* search path over content in the archive.
|
||||
*
|
||||
*
|
||||
* Usage:
|
||||
* archive write|writeall|read|readref file
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes a single file with the contents of the entire database,
|
||||
* or loads the database with multiple cells from the file.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
CmdArchive(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int option = -1;
|
||||
char *filename = NULL;
|
||||
static const char * const cmdArchiveOpt[] = {"write", "writeall",
|
||||
"read", "readref", 0};
|
||||
|
||||
if (cmd->tx_argc != 3)
|
||||
TxError("Usage: %s write|writeall|read|readref filename\n", cmd->tx_argv[0]);
|
||||
else
|
||||
{
|
||||
option = Lookup(cmd->tx_argv[1], cmdArchiveOpt);
|
||||
if (option < 0)
|
||||
{
|
||||
TxError("Usage: %s write|writeall|read|readref filename\n", cmd->tx_argv[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
filename = cmd->tx_argv[2];
|
||||
|
||||
switch(option) {
|
||||
case 0: /* write */
|
||||
DBWriteBackup(filename, TRUE, FALSE);
|
||||
break;
|
||||
case 1: /* writeall */
|
||||
DBWriteBackup(filename, TRUE, TRUE);
|
||||
break;
|
||||
case 2: /* read */
|
||||
DBReadBackup(filename, TRUE, TRUE);
|
||||
break;
|
||||
case 3: /* readref */
|
||||
DBReadBackup(filename, TRUE, FALSE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Linked-list structure for returning information about arrayed cells */
|
||||
|
||||
|
|
@ -130,11 +194,11 @@ typedef struct LA1
|
|||
#define ARRAY_DEFAULT 6
|
||||
|
||||
void
|
||||
CmdArray(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdArray(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
static char *cmdArrayOption[] = {
|
||||
static const char * const cmdArrayOption[] = {
|
||||
"count [[xlo] xhi [ylo] yhi] array subcells",
|
||||
"width [value] set or return array x-spacing",
|
||||
"height [value] set or return array y-spacing",
|
||||
|
|
@ -144,7 +208,7 @@ CmdArray(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
char **msg;
|
||||
const char * const *msg;
|
||||
int option, locargc, argstart;
|
||||
bool doList = FALSE;
|
||||
ArrayInfo a;
|
||||
|
|
@ -156,7 +220,7 @@ CmdArray(w, cmd)
|
|||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
|
||||
extern int selGetArrayFunc();
|
||||
extern int selGetArrayFunc(CellUse *selUse, CellUse *use, Transform *trans, LinkedArray **arg);
|
||||
|
||||
locargc = cmd->tx_argc;
|
||||
argstart = 1;
|
||||
|
|
@ -466,11 +530,15 @@ badusage:
|
|||
}
|
||||
|
||||
freelist:
|
||||
la = lahead;
|
||||
while (la != NULL)
|
||||
{
|
||||
freeMagic((char *)la);
|
||||
la = la->ar_next;
|
||||
la = lahead;
|
||||
while (la != NULL)
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, (char *)la);
|
||||
la = la->ar_next;
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -480,11 +548,11 @@ freelist:
|
|||
*/
|
||||
|
||||
int
|
||||
selGetArrayFunc(selUse, use, trans, arg)
|
||||
CellUse *selUse;
|
||||
CellUse *use;
|
||||
Transform *trans;
|
||||
LinkedArray **arg;
|
||||
selGetArrayFunc(
|
||||
CellUse *selUse,
|
||||
CellUse *use,
|
||||
Transform *trans,
|
||||
LinkedArray **arg)
|
||||
{
|
||||
/* Check "use" for array information and pass this to arrayInfo */
|
||||
|
||||
|
|
@ -593,11 +661,11 @@ selGetArrayFunc(selUse, use, trans, arg)
|
|||
#define BOX_DEFAULT 13
|
||||
|
||||
void
|
||||
CmdBox(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdBox(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
static char *cmdBoxOption[] = {
|
||||
static const char * const cmdBoxOption[] = {
|
||||
"width [value] set or return box width",
|
||||
"height [value] set or return box height",
|
||||
"size [width height] set or return box size",
|
||||
|
|
@ -626,7 +694,7 @@ CmdBox(w, cmd)
|
|||
bool needBox = TRUE; /* require that box be defined */
|
||||
bool refEdit = FALSE; /* referenced to edit cell coordinates */
|
||||
bool cursorRef = FALSE; /* reference position is the cursor */
|
||||
char **msg;
|
||||
const char * const *msg;
|
||||
|
||||
argc = cmd->tx_argc;
|
||||
if (argc > 7) goto badusage;
|
||||
|
|
@ -797,6 +865,13 @@ CmdBox(w, cmd)
|
|||
ToolMoveCorner(tcorner, &cmd->tx_p, TRUE, rootBoxDef);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Recast command as "box values" for logging purposes */
|
||||
ToolGetBox(&rootBoxDef, &rootBox);
|
||||
sprintf(cmd->tx_argstring, "box values %di %di %di %di",
|
||||
rootBox.r_xbot, rootBox.r_ybot,
|
||||
rootBox.r_xtop, rootBox.r_ytop);
|
||||
TxRebuildCommand(cmd);
|
||||
return;
|
||||
}
|
||||
else if (DBWSnapToGrid != DBW_SNAP_USER)
|
||||
|
|
@ -1148,7 +1223,7 @@ CmdBox(w, cmd)
|
|||
boxptr->r_xbot, boxptr->r_ybot,
|
||||
boxptr->r_xtop, boxptr->r_ytop);
|
||||
if (area > 0)
|
||||
TxPrintf(" %-10lld", area);
|
||||
TxPrintf(" %-10"DLONG_PREFIX"d", area);
|
||||
TxPrintf("\n");
|
||||
break;
|
||||
|
||||
|
|
|
|||
|
|
@ -48,9 +48,9 @@
|
|||
*/
|
||||
|
||||
void
|
||||
CmdAutoExtToSim(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdAutoExtToSim(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
|
@ -83,9 +83,9 @@ CmdAutoExtToSim(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdAutoExtToSpice(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdAutoExtToSpice(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
|
@ -119,9 +119,9 @@ CmdAutoExtToSpice(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdAutoRoute(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdAutoRoute(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
|
@ -154,9 +154,9 @@ CmdAutoRoute(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdAutoPlot(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdAutoPlot(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
|
@ -189,9 +189,9 @@ CmdAutoPlot(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdAutoLef(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdAutoLef(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
|
|
|||
968
commands/CmdCD.c
968
commands/CmdCD.c
File diff suppressed because it is too large
Load Diff
269
commands/CmdE.c
269
commands/CmdE.c
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdE.c,v 1.4 2010/06/17 14:38:33 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdE.c,v 1.4 2010/06/17 14:38:33 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -42,6 +42,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "drc/drc.h"
|
||||
#include "textio/txcommands.h"
|
||||
#include "extract/extract.h"
|
||||
#include "extract/extractInt.h"
|
||||
#include "select/select.h"
|
||||
|
||||
/* C99 compat */
|
||||
|
|
@ -55,10 +56,12 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
*
|
||||
* Implement the "edit" command.
|
||||
* Use the cell that is currently selected as the edit cell. If more than
|
||||
* one cell is selected, use the point to choose between them.
|
||||
* one cell is selected, use the point to choose between them. If the
|
||||
* optional argument "<instname>" is provided, then edit the specified
|
||||
* instance (if it exists in the current layout window).
|
||||
*
|
||||
* Usage:
|
||||
* edit
|
||||
* edit [<instname>]
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -76,18 +79,29 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
static bool cmdFoundNewEdit;
|
||||
|
||||
void
|
||||
CmdEdit(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdEdit(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
Rect area, pointArea;
|
||||
CellUse *usave;
|
||||
CellUse *usave, *use = NULL;
|
||||
CellDef *csave;
|
||||
int cmdEditRedisplayFunc(); /* Forward declaration. */
|
||||
int cmdEditEnumFunc(); /* Forward declaration. */
|
||||
int cmdEditRedisplayFunc(MagWindow *w, Rect *area); /* Forward declaration. */
|
||||
int cmdEditEnumFunc(CellUse *selUse, CellUse *use, Transform *transform, Rect *area); /* Forward declaration. */
|
||||
bool noCurrentUse = FALSE;
|
||||
|
||||
if (cmd->tx_argc > 1)
|
||||
if ((w != NULL) && (cmd->tx_argc == 2))
|
||||
{
|
||||
CellUse *rootUse;
|
||||
SearchContext scx;
|
||||
|
||||
rootUse = (CellUse *)w->w_surfaceID;
|
||||
bzero(&scx, sizeof(SearchContext));
|
||||
DBTreeFindUse(cmd->tx_argv[1], rootUse, &scx);
|
||||
use = scx.scx_use;
|
||||
}
|
||||
|
||||
if ((use == NULL) && (cmd->tx_argc > 1))
|
||||
{
|
||||
TxError("Usage: edit\nMaybe you want the \"load\" command\n");
|
||||
return;
|
||||
|
|
@ -120,10 +134,18 @@ CmdEdit(w, cmd)
|
|||
cmdFoundNewEdit = FALSE;
|
||||
csave = EditRootDef;
|
||||
usave = EditCellUse;
|
||||
EditCellUse = NULL;
|
||||
|
||||
(void) SelEnumCells(FALSE, (bool *) NULL, (SearchContext *) NULL,
|
||||
cmdEditEnumFunc, (ClientData) &pointArea);
|
||||
if (use == NULL)
|
||||
{
|
||||
EditCellUse = NULL;
|
||||
SelEnumCells(FALSE, (bool *) NULL, (SearchContext *) NULL,
|
||||
cmdEditEnumFunc, (ClientData) &pointArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditCellUse = use;
|
||||
cmdFoundNewEdit = TRUE;
|
||||
}
|
||||
|
||||
if (EditCellUse == (CellUse *)NULL)
|
||||
{
|
||||
|
|
@ -133,11 +155,7 @@ CmdEdit(w, cmd)
|
|||
return;
|
||||
}
|
||||
else if (!(EditCellUse->cu_def->cd_flags & CDAVAILABLE))
|
||||
{
|
||||
bool dereference = (EditCellUse->cu_def->cd_flags & CDDEREFERENCE) ?
|
||||
TRUE : FALSE;
|
||||
DBCellRead(EditCellUse->cu_def, (char *)NULL, TRUE, dereference, NULL);
|
||||
}
|
||||
DBCellRead(EditCellUse->cu_def, TRUE, TRUE, NULL);
|
||||
|
||||
if (EditCellUse->cu_def->cd_flags & CDNOEDIT)
|
||||
{
|
||||
|
|
@ -161,6 +179,14 @@ CmdEdit(w, cmd)
|
|||
GeoTransRect(&EditToRootTransform, &(EditCellUse->cu_def->cd_bbox), &area);
|
||||
(void) WindSearch(DBWclientID, (ClientData) NULL,
|
||||
(Rect *) NULL, cmdEditRedisplayFunc, (ClientData) &area);
|
||||
|
||||
if ((cmd->tx_argc == 1) && cmdFoundNewEdit)
|
||||
{
|
||||
/* Recast the command with the instance name for logging */
|
||||
sprintf(cmd->tx_argstring, "edit %s", EditCellUse->cu_id);
|
||||
TxRebuildCommand(cmd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Search function to handle redisplays for CmdEdit: it checks to
|
||||
|
|
@ -171,11 +197,11 @@ CmdEdit(w, cmd)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdEditRedisplayFunc(w, area)
|
||||
MagWindow *w; /* Window containing edit cell. */
|
||||
Rect *area; /* Area to be redisplayed. */
|
||||
cmdEditRedisplayFunc(
|
||||
MagWindow *w, /* Window containing edit cell. */
|
||||
Rect *area) /* Area to be redisplayed. */
|
||||
{
|
||||
static Rect origin = {-1, -1, 1, 1};
|
||||
static const Rect origin = {{-1, -1}, {1, 1}};
|
||||
Rect tmp;
|
||||
DBWclientRec *crec = (DBWclientRec *) w->w_clientData;
|
||||
|
||||
|
|
@ -200,13 +226,13 @@ cmdEditRedisplayFunc(w, area)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdEditEnumFunc(selUse, use, transform, area)
|
||||
CellUse *selUse; /* Use from selection (not used). */
|
||||
CellUse *use; /* Use from layout that corresponds to
|
||||
cmdEditEnumFunc(
|
||||
CellUse *selUse, /* Use from selection (not used). */
|
||||
CellUse *use, /* Use from layout that corresponds to
|
||||
* selUse (could be an array!).
|
||||
*/
|
||||
Transform *transform; /* Transform from use->cu_def to root coords. */
|
||||
Rect *area; /* We're looking for a use containing this
|
||||
Transform *transform, /* Transform from use->cu_def to root coords. */
|
||||
Rect *area) /* We're looking for a use containing this
|
||||
* area, in root coords.
|
||||
*/
|
||||
{
|
||||
|
|
@ -279,20 +305,20 @@ cmdEditEnumFunc(selUse, use, transform, area)
|
|||
#define OPTION_FLAGS 3
|
||||
|
||||
void
|
||||
CmdElement(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdElement(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
|
||||
int option, type;
|
||||
char **msg;
|
||||
const char * const *msg;
|
||||
Rect area;
|
||||
int style;
|
||||
CellDef *def;
|
||||
CellUse *use;
|
||||
bool getopt;
|
||||
|
||||
static char *cmdElementOption[] = {
|
||||
static const char * const cmdElementOption[] = {
|
||||
"add create a new element",
|
||||
"delete delete an existing element",
|
||||
"configure configure or query an existing element",
|
||||
|
|
@ -302,14 +328,14 @@ CmdElement(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
static char *cmdElementType[] = {
|
||||
static const char * const cmdElementType[] = {
|
||||
"line name style x1 y1 x2 y2",
|
||||
"rectangle name style llx lly urx ury",
|
||||
"text name style cx cy label",
|
||||
NULL
|
||||
};
|
||||
|
||||
static char *cmdConfigureType[] = {
|
||||
static const char * const cmdConfigureType[] = {
|
||||
"text get (or) replace <string>",
|
||||
"style get (or) add <style> (or) remove <style>",
|
||||
"position get (or) <point> (or) <rect>",
|
||||
|
|
@ -580,7 +606,7 @@ badusage:
|
|||
* EditCellUse->cu_def.
|
||||
*
|
||||
* Usage:
|
||||
* erase [layers | cursor]
|
||||
* erase [layers | cursor | pick x y]
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -601,25 +627,34 @@ static CellUse *cmdEraseCells[MAXCELLS];
|
|||
static int cmdEraseCount;
|
||||
|
||||
void
|
||||
CmdErase(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdErase(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
Rect editRect, areaReturn;
|
||||
TileTypeBitMask mask, errorLayersForErasure, activeLayersForErasure;
|
||||
extern int cmdEraseCellsFunc();
|
||||
extern int cmdEraseCellsFunc(SearchContext *scx, ClientData cdarg);
|
||||
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
if (w == (MagWindow *) NULL) return;
|
||||
|
||||
if ((cmd->tx_argc == 4) && !strcmp(cmd->tx_argv[1], "pick"))
|
||||
{
|
||||
Point editPoint, rootPoint;
|
||||
editPoint.p_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
|
||||
editPoint.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
|
||||
GeoTransPoint(&EditToRootTransform, &editPoint, &rootPoint);
|
||||
CmdPaintEraseButton(w, &rootPoint, FALSE, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd->tx_argc > 2)
|
||||
{
|
||||
TxError("Usage: %s [<layers> | cursor]\n", cmd->tx_argv[0]);
|
||||
TxError("Usage: %s [<layers> | cursor | pick x y]\n", cmd->tx_argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ToolGetEditBox(&editRect)) return;
|
||||
|
||||
if (EditCellUse == NULL)
|
||||
{
|
||||
TxError("No cell def being edited!\n");
|
||||
|
|
@ -636,7 +671,16 @@ CmdErase(w, cmd)
|
|||
(void) CmdParseLayers("*,label", &mask);
|
||||
else if (!strncmp(cmd->tx_argv[1], "cursor", 6))
|
||||
{
|
||||
CmdPaintEraseButton(w, &cmd->tx_p, FALSE);
|
||||
Point editPoint, rootPoint;
|
||||
|
||||
CmdPaintEraseButton(w, &cmd->tx_p, FALSE, TRUE);
|
||||
|
||||
/* Recast the command as "erase pick x y" for logging purposes */
|
||||
CmdGetRootPoint(&rootPoint, (Rect *)NULL);
|
||||
GeoTransPoint(&RootToEditTransform, &rootPoint, &editPoint);
|
||||
sprintf(cmd->tx_argstring, "erase pick %di %di", editPoint.p_x,
|
||||
editPoint.p_y);
|
||||
TxRebuildCommand(cmd);
|
||||
return;
|
||||
}
|
||||
else if (!CmdParseLayers(cmd->tx_argv[1], &mask))
|
||||
|
|
@ -715,9 +759,9 @@ CmdErase(w, cmd)
|
|||
}
|
||||
|
||||
int
|
||||
cmdEraseCellsFunc(scx, cdarg)
|
||||
SearchContext *scx; /* Indicates cell found. */
|
||||
ClientData cdarg; /* Not used. */
|
||||
cmdEraseCellsFunc(
|
||||
SearchContext *scx, /* Indicates cell found. */
|
||||
ClientData cdarg) /* Not used. */
|
||||
{
|
||||
/* All this procedure does is to remember cells that are
|
||||
* found, up to MAXCELLS of them.
|
||||
|
|
@ -753,15 +797,15 @@ ClientData cdarg; /* Not used. */
|
|||
*/
|
||||
|
||||
void
|
||||
CmdExpand(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdExpand(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int windowMask, boxMask, d;
|
||||
Rect rootRect;
|
||||
CellUse *rootBoxUse;
|
||||
CellDef *rootBoxDef;
|
||||
int cmdExpandFunc(); /* Forward reference. */
|
||||
int cmdExpandFunc(CellUse *use, int windowMask); /* Forward reference. */
|
||||
|
||||
if (cmd->tx_argc > 2 || (cmd->tx_argc == 2
|
||||
&& (strncmp(cmd->tx_argv[1], "toggle", strlen(cmd->tx_argv[1])) != 0)))
|
||||
|
|
@ -825,9 +869,9 @@ CmdExpand(w, cmd)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdExpandFunc(use, windowMask)
|
||||
CellUse *use; /* Use that was just expanded. */
|
||||
int windowMask; /* Window where it was expanded. */
|
||||
cmdExpandFunc(
|
||||
CellUse *use, /* Use that was just expanded. */
|
||||
int windowMask) /* Window where it was expanded. */
|
||||
{
|
||||
if (use->cu_parent == NULL) return 0;
|
||||
DBWAreaChanged(use->cu_parent, &use->cu_bbox, windowMask,
|
||||
|
|
@ -860,14 +904,17 @@ cmdExpandFunc(use, windowMask)
|
|||
#define EXTALL 0
|
||||
#define EXTCELL 1
|
||||
#define EXTDO 2
|
||||
#define EXTHELP 3
|
||||
#define EXTLENGTH 4
|
||||
#define EXTNO 5
|
||||
#define EXTPARENTS 6
|
||||
#define EXTSHOWPARENTS 7
|
||||
#define EXTSTYLE 8
|
||||
#define EXTUNIQUE 9
|
||||
#define EXTWARN 10
|
||||
#define EXTHALO 3
|
||||
#define EXTHELP 4
|
||||
#define EXTLENGTH 5
|
||||
#define EXTNO 6
|
||||
#define EXTPARENTS 7
|
||||
#define EXTPATH 8
|
||||
#define EXTSHOWPARENTS 9
|
||||
#define EXTSTEPSIZE 10
|
||||
#define EXTSTYLE 11
|
||||
#define EXTUNIQUE 12
|
||||
#define EXTWARN 13
|
||||
|
||||
#define WARNALL 0
|
||||
#define WARNDUP 1
|
||||
|
|
@ -894,12 +941,14 @@ cmdExpandFunc(use, windowMask)
|
|||
#define UNIQNOTOPPORTS 3
|
||||
|
||||
void
|
||||
CmdExtract(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdExtract(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
char **msg, *namep, *arg;
|
||||
const char * const *msg;
|
||||
char *namep, *arg;
|
||||
int option, warn, len, n, all;
|
||||
int dist;
|
||||
bool no;
|
||||
CellUse *selectedUse;
|
||||
CellDef *selectedDef;
|
||||
|
|
@ -909,7 +958,7 @@ CmdExtract(w, cmd)
|
|||
int argc = cmd->tx_argc;
|
||||
char **argv = cmd->tx_argv;
|
||||
|
||||
static char *cmdExtWarn[] =
|
||||
static const char * const cmdExtWarn[] =
|
||||
{
|
||||
"all enable all warnings",
|
||||
"dup warn when different nodes have the same name",
|
||||
|
|
@ -917,7 +966,7 @@ CmdExtract(w, cmd)
|
|||
"labels warn when subcell nodes are unlabelled",
|
||||
NULL
|
||||
};
|
||||
static char *cmdExtOption[] =
|
||||
static const char * const cmdExtOption[] =
|
||||
{
|
||||
"adjust compensate R and C hierarchically",
|
||||
"all all options",
|
||||
|
|
@ -930,7 +979,7 @@ CmdExtract(w, cmd)
|
|||
"aliases output all net name aliases",
|
||||
NULL
|
||||
};
|
||||
static char *cmdExtLength[] =
|
||||
static const char * const cmdExtLength[] =
|
||||
{
|
||||
"clear clear the driver and receiver tables",
|
||||
"driver termName(s) identify a driving (output) terminal",
|
||||
|
|
@ -940,7 +989,7 @@ CmdExtract(w, cmd)
|
|||
|
||||
/* These must match definitions EXT_UNIQ_* in extract/extract.h: */
|
||||
|
||||
static char *cmdExtUniq[] =
|
||||
static const char * const cmdExtUniq[] =
|
||||
{
|
||||
"all extract matching labels as unique nodes",
|
||||
"# extract tagged labels as unique nodes",
|
||||
|
|
@ -948,16 +997,19 @@ CmdExtract(w, cmd)
|
|||
"notopports ignore top-level ports when making labels unique",
|
||||
NULL
|
||||
};
|
||||
static char *cmdExtCmd[] =
|
||||
static const char * const cmdExtCmd[] =
|
||||
{
|
||||
"all extract root cell and all its children",
|
||||
"cell name extract selected cell into file \"name\"",
|
||||
"do [option] enable extractor option",
|
||||
"halo [value] print or set the sidewall halo distance",
|
||||
"help print this help information",
|
||||
"length [option] control pathlength extraction information",
|
||||
"no [option] disable extractor option",
|
||||
"parents extract selected cell and all its parents",
|
||||
"path [path] if set, extract into the indicated path",
|
||||
"showparents show all parents of selected cell",
|
||||
"stepsize [value] print or set the extraction step size",
|
||||
"style [stylename] set current extraction parameter style",
|
||||
"unique [option] generate unique names when different nodes\n\
|
||||
have the same name",
|
||||
|
|
@ -1060,6 +1112,66 @@ CmdExtract(w, cmd)
|
|||
ExtractOneCell(selectedUse->cu_def, namep, FALSE);
|
||||
return;
|
||||
|
||||
case EXTHALO:
|
||||
if (ExtCurStyle == NULL)
|
||||
{
|
||||
TxError("No extraction style set.\n");
|
||||
return;
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewIntObj(ExtCurStyle->exts_sideCoupleHalo);
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("Side overlap halo is %d\n", ExtCurStyle->exts_sideCoupleHalo);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
else if (argc != 3) goto wrongNumArgs;
|
||||
|
||||
/* argv[2] is a halo distance */
|
||||
dist = cmdParseCoord(w, argv[2], TRUE, TRUE);
|
||||
if (dist < 0)
|
||||
{
|
||||
TxError("Bad halo distance. Halo must be non-negative.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
ExtCurStyle->exts_sideCoupleHalo = dist;
|
||||
break;
|
||||
|
||||
case EXTSTEPSIZE:
|
||||
if (ExtCurStyle == NULL)
|
||||
{
|
||||
TxError("No extraction style set.\n");
|
||||
return;
|
||||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewIntObj(ExtCurStyle->exts_stepSize);
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("Extraction step size is %d\n", ExtCurStyle->exts_stepSize);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
else if (argc != 3) goto wrongNumArgs;
|
||||
|
||||
/* argv[2] is a step size */
|
||||
dist = cmdParseCoord(w, argv[2], TRUE, TRUE);
|
||||
if (dist <= 0)
|
||||
{
|
||||
TxError("Bad step size. Step size must be strictly positive.");
|
||||
return;
|
||||
}
|
||||
else
|
||||
ExtCurStyle->exts_stepSize = dist;
|
||||
break;
|
||||
|
||||
case EXTPARENTS:
|
||||
selectedUse = CmdGetSelectedCell((Transform *) NULL);
|
||||
if (selectedUse == NULL)
|
||||
|
|
@ -1083,6 +1195,13 @@ CmdExtract(w, cmd)
|
|||
ExtShowParents(selectedUse);
|
||||
return;
|
||||
|
||||
case EXTPATH:
|
||||
if (argc == 2)
|
||||
ExtPrintPath(dolist);
|
||||
else
|
||||
ExtSetPath(argv[2]);
|
||||
return;
|
||||
|
||||
case EXTSTYLE:
|
||||
if (argc == 2)
|
||||
ExtPrintStyle(dolist, doforall, !doforall);
|
||||
|
|
@ -1158,7 +1277,6 @@ CmdExtract(w, cmd)
|
|||
TxPrintf("%s capacitance\n", OPTSET(EXT_DOCAPACITANCE));
|
||||
TxPrintf("%s coupling\n", OPTSET(EXT_DOCOUPLING));
|
||||
TxPrintf("%s length\n", OPTSET(EXT_DOLENGTH));
|
||||
TxPrintf("%s local\n", OPTSET(EXT_DOLOCAL));
|
||||
TxPrintf("%s resistance\n", OPTSET(EXT_DORESISTANCE));
|
||||
TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK));
|
||||
TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES));
|
||||
|
|
@ -1188,10 +1306,19 @@ CmdExtract(w, cmd)
|
|||
case DOCAPACITANCE: option = EXT_DOCAPACITANCE; break;
|
||||
case DOCOUPLING: option = EXT_DOCOUPLING; break;
|
||||
case DOLENGTH: option = EXT_DOLENGTH; break;
|
||||
case DOLOCAL: option = EXT_DOLOCAL; break;
|
||||
case DORESISTANCE: option = EXT_DORESISTANCE; break;
|
||||
case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
|
||||
case DOALIASES: option = EXT_DOALIASES; break;
|
||||
case DOLOCAL:
|
||||
/* "extract do local" and "extract no local" are kept for
|
||||
* backwards compatibility, but now effectively implement
|
||||
* "extract path ." and "extract path none", respectively.
|
||||
*/
|
||||
if (no)
|
||||
StrDup(&ExtLocalPath, NULL);
|
||||
else
|
||||
StrDup(&ExtLocalPath, ".");
|
||||
return;
|
||||
}
|
||||
if (no) ExtOptions &= ~option;
|
||||
else ExtOptions |= option;
|
||||
|
|
|
|||
374
commands/CmdFI.c
374
commands/CmdFI.c
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdFI.c,v 1.4 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdFI.c,v 1.4 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -100,17 +100,19 @@ struct cmdFPArg
|
|||
*/
|
||||
|
||||
int
|
||||
feedPolyFunc(tile, arg)
|
||||
Tile *tile;
|
||||
struct cmdFPArg *arg;
|
||||
feedPolyFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
struct cmdFPArg *arg)
|
||||
{
|
||||
Rect area;
|
||||
TiToRect(tile, &area);
|
||||
|
||||
/* (NOTE: Preserve information about the geometry of a diagonal tile) */
|
||||
DBWFeedbackAdd(&area, arg->text, arg->def, FEEDMAGNIFY,
|
||||
arg->style |
|
||||
(TiGetTypeExact(tile) & (TT_DIAGONAL | TT_DIRECTION | TT_SIDE)));
|
||||
/* (preserve information about the geometry of a diagonal tile) */
|
||||
((TiGetTypeExact(tile) | dinfo) &
|
||||
(TT_DIAGONAL | TT_DIRECTION | TT_SIDE)));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -146,11 +148,11 @@ feedPolyFunc(tile, arg)
|
|||
#define WHY 6
|
||||
|
||||
void
|
||||
CmdFeedback(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdFeedback(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
static char *cmdFeedbackOptions[] =
|
||||
static const char * const cmdFeedbackOptions[] =
|
||||
{
|
||||
"add text [style] [points...] create new feedback area over box",
|
||||
"clear [substring] clear all or selected feedback info",
|
||||
|
|
@ -161,11 +163,11 @@ CmdFeedback(w, cmd)
|
|||
"why print all feedback messages under box",
|
||||
NULL
|
||||
};
|
||||
static char *cmdFeedbackStyleNames[] =
|
||||
static const char * const cmdFeedbackStyleNames[] =
|
||||
{
|
||||
"dotted", "medium", "outline", "pale", "solid", NULL
|
||||
};
|
||||
static int cmdFeedbackStyles[] =
|
||||
static const int cmdFeedbackStyles[] =
|
||||
{
|
||||
STYLE_DOTTEDHIGHLIGHTS, STYLE_MEDIUMHIGHLIGHTS,
|
||||
STYLE_OUTLINEHIGHLIGHTS, STYLE_PALEHIGHLIGHTS,
|
||||
|
|
@ -176,7 +178,8 @@ CmdFeedback(w, cmd)
|
|||
*/
|
||||
int option, i, style, pstart;
|
||||
Rect box, r;
|
||||
char *text, **msg;
|
||||
char *text;
|
||||
const char * const *msg;
|
||||
CellDef *rootDef;
|
||||
HashTable table;
|
||||
HashEntry *h;
|
||||
|
|
@ -505,14 +508,16 @@ Rect cmdFillRootBox; /* Root coords of box. */
|
|||
struct cmdFillArea *cmdFillList; /* List of areas to fill. */
|
||||
|
||||
void
|
||||
CmdFill(w, cmd)
|
||||
MagWindow *w; /* Window in which command was invoked. */
|
||||
TxCommand *cmd; /* Describes the command that was invoked. */
|
||||
CmdFill(
|
||||
MagWindow *w, /* Window in which command was invoked. */
|
||||
TxCommand *cmd) /* Describes the command that was invoked. */
|
||||
{
|
||||
TileTypeBitMask maskBits;
|
||||
Rect editBox;
|
||||
SearchContext scx;
|
||||
extern int cmdFillFunc();
|
||||
|
||||
/* Forward declaration */
|
||||
extern int cmdFillFunc(Tile *tile, TileType dinfo, TreeContext *cxp);
|
||||
|
||||
if (cmd->tx_argc < 2 || cmd->tx_argc > 3)
|
||||
{
|
||||
|
|
@ -580,13 +585,15 @@ CmdFill(w, cmd)
|
|||
/* Now that we've got all the material, scan over the list
|
||||
* painting the material and freeing up the entries on the list.
|
||||
*/
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (cmdFillList != NULL)
|
||||
{
|
||||
DBPaint(EditCellUse->cu_def, &cmdFillList->cfa_area,
|
||||
cmdFillList->cfa_type);
|
||||
freeMagic((char *) cmdFillList);
|
||||
freeMagic1(&mm1, (char *) cmdFillList);
|
||||
cmdFillList = cmdFillList->cfa_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
SelectClear();
|
||||
DBAdjustLabels(EditCellUse->cu_def, &editBox);
|
||||
|
|
@ -600,12 +607,17 @@ CmdFill(w, cmd)
|
|||
* paint here it may mess up the search. Instead, the procedures
|
||||
* save areas on a list. The list is post-processed to paint the
|
||||
* areas once the search is finished.
|
||||
*
|
||||
* Split tile information is unused because there is no obvious
|
||||
* meaning to "filling" from a split tile, although probably reasonable
|
||||
* methods could be worked out.
|
||||
*/
|
||||
|
||||
int
|
||||
cmdFillFunc(tile, cxp)
|
||||
Tile *tile; /* Tile to fill with. */
|
||||
TreeContext *cxp; /* Describes state of search. */
|
||||
cmdFillFunc(
|
||||
Tile *tile, /* Tile to fill with. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
TreeContext *cxp) /* Describes state of search. */
|
||||
{
|
||||
Rect r1, r2;
|
||||
struct cmdFillArea *cfa;
|
||||
|
|
@ -658,9 +670,9 @@ cmdFillFunc(tile, cxp)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdFindBox(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdFindBox(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
CellDef *boxDef;
|
||||
Rect box;
|
||||
|
|
@ -751,11 +763,12 @@ typedef struct _labsearchrec
|
|||
} LabSearchRec;
|
||||
|
||||
|
||||
int cmdFindLabelFunc(rect, name, label, cdarg)
|
||||
Rect *rect;
|
||||
char *name;
|
||||
Label *label;
|
||||
LabSearchRec *cdarg;
|
||||
int
|
||||
cmdFindLabelFunc(
|
||||
Rect *rect,
|
||||
char *name,
|
||||
Label *label,
|
||||
LabSearchRec *cdarg)
|
||||
{
|
||||
if (cdarg->lsr_occur == 0)
|
||||
{
|
||||
|
|
@ -790,9 +803,9 @@ int cmdFindLabelFunc(rect, name, label, cdarg)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdFindLabel(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdFindLabel(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
CellDef *boxDef;
|
||||
CellUse *labUse;
|
||||
|
|
@ -801,7 +814,7 @@ CmdFindLabel(w, cmd)
|
|||
int found, occur, plainargs;
|
||||
bool doglob = FALSE; /* csh-style glob matching (see utils/match.c) */
|
||||
LabSearchRec lsr;
|
||||
int dbListLabels(); /* forward declaration */
|
||||
int dbListLabels(SearchContext *scx, Label *label, TerminalPath *tpath, ClientData cdarg); /* forward declaration */
|
||||
|
||||
plainargs = cmd->tx_argc;
|
||||
if ((plainargs > 2) && !strncmp(cmd->tx_argv[1], "-glob", 5))
|
||||
|
|
@ -839,7 +852,7 @@ CmdFindLabel(w, cmd)
|
|||
return;
|
||||
};
|
||||
|
||||
labname = cmd->tx_argv[1 + (doglob) ? 1 : 0];
|
||||
labname = cmd->tx_argv[1 + ((doglob) ? 1 : 0)];
|
||||
labUse = EditCellUse;
|
||||
if (labUse == NULL) labUse = (CellUse *)w->w_surfaceID;
|
||||
|
||||
|
|
@ -889,11 +902,11 @@ usage:
|
|||
*/
|
||||
|
||||
int
|
||||
dbListLabels(scx, label, tpath, cdarg)
|
||||
SearchContext *scx;
|
||||
Label *label; /* Pointer to label structure */
|
||||
TerminalPath *tpath; /* Full pathname of terminal */
|
||||
ClientData cdarg; /* (unused) */
|
||||
dbListLabels(
|
||||
SearchContext *scx,
|
||||
Label *label, /* Pointer to label structure */
|
||||
TerminalPath *tpath, /* Full pathname of terminal */
|
||||
ClientData cdarg) /* (unused) */
|
||||
{
|
||||
char *n = tpath->tp_next;
|
||||
char c = *n;
|
||||
|
|
@ -934,15 +947,16 @@ dbListLabels(scx, label, tpath, cdarg)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdFlush(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdFlush(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
CellDef *def;
|
||||
int action;
|
||||
static char *actionNames[] = { "no", "yes", 0 };
|
||||
static const char * const actionNames[] = { "no", "yes", 0 };
|
||||
char *prompt;
|
||||
bool dereference = FALSE;
|
||||
bool noprompt = FALSE; /* no interactive confirm when changed */
|
||||
|
||||
if (!strncmp(cmd->tx_argv[cmd->tx_argc - 1], "-deref", 6))
|
||||
{
|
||||
|
|
@ -950,9 +964,15 @@ CmdFlush(w, cmd)
|
|||
cmd->tx_argc--;
|
||||
}
|
||||
|
||||
if (!strcmp(cmd->tx_argv[cmd->tx_argc - 1], "-noprompt"))
|
||||
{
|
||||
noprompt = TRUE;
|
||||
cmd->tx_argc--;
|
||||
}
|
||||
|
||||
if (cmd->tx_argc > 2)
|
||||
{
|
||||
TxError("Usage: flush [cellname] [dereference]\n");
|
||||
TxError("Usage: flush [cellname] [-noprompt] [-dereference]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -973,7 +993,9 @@ CmdFlush(w, cmd)
|
|||
}
|
||||
}
|
||||
|
||||
if (def->cd_flags & (CDMODIFIED|CDSTAMPSCHANGED|CDBOXESCHANGED))
|
||||
bool has_changes = (def->cd_flags & (CDMODIFIED|CDSTAMPSCHANGED|CDBOXESCHANGED)) != 0;
|
||||
|
||||
if (!noprompt && has_changes)
|
||||
{
|
||||
prompt = TxPrintString("Really throw away all changes made"
|
||||
" to cell %s? ", def->cd_name);
|
||||
|
|
@ -984,7 +1006,7 @@ CmdFlush(w, cmd)
|
|||
|
||||
cmdFlushCell(def, dereference);
|
||||
SelectClear();
|
||||
TxPrintf("[Flushed]\n");
|
||||
TxPrintf("[Flushed%s]\n", has_changes ? " Modifications were Discarded" : "");
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1015,9 +1037,9 @@ CmdFlush(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdGetcell(w, cmd)
|
||||
MagWindow *w; /* Window in which command was invoked. */
|
||||
TxCommand *cmd; /* Describes command arguments. */
|
||||
CmdGetcell(
|
||||
MagWindow *w, /* Window in which command was invoked. */
|
||||
TxCommand *cmd) /* Describes command arguments. */
|
||||
{
|
||||
CellUse dummy, *newUse;
|
||||
Transform editTrans;
|
||||
|
|
@ -1100,9 +1122,9 @@ CmdGetcell(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdGetnode(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdGetnode(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
#define TBLSIZE 50
|
||||
#define STRINGS 0
|
||||
|
|
@ -1197,7 +1219,7 @@ CmdGetnode(w, cmd)
|
|||
TxError("Put the cursor in a layout window\n");
|
||||
return;
|
||||
}
|
||||
if( is_fast == TRUE )
|
||||
if (is_fast == TRUE)
|
||||
{
|
||||
SimRecomputeSel = TRUE;
|
||||
SimGetsnode();
|
||||
|
|
@ -1205,7 +1227,8 @@ CmdGetnode(w, cmd)
|
|||
else
|
||||
SimGetnode();
|
||||
|
||||
if (SimGetnodeAlias) { /* "erase" the hash table */
|
||||
if (SimGetnodeAlias) /* "erase" the hash table */
|
||||
{
|
||||
HashKill(&SimGNAliasTbl);
|
||||
HashInit(&SimGNAliasTbl, 120, STRINGS);
|
||||
}
|
||||
|
|
@ -1251,15 +1274,15 @@ badusage:
|
|||
#define GRID_WHAT 7
|
||||
|
||||
void
|
||||
CmdGrid(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdGrid(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int option, locargc;
|
||||
int xSpacing, ySpacing, xOrig, yOrig, multiple;
|
||||
DBWclientRec *crec;
|
||||
char *boxvalues;
|
||||
static char *cmdGridOptions[] =
|
||||
static const char * const cmdGridOptions[] =
|
||||
{
|
||||
"box [values] report the box representing the user grid",
|
||||
"help print this message",
|
||||
|
|
@ -1419,9 +1442,9 @@ CmdGrid(w, cmd)
|
|||
|
||||
#ifdef USE_READLINE
|
||||
void
|
||||
CmdHistory(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdHistory(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int i;
|
||||
HIST_ENTRY *he;
|
||||
|
|
@ -1500,11 +1523,11 @@ CmdHistory(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdIdentify(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdIdentify(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
extern int cmdIdFunc(); /* Forward reference. */
|
||||
extern int cmdIdFunc(CellUse *selUse, CellUse *use, Transform *transform, char *newId); /* Forward reference. */
|
||||
|
||||
if (cmd->tx_argc != 2)
|
||||
{
|
||||
|
|
@ -1529,13 +1552,13 @@ CmdIdentify(w, cmd)
|
|||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cmdIdFunc(selUse, use, transform, newId)
|
||||
CellUse *selUse; /* Use from selection cell. */
|
||||
CellUse *use; /* Use from layout that corresponds to
|
||||
cmdIdFunc(
|
||||
CellUse *selUse, /* Use from selection cell. */
|
||||
CellUse *use, /* Use from layout that corresponds to
|
||||
* selUse.
|
||||
*/
|
||||
Transform *transform; /* Not used. */
|
||||
char *newId; /* New id for cell use. */
|
||||
Transform *transform, /* Not used. */
|
||||
char *newId) /* New id for cell use. */
|
||||
{
|
||||
if (EditCellUse == NULL)
|
||||
{
|
||||
|
|
@ -1576,12 +1599,12 @@ cmdIdFunc(selUse, use, transform, newId)
|
|||
}
|
||||
|
||||
TileType
|
||||
CmdFindNetProc(nodename, use, rect, warn_not_found, isvalid)
|
||||
char *nodename;
|
||||
CellUse *use;
|
||||
Rect *rect;
|
||||
bool warn_not_found;
|
||||
bool *isvalid;
|
||||
CmdFindNetProc(
|
||||
char *nodename,
|
||||
CellUse *use,
|
||||
Rect *rect,
|
||||
bool warn_not_found,
|
||||
bool *isvalid)
|
||||
{
|
||||
char *s,*s2;
|
||||
SearchContext scx, scx2;
|
||||
|
|
@ -1591,13 +1614,13 @@ CmdFindNetProc(nodename, use, rect, warn_not_found, isvalid)
|
|||
int pnum, xpos, ypos;
|
||||
char *xstr, *ystr;
|
||||
bool locvalid = FALSE, usefound = TRUE;
|
||||
TileType ttype;
|
||||
TileType ttype, dinfo = (TileType)0;
|
||||
|
||||
scx.scx_use = use;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
s = nodename;
|
||||
trans = GeoIdentityTransform;
|
||||
while (s2 = strchr(s, '/'))
|
||||
while ((s2 = strchr(s, '/')))
|
||||
{
|
||||
*s2 = '\0';
|
||||
DBTreeFindUse(s, scx.scx_use, &scx2);
|
||||
|
|
@ -1629,6 +1652,7 @@ CmdFindNetProc(nodename, use, rect, warn_not_found, isvalid)
|
|||
|
||||
if ((xstr = strchr(s, '_')) != NULL)
|
||||
{
|
||||
char *hashpos;
|
||||
bool isNeg = FALSE;
|
||||
|
||||
/* The characters up to the leading '_' should match one of the */
|
||||
|
|
@ -1672,6 +1696,17 @@ CmdFindNetProc(nodename, use, rect, warn_not_found, isvalid)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Format variant used for node regions where a split tile
|
||||
* occupies the root position of the node but the tile type
|
||||
* belonging to the node is on the right side of the tile,
|
||||
* not at the location encoded into the name. An 'x' is
|
||||
* added before the final hash sign.
|
||||
*/
|
||||
hashpos = strrchr(s, '#');
|
||||
if (hashpos != NULL)
|
||||
if (*(hashpos - 1) == 'r')
|
||||
dinfo = TT_DIAGONAL | TT_SIDE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1694,17 +1729,23 @@ checklocal:
|
|||
|
||||
if (locvalid == TRUE)
|
||||
{
|
||||
int findTile();
|
||||
int findTile(Tile *tile, TileType dinfo, TileAndDinfo *tad);
|
||||
CellDef *targetdef = use->cu_def;
|
||||
Plane *plane = targetdef->cd_planes[pnum];
|
||||
|
||||
ttype = TT_SPACE; /* revert to space in case of failure */
|
||||
TileAndDinfo tad;
|
||||
|
||||
/* Find the tile type of the tile at the specified point which */
|
||||
/* exists on the plane pnum. */
|
||||
/* exists on the plane pnum. Note that in the case of a split */
|
||||
/* tile region marked with "x" in the name, it does not work to */
|
||||
/* call DBSrPainNMArea() because the diagonal position is not */
|
||||
/* known. findTile() determines the proper type and leaves it */
|
||||
/* in the tad.tad_dinfo record. */
|
||||
|
||||
tad.tad_tile = (Tile *)NULL;
|
||||
tad.tad_dinfo = dinfo;
|
||||
DBSrPaintArea(NULL, plane, &localrect, &DBAllTypeBits, findTile,
|
||||
(ClientData) &ttype);
|
||||
(ClientData) &tad);
|
||||
ttype = tad.tad_dinfo & TT_LEFTMASK;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1768,11 +1809,11 @@ checklocal:
|
|||
*/
|
||||
|
||||
void
|
||||
CmdGoto(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdGoto(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
char *s, *nodename = cmd->tx_argv[1];
|
||||
char *nodename = cmd->tx_argv[1];
|
||||
Rect rect;
|
||||
CellUse *use;
|
||||
int locargc;
|
||||
|
|
@ -1813,9 +1854,9 @@ CmdGoto(w, cmd)
|
|||
/* are multiple layers drawn at the indicated point. */
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetResult(magicinterp, DBTypeLongName(ttype), NULL);
|
||||
Tcl_SetResult(magicinterp, (char*)DBTypeLongName(ttype), NULL); /* Tcl treats as const */
|
||||
#else
|
||||
TxPrintf("node %s is type %s\n", s, DBTypeLongName(ttype));
|
||||
TxPrintf("node %s is type %s\n", nodename, DBTypeLongName(ttype));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -1826,22 +1867,33 @@ CmdGoto(w, cmd)
|
|||
*/
|
||||
|
||||
int
|
||||
findTile(tile, rtype)
|
||||
Tile *tile;
|
||||
TileType *rtype;
|
||||
findTile(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* (unused) */
|
||||
TileAndDinfo *tad)
|
||||
{
|
||||
TileType ttype;
|
||||
|
||||
/* Note that since all types are being searched, a split
|
||||
* tile would cause the callback to be called twice. But
|
||||
* this routine will pick the indicated side from the
|
||||
* "tad" structure and return 1 so it does not get called
|
||||
* a second time. The "dinfo" value passed is irrelevant.
|
||||
*/
|
||||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
if (SplitSide(tile))
|
||||
if (tad->tad_dinfo & TT_SIDE)
|
||||
ttype = SplitRightType(tile);
|
||||
else
|
||||
ttype = SplitLeftType(tile);
|
||||
}
|
||||
else
|
||||
ttype = TiGetTypeExact(tile);
|
||||
*rtype = ttype;
|
||||
|
||||
/* Leave the tile type in tad_dinfo before returning */
|
||||
tad->tad_dinfo = ttype;
|
||||
|
||||
return 1; /* stop search */
|
||||
}
|
||||
|
||||
|
|
@ -1851,13 +1903,13 @@ findTile(tile, rtype)
|
|||
*/
|
||||
|
||||
void
|
||||
FlatCopyAllLabels(scx, mask, xMask, targetUse)
|
||||
SearchContext *scx;
|
||||
TileTypeBitMask *mask;
|
||||
int xMask;
|
||||
CellUse *targetUse;
|
||||
FlatCopyAllLabels(
|
||||
SearchContext *scx,
|
||||
TileTypeBitMask *mask,
|
||||
int xMask,
|
||||
CellUse *targetUse)
|
||||
{
|
||||
int flatCopyAllLabels();
|
||||
int flatCopyAllLabels(SearchContext *scx, Label *lab, TerminalPath *tpath, CellUse *targetUse);
|
||||
char pathstring[FLATTERMSIZE];
|
||||
TerminalPath tpath;
|
||||
|
||||
|
|
@ -1870,18 +1922,17 @@ FlatCopyAllLabels(scx, mask, xMask, targetUse)
|
|||
}
|
||||
|
||||
int
|
||||
flatCopyAllLabels(scx, lab, tpath, targetUse)
|
||||
SearchContext *scx;
|
||||
Label *lab;
|
||||
TerminalPath *tpath;
|
||||
CellUse *targetUse;
|
||||
flatCopyAllLabels(
|
||||
SearchContext *scx,
|
||||
Label *lab,
|
||||
TerminalPath *tpath,
|
||||
CellUse *targetUse)
|
||||
{
|
||||
Rect labTargetRect;
|
||||
int targetPos;
|
||||
unsigned short flags = 0;
|
||||
unsigned int port = 0;
|
||||
CellDef *def;
|
||||
char labelname[1024];
|
||||
char *n, *f, c;
|
||||
|
||||
/* Ignore null labels */
|
||||
|
|
@ -1954,52 +2005,52 @@ flatCopyAllLabels(scx, lab, tpath, targetUse)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdFlatten(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdFlatten(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int rval, xMask;
|
||||
bool dolabels, dobox, toplabels, invert, doports;
|
||||
int i, xMask, optargs;
|
||||
bool dolabels, dobox, toplabels, invert, doports, doinplace;
|
||||
char *destname;
|
||||
CellDef *newdef;
|
||||
CellUse *newuse;
|
||||
SearchContext scx;
|
||||
CellUse *flatDestUse;
|
||||
|
||||
destname = cmd->tx_argv[cmd->tx_argc - 1];
|
||||
destname = NULL;
|
||||
xMask = CU_DESCEND_ALL;
|
||||
dolabels = TRUE;
|
||||
toplabels = FALSE;
|
||||
dobox = FALSE;
|
||||
doports = TRUE;
|
||||
doinplace = FALSE;
|
||||
optargs = cmd->tx_argc - 1;
|
||||
|
||||
rval = 0;
|
||||
if (cmd->tx_argc > 2)
|
||||
if (optargs > 0)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < (cmd->tx_argc - 1); i++)
|
||||
for (i = 1; i < (optargs + 1); i++)
|
||||
{
|
||||
if (!strncmp(cmd->tx_argv[i], "-no", 3))
|
||||
if ((cmd->tx_argv[i][0] == '-') && (strlen(cmd->tx_argv[i]) > 3))
|
||||
{
|
||||
invert = TRUE;
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[i], "-do", 3))
|
||||
{
|
||||
invert = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
rval = -1;
|
||||
break;
|
||||
}
|
||||
if (!strncmp(cmd->tx_argv[i] + 1, "no", 2))
|
||||
invert = TRUE;
|
||||
else if (!strncmp(cmd->tx_argv[i] + 1, "do", 2))
|
||||
invert = FALSE;
|
||||
else
|
||||
{
|
||||
TxError("Bad flatten option \"%s\"; must start with \"-no\" or \"-do\"\n",
|
||||
cmd->tx_argv[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen(cmd->tx_argv[i]) > 3)
|
||||
{
|
||||
switch(cmd->tx_argv[i][3])
|
||||
{
|
||||
case 'b':
|
||||
dobox = (invert) ? FALSE : TRUE;
|
||||
break;
|
||||
case 'i':
|
||||
doinplace = (invert) ? FALSE : TRUE;
|
||||
break;
|
||||
case 'l':
|
||||
dolabels = (invert) ? FALSE : TRUE;
|
||||
break;
|
||||
|
|
@ -2020,20 +2071,65 @@ CmdFlatten(w, cmd)
|
|||
break;
|
||||
default:
|
||||
TxError("options are: -nolabels, -nosubcircuits, -noports, "
|
||||
"-novendor, -dotoplabels, -doproperty, -dobox\n");
|
||||
"-novendor, -dotoplabels, -doproperty, -dobox, "
|
||||
"-doinplace\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
destname = cmd->tx_argv[i];
|
||||
}
|
||||
}
|
||||
else if (cmd->tx_argc != 2)
|
||||
rval = -1;
|
||||
|
||||
if (rval != 0)
|
||||
/* Flatten-in-place */
|
||||
if (doinplace)
|
||||
{
|
||||
if (destname != NULL) /* instance name was given in "destname" */
|
||||
{
|
||||
HashEntry *he;
|
||||
CellUse *use;
|
||||
|
||||
if (EditCellUse == NULL)
|
||||
{
|
||||
TxError("The current cell is not editable.\n");
|
||||
return;
|
||||
}
|
||||
he = HashLookOnly(&EditCellUse->cu_def->cd_idHash, destname);
|
||||
if (he == NULL)
|
||||
{
|
||||
TxError("No cell use %s found in edit cell.\n", destname);
|
||||
return;
|
||||
}
|
||||
use = (CellUse *)HashGetValue(he);
|
||||
UndoDisable();
|
||||
DBFlattenInPlace(use, EditCellUse, xMask, dolabels, toplabels, TRUE);
|
||||
UndoEnable();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Instances to flatten are taken from SelectDef */
|
||||
UndoDisable();
|
||||
scx.scx_use = SelectUse;
|
||||
scx.scx_area = SelectUse->cu_bbox;
|
||||
scx.scx_trans = SelectUse->cu_transform;
|
||||
|
||||
DBCellFlattenAllCells(&scx, EditCellUse, xMask, dolabels, toplabels);
|
||||
|
||||
/* Instances in SelectDef need to be removed. The 2nd */
|
||||
/* argument TRUE causes the selection to be deleted. */
|
||||
SelectDeleteUses("flattened", TRUE);
|
||||
|
||||
UndoEnable();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (destname == NULL)
|
||||
{
|
||||
TxError("usage: flatten [-<option>...] destcell\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* create the new def */
|
||||
newdef = DBCellLookDef(destname);
|
||||
if ((newdef != NULL) && (dobox == FALSE))
|
||||
|
|
@ -2081,15 +2177,17 @@ CmdFlatten(w, cmd)
|
|||
UndoDisable();
|
||||
|
||||
DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, xMask, flatDestUse);
|
||||
if (dolabels)
|
||||
FlatCopyAllLabels(&scx, &DBAllTypeBits, xMask, flatDestUse);
|
||||
else if (toplabels)
|
||||
DBFlatCopyMaskHints(&scx, xMask, flatDestUse);
|
||||
if (toplabels)
|
||||
{
|
||||
int savemask = scx.scx_use->cu_expandMask;
|
||||
scx.scx_use->cu_expandMask = CU_DESCEND_SPECIAL;
|
||||
DBCellCopyAllLabels(&scx, &DBAllTypeBits, CU_DESCEND_SPECIAL, flatDestUse);
|
||||
DBCellCopyAllLabels(&scx, &DBAllTypeBits, CU_DESCEND_SPECIAL, flatDestUse,
|
||||
NULL);
|
||||
scx.scx_use->cu_expandMask = savemask;
|
||||
}
|
||||
else if (dolabels)
|
||||
FlatCopyAllLabels(&scx, &DBAllTypeBits, xMask, flatDestUse);
|
||||
|
||||
if (xMask != CU_DESCEND_ALL)
|
||||
DBCellCopyAllCells(&scx, xMask, flatDestUse, (Rect *)NULL);
|
||||
|
|
|
|||
299
commands/CmdLQ.c
299
commands/CmdLQ.c
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdLQ.c,v 1.9 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdLQ.c,v 1.9 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -51,7 +51,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
/* Forward declarations */
|
||||
|
||||
void CmdPaintEraseButton();
|
||||
void CmdPaintEraseButton(MagWindow *w, Point *refPoint, bool isPaint, bool isScreen);
|
||||
|
||||
/* See the SetLabel command */
|
||||
|
||||
|
|
@ -84,18 +84,18 @@ extern bool FileLocking;
|
|||
*/
|
||||
|
||||
void
|
||||
CmdLabelProc(text, font, size, rotate, offx, offy, pos, sticky, type)
|
||||
char *text; /* Text for label. */
|
||||
int font; /* Known font to use, or -1 for X11 fonts */
|
||||
int size; /* Fixed size of font (invalid with X11 fonts) */
|
||||
int rotate; /* Rotation (invalid with X11 fonts) */
|
||||
int offx; /* Position offset X (invalid with X11 fonts) */
|
||||
int offy; /* Position offset Y (invalid with X11 fonts) */
|
||||
int pos; /* Justification of text relative to text. -1
|
||||
CmdLabelProc(
|
||||
char *text, /* Text for label. */
|
||||
int font, /* Known font to use, or -1 for X11 fonts */
|
||||
int size, /* Fixed size of font (invalid with X11 fonts) */
|
||||
int rotate, /* Rotation (invalid with X11 fonts) */
|
||||
int offx, /* Position offset X (invalid with X11 fonts) */
|
||||
int offy, /* Position offset Y (invalid with X11 fonts) */
|
||||
int pos, /* Justification of text relative to text. -1
|
||||
* means "pick a nice one for me."
|
||||
*/
|
||||
bool sticky; /* 1 if label should not be moved off chosen layer */
|
||||
TileType type; /* Type of material label is to be attached
|
||||
bool sticky, /* 1 if label should not be moved off chosen layer */
|
||||
TileType type) /* Type of material label is to be attached
|
||||
* to. -1 means "pick a reasonable layer".
|
||||
*/
|
||||
{
|
||||
|
|
@ -182,9 +182,9 @@ CmdLabelProc(text, font, size, rotate, offx, offy, pos, sticky, type)
|
|||
|
||||
|
||||
void
|
||||
CmdLabel(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdLabel(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
TileType type = (TileType)(-1);
|
||||
int pos = -1, font = -1, size = 0, rotate = 0, offx = 0, offy = 0;
|
||||
|
|
@ -347,7 +347,8 @@ CmdLabel(w, cmd)
|
|||
#define LOAD_DEREFERENCE 1
|
||||
#define LOAD_FORCE 2
|
||||
#define LOAD_QUIET 3
|
||||
#define LOAD_FAIL 4
|
||||
#define LOAD_SILENT 4
|
||||
#define LOAD_FAIL 5
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -387,9 +388,9 @@ CmdLabel(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdLoad(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdLoad(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int n = 1;
|
||||
int d = 1;
|
||||
|
|
@ -398,21 +399,22 @@ CmdLoad(w, cmd)
|
|||
bool ignoreTech = FALSE;
|
||||
bool noWindow = FALSE;
|
||||
bool dereference = FALSE;
|
||||
bool beQuiet = FALSE;
|
||||
char verbose = DB_VERBOSE_ALL;
|
||||
bool failNotFound = FALSE;
|
||||
bool saveVerbose;
|
||||
unsigned char saveVerbose;
|
||||
unsigned char flags;
|
||||
int keepGoing(); /* forward declaration */
|
||||
extern bool DBVerbose; /* from DBio.c */
|
||||
int keepGoing(CellUse *use, ClientData clientdata); /* forward declaration */
|
||||
extern unsigned char DBVerbose; /* from DBio.c */
|
||||
|
||||
saveVerbose = DBVerbose;
|
||||
|
||||
static char *cmdLoadOption[] =
|
||||
static const char * const cmdLoadOption[] =
|
||||
{
|
||||
"-nowindow load file but do not display in the layout window",
|
||||
"-dereference use search paths and ignore embedded cell paths in file",
|
||||
"-force load file even if tech in header does not match",
|
||||
"-quiet no alert if file does not exist",
|
||||
"-quiet only errors printed",
|
||||
"-silent no alert if file does not exist",
|
||||
"-fail if file does not exist, do not create a new cell",
|
||||
NULL
|
||||
};
|
||||
|
|
@ -432,7 +434,10 @@ CmdLoad(w, cmd)
|
|||
ignoreTech = TRUE;
|
||||
break;
|
||||
case LOAD_QUIET:
|
||||
beQuiet = TRUE;
|
||||
verbose = DB_VERBOSE_ERR;
|
||||
break;
|
||||
case LOAD_SILENT:
|
||||
verbose = DB_VERBOSE_NONE;
|
||||
break;
|
||||
case LOAD_FAIL:
|
||||
failNotFound = TRUE;
|
||||
|
|
@ -490,12 +495,12 @@ CmdLoad(w, cmd)
|
|||
*(cmd->tx_argv[1] + strlen(cmd->tx_argv[1]) - 1) = '\0';
|
||||
}
|
||||
#endif
|
||||
DBVerbose = !beQuiet;
|
||||
DBVerbose = verbose;
|
||||
flags = 0;
|
||||
if (ignoreTech) flags |= DBW_LOAD_IGNORE_TECH;
|
||||
if (dereference) flags |= DBW_LOAD_DEREFERENCE;
|
||||
if (failNotFound) flags |= DBW_LOAD_FAIL;
|
||||
if (beQuiet) flags |= DBW_LOAD_QUIET;
|
||||
if (verbose < DB_VERBOSE_WARN) flags |= DBW_LOAD_QUIET;
|
||||
|
||||
DBWloadWindow((noWindow == TRUE) ? NULL : w, cmd->tx_argv[1], flags);
|
||||
DBVerbose = saveVerbose;
|
||||
|
|
@ -533,7 +538,7 @@ CmdLoad(w, cmd)
|
|||
}
|
||||
else
|
||||
{
|
||||
DBVerbose = !beQuiet;
|
||||
DBVerbose = verbose;
|
||||
DBWloadWindow(w, (char *) NULL, DBW_LOAD_IGNORE_TECH);
|
||||
DBVerbose = saveVerbose;
|
||||
}
|
||||
|
|
@ -545,9 +550,9 @@ CmdLoad(w, cmd)
|
|||
*/
|
||||
|
||||
int
|
||||
keepGoing(use, clientdata)
|
||||
CellUse *use;
|
||||
ClientData clientdata;
|
||||
keepGoing(
|
||||
CellUse *use,
|
||||
ClientData clientdata)
|
||||
{
|
||||
return 0; /* keep the search going */
|
||||
}
|
||||
|
|
@ -589,13 +594,13 @@ keepGoing(use, clientdata)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdLocking(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdLocking(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int option;
|
||||
|
||||
static char *cmdLockingYesNo[] = { "disable", "no", "false", "off", "0",
|
||||
static const char * const cmdLockingYesNo[] = { "disable", "no", "false", "off", "0",
|
||||
"enable", "yes", "true", "on", "1", 0 };
|
||||
|
||||
if (cmd->tx_argc <= 1)
|
||||
|
|
@ -663,9 +668,9 @@ CmdLocking(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdMove(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdMove(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
Transform t;
|
||||
Rect rootBox, newBox;
|
||||
|
|
@ -780,7 +785,7 @@ CmdMove(w, cmd)
|
|||
* box exists.
|
||||
* If no selection exists, but the box does, then move the box
|
||||
* anyway (hace 10/8/97)
|
||||
* The above method is superceded by "box move <dir> <dist>"
|
||||
* The above method is superseded by "box move <dir> <dist>"
|
||||
* but is retained for backward compatibility.
|
||||
*/
|
||||
|
||||
|
|
@ -810,6 +815,14 @@ CmdMove(w, cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Recast the command as "move to x y" so that it no longer
|
||||
* depends on the pointer position, for command logging.
|
||||
*/
|
||||
GeoTransPoint(&RootToEditTransform, &rootPoint, &editPoint);
|
||||
sprintf(cmd->tx_argstring, "move to %di %di\n", editPoint.p_x,
|
||||
editPoint.p_y);
|
||||
TxRebuildCommand(cmd);
|
||||
|
||||
moveToPoint:
|
||||
if (!ToolGetBox(&rootDef, &rootBox) || (rootDef != SelectRootDef))
|
||||
{
|
||||
|
|
@ -866,7 +879,7 @@ moveToPoint:
|
|||
* Paint the specified layers underneath the box in EditCellUse->cu_def.
|
||||
*
|
||||
* Usage:
|
||||
* paint <layers> | cursor
|
||||
* paint <layers> | cursor | pick x y
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -878,9 +891,9 @@ moveToPoint:
|
|||
*/
|
||||
|
||||
void
|
||||
CmdPaint(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdPaint(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
Rect editRect;
|
||||
TileTypeBitMask mask;
|
||||
|
|
@ -892,15 +905,34 @@ CmdPaint(w, cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
if ((cmd->tx_argc == 4) && !strcmp(cmd->tx_argv[1], "pick"))
|
||||
{
|
||||
Point editPoint, rootPoint;
|
||||
editPoint.p_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
|
||||
editPoint.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
|
||||
GeoTransPoint(&EditToRootTransform, &editPoint, &rootPoint);
|
||||
CmdPaintEraseButton(w, &rootPoint, TRUE, FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd->tx_argc != 2)
|
||||
{
|
||||
TxError("Usage: %s <layers> | cursor\n", cmd->tx_argv[0]);
|
||||
TxError("Usage: %s <layers> | cursor | pick x y\n", cmd->tx_argv[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strncmp(cmd->tx_argv[1], "cursor", 6))
|
||||
{
|
||||
CmdPaintEraseButton(w, &cmd->tx_p, TRUE);
|
||||
Point editPoint, rootPoint;
|
||||
|
||||
CmdPaintEraseButton(w, &cmd->tx_p, TRUE, TRUE);
|
||||
|
||||
/* Recast the command as "paint pick x y" for logging purposes */
|
||||
CmdGetRootPoint(&rootPoint, (Rect *)NULL);
|
||||
GeoTransPoint(&RootToEditTransform, &rootPoint, &editPoint);
|
||||
sprintf(cmd->tx_argstring, "paint pick %di %di", editPoint.p_x,
|
||||
editPoint.p_y);
|
||||
TxRebuildCommand(cmd);
|
||||
return;
|
||||
}
|
||||
else if (!CmdParseLayers(cmd->tx_argv[1], &mask))
|
||||
|
|
@ -952,10 +984,11 @@ CmdPaint(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdPaintEraseButton(w, butPoint, isPaint)
|
||||
MagWindow *w;
|
||||
Point *butPoint; /* Screen location at which button was raised */
|
||||
bool isPaint; /* True for paint, False for erase. */
|
||||
CmdPaintEraseButton(
|
||||
MagWindow *w,
|
||||
Point *refPoint, /* Screen location at which button was raised */
|
||||
bool isPaint, /* True for paint, False for erase. */
|
||||
bool isScreen) /* True for screen coordinates, False for root */
|
||||
{
|
||||
Rect rootRect, editRect, areaReturn;
|
||||
TileTypeBitMask mask;
|
||||
|
|
@ -969,7 +1002,15 @@ CmdPaintEraseButton(w, butPoint, isPaint)
|
|||
}
|
||||
crec = (DBWclientRec *) w->w_clientData;
|
||||
|
||||
WindPointToSurface(w, butPoint, (Point *) NULL, &rootRect);
|
||||
if (isScreen)
|
||||
WindPointToSurface(w, refPoint, (Point *) NULL, &rootRect);
|
||||
else
|
||||
{
|
||||
rootRect.r_ll.p_x = refPoint->p_x;
|
||||
rootRect.r_ll.p_y = refPoint->p_y;
|
||||
rootRect.r_ur.p_x = refPoint->p_x + 1;
|
||||
rootRect.r_ur.p_y = refPoint->p_y + 1;
|
||||
}
|
||||
|
||||
DBSeeTypesAll(((CellUse *)w->w_surfaceID), &rootRect,
|
||||
crec->dbw_bitmask, &mask);
|
||||
|
|
@ -1005,7 +1046,7 @@ CmdPaintEraseButton(w, butPoint, isPaint)
|
|||
else
|
||||
{
|
||||
DBEraseValid(EditCellUse->cu_def, &editRect, &mask, 0);
|
||||
DBEraseLabel(EditCellUse->cu_def, &editRect, &mask);
|
||||
DBEraseLabel(EditCellUse->cu_def, &editRect, &mask, NULL);
|
||||
}
|
||||
SelectClear();
|
||||
DBAdjustLabels(EditCellUse->cu_def, &editRect);
|
||||
|
|
@ -1044,14 +1085,14 @@ CmdPaintEraseButton(w, butPoint, isPaint)
|
|||
#define PATHHELP 3
|
||||
|
||||
void
|
||||
CmdPath(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdPath(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
char **pathptr;
|
||||
char *srcptr;
|
||||
int option;
|
||||
static char *cmdPathOption[] =
|
||||
static const char * const cmdPathOption[] =
|
||||
{
|
||||
"search [[+]path] set [append to] search path",
|
||||
"cell [[+]path] set [append to] cell path",
|
||||
|
|
@ -1169,9 +1210,9 @@ usage:
|
|||
*/
|
||||
|
||||
void
|
||||
CmdPolygon(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdPolygon(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
TileType type;
|
||||
int points, i, j, pNum;
|
||||
|
|
@ -1242,11 +1283,11 @@ CmdPolygon(w, cmd)
|
|||
/*----------------------------------------------------------------------*/
|
||||
|
||||
int
|
||||
cmdPortLabelFunc1(scx, label, tpath, cdata)
|
||||
SearchContext *scx;
|
||||
Label *label;
|
||||
TerminalPath *tpath;
|
||||
ClientData cdata;
|
||||
cmdPortLabelFunc1(
|
||||
SearchContext *scx,
|
||||
Label *label,
|
||||
TerminalPath *tpath,
|
||||
ClientData cdata)
|
||||
{
|
||||
Label **rlab = (Label **)cdata;
|
||||
|
||||
|
|
@ -1264,11 +1305,11 @@ cmdPortLabelFunc1(scx, label, tpath, cdata)
|
|||
}
|
||||
|
||||
int
|
||||
cmdPortLabelFunc2(scx, label, tpath, cdata)
|
||||
SearchContext *scx;
|
||||
Label *label;
|
||||
TerminalPath *tpath;
|
||||
ClientData cdata;
|
||||
cmdPortLabelFunc2(
|
||||
SearchContext *scx,
|
||||
Label *label,
|
||||
TerminalPath *tpath,
|
||||
ClientData cdata)
|
||||
{
|
||||
Label **rlab = (Label **)cdata;
|
||||
|
||||
|
|
@ -1297,11 +1338,11 @@ cmdPortLabelFunc2(scx, label, tpath, cdata)
|
|||
/*----------------------------------------------------------------------*/
|
||||
|
||||
Label *
|
||||
portFindLabel(editDef, port, unique, nonEdit)
|
||||
CellDef *editDef;
|
||||
bool unique;
|
||||
bool port; // If TRUE, only look for labels that are ports
|
||||
bool *nonEdit; // TRUE if label is not in the edit cell
|
||||
portFindLabel(
|
||||
CellDef *editDef,
|
||||
bool port, // If TRUE, only look for labels that are ports
|
||||
bool unique,
|
||||
bool *nonEdit) // TRUE if label is not in the edit cell
|
||||
{
|
||||
int found, wrongkind;
|
||||
Label *lab, *sl;
|
||||
|
|
@ -1400,11 +1441,18 @@ portFindLabel(editDef, port, unique, nonEdit)
|
|||
*/
|
||||
|
||||
int
|
||||
complabel(const void *one, const void *two)
|
||||
complabel(
|
||||
const void *one,
|
||||
const void *two)
|
||||
{
|
||||
/* Natural sort order routine from DBcellname.c
|
||||
* replaces strcasecmp().
|
||||
*/
|
||||
int strcmpbynum(const char *s1, const char *s2);
|
||||
|
||||
Label *l1 = *((Label **)one);
|
||||
Label *l2 = *((Label **)two);
|
||||
return strcasecmp(l1->lab_text, l2->lab_text);
|
||||
return strcmpbynum(l1->lab_text, l2->lab_text);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1470,11 +1518,11 @@ complabel(const void *one, const void *two)
|
|||
#define PORT_HELP 15
|
||||
|
||||
void
|
||||
CmdPort(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdPort(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
char **msg;
|
||||
const char * const *msg;
|
||||
int argstart;
|
||||
int i, refidx, idx, pos, type, option, argc;
|
||||
unsigned int dirmask;
|
||||
|
|
@ -1484,7 +1532,7 @@ CmdPort(w, cmd)
|
|||
Rect editBox, tmpArea;
|
||||
CellDef *editDef;
|
||||
|
||||
static char *cmdPortOption[] =
|
||||
static const char * const cmdPortOption[] =
|
||||
{
|
||||
"class [type] get [set] port class type",
|
||||
"use [type] get [set] port use type",
|
||||
|
|
@ -1505,7 +1553,7 @@ CmdPort(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
static char *cmdPortClassTypes[] =
|
||||
static const char * const cmdPortClassTypes[] =
|
||||
{
|
||||
"default",
|
||||
"input",
|
||||
|
|
@ -1518,7 +1566,7 @@ CmdPort(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
static int cmdClassToBitmask[] =
|
||||
static const int cmdClassToBitmask[] =
|
||||
{
|
||||
PORT_CLASS_DEFAULT,
|
||||
PORT_CLASS_INPUT,
|
||||
|
|
@ -1530,7 +1578,7 @@ CmdPort(w, cmd)
|
|||
PORT_CLASS_FEEDTHROUGH
|
||||
};
|
||||
|
||||
static char *cmdPortUseTypes[] =
|
||||
static const char * const cmdPortUseTypes[] =
|
||||
{
|
||||
"default",
|
||||
"analog",
|
||||
|
|
@ -1542,7 +1590,7 @@ CmdPort(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
static int cmdUseToBitmask[] =
|
||||
static const int cmdUseToBitmask[] =
|
||||
{
|
||||
PORT_USE_DEFAULT,
|
||||
PORT_USE_ANALOG,
|
||||
|
|
@ -1553,7 +1601,7 @@ CmdPort(w, cmd)
|
|||
PORT_USE_CLOCK
|
||||
};
|
||||
|
||||
static char *cmdPortShapeTypes[] =
|
||||
static const char * const cmdPortShapeTypes[] =
|
||||
{
|
||||
"default",
|
||||
"abutment",
|
||||
|
|
@ -1563,7 +1611,7 @@ CmdPort(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
static int cmdShapeToBitmask[] =
|
||||
static const int cmdShapeToBitmask[] =
|
||||
{
|
||||
PORT_SHAPE_DEFAULT,
|
||||
PORT_SHAPE_ABUT,
|
||||
|
|
@ -1827,7 +1875,7 @@ CmdPort(w, cmd)
|
|||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_AppendResult(magicinterp, cmdPortClassTypes[idx],
|
||||
NULL);
|
||||
(char *)NULL);
|
||||
#else
|
||||
TxPrintf("Class = %s\n", cmdPortClassTypes[idx]);
|
||||
#endif
|
||||
|
|
@ -1872,7 +1920,7 @@ CmdPort(w, cmd)
|
|||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_AppendResult(magicinterp, cmdPortUseTypes[idx],
|
||||
NULL);
|
||||
(char *)NULL);
|
||||
#else
|
||||
TxPrintf("Use = %s\n", cmdPortUseTypes[idx]);
|
||||
#endif
|
||||
|
|
@ -1917,7 +1965,7 @@ CmdPort(w, cmd)
|
|||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_AppendResult(magicinterp, cmdPortShapeTypes[idx],
|
||||
NULL);
|
||||
(char *)NULL);
|
||||
#else
|
||||
TxPrintf("Shape = %s\n", cmdPortShapeTypes[idx]);
|
||||
#endif
|
||||
|
|
@ -1996,7 +2044,7 @@ CmdPort(w, cmd)
|
|||
if (pos & PORT_DIR_SOUTH) strcat(cdir, "s");
|
||||
if (pos & PORT_DIR_WEST) strcat(cdir, "w");
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_AppendResult(magicinterp, cdir, NULL);
|
||||
Tcl_AppendResult(magicinterp, cdir, (char *)NULL);
|
||||
#else
|
||||
TxPrintf("Directions = %s\n", cdir);
|
||||
#endif
|
||||
|
|
@ -2022,11 +2070,13 @@ CmdPort(w, cmd)
|
|||
* order of the label text). NOTE: Because SPICE is
|
||||
* case-insensitive, case-insensitive alphabetical order
|
||||
* is used.
|
||||
* Update (2/26/2023): Use *natural sort* order so that
|
||||
* indexes get sorted in numerical, not alphabetical, order.
|
||||
*/
|
||||
{
|
||||
int numlabels, n, p;
|
||||
Label **slablist, *tlab, *lastlab;
|
||||
extern int complabel();
|
||||
extern int complabel(const void *one, const void *two);
|
||||
|
||||
/* Create a sortable list of labels */
|
||||
numlabels = 0;
|
||||
|
|
@ -2126,11 +2176,15 @@ parseindex:
|
|||
{
|
||||
if ((int)sl->lab_port == idx)
|
||||
{
|
||||
TxError("Port index %d is already used by port %s.\n"
|
||||
"Use command \"port index %d\" to force "
|
||||
"equivalence after defining the port.\n",
|
||||
idx, sl->lab_text, idx);
|
||||
return;
|
||||
/* This is only an error if port name doesn't match */
|
||||
if (strcmp(sl->lab_text, lab->lab_text))
|
||||
{
|
||||
TxError("Port index %d is already used by port %s.\n"
|
||||
"Use command \"port index %d\" to force "
|
||||
"equivalence after defining the port.\n",
|
||||
idx, sl->lab_text, idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2263,10 +2317,10 @@ parsepositions:
|
|||
*/
|
||||
|
||||
void
|
||||
CmdDoProperty(def, cmd, argstart)
|
||||
CellDef *def;
|
||||
TxCommand *cmd;
|
||||
int argstart;
|
||||
CmdDoProperty(
|
||||
CellDef *def,
|
||||
TxCommand *cmd,
|
||||
int argstart)
|
||||
{
|
||||
int printPropertiesFunc();
|
||||
char *value;
|
||||
|
|
@ -2276,8 +2330,9 @@ CmdDoProperty(def, cmd, argstart)
|
|||
if (locargc == 1)
|
||||
{
|
||||
/* print all properties and their values */
|
||||
DBPropEnum(def, printPropertiesFunc);
|
||||
DBPropEnum(def, printPropertiesFunc, NULL);
|
||||
}
|
||||
|
||||
else if (locargc == 2)
|
||||
{
|
||||
/* print the value of the indicated property */
|
||||
|
|
@ -2294,7 +2349,7 @@ CmdDoProperty(def, cmd, argstart)
|
|||
/* just return NULL if the property was not found. */
|
||||
if (strcmp(cmd->tx_argv[1], "list"))
|
||||
#endif
|
||||
TxError("Property name %s is not defined\n");
|
||||
TxError("Property name \"%s\" is not defined\n", cmd->tx_argv[1]);
|
||||
}
|
||||
}
|
||||
else if (locargc == 3)
|
||||
|
|
@ -2340,9 +2395,9 @@ CmdDoProperty(def, cmd, argstart)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdProperty(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdProperty(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
CellDef *def;
|
||||
|
||||
|
|
@ -2365,9 +2420,10 @@ CmdProperty(w, cmd)
|
|||
*/
|
||||
|
||||
int
|
||||
printPropertiesFunc(name, value)
|
||||
char *name;
|
||||
ClientData value;
|
||||
printPropertiesFunc(
|
||||
const char *name,
|
||||
ClientData value,
|
||||
ClientData cdata) /* not used */
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *keyvalue;
|
||||
|
|
@ -2379,14 +2435,14 @@ printPropertiesFunc(name, value)
|
|||
}
|
||||
else
|
||||
{
|
||||
keyvalue = (char *)mallocMagic(strlen(name) + strlen((char *)value) + 2);
|
||||
sprintf(keyvalue, "%s %s", name, (char *)value);
|
||||
keyvalue = (char *)mallocMagic(strlen(name) + strlen((const char *)value) + 2);
|
||||
sprintf(keyvalue, "%s %s", name, (const char *)value);
|
||||
}
|
||||
Tcl_AppendElement(magicinterp, keyvalue);
|
||||
freeMagic(keyvalue);
|
||||
|
||||
#else
|
||||
TxPrintf("%s = %s\n", name, value);
|
||||
TxPrintf("%s = %s\n", name, (const char *)value);
|
||||
#endif
|
||||
|
||||
return 0; /* keep the search alive */
|
||||
|
|
@ -2417,14 +2473,15 @@ printPropertiesFunc(name, value)
|
|||
#define NLIST_TERMINAL 3
|
||||
|
||||
void
|
||||
CmdNetlist(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdNetlist(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int option;
|
||||
char **msg, *lastargv;
|
||||
const char * const *msg;
|
||||
char *lastargv;
|
||||
Point cursor;
|
||||
static char *cmdNetlistOption[] =
|
||||
static const char * const cmdNetlistOption[] =
|
||||
{
|
||||
"help print this help information",
|
||||
"select select the net nearest the cursor",
|
||||
|
|
@ -2500,9 +2557,9 @@ CmdNetlist(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdOrient(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdOrient(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
Transform trans, t2;
|
||||
int orientidx, locargc;
|
||||
|
|
@ -2511,7 +2568,7 @@ CmdOrient(w, cmd)
|
|||
CellDef *rootDef;
|
||||
bool noAdjust = FALSE;
|
||||
|
||||
static char *orientNames[] = { "0", "90", "180", "270",
|
||||
static const char * const orientNames[] = { "0", "90", "180", "270",
|
||||
"v", "0v", "90v", "180v", "270v",
|
||||
"h", "0h", "90h", "180h", "270h",
|
||||
"N", "E", "S", "W",
|
||||
|
|
|
|||
617
commands/CmdRS.c
617
commands/CmdRS.c
File diff suppressed because it is too large
Load Diff
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdSubrs.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdSubrs.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -52,9 +52,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
/* Forward declarations */
|
||||
|
||||
extern char *cmdCheckNewName();
|
||||
extern int cmdSaveWindSet();
|
||||
extern void CmdSetWindCaption();
|
||||
extern char *cmdCheckNewName(CellDef *def, char *newName, bool tryRename, bool noninteractive);
|
||||
extern int cmdSaveWindSet(MagWindow *window, CellDef *def);
|
||||
extern void CmdSetWindCaption(CellUse *newEditUse, CellDef *rootDef);
|
||||
|
||||
TileTypeBitMask CmdYMLabel;
|
||||
TileTypeBitMask CmdYMCell;
|
||||
|
|
@ -100,11 +100,12 @@ TileTypeBitMask CmdYMAllButSpace;
|
|||
*/
|
||||
|
||||
int
|
||||
cmdScaleCoord(w, arg, is_relative, is_x, scale)
|
||||
MagWindow *w;
|
||||
char *arg;
|
||||
bool is_relative, is_x;
|
||||
int scale;
|
||||
cmdScaleCoord(
|
||||
MagWindow *w,
|
||||
char *arg,
|
||||
bool is_relative,
|
||||
bool is_x,
|
||||
int scale)
|
||||
{
|
||||
char *endptr;
|
||||
double dval = 0;
|
||||
|
|
@ -190,6 +191,11 @@ cmdScaleCoord(w, arg, is_relative, is_x, scale)
|
|||
return round(dval);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(endptr, "u"))
|
||||
/* Maybe "u" is too ambiguous but it is very commonly used as
|
||||
* an abbreviation for "micron".
|
||||
*/
|
||||
mscale = 1000;
|
||||
else if (!strncmp(endptr, "micron", 6))
|
||||
mscale = 1000;
|
||||
else if (!strncmp(endptr, "centimicron", 11) || !strcmp(endptr, "cu"))
|
||||
|
|
@ -201,7 +207,8 @@ cmdScaleCoord(w, arg, is_relative, is_x, scale)
|
|||
return round(dval);
|
||||
}
|
||||
}
|
||||
dval /= CIFGetOutputScale(mscale);
|
||||
if (!isspace(*endptr))
|
||||
dval /= CIFGetOutputScale(mscale);
|
||||
return round(dval);
|
||||
}
|
||||
|
||||
|
|
@ -224,10 +231,11 @@ cmdScaleCoord(w, arg, is_relative, is_x, scale)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdParseCoord(w, arg, is_relative, is_x)
|
||||
MagWindow *w;
|
||||
char *arg;
|
||||
bool is_relative, is_x;
|
||||
cmdParseCoord(
|
||||
MagWindow *w,
|
||||
char *arg,
|
||||
bool is_relative,
|
||||
bool is_x)
|
||||
{
|
||||
return cmdScaleCoord(w, arg, is_relative, is_x, 1);
|
||||
}
|
||||
|
|
@ -251,7 +259,7 @@ cmdParseCoord(w, arg, is_relative, is_x)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdInit()
|
||||
CmdInit(void)
|
||||
{
|
||||
TTMaskZero(&CmdYMLabel);
|
||||
TTMaskSetType(&CmdYMLabel, L_LABEL);
|
||||
|
|
@ -285,12 +293,11 @@ CmdInit()
|
|||
*/
|
||||
|
||||
void
|
||||
cmdFlushCell(def, force_deref)
|
||||
CellDef *def;
|
||||
bool force_deref;
|
||||
cmdFlushCell(
|
||||
CellDef *def,
|
||||
bool force_deref)
|
||||
{
|
||||
CellUse *parentUse;
|
||||
bool dereference;
|
||||
|
||||
if (def == NULL) return;
|
||||
|
||||
|
|
@ -323,8 +330,7 @@ cmdFlushCell(def, force_deref)
|
|||
}
|
||||
DBCellClearDef(def);
|
||||
DBCellClearAvail(def);
|
||||
dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
(void) DBCellRead(def, (char *) NULL, TRUE, dereference, NULL);
|
||||
(void) DBCellRead(def, TRUE, TRUE, NULL);
|
||||
DBCellSetAvail(def);
|
||||
DBReComputeBbox(def);
|
||||
DBCellSetModified(def, FALSE);
|
||||
|
|
@ -369,9 +375,9 @@ cmdFlushCell(def, force_deref)
|
|||
*/
|
||||
|
||||
bool
|
||||
CmdParseLayers(s, mask)
|
||||
char *s;
|
||||
TileTypeBitMask *mask;
|
||||
CmdParseLayers(
|
||||
char *s,
|
||||
TileTypeBitMask *mask)
|
||||
{
|
||||
TileTypeBitMask newmask, tempmask;
|
||||
char *dp, c;
|
||||
|
|
@ -390,23 +396,23 @@ CmdParseLayers(s, mask)
|
|||
#define LN_CONNECT 5
|
||||
static struct
|
||||
{
|
||||
char *layer_name;
|
||||
const char *layer_name;
|
||||
int layer_value;
|
||||
}
|
||||
special[] =
|
||||
const special[] =
|
||||
{
|
||||
"$", LN_DOLLAR,
|
||||
"*", LN_ALL,
|
||||
"errors", LN_ERRORS,
|
||||
"labels", LN_LABELS,
|
||||
"subcell", LN_CELL,
|
||||
"connect", LN_CONNECT,
|
||||
0,
|
||||
{"$", LN_DOLLAR},
|
||||
{"*", LN_ALL},
|
||||
{"errors", LN_ERRORS},
|
||||
{"labels", LN_LABELS},
|
||||
{"subcell", LN_CELL},
|
||||
{"connect", LN_CONNECT},
|
||||
{0},
|
||||
};
|
||||
|
||||
|
||||
TTMaskZero(mask);
|
||||
while (c = *s++)
|
||||
while ((c = *s++))
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
|
|
@ -433,7 +439,7 @@ CmdParseLayers(s, mask)
|
|||
type = DBTechNameTypes(name, &newmask);
|
||||
if (type == -2)
|
||||
{
|
||||
which = LookupStruct(name, (LookupTable *) special, sizeof special[0]);
|
||||
which = LookupStruct(name, (const LookupTable *) special, sizeof special[0]);
|
||||
if (which >= 0)
|
||||
{
|
||||
switch (special[which].layer_value)
|
||||
|
|
@ -543,8 +549,8 @@ printTypes:
|
|||
*/
|
||||
|
||||
TileType
|
||||
cmdMaskToType(mask)
|
||||
TileTypeBitMask *mask;
|
||||
cmdMaskToType(
|
||||
TileTypeBitMask *mask)
|
||||
{
|
||||
TileType type, t;
|
||||
|
||||
|
|
@ -589,16 +595,16 @@ cmdMaskToType(mask)
|
|||
*/
|
||||
|
||||
void
|
||||
cmdSaveCell(cellDef, newName, noninteractive, tryRename)
|
||||
CellDef *cellDef; /* Pointer to def of cell to be saved */
|
||||
char *newName; /* Pointer to name of file in which cell is to be
|
||||
cmdSaveCell(
|
||||
CellDef *cellDef, /* Pointer to def of cell to be saved */
|
||||
char *newName, /* Pointer to name of file in which cell is to be
|
||||
* saved. May be NULL, in which case the name from
|
||||
* the CellDef is taken.
|
||||
*/
|
||||
bool noninteractive;/* If true, try hard but don't ask the user
|
||||
bool noninteractive,/* If true, try hard but don't ask the user
|
||||
* questions.
|
||||
*/
|
||||
bool tryRename; /* We should rename the cell to the name of the
|
||||
bool tryRename) /* We should rename the cell to the name of the
|
||||
* place where it was saved.
|
||||
*/
|
||||
{
|
||||
|
|
@ -708,13 +714,13 @@ cleanup:
|
|||
*/
|
||||
|
||||
char *
|
||||
cmdCheckNewName(def, newName, tryRename, noninteractive)
|
||||
CellDef *def;
|
||||
char *newName;
|
||||
bool tryRename;
|
||||
bool noninteractive;
|
||||
cmdCheckNewName(
|
||||
CellDef *def,
|
||||
char *newName,
|
||||
bool tryRename,
|
||||
bool noninteractive)
|
||||
{
|
||||
static char *yesno[] = { "no", "yes", 0 };
|
||||
static const char * const yesno[] = { "no", "yes", 0 };
|
||||
char *filename;
|
||||
char *prompt;
|
||||
char *returnname;
|
||||
|
|
@ -752,7 +758,7 @@ again:
|
|||
|
||||
if (strcmp(returnname, def->cd_name) != 0)
|
||||
{
|
||||
if (f = PaOpen(returnname, "r", DBSuffix, ".", (char *) NULL, &filename))
|
||||
if ((f = PaOpen(returnname, "r", DBSuffix, ".", (char *) NULL, &filename)))
|
||||
{
|
||||
(void) fclose(f);
|
||||
if (noninteractive) {
|
||||
|
|
@ -799,10 +805,10 @@ again:
|
|||
*/
|
||||
|
||||
static char *
|
||||
nameEllipsis(name, maxlen, prefix)
|
||||
char *name;
|
||||
int maxlen;
|
||||
char **prefix;
|
||||
nameEllipsis(
|
||||
char *name,
|
||||
int maxlen,
|
||||
char **prefix)
|
||||
{
|
||||
int l = strlen(name);
|
||||
|
||||
|
|
@ -842,9 +848,9 @@ nameEllipsis(name, maxlen, prefix)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdSaveWindSet(window, def)
|
||||
MagWindow *window;
|
||||
CellDef *def;
|
||||
cmdSaveWindSet(
|
||||
MagWindow *window,
|
||||
CellDef *def)
|
||||
{
|
||||
char caption[200];
|
||||
CellDef *rootDef;
|
||||
|
|
@ -896,13 +902,13 @@ static CellDef *newRootDef; /* Pointer to root def of window in which
|
|||
*/
|
||||
|
||||
void
|
||||
CmdSetWindCaption(newEditUse, rootDef)
|
||||
CellUse *newEditUse; /* Pointer to new edit cell use */
|
||||
CellDef *rootDef; /* Root cell def of the window in which the
|
||||
CmdSetWindCaption(
|
||||
CellUse *newEditUse, /* Pointer to new edit cell use */
|
||||
CellDef *rootDef) /* Root cell def of the window in which the
|
||||
* edit cell was selected.
|
||||
*/
|
||||
{
|
||||
int cmdWindSet();
|
||||
int cmdWindSet(MagWindow *window);
|
||||
|
||||
newEditDef = (newEditUse) ? newEditUse->cu_def : NULL;
|
||||
newRootDef = rootDef;
|
||||
|
|
@ -937,8 +943,8 @@ CmdSetWindCaption(newEditUse, rootDef)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdWindSet(window)
|
||||
MagWindow *window;
|
||||
cmdWindSet(
|
||||
MagWindow *window)
|
||||
{
|
||||
char caption[200];
|
||||
CellDef *wDef;
|
||||
|
|
@ -994,9 +1000,9 @@ cmdWindSet(window)
|
|||
*/
|
||||
|
||||
MagWindow *
|
||||
CmdGetRootPoint(point, rect)
|
||||
Point *point;
|
||||
Rect *rect;
|
||||
CmdGetRootPoint(
|
||||
Point *point,
|
||||
Rect *rect)
|
||||
{
|
||||
MagWindow *window;
|
||||
|
||||
|
|
@ -1029,9 +1035,9 @@ CmdGetRootPoint(point, rect)
|
|||
*/
|
||||
|
||||
MagWindow *
|
||||
CmdGetEditPoint(point, rect)
|
||||
Point *point;
|
||||
Rect *rect;
|
||||
CmdGetEditPoint(
|
||||
Point *point,
|
||||
Rect *rect)
|
||||
{
|
||||
MagWindow *window;
|
||||
Rect rootRect;
|
||||
|
|
@ -1066,11 +1072,11 @@ CmdGetEditPoint(point, rect)
|
|||
*/
|
||||
|
||||
bool
|
||||
CmdWarnWrite()
|
||||
CmdWarnWrite(void)
|
||||
{
|
||||
int count, code;
|
||||
int cmdWarnWriteFunc();
|
||||
static char *yesno[] = { "no", "yes", 0 };
|
||||
int cmdWarnWriteFunc(CellDef *cellDef, int *pcount);
|
||||
static const char * const yesno[] = { "no", "yes", 0 };
|
||||
char *prompt;
|
||||
|
||||
count = 0;
|
||||
|
|
@ -1088,9 +1094,9 @@ CmdWarnWrite()
|
|||
}
|
||||
|
||||
int
|
||||
cmdWarnWriteFunc(cellDef, pcount)
|
||||
CellDef *cellDef;
|
||||
int *pcount;
|
||||
cmdWarnWriteFunc(
|
||||
CellDef *cellDef,
|
||||
int *pcount)
|
||||
{
|
||||
if ((cellDef->cd_flags & CDINTERNAL) == 0)
|
||||
(*pcount)++;
|
||||
|
|
@ -1114,27 +1120,27 @@ cmdWarnWriteFunc(cellDef, pcount)
|
|||
*/
|
||||
|
||||
void
|
||||
cmdExpandOneLevel(cu, bitmask, expand)
|
||||
CellUse *cu;
|
||||
int bitmask;
|
||||
bool expand;
|
||||
cmdExpandOneLevel(
|
||||
CellUse *cu,
|
||||
int bitmask,
|
||||
bool expand)
|
||||
{
|
||||
extern int cmdExpand1func();
|
||||
extern int cmdExpand1func(CellUse *cu, ClientData bitmask);
|
||||
|
||||
/* first, expand this cell use */
|
||||
DBExpand(cu, bitmask, expand);
|
||||
|
||||
/* now, unexpand its direct children (ONE LEVEL ONLY) */
|
||||
if (expand)
|
||||
(void) DBCellEnum(cu->cu_def, cmdExpand1func, (ClientData) bitmask);
|
||||
(void) DBCellEnum(cu->cu_def, cmdExpand1func, INT2CD(bitmask));
|
||||
}
|
||||
|
||||
int
|
||||
cmdExpand1func(cu, bitmask)
|
||||
CellUse *cu;
|
||||
ClientData bitmask;
|
||||
cmdExpand1func(
|
||||
CellUse *cu,
|
||||
ClientData bitmask)
|
||||
{
|
||||
DBExpand(cu, (int) bitmask, FALSE);
|
||||
DBExpand(cu, (int)CD2INT(bitmask), FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1162,13 +1168,13 @@ Transform *cmdSelTrans; /* Shared between CmdGetSelectedCell and
|
|||
*/
|
||||
|
||||
CellUse *
|
||||
CmdGetSelectedCell(pTrans)
|
||||
Transform *pTrans; /* If non-NULL, transform from selected
|
||||
CmdGetSelectedCell(
|
||||
Transform *pTrans) /* If non-NULL, transform from selected
|
||||
* cell to root coords is stored here.
|
||||
*/
|
||||
{
|
||||
CellUse *result = NULL;
|
||||
int cmdGetSelFunc(); /* Forward declaration. */
|
||||
int cmdGetSelFunc(CellUse *selUse, CellUse *realUse, Transform *transform, CellUse **pResult); /* Forward declaration. */
|
||||
|
||||
cmdSelTrans = pTrans;
|
||||
(void) SelEnumCells(FALSE, (bool *) NULL, (SearchContext *) NULL,
|
||||
|
|
@ -1178,11 +1184,11 @@ CmdGetSelectedCell(pTrans)
|
|||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
cmdGetSelFunc(selUse, realUse, transform, pResult)
|
||||
CellUse *selUse; /* Not used. */
|
||||
CellUse *realUse; /* The first selected use. */
|
||||
Transform *transform; /* Transform from coords of realUse to root. */
|
||||
CellUse **pResult; /* Store realUse here. */
|
||||
cmdGetSelFunc(
|
||||
CellUse *selUse, /* Not used. */
|
||||
CellUse *realUse, /* The first selected use. */
|
||||
Transform *transform, /* Transform from coords of realUse to root. */
|
||||
CellUse **pResult) /* Store realUse here. */
|
||||
{
|
||||
*pResult = realUse;
|
||||
if (cmdSelTrans != NULL)
|
||||
|
|
@ -1190,6 +1196,17 @@ cmdGetSelFunc(selUse, realUse, transform, pResult)
|
|||
return 1; /* Skip any other selected cells. */
|
||||
}
|
||||
|
||||
|
||||
/* The Open Group, Sep 2006, Austin/317 deprecated isascii(),
|
||||
* Apparently it cannot be used portably in a localized application.
|
||||
*/
|
||||
static int
|
||||
magic_isascii(int c)
|
||||
{
|
||||
return (c & ~0x7f) == 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1210,10 +1227,10 @@ cmdGetSelFunc(selUse, realUse, transform, pResult)
|
|||
*/
|
||||
|
||||
bool
|
||||
CmdIllegalChars(string, illegal, msg)
|
||||
char *string; /* String to check for illegal chars. */
|
||||
char *illegal; /* String containing illegal chars. */
|
||||
char *msg; /* String identifying what string is
|
||||
CmdIllegalChars(
|
||||
char *string, /* String to check for illegal chars. */
|
||||
char *illegal, /* String containing illegal chars. */
|
||||
char *msg) /* String identifying what string is
|
||||
* supposed to represent, for ease in
|
||||
* printing error messages.
|
||||
*/
|
||||
|
|
@ -1222,7 +1239,7 @@ CmdIllegalChars(string, illegal, msg)
|
|||
|
||||
for (p = string; *p != 0; p++)
|
||||
{
|
||||
if (!isascii(*p)) goto error;
|
||||
if (!magic_isascii(*p)) goto error;
|
||||
if (iscntrl(*p)) goto error;
|
||||
for (bad = illegal; *bad != 0; bad++)
|
||||
{
|
||||
|
|
@ -1231,7 +1248,7 @@ CmdIllegalChars(string, illegal, msg)
|
|||
continue;
|
||||
|
||||
error:
|
||||
if (!isascii(*p) || iscntrl(*p))
|
||||
if (!magic_isascii(*p) || iscntrl(*p))
|
||||
{
|
||||
TxError("%s contains illegal control character 0x%x\n",
|
||||
msg, *p);
|
||||
|
|
|
|||
308
commands/CmdTZ.c
308
commands/CmdTZ.c
|
|
@ -17,7 +17,7 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdTZ.c,v 1.8 2010/06/24 12:37:15 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdTZ.c,v 1.8 2010/06/24 12:37:15 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -57,13 +57,13 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "yacr.h"
|
||||
#endif /* LLNL */
|
||||
|
||||
extern void DisplayWindow();
|
||||
|
||||
/* Trivial function that returns 1 if called */
|
||||
|
||||
int
|
||||
existFunc(tile)
|
||||
Tile *tile;
|
||||
existFunc(
|
||||
Tile *tile, /* (unused) */
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -82,9 +82,9 @@ existFunc(tile)
|
|||
*/
|
||||
|
||||
int
|
||||
checkForPaintFunc(cellDef, arg)
|
||||
CellDef *cellDef;
|
||||
ClientData arg;
|
||||
checkForPaintFunc(
|
||||
CellDef *cellDef,
|
||||
ClientData arg)
|
||||
{
|
||||
int numPlanes = *((int *)arg);
|
||||
int pNum, result;
|
||||
|
|
@ -121,7 +121,7 @@ checkForPaintFunc(cellDef, arg)
|
|||
*/
|
||||
|
||||
bool
|
||||
CmdCheckForPaintFunc()
|
||||
CmdCheckForPaintFunc(void)
|
||||
{
|
||||
if (DBCellSrDefs(0, checkForPaintFunc, (ClientData)&DBNumPlanes))
|
||||
return TRUE;
|
||||
|
|
@ -165,21 +165,21 @@ CmdCheckForPaintFunc()
|
|||
#define TECH_REVERT 11
|
||||
|
||||
void
|
||||
CmdTech(w, cmd)
|
||||
MagWindow *w; /* Window in which command was invoked. */
|
||||
TxCommand *cmd; /* Info about command options. */
|
||||
CmdTech(
|
||||
MagWindow *w, /* Window in which command was invoked. */
|
||||
TxCommand *cmd) /* Info about command options. */
|
||||
{
|
||||
int option, action, i, locargc;
|
||||
char **msg;
|
||||
const char * const *msg;
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *lobj;
|
||||
#endif
|
||||
bool noprompt = FALSE;
|
||||
|
||||
static char *actionNames[] =
|
||||
static const char * const actionNames[] =
|
||||
{ "no", "yes", 0 };
|
||||
|
||||
static char *cmdTechOption[] =
|
||||
static const char * const cmdTechOption[] =
|
||||
{
|
||||
"load filename [-noprompt][-[no]override]\n\
|
||||
Load a new technology",
|
||||
|
|
@ -218,7 +218,7 @@ CmdTech(w, cmd)
|
|||
Tcl_SetResult(magicinterp, DBTechName, NULL);
|
||||
break;
|
||||
case TECH_FILE:
|
||||
Tcl_SetResult(magicinterp, TechFileName, NULL);
|
||||
Tcl_SetResult(magicinterp, (char *)TechFileName, NULL);
|
||||
break;
|
||||
case TECH_VERSION:
|
||||
Tcl_SetResult(magicinterp, DBTechVersion, NULL);
|
||||
|
|
@ -415,10 +415,12 @@ CmdTech(w, cmd)
|
|||
|
||||
for (ctype = TT_TECHDEPBASE; ctype < DBNumUserLayers; ctype++)
|
||||
if (DBIsContact(ctype))
|
||||
{
|
||||
if (TTMaskHasType(&DBActiveLayerBits, ctype))
|
||||
DBUnlockContact(ctype);
|
||||
else
|
||||
DBLockContact(ctype);
|
||||
}
|
||||
|
||||
for (ctype = DBNumUserLayers; ctype < DBNumTypes; ctype++)
|
||||
{
|
||||
|
|
@ -653,9 +655,9 @@ usage2:
|
|||
*/
|
||||
|
||||
void
|
||||
CmdTool(w, cmd)
|
||||
MagWindow *w; /* Window in which command was invoked. */
|
||||
TxCommand *cmd; /* Info about command options. */
|
||||
CmdTool(
|
||||
MagWindow *w, /* Window in which command was invoked. */
|
||||
TxCommand *cmd) /* Info about command options. */
|
||||
{
|
||||
if (cmd->tx_argc == 1)
|
||||
{
|
||||
|
|
@ -671,6 +673,15 @@ CmdTool(w, cmd)
|
|||
|
||||
if (strcmp(cmd->tx_argv[1], "info") == 0)
|
||||
DBWPrintButtonDoc();
|
||||
else if (strcmp(cmd->tx_argv[1], "type") == 0)
|
||||
{
|
||||
char *toolType = DBWGetButtonHandler();
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(toolType, -1));
|
||||
#else
|
||||
TxPrintf("Current tool is \"%s\".\n", toolType);
|
||||
#endif /* MAGIC_WRAPPER */
|
||||
}
|
||||
else (void) DBWChangeButtonHandler(cmd->tx_argv[1]);
|
||||
}
|
||||
|
||||
|
|
@ -695,13 +706,13 @@ CmdTool(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdUnexpand(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdUnexpand(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int windowMask, boxMask;
|
||||
Rect rootRect;
|
||||
int cmdUnexpandFunc(); /* Forward reference. */
|
||||
int cmdUnexpandFunc(CellUse *use, int windowMask); /* Forward reference. */
|
||||
|
||||
if (cmd->tx_argc != 1)
|
||||
{
|
||||
|
|
@ -733,9 +744,9 @@ CmdUnexpand(w, cmd)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdUnexpandFunc(use, windowMask)
|
||||
CellUse *use; /* Use that was just unexpanded. */
|
||||
int windowMask; /* Window where it was unexpanded. */
|
||||
cmdUnexpandFunc(
|
||||
CellUse *use, /* Use that was just unexpanded. */
|
||||
int windowMask) /* Window where it was unexpanded. */
|
||||
{
|
||||
if (use->cu_parent == NULL) return 0;
|
||||
DBWAreaChanged(use->cu_parent, &use->cu_bbox, windowMask,
|
||||
|
|
@ -764,9 +775,9 @@ cmdUnexpandFunc(use, windowMask)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdUpsidedown(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdUpsidedown(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
Transform trans;
|
||||
Rect rootBox, bbox;
|
||||
|
|
@ -828,9 +839,11 @@ struct linked_id {
|
|||
};
|
||||
|
||||
|
||||
int cmdWhatPrintCell(tile, cxp)
|
||||
Tile *tile;
|
||||
TreeContext *cxp;
|
||||
int
|
||||
cmdWhatPrintCell(
|
||||
Tile *tile, /* (unused) */
|
||||
TileType dinfo, /* (unused) */
|
||||
TreeContext *cxp)
|
||||
{
|
||||
struct linked_id **lid = (struct linked_id **)cxp->tc_filter->tf_arg;
|
||||
struct linked_id *curlid = *lid;
|
||||
|
|
@ -882,7 +895,10 @@ static LabelStore *labelBlockTop, *labelEntry;
|
|||
*/
|
||||
|
||||
int
|
||||
cmdFindWhatTileFunc(Tile *tile, ClientData clientData)
|
||||
cmdFindWhatTileFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData clientData)
|
||||
{
|
||||
struct linked_id **lid = (struct linked_id **)clientData;
|
||||
SearchContext scx;
|
||||
|
|
@ -893,7 +909,7 @@ cmdFindWhatTileFunc(Tile *tile, ClientData clientData)
|
|||
scx.scx_use = EditCellUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
|
||||
if (SplitSide(tile))
|
||||
if (dinfo & TT_SIDE)
|
||||
type = SplitRightType(tile);
|
||||
else
|
||||
type = SplitLeftType(tile);
|
||||
|
|
@ -928,9 +944,9 @@ cmdFindWhatTileFunc(Tile *tile, ClientData clientData)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdWhat(w, cmd)
|
||||
MagWindow *w; /* Window in which command was invoked. */
|
||||
TxCommand *cmd; /* Information about the command. */
|
||||
CmdWhat(
|
||||
MagWindow *w, /* Window in which command was invoked. */
|
||||
TxCommand *cmd) /* Information about the command. */
|
||||
{
|
||||
int i, locargc;
|
||||
bool foundAny, editNull = FALSE;
|
||||
|
|
@ -940,11 +956,14 @@ CmdWhat(w, cmd)
|
|||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *lobj, *paintobj, *paintcellobj, *celllistobj, *labelobj, *cellobj;
|
||||
extern int cmdWhatCellListFunc();
|
||||
extern int cmdWhatCellListFunc(CellUse *selUse, CellUse *realUse, Transform *transform, Tcl_Obj *newobj);
|
||||
#endif
|
||||
|
||||
extern int cmdWhatPaintFunc(), cmdWhatLabelFunc(), cmdWhatCellFunc();
|
||||
extern int cmdWhatLabelPreFunc(), orderLabelFunc();
|
||||
extern int cmdWhatPaintFunc(Rect *rect, TileType type, TileTypeBitMask *mask);
|
||||
extern int cmdWhatLabelFunc(LabelStore *entry, bool *foundAny);
|
||||
extern int cmdWhatCellFunc(CellUse *selUse, CellUse *realUse, Transform *transform, bool *foundAny);
|
||||
extern int cmdWhatLabelPreFunc(Label *label, CellUse *cellUse, Transform *transform, bool *foundAny);
|
||||
extern int orderLabelFunc(const void *, const void *); /* (LabelStore *one, LabelStore *two) */
|
||||
|
||||
locargc = cmd->tx_argc;
|
||||
|
||||
|
|
@ -981,7 +1000,7 @@ CmdWhat(w, cmd)
|
|||
if (EditCellUse == NULL)
|
||||
{
|
||||
editNull = TRUE;
|
||||
EditCellUse = w->w_surfaceID;
|
||||
EditCellUse = (CellUse *)w->w_surfaceID;
|
||||
}
|
||||
|
||||
/* Find all the selected paint and print out the layer names. */
|
||||
|
|
@ -1088,11 +1107,13 @@ CmdWhat(w, cmd)
|
|||
}
|
||||
#endif
|
||||
|
||||
while (lid != NULL)
|
||||
{
|
||||
freeMagic(lid);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (lid != NULL)
|
||||
{
|
||||
freeMagic1(&mm1, lid);
|
||||
lid = lid->lid_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doListAll)
|
||||
Tcl_ListObjAppendElement(magicinterp, paintobj,
|
||||
|
|
@ -1197,10 +1218,10 @@ CmdWhat(w, cmd)
|
|||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
cmdWhatPaintFunc(rect, type, mask)
|
||||
Rect *rect; /* Not used. */
|
||||
TileType type; /* Type of this piece of paint. */
|
||||
TileTypeBitMask *mask; /* Place to OR in type's bit. */
|
||||
cmdWhatPaintFunc(
|
||||
Rect *rect, /* Not used. */
|
||||
TileType type, /* Type of this piece of paint. */
|
||||
TileTypeBitMask *mask) /* Place to OR in type's bit. */
|
||||
{
|
||||
if (type & TT_DIAGONAL)
|
||||
type = (type & TT_SIDE) ? (type & TT_RIGHTMASK) >> 14 :
|
||||
|
|
@ -1215,11 +1236,11 @@ cmdWhatPaintFunc(rect, type, mask)
|
|||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
cmdWhatLabelPreFunc(label, cellUse, transform, foundAny)
|
||||
Label *label; /* Label that's selected. */
|
||||
CellUse *cellUse; /* Cell use containing label. */
|
||||
Transform *transform; /* Not used. */
|
||||
bool *foundAny; /* Use to print extra stuff for the first
|
||||
cmdWhatLabelPreFunc(
|
||||
Label *label, /* Label that's selected. */
|
||||
CellUse *cellUse, /* Cell use containing label. */
|
||||
Transform *transform, /* Not used. */
|
||||
bool *foundAny) /* Use to print extra stuff for the first
|
||||
* label found.
|
||||
*/
|
||||
{
|
||||
|
|
@ -1259,9 +1280,9 @@ cmdWhatLabelPreFunc(label, cellUse, transform, foundAny)
|
|||
|
||||
|
||||
int
|
||||
cmdWhatLabelFunc(entry, foundAny)
|
||||
LabelStore *entry; /* stored pointers to label info*/
|
||||
bool *foundAny; /* Use to print extra stuff for the first
|
||||
cmdWhatLabelFunc(
|
||||
LabelStore *entry, /* stored pointers to label info*/
|
||||
bool *foundAny) /* Use to print extra stuff for the first
|
||||
* label found.
|
||||
*/
|
||||
{
|
||||
|
|
@ -1311,10 +1332,12 @@ cmdWhatLabelFunc(entry, foundAny)
|
|||
/* they are sorted by label name, then cell name, then attached material */
|
||||
/* that way all of identical names are grouped together */
|
||||
int
|
||||
orderLabelFunc(one, two)
|
||||
LabelStore *one; /* one of the labels being compared */
|
||||
LabelStore *two; /* the other label to compare with */
|
||||
orderLabelFunc(
|
||||
const void *a, /* one of the labels being compared */
|
||||
const void *b) /* the other label to compare with */
|
||||
{
|
||||
LabelStore *one = (LabelStore *)a; /* qsort compar 1st */
|
||||
LabelStore *two = (LabelStore *)b; /* qsort compar 2nd */
|
||||
int i;
|
||||
|
||||
if ((i = strcmp(one->lab_text, two->lab_text)) != 0)
|
||||
|
|
@ -1333,16 +1356,16 @@ orderLabelFunc(one, two)
|
|||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
cmdWhatCellFunc(selUse, realUse, transform, foundAny)
|
||||
CellUse *selUse; /* Not used. */
|
||||
CellUse *realUse; /* Selected cell use. */
|
||||
Transform *transform; /* Not used. */
|
||||
bool *foundAny; /* Used to print extra stuff for the first
|
||||
cmdWhatCellFunc(
|
||||
CellUse *selUse, /* Not used. */
|
||||
CellUse *realUse, /* Selected cell use. */
|
||||
Transform *transform, /* Not used. */
|
||||
bool *foundAny) /* Used to print extra stuff for the first
|
||||
* use found.
|
||||
*/
|
||||
{
|
||||
/* Forward reference */
|
||||
char *dbGetUseName();
|
||||
char *dbGetUseName(CellUse *celluse);
|
||||
|
||||
if (!*foundAny)
|
||||
{
|
||||
|
|
@ -1359,15 +1382,15 @@ cmdWhatCellFunc(selUse, realUse, transform, foundAny)
|
|||
/* Same search function as above, but appends use names to a Tcl list */
|
||||
|
||||
int
|
||||
cmdWhatCellListFunc(selUse, realUse, transform, newobj)
|
||||
CellUse *selUse; /* Not used. */
|
||||
CellUse *realUse; /* Selected cell use. */
|
||||
Transform *transform; /* Not used. */
|
||||
Tcl_Obj *newobj; /* Tcl list object holding use names */
|
||||
cmdWhatCellListFunc(
|
||||
CellUse *selUse, /* Not used. */
|
||||
CellUse *realUse, /* Selected cell use. */
|
||||
Transform *transform, /* Not used. */
|
||||
Tcl_Obj *newobj) /* Tcl list object holding use names */
|
||||
{
|
||||
Tcl_Obj *tuple;
|
||||
/* Forward reference */
|
||||
char *dbGetUseName();
|
||||
char *dbGetUseName(CellUse *celluse);
|
||||
|
||||
tuple = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tuple,
|
||||
|
|
@ -1414,20 +1437,23 @@ cmdWhatCellListFunc(selUse, realUse, transform, newobj)
|
|||
#define SEGMENT 11
|
||||
|
||||
void
|
||||
CmdWire(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdWire(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int option, locargc;
|
||||
char **msg, *lastargv;
|
||||
const char * const *msg;
|
||||
char *lastargv;
|
||||
TileType type;
|
||||
int width;
|
||||
Point point, rootPoint;
|
||||
bool needCoord = FALSE;
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *lobj;
|
||||
#endif
|
||||
|
||||
static char *cmdWireOption[] =
|
||||
static const char * const cmdWireOption[] =
|
||||
{
|
||||
"decrement layer|width decrement the wire layer or width",
|
||||
"help print this help information",
|
||||
|
|
@ -1499,11 +1525,11 @@ CmdWire(w, cmd)
|
|||
int value = 1;
|
||||
if (cmd->tx_argc == 4)
|
||||
value = cmdParseCoord(w, cmd->tx_argv[3], TRUE, TRUE);
|
||||
WirePickType(WireType, WireWidth - value);
|
||||
WirePickType(WireType, (Point *)NULL, WireWidth - value);
|
||||
}
|
||||
else
|
||||
goto badargs;
|
||||
return;
|
||||
break;
|
||||
|
||||
case INCREMENT:
|
||||
if (cmd->tx_argc != 3 && cmd->tx_argc != 4)
|
||||
|
|
@ -1539,11 +1565,11 @@ CmdWire(w, cmd)
|
|||
int value = 1;
|
||||
if (cmd->tx_argc == 4)
|
||||
value = cmdParseCoord(w, cmd->tx_argv[3], TRUE, TRUE);
|
||||
WirePickType(WireType, WireWidth + value);
|
||||
WirePickType(WireType, (Point *)NULL, WireWidth + value);
|
||||
}
|
||||
else
|
||||
goto badargs;
|
||||
return;
|
||||
break;
|
||||
|
||||
|
||||
case HELP:
|
||||
|
|
@ -1553,15 +1579,41 @@ CmdWire(w, cmd)
|
|||
{
|
||||
TxPrintf(" %s\n", *msg);
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
case HORIZONTAL:
|
||||
WireAddLeg((Rect *) NULL, (Point *) NULL, WIRE_HORIZONTAL);
|
||||
return;
|
||||
if ((cmd->tx_argc > 2) && strcmp(cmd->tx_argv[2], "to") == 0)
|
||||
{
|
||||
if (cmd->tx_argc != 5)
|
||||
goto badargs;
|
||||
point.p_x = cmdParseCoord(w, cmd->tx_argv[3], FALSE, TRUE);
|
||||
point.p_y = cmdParseCoord(w, cmd->tx_argv[4], FALSE, FALSE);
|
||||
GeoTransPoint(&EditToRootTransform, &point, &rootPoint);
|
||||
WireAddLeg((Rect *)NULL, &rootPoint, WIRE_HORIZONTAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
WireAddLeg((Rect *) NULL, (Point *) NULL, WIRE_HORIZONTAL);
|
||||
needCoord = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case LEG:
|
||||
WireAddLeg((Rect *) NULL, (Point *) NULL, WIRE_CHOOSE);
|
||||
return;
|
||||
if ((cmd->tx_argc > 2) && strcmp(cmd->tx_argv[2], "to") == 0)
|
||||
{
|
||||
if (cmd->tx_argc != 5)
|
||||
goto badargs;
|
||||
point.p_x = cmdParseCoord(w, cmd->tx_argv[3], FALSE, TRUE);
|
||||
point.p_y = cmdParseCoord(w, cmd->tx_argv[4], FALSE, FALSE);
|
||||
GeoTransPoint(&EditToRootTransform, &point, &rootPoint);
|
||||
WireAddLeg((Rect *)NULL, &rootPoint, WIRE_CHOOSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
WireAddLeg((Rect *)NULL, (Point *)NULL, WIRE_CHOOSE);
|
||||
needCoord = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case SHOW:
|
||||
WireShowLeg();
|
||||
|
|
@ -1595,7 +1647,17 @@ CmdWire(w, cmd)
|
|||
|
||||
case TYPE:
|
||||
if (locargc == 2)
|
||||
WirePickType(-1, 0);
|
||||
{
|
||||
WirePickType(-1, (Point *)NULL, 0);
|
||||
needCoord = TRUE;
|
||||
}
|
||||
else if ((locargc == 5) && !strcmp(cmd->tx_argv[2], "at"))
|
||||
{
|
||||
point.p_x = cmdParseCoord(w, cmd->tx_argv[3], FALSE, TRUE);
|
||||
point.p_y = cmdParseCoord(w, cmd->tx_argv[4], FALSE, FALSE);
|
||||
GeoTransPoint(&EditToRootTransform, &point, &rootPoint);
|
||||
WirePickType(-1, &rootPoint, 0);
|
||||
}
|
||||
else if (locargc != 3 && locargc != 4)
|
||||
{
|
||||
badargs:
|
||||
|
|
@ -1626,7 +1688,7 @@ CmdWire(w, cmd)
|
|||
}
|
||||
else
|
||||
width = cmdParseCoord(w, cmd->tx_argv[3], TRUE, TRUE);
|
||||
WirePickType(type, width);
|
||||
WirePickType(type, (Point *)NULL, width);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1648,11 +1710,24 @@ CmdWire(w, cmd)
|
|||
DBTypeLongNameTbl[type], width);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
case VERTICAL:
|
||||
WireAddLeg((Rect *) NULL, (Point *) NULL, WIRE_VERTICAL);
|
||||
return;
|
||||
if ((cmd->tx_argc > 2) && strcmp(cmd->tx_argv[2], "to") == 0)
|
||||
{
|
||||
if (cmd->tx_argc != 5)
|
||||
goto badargs;
|
||||
point.p_x = cmdParseCoord(w, cmd->tx_argv[3], FALSE, TRUE);
|
||||
point.p_y = cmdParseCoord(w, cmd->tx_argv[4], FALSE, FALSE);
|
||||
GeoTransPoint(&EditToRootTransform, &point, &rootPoint);
|
||||
WireAddLeg((Rect *)NULL, &rootPoint, WIRE_VERTICAL);
|
||||
}
|
||||
else
|
||||
{
|
||||
WireAddLeg((Rect *) NULL, (Point *) NULL, WIRE_VERTICAL);
|
||||
needCoord = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
case WIDTH:
|
||||
if (locargc == 2)
|
||||
|
|
@ -1671,7 +1746,7 @@ CmdWire(w, cmd)
|
|||
{
|
||||
width = cmdParseCoord(w, cmd->tx_argv[2], TRUE, TRUE);
|
||||
type = WireGetType();
|
||||
WirePickType(type, width);
|
||||
WirePickType(type, (Point *)NULL, width);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
@ -1761,6 +1836,7 @@ CmdWire(w, cmd)
|
|||
TxError("Bad coordinate pair at %s line %d\n",
|
||||
cmd->tx_argv[4], i + 1);
|
||||
freeMagic(plist);
|
||||
fclose(pfile);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1820,6 +1896,22 @@ CmdWire(w, cmd)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Recast the command as "wire <option> to <x> <y>" so that it no longer
|
||||
* depends on the pointer position, for command logging.
|
||||
*/
|
||||
if (needCoord)
|
||||
{
|
||||
if (ToolGetPoint(&rootPoint, (Rect *)NULL) != NULL)
|
||||
{
|
||||
GeoTransPoint(&RootToEditTransform, &rootPoint, &point);
|
||||
sprintf(cmd->tx_argstring, "wire %s %s %di %di",
|
||||
cmd->tx_argv[1],
|
||||
(option == TYPE) ? "at" : "to",
|
||||
point.p_x, point.p_y);
|
||||
TxRebuildCommand(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1852,13 +1944,13 @@ CmdWire(w, cmd)
|
|||
#define OPT_WRITEALL_MODIFIED 1
|
||||
|
||||
void
|
||||
CmdWriteall(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdWriteall(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int cmdWriteallFunc();
|
||||
int cmdWriteallFunc(CellDef *def, TxCommand *cmd);
|
||||
int option = -1;
|
||||
static char *writeallOpts[] = { "force", "modified", 0 };
|
||||
static const char * const writeallOpts[] = { "force", "modified", 0 };
|
||||
int argc;
|
||||
int flags = CDMODIFIED | CDBOXESCHANGED | CDSTAMPSCHANGED;
|
||||
|
||||
|
|
@ -1868,7 +1960,7 @@ CmdWriteall(w, cmd)
|
|||
option = Lookup(cmd->tx_argv[1], writeallOpts);
|
||||
if (option < 0)
|
||||
{
|
||||
TxError("Usage: %s [force|modified|noupdate [cellname ...]]\n",
|
||||
TxError("Usage: %s [force|modified [cellname ...]]\n",
|
||||
cmd->tx_argv[0]);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1909,11 +2001,11 @@ CmdWriteall(w, cmd)
|
|||
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
cmdWriteallFunc(def, cmd)
|
||||
CellDef *def; /* Pointer to CellDef to be saved. This def might
|
||||
cmdWriteallFunc(
|
||||
CellDef *def, /* Pointer to CellDef to be saved. This def might
|
||||
* be an internal buffer; if so, we ignore it.
|
||||
*/
|
||||
TxCommand *cmd; /* Client data passed to DBCellSrDefs, a pointer
|
||||
TxCommand *cmd) /* Client data passed to DBCellSrDefs, a pointer
|
||||
* to the command structure. If cmd->tx_argc == 1,
|
||||
* then prompt for each action. If cmd->tx_argc
|
||||
* == 2, then write all cells without asking. If
|
||||
|
|
@ -1923,9 +2015,9 @@ cmdWriteallFunc(def, cmd)
|
|||
{
|
||||
char *prompt, *argv;
|
||||
int i, action, cidx = 0;
|
||||
static char *actionNames[] =
|
||||
static const char * const actionNames[] =
|
||||
{ "write", "flush", "skip", "abort", "autowrite", 0 };
|
||||
static char *explain[] =
|
||||
static const char * const explain[] =
|
||||
{ "", "(bboxes)", "(timestamps)", "(bboxes/timestamps)", 0 };
|
||||
|
||||
if (def->cd_flags & CDINTERNAL) return 0;
|
||||
|
|
@ -2012,9 +2104,9 @@ cmdWriteallFunc(def, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdXload(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdXload(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
if (w == (MagWindow *) NULL)
|
||||
|
|
@ -2060,9 +2152,9 @@ CmdXload(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdXor(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdXor(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int rval, xMask;
|
||||
bool dolabels;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,11 @@
|
|||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdWizard.c,v 1.2 2008/02/10 19:30:19 tim Exp $";
|
||||
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdWizard.c,v 1.2 2008/02/10 19:30:19 tim Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -46,12 +47,16 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "utils/utils.h"
|
||||
#include "textio/txcommands.h"
|
||||
|
||||
/* For diagnostics */
|
||||
#include "cif/CIFint.h"
|
||||
#include "database/databaseInt.h"
|
||||
|
||||
/* C99 compat */
|
||||
#include "extract/extract.h"
|
||||
|
||||
/* Forward declarations */
|
||||
|
||||
extern void cmdPsearchStats();
|
||||
extern void cmdPsearchStats(char *str, struct tms *tl, struct tms *td, int count);
|
||||
|
||||
void cmdStatsHier(CellDef *, int, CellDef *);
|
||||
|
||||
|
|
@ -78,9 +83,9 @@ void cmdStatsHier(CellDef *, int, CellDef *);
|
|||
*/
|
||||
|
||||
void
|
||||
CmdCoord(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdCoord(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
MagWindow *pointW = (MagWindow *) NULL;
|
||||
Rect editRect, rootRect;
|
||||
|
|
@ -180,14 +185,242 @@ CmdCoord(w, cmd)
|
|||
|
||||
#ifndef NO_EXT
|
||||
void
|
||||
CmdExtractTest(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdExtractTest(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
ExtractTest(w, cmd);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* tileCountProc --
|
||||
*
|
||||
* Routine to count tiles.
|
||||
*
|
||||
* Return:
|
||||
* 0 to keep the search going
|
||||
*
|
||||
* Side effects:
|
||||
* Keeps count in clientData
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
tileCountProc(
|
||||
Tile *tile, /* (unused) */
|
||||
TileType dinfo, /* (unused) */
|
||||
int *tcount)
|
||||
{
|
||||
(*tcount)++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* showMem --
|
||||
* CmdShowmem --
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* showmem [outfile]
|
||||
*
|
||||
* Display all the (principle) internal memory usage for tiles, including
|
||||
* all cell defs, and all CIF generated planes.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* May write to a disk file.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
showMem(
|
||||
FILE *outf, /* File to which information is to be output */
|
||||
bool verbose) /* If TRUE, output detailed erase table */
|
||||
{
|
||||
int ttotal, ttotal1, ttotal2;
|
||||
int i;
|
||||
Plane *plane;
|
||||
CellDef *def;
|
||||
int pNum;
|
||||
HashSearch hs;
|
||||
HashEntry *entry;
|
||||
|
||||
fprintf(outf, "Tile memory usage summary\n");
|
||||
fprintf(outf, "Technology %s\n", DBTechName);
|
||||
|
||||
/* Search every cell def (including internal ones), count tiles,
|
||||
* and add up the tile memory usage on every plane.
|
||||
*/
|
||||
|
||||
/* Search the CIFPlanes and count tiles. */
|
||||
/* CIFPlanes, CIFTotalPlanes, CIFComponentPlanes */
|
||||
|
||||
ttotal2 = 0;
|
||||
if (CIFCurStyle != NULL)
|
||||
{
|
||||
fprintf(outf, "\nCIFPlanes:\n");
|
||||
ttotal1 = 0;
|
||||
for (i = 0; i < MAXCIFLAYERS; i++)
|
||||
{
|
||||
plane = CIFPlanes[i];
|
||||
if (plane != NULL)
|
||||
{
|
||||
ttotal = 0;
|
||||
DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect,
|
||||
&DBAllTypeBits, tileCountProc, &ttotal);
|
||||
ttotal1 += ttotal;
|
||||
|
||||
if (CIFCurStyle->cs_layers[i])
|
||||
fprintf(outf, " layer %s: %ld\n",
|
||||
CIFCurStyle->cs_layers[i]->cl_name,
|
||||
(long)ttotal * (long)sizeof(Tile));
|
||||
else
|
||||
fprintf(outf, " layer %d: %d\n", i,
|
||||
(long)ttotal * (long)sizeof(Tile));
|
||||
}
|
||||
}
|
||||
fprintf(outf, " Subtotal: %ld bytes\n",
|
||||
(long)ttotal1 * (long)sizeof(Tile));
|
||||
ttotal2 += ttotal1;
|
||||
|
||||
fprintf(outf, "\nCIFTotalPlanes\n");
|
||||
ttotal1 = 0;
|
||||
for (i = 0; i < MAXCIFLAYERS; i++)
|
||||
{
|
||||
plane = CIFTotalPlanes[i];
|
||||
if (plane != NULL)
|
||||
{
|
||||
ttotal = 0;
|
||||
DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect,
|
||||
&DBAllTypeBits, tileCountProc, &ttotal);
|
||||
ttotal1 += ttotal;
|
||||
|
||||
if (CIFCurStyle->cs_layers[i])
|
||||
fprintf(outf, " layer %s: %ld\n",
|
||||
CIFCurStyle->cs_layers[i]->cl_name,
|
||||
(long)ttotal * (long)sizeof(Tile));
|
||||
else
|
||||
fprintf(outf, " layer %d: %d\n", i,
|
||||
(long)ttotal * (long)sizeof(Tile));
|
||||
}
|
||||
}
|
||||
fprintf(outf, " Subtotal: %ld bytes\n",
|
||||
(long)ttotal1 * (long)sizeof(Tile));
|
||||
ttotal2 += ttotal1;
|
||||
|
||||
fprintf(outf, "\nCIFComponentPlanes\n");
|
||||
ttotal1 = 0;
|
||||
for (i = 0; i < MAXCIFLAYERS; i++)
|
||||
{
|
||||
plane = CIFComponentPlanes[i];
|
||||
if (plane != NULL)
|
||||
{
|
||||
ttotal = 0;
|
||||
DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect,
|
||||
&DBAllTypeBits, tileCountProc, &ttotal);
|
||||
ttotal1 += ttotal;
|
||||
|
||||
if (CIFCurStyle->cs_layers[i])
|
||||
fprintf(outf, " layer %s: %ld bytes\n",
|
||||
CIFCurStyle->cs_layers[i]->cl_name,
|
||||
(long)ttotal * (long)sizeof(Tile));
|
||||
else
|
||||
fprintf(outf, " layer %d: %ld bytes\n", i,
|
||||
(long)ttotal * (long)sizeof(Tile));
|
||||
}
|
||||
}
|
||||
fprintf(outf, " Subtotal: %ld bytes\n",
|
||||
(long)ttotal1 * (long)sizeof(Tile));
|
||||
ttotal2 += ttotal1;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(outf, "CIF planes: No memory usage\n");
|
||||
}
|
||||
|
||||
HashStartSearch(&hs);
|
||||
while ((entry = HashNext(&dbCellDefTable, &hs)) != NULL)
|
||||
{
|
||||
def = (CellDef *)HashGetValue(entry);
|
||||
if (def != (CellDef *)NULL)
|
||||
{
|
||||
fprintf(outf, "\nCell def %s\n", def->cd_name);
|
||||
ttotal1 = 0;
|
||||
for (pNum = 0; pNum < DBNumPlanes; pNum++)
|
||||
{
|
||||
plane = def->cd_planes[pNum];
|
||||
if (plane != NULL)
|
||||
{
|
||||
ttotal = 0;
|
||||
DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect,
|
||||
&DBAllTypeBits, tileCountProc, &ttotal);
|
||||
|
||||
fprintf(outf, " plane %s: %ld bytes\n",
|
||||
DBPlaneLongNameTbl[pNum],
|
||||
(long)ttotal * (long)sizeof(Tile));
|
||||
ttotal1 += ttotal;
|
||||
}
|
||||
}
|
||||
fprintf(outf, " Subtotal: %ld bytes\n",
|
||||
(long)ttotal1 * (long)sizeof(Tile));
|
||||
ttotal2 += ttotal1;
|
||||
}
|
||||
}
|
||||
fprintf(outf, " Grand total: %ld bytes\n",
|
||||
(long)ttotal2 * (long)sizeof(Tile));
|
||||
}
|
||||
|
||||
void
|
||||
CmdShowmem(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
FILE *outf;
|
||||
bool verbose;
|
||||
char **av;
|
||||
int ac;
|
||||
|
||||
if (cmd->tx_argc > 3)
|
||||
{
|
||||
TxError("Usage: showmem [-v] [file]\n");
|
||||
return;
|
||||
}
|
||||
|
||||
verbose = FALSE;
|
||||
av = &cmd->tx_argv[1];
|
||||
ac = cmd->tx_argc - 1;
|
||||
|
||||
outf = stdout;
|
||||
if (ac > 0 && strcmp(av[0], "-v") == 0)
|
||||
{
|
||||
verbose = TRUE;
|
||||
av++, ac--;
|
||||
}
|
||||
|
||||
if (ac > 0)
|
||||
{
|
||||
outf = fopen(av[0], "w");
|
||||
if (outf == (FILE *) NULL)
|
||||
{
|
||||
perror(av[0]);
|
||||
TxError("Nothing written\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
showMem(outf, verbose);
|
||||
if (outf != stdout)
|
||||
(void) fclose(outf);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -211,9 +444,9 @@ CmdExtractTest(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
showTech(outf, verbose)
|
||||
FILE *outf; /* File to which information is to be output */
|
||||
bool verbose; /* If TRUE, output detailed erase table */
|
||||
showTech(
|
||||
FILE *outf, /* File to which information is to be output */
|
||||
bool verbose) /* If TRUE, output detailed erase table */
|
||||
{
|
||||
int i, j;
|
||||
int pNum;
|
||||
|
|
@ -231,7 +464,7 @@ showTech(outf, verbose)
|
|||
fprintf(outf, "\n");
|
||||
fprintf(outf, "Types:\n");
|
||||
for (i = 0; i < DBNumTypes; i++) {
|
||||
int pl ; char *spl ;
|
||||
int pl ; const char *spl ;
|
||||
|
||||
pl = DBPlane(i);
|
||||
spl = ( pl <= 0 || pl > DBNumPlanes ) ? "??" : DBPlaneLongName(pl);
|
||||
|
|
@ -358,9 +591,9 @@ showTech(outf, verbose)
|
|||
}
|
||||
|
||||
void
|
||||
CmdShowtech(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdShowtech(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
FILE *outf;
|
||||
bool verbose;
|
||||
|
|
@ -426,16 +659,16 @@ CmdShowtech(w, cmd)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdTilestats(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdTilestats(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
CellUse *selectedUse;
|
||||
FILE *outf = stdout;
|
||||
bool allDefs = FALSE;
|
||||
char **av = cmd->tx_argv + 1;
|
||||
int ac = cmd->tx_argc - 1;
|
||||
int cmdStatsFunc();
|
||||
int cmdStatsFunc(CellDef *def, FILE *outf);
|
||||
|
||||
if (ac > 2)
|
||||
{
|
||||
|
|
@ -510,11 +743,12 @@ int totalTiles[TT_MAXTYPES];
|
|||
*/
|
||||
|
||||
int
|
||||
cmdStatsFunc(def, outf)
|
||||
CellDef *def;
|
||||
FILE *outf;
|
||||
cmdStatsFunc(
|
||||
CellDef *def,
|
||||
FILE *outf)
|
||||
{
|
||||
int cmdStatsCount(), cmdStatsOutput();
|
||||
int cmdStatsCount(CellDef *def, struct countClient *cc);
|
||||
int cmdStatsOutput(CellDef *def, struct countClient *cc);
|
||||
struct countClient cc;
|
||||
int total;
|
||||
TileType t;
|
||||
|
|
@ -563,15 +797,17 @@ cmdStatsFunc(def, outf)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdStatsCount(def, cc)
|
||||
CellDef *def;
|
||||
struct countClient *cc;
|
||||
cmdStatsCount(
|
||||
CellDef *def,
|
||||
struct countClient *cc)
|
||||
{
|
||||
int cmdStatsCountTile();
|
||||
int pNum;
|
||||
struct cellInfo *ci;
|
||||
TileType t;
|
||||
|
||||
/* Forward declaration */
|
||||
int cmdStatsCountTile(Tile *tile, TileType dinfo, struct cellInfo *ci);
|
||||
|
||||
if (def->cd_client)
|
||||
return (1);
|
||||
|
||||
|
|
@ -594,9 +830,10 @@ cmdStatsCount(def, cc)
|
|||
}
|
||||
|
||||
int
|
||||
cmdStatsCountTile(tile, ci)
|
||||
Tile *tile;
|
||||
struct cellInfo *ci;
|
||||
cmdStatsCountTile(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* (unused) */
|
||||
struct cellInfo *ci)
|
||||
{
|
||||
TileType type = TiGetType(tile);
|
||||
|
||||
|
|
@ -637,9 +874,10 @@ cmdStatsCountTile(tile, ci)
|
|||
*/
|
||||
|
||||
void
|
||||
cmdStatsHier(parent, nuses, child)
|
||||
CellDef *parent, *child;
|
||||
int nuses;
|
||||
cmdStatsHier(
|
||||
CellDef *parent,
|
||||
int nuses,
|
||||
CellDef *child)
|
||||
{
|
||||
struct cellInfo *pi, *ci;
|
||||
TileType t;
|
||||
|
|
@ -684,9 +922,9 @@ cmdStatsHier(parent, nuses, child)
|
|||
*/
|
||||
|
||||
int
|
||||
cmdStatsOutput(def, cc)
|
||||
CellDef *def;
|
||||
struct countClient *cc;
|
||||
cmdStatsOutput(
|
||||
CellDef *def,
|
||||
struct countClient *cc)
|
||||
{
|
||||
TileType t;
|
||||
struct cellInfo *ci;
|
||||
|
|
@ -749,11 +987,11 @@ cmdStatsOutput(def, cc)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdPsearch(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdPsearch(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
char *RunStats();
|
||||
char *RunStats(int flags, struct tms *lastt, struct tms *deltat);
|
||||
static struct tms tlast, tdelta;
|
||||
Point p;
|
||||
Plane *plane;
|
||||
|
|
@ -815,12 +1053,13 @@ CmdPsearch(w, cmd)
|
|||
}
|
||||
|
||||
void
|
||||
cmdPsearchStats(str, tl, td, count)
|
||||
char *str;
|
||||
struct tms *tl, *td;
|
||||
int count;
|
||||
cmdPsearchStats(
|
||||
char *str,
|
||||
struct tms *tl,
|
||||
struct tms *td,
|
||||
int count)
|
||||
{
|
||||
char *RunStats();
|
||||
char *RunStats(int flags, struct tms *lastt, struct tms *deltat);
|
||||
char *rstatp;
|
||||
int us, ups;
|
||||
|
||||
|
|
@ -860,20 +1099,22 @@ int numTilesFound;
|
|||
bool cmdTsearchDebug = FALSE;
|
||||
|
||||
void
|
||||
CmdTsearch(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdTsearch(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int cmdTsrFunc();
|
||||
char *RunStats(), *rstatp;
|
||||
char *rstatp;
|
||||
static TileTypeBitMask mask;
|
||||
static struct tms tlast, tdelta;
|
||||
Rect rtool, rsearch;
|
||||
/**** Rect *ebox; ****/
|
||||
Plane *plane;
|
||||
int i, pNum, count;
|
||||
int usPerSearch, usPerTile, usPerL2, us, boxarea;
|
||||
|
||||
/* Forward declarations */
|
||||
int cmdTsrFunc(Tile *tp, TileType dinfo, ClientData clientdata);
|
||||
char *RunStats(int flags, struct tms *lastt, struct tms *deltat);
|
||||
|
||||
if (cmd->tx_argc < 3 || cmd->tx_argc > 5)
|
||||
{
|
||||
TxError("Usage: tsearch plane count [mask [new|mayo]]\n");
|
||||
|
|
@ -972,11 +1213,13 @@ CmdTsearch(w, cmd)
|
|||
}
|
||||
|
||||
int
|
||||
cmdTsrFunc(tp)
|
||||
Tile *tp;
|
||||
cmdTsrFunc(
|
||||
Tile *tp,
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
if (cmdTsearchDebug)
|
||||
TxPrintf("%x\n", tp);
|
||||
TxPrintf("%lx\n", (intptr_t) tp);
|
||||
numTilesFound++;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -999,9 +1242,9 @@ cmdTsrFunc(tp)
|
|||
*/
|
||||
|
||||
void
|
||||
CmdWatch(w, cmd)
|
||||
MagWindow *w;
|
||||
TxCommand *cmd;
|
||||
CmdWatch(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
DBWclientRec *crec;
|
||||
int pNum;
|
||||
|
|
@ -1042,7 +1285,7 @@ CmdWatch(w, cmd)
|
|||
pNum = DBTechNamePlane(cmd->tx_argv[1]);
|
||||
if (pNum < 0)
|
||||
{
|
||||
char *cp;
|
||||
const char *cp;
|
||||
TxError("Unrecognized plane: %s. Legal names are:\n",
|
||||
cmd->tx_argv[1]);
|
||||
for(pNum=0; pNum < PL_MAXTYPES; pNum++) {
|
||||
|
|
@ -1052,8 +1295,16 @@ CmdWatch(w, cmd)
|
|||
};
|
||||
return;
|
||||
}
|
||||
crec->dbw_watchDef = EditCellUse->cu_def;
|
||||
crec->dbw_watchTrans = EditToRootTransform;
|
||||
if (EditCellUse != NULL)
|
||||
{
|
||||
crec->dbw_watchDef = EditCellUse->cu_def;
|
||||
crec->dbw_watchTrans = EditToRootTransform;
|
||||
}
|
||||
else
|
||||
{
|
||||
crec->dbw_watchDef = ((CellUse *)w->w_surfaceID)->cu_def;
|
||||
crec->dbw_watchTrans = ((CellUse *)w->w_surfaceID)->cu_transform;
|
||||
}
|
||||
}
|
||||
|
||||
crec->dbw_watchPlane = pNum;
|
||||
|
|
|
|||
|
|
@ -12,10 +12,9 @@ SRCS = CmdSubrs.c CmdAB.c CmdCD.c CmdE.c CmdFI.c \
|
|||
|
||||
module: ${MAGICDIR}/readline/readline lib${MODULE}.o
|
||||
|
||||
# Delegate this task to the readline/Makefile
|
||||
${MAGICDIR}/readline/readline:
|
||||
@if ( ! test -f ${MAGICDIR}/readline/readline ) ; then \
|
||||
(cd ${MAGICDIR}/readline; ln -s `ls | grep readline` readline) ; \
|
||||
fi
|
||||
${MAKE} -C ${MAGICDIR}/readline readline-create-symlinks
|
||||
|
||||
include ${MAGICDIR}/defs.mak
|
||||
include ${MAGICDIR}/rules.mak
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/commands/commands.h,v 1.3 2009/01/19 15:43:03 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _COMMANDS_H
|
||||
#define _COMMANDS_H
|
||||
#ifndef _MAGIC__COMMANDS__COMMANDS_H
|
||||
#define _MAGIC__COMMANDS__COMMANDS_H
|
||||
|
||||
#include "windows/windows.h"
|
||||
#include "database/database.h"
|
||||
#include "textio/txcommands.h" /* TxCommand */
|
||||
|
||||
/*
|
||||
* Name of default yank buffer
|
||||
|
|
@ -50,30 +51,28 @@ extern TileTypeBitMask CmdYMAllButSpace;
|
|||
|
||||
/* --------------------- Global procedure headers --------------------- */
|
||||
|
||||
extern MagWindow *CmdGetRootBox();
|
||||
extern MagWindow *CmdGetEditPoint();
|
||||
extern MagWindow *CmdGetRootPoint();
|
||||
extern bool CmdWarnWrite();
|
||||
extern bool CmdParseLayers();
|
||||
extern void CmdAddSlop();
|
||||
extern void CmdLabelProc();
|
||||
extern void CmdSetWindCaption();
|
||||
extern CellUse *CmdGetSelectedCell();
|
||||
extern bool CmdIllegalChars();
|
||||
extern void CmdDoMacro();
|
||||
extern TileType CmdFindNetProc();
|
||||
extern bool CmdCheckForPaintFunc();
|
||||
extern MagWindow *CmdGetEditPoint(Point *point, Rect *rect);
|
||||
extern MagWindow *CmdGetRootPoint(Point *point, Rect *rect);
|
||||
extern bool CmdWarnWrite(void);
|
||||
extern bool CmdParseLayers(char *s, TileTypeBitMask *mask);
|
||||
extern void CmdLabelProc(char *text, int font, int size, int rotate, int offx, int offy,
|
||||
int pos, bool sticky, TileType type);
|
||||
extern void CmdSetWindCaption(CellUse *newEditUse, CellDef *rootDef);
|
||||
extern CellUse *CmdGetSelectedCell(Transform *pTrans);
|
||||
extern bool CmdIllegalChars(char *string, char *illegal, char *msg);
|
||||
extern TileType CmdFindNetProc(char *nodename, CellUse *use, Rect *rect, bool warn_not_found, bool *isvalid);
|
||||
extern bool CmdCheckForPaintFunc(void);
|
||||
|
||||
/* C99 compat */
|
||||
extern int cmdScaleCoord();
|
||||
extern void FlatCopyAllLabels();
|
||||
extern bool cmdDumpParseArgs();
|
||||
extern void cmdFlushCell();
|
||||
extern int cmdParseCoord();
|
||||
extern void cmdSaveCell();
|
||||
extern void CmdInit();
|
||||
extern int cmdScaleCoord(MagWindow *w, char *arg, bool is_relative, bool is_x, int scale);
|
||||
extern void FlatCopyAllLabels(SearchContext *scx, TileTypeBitMask *mask, int xMask, CellUse *targetUse);
|
||||
extern bool cmdDumpParseArgs(char *cmdName, MagWindow *w, TxCommand *cmd, CellUse *dummy, SearchContext *scx);
|
||||
extern void cmdFlushCell(CellDef *def, bool force_deref);
|
||||
extern int cmdParseCoord(MagWindow *w, char *arg, bool is_relative, bool is_x);
|
||||
extern void cmdSaveCell(CellDef *cellDef, char *newName, bool noninteractive, bool tryRename);
|
||||
extern void CmdInit(void);
|
||||
|
||||
extern void CmdDoProperty();
|
||||
extern void CmdPaintEraseButton();
|
||||
extern void CmdDoProperty(CellDef *def, TxCommand *cmd, int argstart);
|
||||
extern void CmdPaintEraseButton(MagWindow *w, Point *refPoint, bool isPaint, bool isScreen);
|
||||
|
||||
#endif /* _COMMANDS_H */
|
||||
#endif /* _MAGIC__COMMANDS__COMMANDS_H */
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@
|
|||
# script itself. It also sets up CFLAGS without the default optimizer
|
||||
# flag (-O2).
|
||||
|
||||
( CFLAGS="-g"; export CFLAGS; cd scripts ; ./configure "$@" )
|
||||
( CFLAGS=${CFLAGS:-"-g"}; export CFLAGS; cd scripts ; ./configure "$@" )
|
||||
|
|
|
|||
|
|
@ -30,19 +30,32 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
typedef struct dbcellboundstruct
|
||||
{
|
||||
Rect *area;
|
||||
bool extended;
|
||||
Rect *extended;
|
||||
bool found;
|
||||
} DBCellBoundStruct;
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
* DBBoundCellPlane ---
|
||||
*
|
||||
* Find the extents of all subcells of the cell "def", both the
|
||||
* extent of geometry (rect) and the extent of geometry plus any
|
||||
* labels extending outside the extent of geometry (extended).
|
||||
*
|
||||
* Results:
|
||||
* TRUE if subcells were found and measured; FALSE if no subcells
|
||||
* were found (in which case "extended" and "rect" may not be
|
||||
* valid).
|
||||
*
|
||||
* Side effects:
|
||||
* Values may be recorded in "extended" and "rect".
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
DBBoundCellPlane(def, extended, rect)
|
||||
CellDef *def;
|
||||
bool extended;
|
||||
Rect *extended;
|
||||
Rect *rect;
|
||||
{
|
||||
TreeFilter filter;
|
||||
|
|
@ -70,25 +83,19 @@ dbCellBoundFunc(use, fp)
|
|||
CellUse *use;
|
||||
TreeFilter *fp;
|
||||
{
|
||||
Rect *bbox;
|
||||
DBCellBoundStruct *cbs;
|
||||
|
||||
cbs = (DBCellBoundStruct *)fp->tf_arg;
|
||||
|
||||
bbox = &use->cu_bbox;
|
||||
if (cbs->found)
|
||||
{
|
||||
if (cbs->extended)
|
||||
GeoInclude(&use->cu_extended, cbs->area);
|
||||
else
|
||||
GeoInclude(&use->cu_bbox, cbs->area);
|
||||
GeoInclude(&use->cu_extended, cbs->extended);
|
||||
GeoInclude(&use->cu_bbox, cbs->area);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cbs->extended)
|
||||
*cbs->area = use->cu_extended;
|
||||
else
|
||||
*cbs->area = use->cu_bbox;
|
||||
*cbs->extended = use->cu_extended;
|
||||
*cbs->area = use->cu_bbox;
|
||||
cbs->found = TRUE;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -106,8 +106,57 @@ DBCellFindDup(use, parent)
|
|||
|
||||
BPEnumInit(&bpe, parent->cd_cellPlane, &use->cu_bbox, BPE_EQUAL,
|
||||
"DBCellFindDup");
|
||||
while (dupUse = BPEnumNext(&bpe))
|
||||
if (dupUse->cu_def == use->cu_def) break;
|
||||
while ((dupUse = BPEnumNext(&bpe)))
|
||||
if (dupUse->cu_def == use->cu_def)
|
||||
{
|
||||
bool transMatch, arrayMatch, notXarray, notYarray;
|
||||
|
||||
/* Transforms must be equal---Aligned bounding boxes are
|
||||
* an insufficient measure of exact overlap. Also, array
|
||||
* counts and separation must match for arrayed devices
|
||||
*/
|
||||
transMatch = ((dupUse->cu_transform.t_a == use->cu_transform.t_a) &&
|
||||
(dupUse->cu_transform.t_b == use->cu_transform.t_b) &&
|
||||
(dupUse->cu_transform.t_c == use->cu_transform.t_c) &&
|
||||
(dupUse->cu_transform.t_d == use->cu_transform.t_d) &&
|
||||
(dupUse->cu_transform.t_e == use->cu_transform.t_e) &&
|
||||
(dupUse->cu_transform.t_f == use->cu_transform.t_f));
|
||||
|
||||
/* First check if both use and dupUse are not arrays. */
|
||||
notXarray = (dupUse->cu_xhi == dupUse->cu_xlo) &&
|
||||
(use->cu_xhi == use->cu_xlo);
|
||||
|
||||
notYarray = (dupUse->cu_yhi == dupUse->cu_ylo) &&
|
||||
(use->cu_yhi == use->cu_ylo);
|
||||
|
||||
arrayMatch = (notXarray && notYarray);
|
||||
|
||||
/* If they are arrays, then the array parameters must match. */
|
||||
|
||||
if (!notXarray && notYarray)
|
||||
{
|
||||
arrayMatch = ((dupUse->cu_xhi - dupUse->cu_xlo) ==
|
||||
(use->cu_xhi - use->cu_xlo)) &&
|
||||
(dupUse->cu_xsep == use->cu_xsep);
|
||||
}
|
||||
else if (!notYarray && notXarray)
|
||||
{
|
||||
arrayMatch = ((dupUse->cu_yhi - dupUse->cu_ylo) ==
|
||||
(use->cu_yhi - use->cu_ylo)) &&
|
||||
(dupUse->cu_ysep == use->cu_ysep);
|
||||
}
|
||||
else if (!notYarray && !notXarray)
|
||||
{
|
||||
arrayMatch = (((dupUse->cu_xhi - dupUse->cu_xlo) ==
|
||||
(use->cu_xhi - use->cu_xlo)) &&
|
||||
(dupUse->cu_xsep == use->cu_xsep)) &&
|
||||
(((dupUse->cu_yhi - dupUse->cu_ylo) ==
|
||||
(use->cu_yhi - use->cu_ylo)) &&
|
||||
(dupUse->cu_ysep == use->cu_ysep));
|
||||
}
|
||||
if (transMatch && arrayMatch)
|
||||
break;
|
||||
}
|
||||
|
||||
BPEnumTerm(&bpe);
|
||||
return dupUse;
|
||||
|
|
|
|||
|
|
@ -59,15 +59,15 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
*/
|
||||
|
||||
char *
|
||||
DBPrintUseId(scx, name, size, display_only)
|
||||
SearchContext *scx; /* Pointer to current search context, specifying a
|
||||
DBPrintUseId(
|
||||
SearchContext *scx, /* Pointer to current search context, specifying a
|
||||
* cell use and X,Y array indices.
|
||||
*/
|
||||
char *name; /* Pointer to string into which we will copy the
|
||||
char *name, /* Pointer to string into which we will copy the
|
||||
* print name of this instance.
|
||||
*/
|
||||
int size; /* Maximum number of characters to copy into string. */
|
||||
bool display_only; /* TRUE if called for displaying only */
|
||||
int size, /* Maximum number of characters to copy into string. */
|
||||
bool display_only) /* TRUE if called for displaying only */
|
||||
{
|
||||
CellUse *use = scx->scx_use;
|
||||
char *sp, *id, *ep;
|
||||
|
|
@ -619,8 +619,9 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
|
|||
/*
|
||||
* Include area of subcells separately
|
||||
*/
|
||||
if ((foundAny = DBBoundCellPlane(cellDef, TRUE, &rect)) > 0)
|
||||
area = rect;
|
||||
if (!((foundAny = DBBoundCellPlane(cellDef, &extended, &rect)) > 0))
|
||||
extended = GeoNullRect;
|
||||
area = rect;
|
||||
|
||||
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
|
||||
if (pNum != PL_DRC_CHECK)
|
||||
|
|
@ -634,7 +635,7 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
|
|||
}
|
||||
|
||||
/*
|
||||
* Include the area of labels, too.
|
||||
* Include the area of label anchors, too.
|
||||
*/
|
||||
for (label = cellDef->cd_labels; label != NULL; label = label->lab_next)
|
||||
{
|
||||
|
|
@ -656,7 +657,11 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
|
|||
}
|
||||
}
|
||||
|
||||
extended = area;
|
||||
/* Make sure the extended bounding box includes the area of all
|
||||
* paint material just found, then include the area of all text
|
||||
* in the current cell.
|
||||
*/
|
||||
GeoInclude(&area, &extended);
|
||||
if (foundAny)
|
||||
{
|
||||
for (label = cellDef->cd_labels; label != NULL; label = label->lab_next)
|
||||
|
|
@ -673,6 +678,7 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
|
|||
degenerate = TRUE;
|
||||
area.r_xbot = area.r_ybot = 0;
|
||||
area.r_xtop = area.r_ytop = 1;
|
||||
extended = area;
|
||||
}
|
||||
else degenerate = FALSE;
|
||||
|
||||
|
|
@ -687,7 +693,11 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
|
|||
if (area.r_ybot == area.r_ytop)
|
||||
area.r_ytop = area.r_ybot + 1;
|
||||
|
||||
if (degenerate) extended = area;
|
||||
if (extended.r_xbot == extended.r_xtop)
|
||||
extended.r_xtop = extended.r_xbot + 1;
|
||||
|
||||
if (extended.r_ybot == extended.r_ytop)
|
||||
extended.r_ytop = extended.r_ybot + 1;
|
||||
|
||||
/* Did the bounding box change? If not then there's no need to
|
||||
* recompute the parents. If the cell has no material, then
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* For strlen() and strncmp() */
|
||||
#include <ctype.h> /* for isspace() */
|
||||
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
#include "utils/geofast.h"
|
||||
|
|
@ -349,6 +352,430 @@ DBCellCheckCopyAllPaint(scx, mask, xMask, targetUse, func)
|
|||
DBTreeSrTiles(scx, &locMask, xMask, dbCopyAllPaint, (ClientData) &arg);
|
||||
}
|
||||
|
||||
/* Data structure used by dbCopyMaskHintsFunc */
|
||||
|
||||
struct propUseDefStruct {
|
||||
CellDef *puds_source;
|
||||
CellDef *puds_dest;
|
||||
Transform *puds_trans; /* Transform from source use to dest */
|
||||
};
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* dbCopyMaskHintsFunc --
|
||||
*
|
||||
* Callback function used by DBCellCopyMaskHints(). Does the work
|
||||
* of copying a "mask-hints" property from a child instance into its
|
||||
* parent def, modifying coordinates according to the child instance's
|
||||
* transform.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Creates properties in the parent cell.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbCopyMaskHintsFunc(key, value, puds)
|
||||
char *key;
|
||||
ClientData value;
|
||||
struct propUseDefStruct *puds;
|
||||
{
|
||||
CellDef *dest = puds->puds_dest;
|
||||
Transform *trans = puds->puds_trans;
|
||||
char *propstr = (char *)value;
|
||||
char *parentprop, *newvalue, *vptr;
|
||||
Rect r, rnew;
|
||||
bool propfound;
|
||||
|
||||
if (!strncmp(key, "MASKHINTS_", 10))
|
||||
{
|
||||
char *vptr, *lastval;
|
||||
int lastlen;
|
||||
|
||||
/* Append to existing mask hint (if any) */
|
||||
parentprop = (char *)DBPropGet(dest, key, &propfound);
|
||||
newvalue = (propfound) ? StrDup((char **)NULL, parentprop) : (char *)NULL;
|
||||
|
||||
vptr = propstr;
|
||||
while (*vptr != '\0')
|
||||
{
|
||||
if (sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop) == 4)
|
||||
{
|
||||
GeoTransRect(trans, &r, &rnew);
|
||||
|
||||
lastval = newvalue;
|
||||
lastlen = (lastval) ? strlen(lastval) : 0;
|
||||
newvalue = mallocMagic(40 + lastlen);
|
||||
|
||||
if (lastval)
|
||||
strcpy(newvalue, lastval);
|
||||
else
|
||||
*newvalue = '\0';
|
||||
|
||||
sprintf(newvalue + lastlen, "%s%d %d %d %d", (lastval) ? " " : "",
|
||||
rnew.r_xbot, rnew.r_ybot, rnew.r_xtop, rnew.r_ytop);
|
||||
if (lastval) freeMagic(lastval);
|
||||
|
||||
while (*vptr && !isspace(*vptr)) vptr++;
|
||||
while (*vptr && isspace(*vptr)) vptr++;
|
||||
while (*vptr && !isspace(*vptr)) vptr++;
|
||||
while (*vptr && isspace(*vptr)) vptr++;
|
||||
while (*vptr && !isspace(*vptr)) vptr++;
|
||||
while (*vptr && isspace(*vptr)) vptr++;
|
||||
while (*vptr && !isspace(*vptr)) vptr++;
|
||||
while (*vptr && isspace(*vptr)) vptr++;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
if (newvalue)
|
||||
DBPropPut(dest, key, newvalue);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DBCellCopyMaskHints --
|
||||
*
|
||||
* This function is used by the "flatten -inplace" command option to
|
||||
* transfer information from mask-hint properties from a flattened
|
||||
* child cell to the parent.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Properties copied from child to parent cell and modified.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
DBCellCopyMaskHints(child, parent, transform)
|
||||
CellUse *child;
|
||||
CellDef *parent;
|
||||
Transform *transform;
|
||||
{
|
||||
struct propUseDefStruct puds;
|
||||
|
||||
puds.puds_source = child->cu_def;
|
||||
puds.puds_dest = parent;
|
||||
puds.puds_trans = transform;
|
||||
DBPropEnum(child->cu_def, dbCopyMaskHintsFunc, (ClientData)&puds);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* dbFlatCopyMaskHintsFunc ---
|
||||
*
|
||||
* Callback function used by DBFlatCopyMaskHints() to copy mask hint
|
||||
* properties from a child cell into a flattened cell def. This is
|
||||
* simply a variant of DBCellCopyMaskHints() above, with arguments
|
||||
* appropriate to being called from DBTreeSrCells(), and applying
|
||||
* the transform from the search context.
|
||||
*
|
||||
* Results:
|
||||
* 0 to keep the cell search going.
|
||||
*
|
||||
* Side effects:
|
||||
* Generates properties in the target def.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
int
|
||||
dbFlatCopyMaskHintsFunc(scx, def)
|
||||
SearchContext *scx;
|
||||
CellDef *def;
|
||||
{
|
||||
struct propUseDefStruct puds;
|
||||
CellUse *use = scx->scx_use;
|
||||
|
||||
puds.puds_source = scx->scx_use->cu_def;
|
||||
puds.puds_dest = def;
|
||||
puds.puds_trans = &scx->scx_trans;
|
||||
|
||||
DBPropEnum(use->cu_def, dbCopyMaskHintsFunc, (ClientData)&puds);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DBFlatCopyMaskHints --
|
||||
*
|
||||
* This function is used by the "flatten" command option to copy information
|
||||
* in mask-hint properties from flattened children to a flattened cell def.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Properties copied from child to parent cell and modified.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
void
|
||||
DBFlatCopyMaskHints(scx, xMask, targetUse)
|
||||
SearchContext *scx; /* Describes root cell to search, area to
|
||||
* copy, transform from root cell to coords
|
||||
* of targetUse.
|
||||
*/
|
||||
int xMask; /* Expansion state mask to be used in search */
|
||||
CellUse *targetUse; /* Cell into which properties will be added */
|
||||
{
|
||||
DBTreeSrCells(scx, xMask, dbFlatCopyMaskHintsFunc, (ClientData)targetUse->cu_def);
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DBFlattenInPlace --
|
||||
*
|
||||
* This function is used by the "flatten" command "-doinplace" option to
|
||||
* flatten a cell instance into its parent cell.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Indicated cell use is flattened into the edit cell def.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DBFlattenInPlace(use, dest, xMask, dolabels, toplabels, doclear)
|
||||
CellUse *use; /* Cell use to flatten */
|
||||
CellUse *dest; /* Cell use to flatten into */
|
||||
int xMask; /* Search mask for flattening */
|
||||
bool dolabels; /* Option to flatten labels */
|
||||
bool toplabels; /* Option to selectively flatten top-level labels */
|
||||
bool doclear; /* Delete the original use if TRUE */
|
||||
{
|
||||
Label *lab;
|
||||
SearchContext scx;
|
||||
int xsep, ysep, xbase, ybase;
|
||||
|
||||
if (dest == NULL)
|
||||
{
|
||||
TxError("The target cell does not exist or is not editable.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
scx.scx_use = use;
|
||||
scx.scx_area = use->cu_def->cd_bbox;
|
||||
|
||||
/* Mark labels in the subcell top level for later handling */
|
||||
for (lab = scx.scx_use->cu_def->cd_labels; lab; lab = lab->lab_next)
|
||||
lab->lab_flags |= LABEL_GENERATE;
|
||||
|
||||
scx.scx_x = use->cu_xlo;
|
||||
scx.scx_y = use->cu_ylo;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if ((use->cu_xlo == use->cu_xhi) && (use->cu_ylo == use->cu_yhi))
|
||||
scx.scx_trans = use->cu_transform;
|
||||
else
|
||||
{
|
||||
if (use->cu_xlo > use->cu_xhi) xsep = -use->cu_xsep;
|
||||
else xsep = use->cu_xsep;
|
||||
if (use->cu_ylo > use->cu_yhi) ysep = -use->cu_ysep;
|
||||
else ysep = use->cu_ysep;
|
||||
xbase = xsep * (scx.scx_x - use->cu_xlo);
|
||||
ybase = ysep * (scx.scx_y - use->cu_ylo);
|
||||
GeoTransTranslate(xbase, ybase, &use->cu_transform, &scx.scx_trans);
|
||||
}
|
||||
|
||||
DBCellCopyAllPaint(&scx, &DBAllButSpaceAndDRCBits, xMask, dest);
|
||||
if (dolabels)
|
||||
FlatCopyAllLabels(&scx, &DBAllTypeBits, xMask, dest);
|
||||
else if (toplabels)
|
||||
{
|
||||
int savemask = scx.scx_use->cu_expandMask;
|
||||
scx.scx_use->cu_expandMask = CU_DESCEND_SPECIAL;
|
||||
DBCellCopyAllLabels(&scx, &DBAllTypeBits, CU_DESCEND_SPECIAL, dest, NULL);
|
||||
scx.scx_use->cu_expandMask = savemask;
|
||||
}
|
||||
|
||||
if (xMask != CU_DESCEND_ALL)
|
||||
DBCellCopyAllCells(&scx, xMask, dest, (Rect *)NULL);
|
||||
|
||||
/* Marked labels coming from the subcell top level must not be */
|
||||
/* ports, and text should be prefixed with the subcell name. */
|
||||
|
||||
for (lab = dest->cu_def->cd_labels; lab; lab = lab->lab_next)
|
||||
{
|
||||
Label *newlab;
|
||||
char *newtext;
|
||||
|
||||
if (lab->lab_flags & LABEL_GENERATE)
|
||||
{
|
||||
newtext = mallocMagic(strlen(lab->lab_text)
|
||||
+ strlen(scx.scx_use->cu_id) + 2);
|
||||
|
||||
if ((use->cu_xlo != use->cu_xhi) && (use->cu_ylo != use->cu_yhi))
|
||||
sprintf(newtext, "%s[%d][%d]/%s", scx.scx_use->cu_id,
|
||||
scx.scx_x, scx.scx_y, lab->lab_text);
|
||||
else if (use->cu_xlo != use->cu_xhi)
|
||||
sprintf(newtext, "%s[%d]/%s", scx.scx_use->cu_id,
|
||||
scx.scx_x, lab->lab_text);
|
||||
else if (use->cu_ylo != use->cu_yhi)
|
||||
sprintf(newtext, "%s[%d]/%s", scx.scx_use->cu_id,
|
||||
scx.scx_y, lab->lab_text);
|
||||
else
|
||||
sprintf(newtext, "%s/%s", scx.scx_use->cu_id, lab->lab_text);
|
||||
|
||||
DBPutFontLabel(dest->cu_def,
|
||||
&lab->lab_rect, lab->lab_font, lab->lab_size,
|
||||
lab->lab_rotate, &lab->lab_offset, lab->lab_just,
|
||||
newtext, lab->lab_type, 0, 0);
|
||||
DBEraseLabelsByContent(dest->cu_def, &lab->lab_rect,
|
||||
-1, lab->lab_text);
|
||||
|
||||
freeMagic(newtext);
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy and transform mask hints from child to parent */
|
||||
DBCellCopyMaskHints(scx.scx_use, dest->cu_def, &scx.scx_trans);
|
||||
|
||||
/* Stop processing if the use is not arrayed. */
|
||||
if ((scx.scx_x == use->cu_xhi) && (scx.scx_y == use->cu_yhi))
|
||||
break;
|
||||
|
||||
if (use->cu_xlo < use->cu_xhi)
|
||||
scx.scx_x++;
|
||||
else if (use->cu_xlo > use->cu_xhi)
|
||||
scx.scx_x--;
|
||||
|
||||
if (((use->cu_xlo < use->cu_xhi) && (scx.scx_x > use->cu_xhi)) ||
|
||||
((use->cu_xlo > use->cu_xhi) && (scx.scx_x < use->cu_xhi)))
|
||||
{
|
||||
if (use->cu_ylo < use->cu_yhi)
|
||||
{
|
||||
scx.scx_y++;
|
||||
scx.scx_x = use->cu_xlo;
|
||||
}
|
||||
else if (use->cu_ylo > use->cu_yhi)
|
||||
{
|
||||
scx.scx_y--;
|
||||
scx.scx_x = use->cu_xlo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmark labels in the subcell top level */
|
||||
for (lab = scx.scx_use->cu_def->cd_labels; lab; lab = lab->lab_next)
|
||||
lab->lab_flags &= ~LABEL_GENERATE;
|
||||
|
||||
/* Remove the use from the parent def */
|
||||
if (doclear)
|
||||
DBDeleteCell(scx.scx_use);
|
||||
|
||||
/* Was: &scx.scx_use->cu_def->cd_bbox */
|
||||
DBWAreaChanged(dest->cu_def, &scx.scx_use->cu_bbox,
|
||||
DBW_ALLWINDOWS, &DBAllButSpaceAndDRCBits);
|
||||
}
|
||||
|
||||
/* Client data structure used by DBCellFlattenAllCells() */
|
||||
|
||||
struct dbFlattenAllData {
|
||||
CellUse *fad_dest; /* Cell use to flatten into */
|
||||
int fad_xmask; /* Search mask for flattening */
|
||||
bool fad_dolabels; /* Option to flatten labels */
|
||||
bool fad_toplabels; /* Option to selectively flatten top-level labels */
|
||||
};
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* dbCellFlattenCellsFunc --
|
||||
*
|
||||
* Do the actual work of flattening cells for DBCellFlattenAllCells().
|
||||
*
|
||||
* Results:
|
||||
* Always return 2.
|
||||
*
|
||||
* Side effects:
|
||||
* Updates the paint planes of EditRootDef.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbCellFlattenCellsFunc(scx, clientData)
|
||||
SearchContext *scx; /* Pointer to search context containing
|
||||
* ptr to cell use to be copied,
|
||||
* and transform to the target def.
|
||||
*/
|
||||
ClientData clientData; /* Data passed to client function */
|
||||
{
|
||||
CellUse *use, *dest;
|
||||
int xMask;
|
||||
bool dolabels;
|
||||
bool toplabels;
|
||||
struct dbFlattenAllData *fad = (struct dbFlattenAllData *)clientData;
|
||||
|
||||
dest = fad->fad_dest;
|
||||
xMask = fad->fad_xmask;
|
||||
dolabels = fad->fad_dolabels;
|
||||
toplabels = fad->fad_toplabels;
|
||||
|
||||
use = scx->scx_use;
|
||||
DBFlattenInPlace(use, dest, xMask, dolabels, toplabels, FALSE);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DBCellFlattenAllCells --
|
||||
*
|
||||
* Flatten subcells from the tree rooted at scx->scx_use into the edit root
|
||||
* CellDef, transforming according to the transform in scx.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Updates the paint planes in EditRootDef.
|
||||
*
|
||||
*-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DBCellFlattenAllCells(scx, dest, xMask, dolabels, toplabels)
|
||||
SearchContext *scx; /* Describes root cell to search and transform
|
||||
* from root cell to coords of targetUse.
|
||||
*/
|
||||
CellUse *dest; /* CellUse to flatten into (usually EditCellUse) */
|
||||
int xMask; /* Expansion state mask to be passed to
|
||||
* the flattening routine that determines
|
||||
* whether to do a shallow or deep flattening.
|
||||
*/
|
||||
bool dolabels; /* Option to flatten labels */
|
||||
bool toplabels; /* Option to selectively flatten top-level labels */
|
||||
{
|
||||
int dbCellFlattenCellsFunc();
|
||||
struct dbFlattenAllData fad;
|
||||
|
||||
fad.fad_dest = dest;
|
||||
fad.fad_xmask = xMask;
|
||||
fad.fad_dolabels = dolabels;
|
||||
fad.fad_toplabels = toplabels;
|
||||
DBTreeSrCells(scx, CU_DESCEND_ALL, dbCellFlattenCellsFunc, (ClientData)&fad);
|
||||
}
|
||||
|
||||
/* Client data structure used by DBCellGenerateSubstrate() */
|
||||
|
||||
struct dbCopySubData {
|
||||
|
|
@ -450,6 +877,89 @@ DBCellGenerateSubstrate(scx, subType, notSubMask, subShieldMask, targetDef)
|
|||
return tempPlane;
|
||||
}
|
||||
|
||||
/*
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
* DBCellGenerateSimpleSubstrate --
|
||||
*
|
||||
* This function is used by the extraction code in "extresist".
|
||||
* It is similar to DBCellGenerateSubstrate(), above. It finds space
|
||||
* tiles on the substrate plane and converts them to a substrate type
|
||||
* in the target, clipped to the cell boundary. This allows the
|
||||
* extraction to find and record all common (global) substrate regions,
|
||||
* without requiring a physical substrate type to be drawn into all cells.
|
||||
*
|
||||
* Unlike normal paint copying, this can only be done by painting the
|
||||
* substrate type over the entire cell area and then erasing all areas
|
||||
* belonging to not-substrate types in the source.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*
|
||||
* Side Effects:
|
||||
* Paints into the targetUse's CellDef. This only happens if two
|
||||
* conditions are met:
|
||||
* (1) The techfile has defined "substrate"
|
||||
* (2) The techfile defines a type corresponding to the substrate
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
Plane *
|
||||
DBCellGenerateSimpleSubstrate(scx, subType, notSubMask, targetDef)
|
||||
SearchContext *scx;
|
||||
TileType subType; /* Substrate paint type */
|
||||
TileTypeBitMask *notSubMask; /* Mask of types that are not substrate */
|
||||
CellDef *targetDef;
|
||||
{
|
||||
struct dbCopySubData csd;
|
||||
Plane *tempPlane;
|
||||
int plane;
|
||||
Rect rect;
|
||||
TileTypeBitMask allButSubMask;
|
||||
TileTypeBitMask defaultSubTypeMask;
|
||||
int dbEraseSubFunc();
|
||||
int dbPaintSubFunc();
|
||||
int dbEraseNonSub();
|
||||
int dbCopySubFunc();
|
||||
|
||||
GEOTRANSRECT(&scx->scx_trans, &scx->scx_area, &rect);
|
||||
|
||||
/* Clip to bounding box of the top level cell */
|
||||
GEOCLIP(&rect, &scx->scx_use->cu_def->cd_bbox);
|
||||
|
||||
plane = DBPlane(subType);
|
||||
|
||||
tempPlane = DBNewPlane((ClientData) TT_SPACE);
|
||||
DBClearPaintPlane(tempPlane);
|
||||
|
||||
csd.csd_subtype = subType;
|
||||
csd.csd_plane = tempPlane;
|
||||
csd.csd_pNum = plane;
|
||||
csd.csd_modified = FALSE;
|
||||
|
||||
/* Paint the substrate type in the temporary plane over the area of */
|
||||
/* the entire cell. */
|
||||
DBPaintPlane(tempPlane, &rect, DBStdPaintTbl(subType, plane),
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
||||
/* Now erase all areas that are non-substrate types in the source */
|
||||
DBTreeSrTiles(scx, notSubMask, 0, dbEraseNonSub, (ClientData)&csd);
|
||||
|
||||
/* Finally, copy the destination plane contents onto tempPlane, */
|
||||
/* ignoring the substrate type. */
|
||||
TTMaskZero(&allButSubMask);
|
||||
TTMaskSetMask(&allButSubMask, &DBAllButSpaceBits);
|
||||
TTMaskClearType(&allButSubMask, subType);
|
||||
DBSrPaintArea((Tile *)NULL, targetDef->cd_planes[plane], &TiPlaneRect,
|
||||
&allButSubMask, dbCopySubFunc, (ClientData)&csd);
|
||||
|
||||
/* Now we have a plane where the substrate type occupies the whole */
|
||||
/* area of the cell except where there are conflicting types (e.g., */
|
||||
/* nwell). Return this plane. */
|
||||
return tempPlane;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback function for DBCellGenerateSubstrate()
|
||||
* Finds tiles in the source def that belong to the type that represents
|
||||
|
|
@ -457,14 +967,15 @@ DBCellGenerateSubstrate(scx, subType, notSubMask, subShieldMask, targetDef)
|
|||
*/
|
||||
|
||||
int
|
||||
dbEraseSubFunc(tile, cxp)
|
||||
dbEraseSubFunc(tile, dinfo, cxp)
|
||||
Tile *tile; /* Pointer to source tile with shield type */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TreeContext *cxp; /* Context from DBTreeSrTiles */
|
||||
{
|
||||
SearchContext *scx;
|
||||
Rect sourceRect, targetRect;
|
||||
int pNum;
|
||||
TileType type, loctype, subType;
|
||||
TileType newdinfo, loctype, subType;
|
||||
Plane *plane;
|
||||
struct dbCopySubData *csd; /* Client data */
|
||||
|
||||
|
|
@ -473,12 +984,14 @@ dbEraseSubFunc(tile, cxp)
|
|||
plane = csd->csd_plane;
|
||||
pNum = csd->csd_pNum;
|
||||
subType = csd->csd_subtype;
|
||||
type = TiGetTypeExact(tile);
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
if (loctype == TT_SPACE) return 0;
|
||||
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans);
|
||||
}
|
||||
else
|
||||
newdinfo = (TileType)0;
|
||||
|
||||
/* Construct the rect for the tile */
|
||||
TITORECT(tile, &sourceRect);
|
||||
|
|
@ -488,7 +1001,7 @@ dbEraseSubFunc(tile, cxp)
|
|||
|
||||
csd->csd_modified = TRUE;
|
||||
|
||||
return DBNMPaintPlane(plane, type, &targetRect, DBStdEraseTbl(subType, pNum),
|
||||
return DBNMPaintPlane(plane, newdinfo, &targetRect, DBStdEraseTbl(subType, pNum),
|
||||
(PaintUndoInfo *)NULL);
|
||||
}
|
||||
|
||||
|
|
@ -500,14 +1013,15 @@ dbEraseSubFunc(tile, cxp)
|
|||
*/
|
||||
|
||||
int
|
||||
dbPaintSubFunc(tile, cxp)
|
||||
dbPaintSubFunc(tile, dinfo, cxp)
|
||||
Tile *tile; /* Pointer to source tile with shield type */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TreeContext *cxp; /* Context from DBTreeSrTiles */
|
||||
{
|
||||
SearchContext *scx;
|
||||
Rect sourceRect, targetRect;
|
||||
int pNum;
|
||||
TileType type, loctype, subType;
|
||||
TileType newdinfo, loctype, subType;
|
||||
Plane *plane;
|
||||
struct dbCopySubData *csd; /* Client data */
|
||||
|
||||
|
|
@ -516,12 +1030,14 @@ dbPaintSubFunc(tile, cxp)
|
|||
plane = csd->csd_plane;
|
||||
pNum = csd->csd_pNum;
|
||||
subType = csd->csd_subtype;
|
||||
type = TiGetTypeExact(tile);
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
if (loctype == TT_SPACE) return 0;
|
||||
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans);
|
||||
}
|
||||
else
|
||||
newdinfo = (TileType)0;
|
||||
|
||||
/* Construct the rect for the tile */
|
||||
TITORECT(tile, &sourceRect);
|
||||
|
|
@ -531,7 +1047,7 @@ dbPaintSubFunc(tile, cxp)
|
|||
|
||||
csd->csd_modified = TRUE;
|
||||
|
||||
return DBNMPaintPlane(plane, type, &targetRect, DBStdPaintTbl(subType, pNum),
|
||||
return DBNMPaintPlane(plane, newdinfo, &targetRect, DBStdPaintTbl(subType, pNum),
|
||||
(PaintUndoInfo *)NULL);
|
||||
}
|
||||
|
||||
|
|
@ -544,14 +1060,15 @@ dbPaintSubFunc(tile, cxp)
|
|||
*/
|
||||
|
||||
int
|
||||
dbEraseNonSub(tile, cxp)
|
||||
dbEraseNonSub(tile, dinfo, cxp)
|
||||
Tile *tile; /* Pointer to tile to erase from target */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TreeContext *cxp; /* Context from DBTreeSrTiles */
|
||||
{
|
||||
SearchContext *scx;
|
||||
Rect sourceRect, targetRect;
|
||||
Plane *plane; /* Plane of target data */
|
||||
TileType type, loctype, subType;
|
||||
TileType newdinfo, loctype, subType;
|
||||
struct dbCopySubData *csd;
|
||||
int pNum;
|
||||
|
||||
|
|
@ -562,12 +1079,14 @@ dbEraseNonSub(tile, cxp)
|
|||
|
||||
scx = cxp->tc_scx;
|
||||
|
||||
type = TiGetTypeExact(tile);
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
if (loctype == TT_SPACE) return 0;
|
||||
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans);
|
||||
}
|
||||
else
|
||||
newdinfo = (TileType)0;
|
||||
|
||||
/* Construct the rect for the tile */
|
||||
TITORECT(tile, &sourceRect);
|
||||
|
|
@ -576,7 +1095,7 @@ dbEraseNonSub(tile, cxp)
|
|||
GEOTRANSRECT(&scx->scx_trans, &sourceRect, &targetRect);
|
||||
|
||||
/* Erase the substrate type from the area of this tile in the target plane. */
|
||||
return DBNMPaintPlane(plane, type, &targetRect, DBStdEraseTbl(subType, pNum),
|
||||
return DBNMPaintPlane(plane, newdinfo, &targetRect, DBStdEraseTbl(subType, pNum),
|
||||
(PaintUndoInfo *)NULL);
|
||||
}
|
||||
|
||||
|
|
@ -588,8 +1107,9 @@ dbEraseNonSub(tile, cxp)
|
|||
*/
|
||||
|
||||
int
|
||||
dbCopySubFunc(tile, csd)
|
||||
dbCopySubFunc(tile, dinfo, csd)
|
||||
Tile *tile; /* Pointer to tile to erase from target */
|
||||
TileType dinfo; /* Split tile information */
|
||||
struct dbCopySubData *csd; /* Client data */
|
||||
{
|
||||
Rect rect;
|
||||
|
|
@ -599,10 +1119,10 @@ dbCopySubFunc(tile, csd)
|
|||
|
||||
plane = csd->csd_plane;
|
||||
pNum = csd->csd_pNum;
|
||||
type = TiGetTypeExact(tile);
|
||||
type = TiGetTypeExact(tile) | dinfo;
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
if (loctype == TT_SPACE) return 0;
|
||||
}
|
||||
else
|
||||
|
|
@ -923,8 +1443,9 @@ DBCellCopyLabels(scx, mask, xMask, targetUse, pArea)
|
|||
***/
|
||||
|
||||
int
|
||||
dbCopyManhattanPaint(tile, cxp)
|
||||
Tile *tile; /* Pointer to tile to copy */
|
||||
dbCopyManhattanPaint(tile, dinfo, cxp)
|
||||
Tile *tile; /* Pointer to tile to copy */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TreeContext *cxp; /* Context from DBTreeSrTiles */
|
||||
{
|
||||
SearchContext *scx = cxp->tc_scx;
|
||||
|
|
@ -970,8 +1491,9 @@ dbCopyManhattanPaint(tile, cxp)
|
|||
***/
|
||||
|
||||
int
|
||||
dbCopyAllPaint(tile, cxp)
|
||||
Tile *tile; /* Pointer to tile to copy */
|
||||
dbCopyAllPaint(tile, dinfo, cxp)
|
||||
Tile *tile; /* Pointer to tile to copy */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TreeContext *cxp; /* Context from DBTreeSrTiles */
|
||||
{
|
||||
SearchContext *scx = cxp->tc_scx;
|
||||
|
|
@ -979,7 +1501,7 @@ dbCopyAllPaint(tile, cxp)
|
|||
Rect sourceRect, targetRect;
|
||||
PaintUndoInfo ui;
|
||||
CellDef *def;
|
||||
TileType type = TiGetTypeExact(tile);
|
||||
TileType type = TiGetTypeExact(tile) | dinfo;
|
||||
int pNum = cxp->tc_plane;
|
||||
int result;
|
||||
TileTypeBitMask *typeMask;
|
||||
|
|
@ -992,13 +1514,13 @@ dbCopyAllPaint(tile, cxp)
|
|||
*/
|
||||
|
||||
bool splittile = FALSE;
|
||||
TileType dinfo = 0;
|
||||
TileType newdinfo = 0;
|
||||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
splittile = TRUE;
|
||||
dinfo = DBTransformDiagonal(type, &scx->scx_trans);
|
||||
type = (SplitSide(tile)) ? SplitRightType(tile) :
|
||||
newdinfo = DBTransformDiagonal(type, &scx->scx_trans);
|
||||
type = (dinfo & TT_SIDE) ? SplitRightType(tile) :
|
||||
SplitLeftType(tile);
|
||||
}
|
||||
|
||||
|
|
@ -1058,7 +1580,7 @@ dbCopyAllPaint(tile, cxp)
|
|||
Rect rrect, orect;
|
||||
int np, i, j;
|
||||
|
||||
GrClipTriangle(&targetRect, &arg->caa_rect, TRUE, dinfo, points, &np);
|
||||
GrClipTriangle(&targetRect, &arg->caa_rect, TRUE, newdinfo, points, &np);
|
||||
|
||||
if (np == 0)
|
||||
return(0);
|
||||
|
|
@ -1087,7 +1609,7 @@ dbCopyAllPaint(tile, cxp)
|
|||
rrect.r_ybot = points[0].p_y;
|
||||
rrect.r_ytop = points[2].p_y;
|
||||
GeoCanonicalRect(&rrect, &targetRect);
|
||||
dinfo = 0;
|
||||
newdinfo = 0;
|
||||
}
|
||||
else if (np >= 4) /* Process extra rectangles in the area */
|
||||
{
|
||||
|
|
@ -1144,7 +1666,7 @@ topbottom:
|
|||
|
||||
splitdone:
|
||||
|
||||
result = (*dbCurPaintPlane)(def, pNum, dinfo | type, &targetRect, &ui);
|
||||
result = (*dbCurPaintPlane)(def, pNum, newdinfo | type, &targetRect, &ui);
|
||||
if ((result != 0) && (arg->caa_func != NULL))
|
||||
{
|
||||
/* result == 1 used exclusively for DRC off-grid error flagging */
|
||||
|
|
@ -1215,7 +1737,8 @@ DBCellCopyAllCells(scx, xMask, targetUse, pArea)
|
|||
|
||||
/* dbCellCopyCellsFunc() allows cells to be left with duplicate IDs */
|
||||
/* so generate unique IDs as needed now. */
|
||||
DBGenerateUniqueIds(targetUse->cu_def, FALSE);
|
||||
|
||||
if (targetUse != NULL) DBGenerateUniqueIds(targetUse->cu_def, FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -117,6 +117,14 @@ DBCellRename(cellname, newname, doforce)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Cannot rename a cell with the name of an existing cell */
|
||||
entry = HashLookOnly(&dbCellDefTable, newname);
|
||||
if (entry != NULL)
|
||||
{
|
||||
TxError("Cannot rename; cell \"%s\" already exists!\n", newname);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Disallow renaming if the cell has the READONLY flag set, */
|
||||
/* because the cellname must match the name in the GDS */
|
||||
/* file referenced. */
|
||||
|
|
@ -224,7 +232,7 @@ DBCellDelete(cellname, force)
|
|||
{
|
||||
HashEntry *entry;
|
||||
CellDef *celldef;
|
||||
CellUse *celluse;
|
||||
CellUse *celluse, *lastuse;
|
||||
bool result;
|
||||
|
||||
entry = HashLookOnly(&dbCellDefTable, cellname);
|
||||
|
|
@ -259,13 +267,36 @@ DBCellDelete(cellname, force)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* 2nd pass: If there are instances of the cell in */
|
||||
/* internal cells like SelectDef, etc., then remove the use */
|
||||
/* from the definition. */
|
||||
|
||||
lastuse = NULL;
|
||||
celluse = celldef->cd_parents;
|
||||
while (celluse != (CellUse *) NULL)
|
||||
{
|
||||
if (celluse->cu_parent != (CellDef *)NULL)
|
||||
{
|
||||
if ((celluse->cu_parent->cd_flags & CDINTERNAL) == CDINTERNAL)
|
||||
{
|
||||
DBDeleteCell(celluse);
|
||||
celluse = lastuse;
|
||||
}
|
||||
}
|
||||
lastuse = celluse;
|
||||
if (lastuse == NULL)
|
||||
celluse = celldef->cd_parents;
|
||||
else
|
||||
celluse = celluse->cu_nextuse;
|
||||
}
|
||||
|
||||
/* Cleared to delete. . . now prompt user if the cell has changes. */
|
||||
/* Last chance to save! */
|
||||
|
||||
if ((force == FALSE) &&
|
||||
(celldef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED)))
|
||||
{
|
||||
static char *yesno[] = { "no", "yes", 0 };
|
||||
static const char *yesno[] = { "no", "yes", 0 };
|
||||
int code;
|
||||
char *prompt = TxPrintString("Cell %s has been modified.\n Do you"
|
||||
" want to delete it and lose all changes? ",
|
||||
|
|
@ -283,12 +314,13 @@ DBCellDelete(cellname, force)
|
|||
/* so that WindUnload() will create a new one. */
|
||||
|
||||
if (!strcmp(cellname, UNNAMED))
|
||||
DBCellRename(cellname, "__UNNAMED__");
|
||||
DBCellRename(cellname, "__UNNAMED__", FALSE);
|
||||
|
||||
/* For all top-level cell uses, check if any windows have this */
|
||||
/* use. If so, load the window with (UNNAMED). */
|
||||
|
||||
UndoDisable();
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (celluse = celldef->cd_parents; celluse != (CellUse *) NULL;
|
||||
celluse = celluse->cu_nextuse)
|
||||
{
|
||||
|
|
@ -297,8 +329,9 @@ DBCellDelete(cellname, force)
|
|||
WindUnload(celluse);
|
||||
freeMagic(celluse->cu_id);
|
||||
}
|
||||
freeMagic((char *)celluse);
|
||||
freeMagic1(&mm1, (char *)celluse);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
celldef->cd_parents = (CellUse *)NULL;
|
||||
|
||||
DBWResetBox(celldef);
|
||||
|
|
@ -368,6 +401,12 @@ dbGetUseName(celluse)
|
|||
ybuf[0] = '\0';
|
||||
|
||||
useID = celluse->cu_id;
|
||||
if (useID == NULL)
|
||||
{
|
||||
newID = (char *)mallocMagic(7);
|
||||
sprintf(newID, "(null)");
|
||||
return (newID);
|
||||
}
|
||||
newsize = strlen(useID) + 1;
|
||||
if (isx || isy)
|
||||
{
|
||||
|
|
@ -637,7 +676,7 @@ DBTopPrint(mw, dolist)
|
|||
|
||||
int strcmpbynum(const char *s1, const char *s2)
|
||||
{
|
||||
/* Like strcmp() but compare sequences of digits numerically */
|
||||
/* Like strcasecmp() but compare sequences of digits numerically */
|
||||
for (;;)
|
||||
{
|
||||
if (*s2 == '\0')
|
||||
|
|
@ -646,8 +685,11 @@ int strcmpbynum(const char *s1, const char *s2)
|
|||
return 1;
|
||||
else if (!(isdigit(*s1) && isdigit(*s2)))
|
||||
{
|
||||
if (*s1 != *s2)
|
||||
return (int)*s1 - (int)*s2;
|
||||
char c1, c2;
|
||||
c1 = tolower(*s1);
|
||||
c2 = tolower(*s2);
|
||||
if (c1 != c2)
|
||||
return (int)c1 - (int)c2;
|
||||
else
|
||||
{
|
||||
++s1;
|
||||
|
|
@ -1118,11 +1160,13 @@ DBUsePrint(CellName, who, dolist)
|
|||
celldef = DBCellLookDef(CellName);
|
||||
*lasthier = '/';
|
||||
}
|
||||
else
|
||||
else if (EditCellUse != NULL)
|
||||
{
|
||||
/* Referenced cellDef is the current edit def */
|
||||
celldef = EditCellUse->cu_def;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
switch (who)
|
||||
{
|
||||
|
|
@ -1304,7 +1348,7 @@ DBLockUse(UseName, bval)
|
|||
while( (entry = HashNext(&dbCellDefTable, &hs)) != NULL)
|
||||
{
|
||||
celldef = (CellDef *) HashGetValue(entry);
|
||||
if (celldef != (CellDef *) NULL)
|
||||
if ((celldef != (CellDef *)NULL) && !(celldef->cd_flags & CDINTERNAL))
|
||||
{
|
||||
celluse = celldef->cd_parents; /* only need one */
|
||||
if (celluse != (CellUse *)NULL) {
|
||||
|
|
@ -1383,7 +1427,7 @@ DBOrientUse(UseName, dodef)
|
|||
while( (entry = HashNext(&dbCellDefTable, &hs)) != NULL)
|
||||
{
|
||||
celldef = (CellDef *) HashGetValue(entry);
|
||||
if (celldef != (CellDef *) NULL)
|
||||
if ((celldef != (CellDef *)NULL) && !(celldef->cd_flags & CDINTERNAL))
|
||||
{
|
||||
celluse = celldef->cd_parents; /* only need one */
|
||||
if (celluse != (CellUse *)NULL) {
|
||||
|
|
@ -1546,7 +1590,7 @@ DBAbutmentUse(UseName, dolist)
|
|||
while( (entry = HashNext(&dbCellDefTable, &hs)) != NULL)
|
||||
{
|
||||
celldef = (CellDef *) HashGetValue(entry);
|
||||
if (celldef != (CellDef *) NULL)
|
||||
if ((celldef != (CellDef *)NULL) && !(celldef->cd_flags & CDINTERNAL))
|
||||
{
|
||||
celluse = celldef->cd_parents; /* only need one */
|
||||
if (celluse != (CellUse *)NULL) {
|
||||
|
|
@ -1598,7 +1642,7 @@ dbAbutmentUseFunc(selUse, use, transform, data)
|
|||
}
|
||||
|
||||
trans = &use->cu_transform;
|
||||
propvalue = DBPropGet(use->cu_def, "FIXED_BBOX", &found);
|
||||
propvalue = (char *)DBPropGet(use->cu_def, "FIXED_BBOX", &found);
|
||||
if (!found)
|
||||
bbox = use->cu_def->cd_bbox;
|
||||
else
|
||||
|
|
@ -1695,7 +1739,7 @@ DBCellNewDef(cellName)
|
|||
cellName = UNNAMED;
|
||||
|
||||
entry = HashFind(&dbCellDefTable, cellName);
|
||||
if (HashGetValue(entry) != (ClientData) NULL)
|
||||
if (HashGetValue(entry) != NULL)
|
||||
return ((CellDef *) NULL);
|
||||
|
||||
cellDef = DBCellDefAlloc();
|
||||
|
|
@ -1856,7 +1900,7 @@ DBCellRenameDef(cellDef, newName)
|
|||
ASSERT(HashGetValue(oldEntry) == (ClientData) cellDef, "DBCellRenameDef");
|
||||
|
||||
newEntry = HashFind(&dbCellDefTable, newName);
|
||||
if (HashGetValue(newEntry) != (ClientData) NULL)
|
||||
if (HashGetValue(newEntry) != NULL)
|
||||
return (FALSE);
|
||||
|
||||
HashSetValue(oldEntry, (ClientData) NULL);
|
||||
|
|
@ -1902,6 +1946,7 @@ DBCellDeleteDef(cellDef)
|
|||
entry = HashFind(&dbCellDefTable, cellDef->cd_name);
|
||||
ASSERT(HashGetValue(entry) == (ClientData) cellDef, "DBCellDeleteDef");
|
||||
HashSetValue(entry, (ClientData) NULL);
|
||||
HashRemove(&dbCellDefTable, cellDef->cd_name);
|
||||
if (cellDef->cd_props)
|
||||
DBPropClearAll(cellDef);
|
||||
|
||||
|
|
@ -1963,8 +2008,10 @@ DBCellDefFree(cellDef)
|
|||
cellDef->cd_planes[pNum] = (Plane *) NULL;
|
||||
}
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
|
||||
freeMagic((char *) lab);
|
||||
freeMagic1(&mm1, (char *) lab);
|
||||
freeMagic1_end(&mm1);
|
||||
SigEnableInterrupts();
|
||||
HashKill(&cellDef->cd_idHash);
|
||||
|
||||
|
|
@ -2291,8 +2338,14 @@ DBFindUse(id, parentDef)
|
|||
he = HashLookOnly(&parentDef->cd_idHash, id);
|
||||
if (delimit != NULL) *delimit = '[';
|
||||
if (he == NULL)
|
||||
return (CellUse *) NULL;
|
||||
{
|
||||
/* Try again without ignoring the delimiter */
|
||||
if (delimit != NULL)
|
||||
he = HashLookOnly(&parentDef->cd_idHash, id);
|
||||
|
||||
if (he == NULL)
|
||||
return (CellUse *) NULL;
|
||||
}
|
||||
return (CellUse *) HashGetValue(he);
|
||||
}
|
||||
|
||||
|
|
@ -2340,6 +2393,50 @@ DBGenerateUniqueIds(def, warn)
|
|||
HashKill(&dbUniqueNameTable);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBSelectionUniqueIds --
|
||||
*
|
||||
* This is similar to DBGenerateUniqueIds(), but the purpose is to make
|
||||
* sure that cell IDs in the selection do not collide with IDs in the
|
||||
* definition. This is done before copying from Select2Def back to the
|
||||
* root edit CellDef. Otherwise, any copied cell takes the name of the
|
||||
* original, and the original gets renamed, which is unexpected behavior.
|
||||
* Called only from SelectCopy().
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* May modify the use-id's of the cells in the cell plane of 'selDef'.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DBSelectionUniqueIds(selDef, rootDef)
|
||||
CellDef *selDef; /* Should be Select2Def */
|
||||
CellDef *rootDef; /* Should be EditRootDef */
|
||||
{
|
||||
int dbFindNamesFunc();
|
||||
int dbGenerateUniqueIdsFunc();
|
||||
|
||||
dbWarnUniqueIds = FALSE;
|
||||
HashInit(&dbUniqueDefTable, 32, 1); /* Indexed by (CellDef *) */
|
||||
HashInit(&dbUniqueNameTable, 32, 0); /* Indexed by use-id */
|
||||
|
||||
/* Build up tables of names */
|
||||
DBCellEnum(rootDef, dbFindNamesFunc, (ClientData) rootDef);
|
||||
DBCellEnum(selDef, dbFindNamesFunc, (ClientData) selDef);
|
||||
|
||||
/* Assign unique use-ids to all cells in the selection */
|
||||
DBCellEnum(selDef, dbGenerateUniqueIdsFunc, (ClientData) selDef);
|
||||
|
||||
HashKill(&dbUniqueDefTable);
|
||||
HashKill(&dbUniqueNameTable);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -2498,7 +2595,7 @@ DBUnLinkCell(use, parentDef)
|
|||
{
|
||||
HashEntry *he;
|
||||
|
||||
if (he = HashLookOnly(&parentDef->cd_idHash, use->cu_id))
|
||||
if ((he = HashLookOnly(&parentDef->cd_idHash, use->cu_id)))
|
||||
HashSetValue(he, (ClientData) NULL);
|
||||
}
|
||||
|
||||
|
|
@ -2516,7 +2613,7 @@ DBUnLinkCell(use, parentDef)
|
|||
* Side effects:
|
||||
* Fills in *pydef with a newly created CellDef by that name, and
|
||||
* *pyuse with a newly created CellUse pointing to the new def.
|
||||
* The CellDef pointed to by *pydef has the CD_INTERNAL flag
|
||||
* The CellDef pointed to by *pydef has the CDINTERNAL flag
|
||||
* set, and is marked as being available.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -83,16 +83,18 @@ struct seeTypesArg
|
|||
*/
|
||||
|
||||
int
|
||||
DBSrCellPlaneArea(BPlane *plane, Rect *rect, int (*func)(), ClientData arg)
|
||||
DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg)
|
||||
{
|
||||
BPEnum sbpe;
|
||||
BPEnum *bpe;
|
||||
CellUse *use;
|
||||
int rval = 0;
|
||||
|
||||
bpe = (BPEnum *)mallocMagic(sizeof(BPEnum));
|
||||
/* bpe = (BPEnum *)mallocMagic(sizeof(BPEnum)); */
|
||||
bpe = &sbpe;
|
||||
BPEnumInit(bpe, plane, rect, BPE_OVERLAP, "DBSrCellPlaneArea");
|
||||
|
||||
while (use = BPEnumNext(bpe))
|
||||
while ((use = BPEnumNext(bpe)))
|
||||
{
|
||||
if ((*func)(use, arg))
|
||||
{
|
||||
|
|
@ -102,7 +104,7 @@ DBSrCellPlaneArea(BPlane *plane, Rect *rect, int (*func)(), ClientData arg)
|
|||
}
|
||||
|
||||
BPEnumTerm(bpe);
|
||||
freeMagic(bpe);
|
||||
/* freeMagic(bpe); */
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
@ -118,6 +120,7 @@ DBSrCellPlaneArea(BPlane *plane, Rect *rect, int (*func)(), ClientData arg)
|
|||
* int
|
||||
* func(tile, cxp)
|
||||
* Tile *tile;
|
||||
* TileType dinfo;
|
||||
* TreeContext *cxp;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -242,10 +245,8 @@ dbCellPlaneSrFunc(scx, fp)
|
|||
if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask))
|
||||
return 0;
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
|
||||
}
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
|
||||
context.tc_scx = scx;
|
||||
context.tc_filter = fp;
|
||||
|
|
@ -364,10 +365,8 @@ dbCellUniqueTileSrFunc(scx, fp)
|
|||
if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask))
|
||||
return 0;
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
|
||||
}
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
|
||||
context.tc_scx = scx;
|
||||
context.tc_filter = fp;
|
||||
|
|
@ -418,6 +417,7 @@ dbCellUniqueTileSrFunc(scx, fp)
|
|||
* int
|
||||
* func(tile, cxp)
|
||||
* Tile *tile;
|
||||
* TileType dinfo;
|
||||
* TreeContext *cxp;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -476,10 +476,8 @@ DBNoTreeSrTiles(scx, mask, xMask, func, cdarg)
|
|||
return 0;
|
||||
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
|
||||
}
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
|
||||
filter.tf_func = func;
|
||||
filter.tf_arg = cdarg;
|
||||
|
|
@ -587,10 +585,8 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
|
|||
ASSERT(def != (CellDef *) NULL, "DBTreeSrLabels");
|
||||
if (!DBDescendSubcell(cellUse, xMask)) return 0;
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
|
||||
}
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
|
||||
for (lab = def->cd_labels; lab; lab = lab->lab_next)
|
||||
{
|
||||
|
|
@ -627,8 +623,8 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
|
|||
r1.r_ybot = r->r_ytop;
|
||||
r2.r_xbot = r->r_xtop;
|
||||
}
|
||||
is_touching = GEO_TOUCH(&lab->lab_bbox, &r1) ||
|
||||
GEO_TOUCH(&lab->lab_bbox, &r2);
|
||||
is_touching = GEO_TOUCH(&lab->lab_rect, &r1) ||
|
||||
GEO_TOUCH(&lab->lab_rect, &r2);
|
||||
}
|
||||
else
|
||||
is_touching = GEO_TOUCH(&lab->lab_rect, r);
|
||||
|
|
@ -685,7 +681,7 @@ dbCellLabelSrFunc(scx, fp)
|
|||
{
|
||||
Label *lab;
|
||||
Rect *r = &scx->scx_area;
|
||||
TileTypeBitMask *mask = fp->tf_mask;
|
||||
const TileTypeBitMask *mask = fp->tf_mask;
|
||||
CellDef *def = scx->scx_use->cu_def;
|
||||
char *tnext;
|
||||
int result;
|
||||
|
|
@ -694,10 +690,8 @@ dbCellLabelSrFunc(scx, fp)
|
|||
ASSERT(def != (CellDef *) NULL, "dbCellLabelSrFunc");
|
||||
if (!DBDescendSubcell(scx->scx_use, fp->tf_xmask)) return 0;
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL)) return 0;
|
||||
}
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
|
||||
/* Do not add a path name of a top level window */
|
||||
if (strncmp(scx->scx_use->cu_id, "Topmost ", 8))
|
||||
|
|
@ -818,11 +812,8 @@ DBTreeSrCells(scx, xMask, func, cdarg)
|
|||
if (!DBDescendSubcell(cellUse, xMask))
|
||||
return 0;
|
||||
if ((cellUse->cu_def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (cellUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(cellUse->cu_def, (char *) NULL, TRUE, dereference, NULL))
|
||||
if (!DBCellRead(cellUse->cu_def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
}
|
||||
|
||||
context.tc_scx = scx;
|
||||
context.tc_filter = &filter;
|
||||
|
|
@ -866,11 +857,8 @@ dbTreeCellSrFunc(scx, fp)
|
|||
else
|
||||
{
|
||||
if ((use->cu_def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (use->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, dereference, NULL))
|
||||
if (!DBCellRead(use->cu_def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (fp->tf_xmask == CU_DESCEND_ALL)
|
||||
{
|
||||
|
|
@ -928,8 +916,9 @@ DBSeeTypesAll(rootUse, rootRect, xMask, mask)
|
|||
*/
|
||||
|
||||
int
|
||||
dbSeeTypesAllSrFunc(tile, cxp)
|
||||
dbSeeTypesAllSrFunc(tile, dinfo, cxp)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
TreeContext *cxp;
|
||||
{
|
||||
Rect tileRect;
|
||||
|
|
@ -940,7 +929,7 @@ dbSeeTypesAllSrFunc(tile, cxp)
|
|||
if (GEO_OVERLAP((&tileRect), area))
|
||||
{
|
||||
if (IsSplit(tile))
|
||||
TTMaskSetType(mask, SplitSide(tile) ?
|
||||
TTMaskSetType(mask, (dinfo & TT_SIDE) ?
|
||||
SplitRightType(tile) : SplitLeftType(tile));
|
||||
else
|
||||
TTMaskSetType(mask, TiGetType(tile));
|
||||
|
|
@ -1126,12 +1115,8 @@ DBCellSrArea(scx, func, cdarg)
|
|||
context.tc_scx = scx;
|
||||
|
||||
if ((scx->scx_use->cu_def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (scx->scx_use->cu_def->cd_flags & CDDEREFERENCE) ?
|
||||
TRUE : FALSE;
|
||||
if (!DBCellRead(scx->scx_use->cu_def, (char *) NULL, TRUE, dereference, NULL))
|
||||
if (!DBCellRead(scx->scx_use->cu_def, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (DBSrCellPlaneArea(scx->scx_use->cu_def->cd_cellPlane,
|
||||
&scx->scx_area, dbCellSrFunc, (ClientData) &context))
|
||||
|
|
@ -1253,10 +1238,9 @@ DBCellEnum(cellDef, func, cdarg)
|
|||
filter.tf_func = func;
|
||||
filter.tf_arg = cdarg;
|
||||
if ((cellDef->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(cellDef, (char *) NULL, TRUE, dereference, NULL)) return 0;
|
||||
}
|
||||
if (!DBCellRead(cellDef, TRUE, TRUE, NULL))
|
||||
return 0;
|
||||
|
||||
if (DBSrCellPlaneArea(cellDef->cd_cellPlane,
|
||||
&TiPlaneRect, dbEnumFunc, (ClientData) &filter))
|
||||
return 1;
|
||||
|
|
@ -1535,19 +1519,22 @@ DBScaleEverything(scalen, scaled)
|
|||
}
|
||||
|
||||
/* Free the linked CellDef list */
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
lcd = lhead;
|
||||
while (lcd != NULL)
|
||||
{
|
||||
freeMagic((char *)lcd);
|
||||
freeMagic1(&mm1, (char *)lcd);
|
||||
lcd = lcd->cd_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
/* Scale all elements */
|
||||
DBWScaleElements(scalen, scaled);
|
||||
|
||||
#ifdef ROUTE_MODULE
|
||||
/* Recovery of global plane pointers */
|
||||
MZAttachHintPlanes();
|
||||
#endif
|
||||
|
||||
/* Modify root box */
|
||||
ToolScaleBox(scalen, scaled);
|
||||
|
|
@ -1623,8 +1610,9 @@ dbScalePlane(oldplane, newplane, pnum, scalen, scaled, doCIF)
|
|||
*/
|
||||
|
||||
int
|
||||
dbTileScaleFunc(tile, scvals)
|
||||
dbTileScaleFunc(tile, dinfo, scvals)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
struct scaleArg *scvals;
|
||||
{
|
||||
TileType type;
|
||||
|
|
@ -1642,17 +1630,20 @@ dbTileScaleFunc(tile, scvals)
|
|||
if ((targetRect.r_xtop - targetRect.r_xbot == 0) ||
|
||||
(targetRect.r_ytop - targetRect.r_ybot == 0))
|
||||
{
|
||||
TxPrintf("Tile 0x%x at (%d, %d) has zero area after scaling: Removed.\n",
|
||||
tile, targetRect.r_xbot, targetRect.r_ybot);
|
||||
TxPrintf("Tile %p at (%d, %d) has zero area after scaling: Removed.\n",
|
||||
(void *) tile, targetRect.r_xbot, targetRect.r_ybot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
type = TiGetTypeExact(tile);
|
||||
type = TiGetTypeExact(tile) | dinfo;
|
||||
exact = type;
|
||||
if (IsSplit(tile))
|
||||
type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
DBNMPaintPlane(scvals->ptarget, exact, &targetRect,
|
||||
((scvals->doCIF) ? CIFPaintTable :
|
||||
(
|
||||
#ifdef CIF_MODULE
|
||||
(scvals->doCIF) ? CIFPaintTable :
|
||||
#endif
|
||||
DBStdPaintTbl(type, scvals->pnum)),
|
||||
(PaintUndoInfo *)NULL);
|
||||
return 0;
|
||||
|
|
@ -1702,8 +1693,9 @@ dbMovePlane(oldplane, newplane, pnum, origx, origy)
|
|||
*/
|
||||
|
||||
int
|
||||
dbTileMoveFunc(tile, mvvals)
|
||||
dbTileMoveFunc(tile, dinfo, mvvals)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
struct moveArg *mvvals;
|
||||
{
|
||||
TileType type;
|
||||
|
|
@ -1716,10 +1708,10 @@ dbTileMoveFunc(tile, mvvals)
|
|||
DBMovePoint(&targetRect.r_ll, mvvals->origx, mvvals->origy);
|
||||
DBMovePoint(&targetRect.r_ur, mvvals->origx, mvvals->origy);
|
||||
|
||||
type = TiGetTypeExact(tile);
|
||||
type = TiGetTypeExact(tile) | dinfo;
|
||||
exact = type;
|
||||
if (IsSplit(tile))
|
||||
type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
DBNMPaintPlane(mvvals->ptarget, exact, &targetRect,
|
||||
DBStdPaintTbl(type, mvvals->pnum),
|
||||
(PaintUndoInfo *)NULL);
|
||||
|
|
@ -1783,12 +1775,14 @@ DBSrCellUses(cellDef, func, arg)
|
|||
}
|
||||
|
||||
/* Free this linked cellUse structure */
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
lu = luhead;
|
||||
while (lu != NULL)
|
||||
{
|
||||
freeMagic((char *)lu);
|
||||
freeMagic1(&mm1, (char *)lu);
|
||||
lu = lu->cu_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
@ -1804,7 +1798,7 @@ typedef struct _cellpropstruct {
|
|||
* dbScaleProp --
|
||||
*
|
||||
* Callback function for dbScaleCell. Finds properties that represent
|
||||
* internal geometry (FIXED_BBOX and MASKHINTS_*) and scale the values
|
||||
* internal geometry (*_BBOX and MASKHINTS_*) and scale the values
|
||||
* by the numerator / denominator values passed as a pointer to a Point
|
||||
* structure, where p_x is the numerator value and p_y is the denominator
|
||||
* value.
|
||||
|
|
@ -1821,7 +1815,7 @@ int dbScaleProp(name, value, cps)
|
|||
char *newvalue, *vptr;
|
||||
Rect r;
|
||||
|
||||
if (!strcmp(name, "FIXED_BBOX"))
|
||||
if ((strlen(name) > 5) && !strncmp(name + strlen(name) - 5, "_BBOX", 5))
|
||||
{
|
||||
if (sscanf(value, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop) == 4)
|
||||
|
|
@ -1899,7 +1893,7 @@ int dbScaleProp(name, value, cps)
|
|||
* dbMoveProp --
|
||||
*
|
||||
* Callback function for ??. Finds properties that represent
|
||||
* internal geometry (FIXED_BBOX and MASKHINTS_*) and modifies the values
|
||||
* internal geometry (*_BBOX and MASKHINTS_*) and modifies the values
|
||||
* by the X, Y values passed as a pointer to a Point structure in ClientData.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -1914,7 +1908,8 @@ int dbMoveProp(name, value, cps)
|
|||
char *newvalue;
|
||||
Rect r;
|
||||
|
||||
if (!strcmp(name, "FIXED_BBOX") || !strncmp(name, "MASKHINTS_", 10))
|
||||
if (((strlen(name) > 5) && !strncmp(name + strlen(name) - 5, "_BBOX", 5))
|
||||
|| !strncmp(name, "MASKHINTS_", 10))
|
||||
{
|
||||
if (sscanf(value, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop) == 4)
|
||||
|
|
@ -2015,12 +2010,14 @@ dbScaleCell(cellDef, scalen, scaled)
|
|||
BPFree(cellPlaneOrig);
|
||||
|
||||
/* Free this linked cellUse structure */
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
lu = luhead;
|
||||
while (lu != NULL)
|
||||
{
|
||||
freeMagic((char *)lu);
|
||||
freeMagic1(&mm1, (char *)lu);
|
||||
lu = lu->cu_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
/* Scale all of the paint tiles in this cell by creating a new plane */
|
||||
/* and copying all tiles into the new plane at scaled dimensions. */
|
||||
|
|
@ -2072,38 +2069,16 @@ donecell:
|
|||
DBScalePoint(&cellDef->cd_extended.r_ll, scalen, scaled);
|
||||
DBScalePoint(&cellDef->cd_extended.r_ur, scalen, scaled);
|
||||
|
||||
/* If the cell is an abstract view with a fixed bounding box, then */
|
||||
/* adjust the bounding box property to match the new scale. */
|
||||
|
||||
if ((cellDef->cd_flags & CDFIXEDBBOX) != 0)
|
||||
{
|
||||
Rect r;
|
||||
bool found;
|
||||
char *propval;
|
||||
|
||||
propval = (char *)DBPropGet(cellDef, "FIXED_BBOX", &found);
|
||||
if (found)
|
||||
{
|
||||
if (sscanf(propval, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
|
||||
&r.r_xtop, &r.r_ytop) == 4)
|
||||
{
|
||||
DBScalePoint(&r.r_ll, scalen, scaled);
|
||||
DBScalePoint(&r.r_ur, scalen, scaled);
|
||||
|
||||
propval = (char *)mallocMagic(40);
|
||||
sprintf(propval, "%d %d %d %d", r.r_xbot, r.r_ybot,
|
||||
r.r_xtop, r.r_ytop);
|
||||
DBPropPut(cellDef, "FIXED_BBOX", propval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check all properties for ones with keys beginning with "MASKHINTS_"
|
||||
* or the key "FIXED_BBOX", and scale them by the same amount as all
|
||||
* or ending with "_BBOX", and scale them by the same amount as all
|
||||
* the geometry.
|
||||
*
|
||||
* Note: This would be better handled if there were a special type
|
||||
* for properties which are coordinates; currently the only property
|
||||
* type is a string, thus requiring the string to be parsed every time
|
||||
* the coordinates are needed.
|
||||
*/
|
||||
|
||||
|
||||
cps.cps_point.p_x = scalen;
|
||||
cps.cps_point.p_y = scaled;
|
||||
cps.cps_def = cellDef;
|
||||
|
|
@ -2245,12 +2220,14 @@ DBMoveCell(cellDef, origx, origy)
|
|||
BPFree(cellPlaneOrig);
|
||||
|
||||
/* Free this linked cellUse structure */
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
lu = luhead;
|
||||
while (lu != NULL)
|
||||
{
|
||||
freeMagic((char *)lu);
|
||||
freeMagic1(&mm1, (char *)lu);
|
||||
lu = lu->cu_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
/* Move all of the paint tiles in this cell by creating a new plane */
|
||||
/* and copying all tiles into the new plane at the new position. */
|
||||
|
|
@ -2261,7 +2238,7 @@ DBMoveCell(cellDef, origx, origy)
|
|||
newplane = DBNewPlane((ClientData) TT_SPACE);
|
||||
DBClearPaintPlane(newplane);
|
||||
if (dbMovePlane(cellDef->cd_planes[pNum], newplane, pNum,
|
||||
origx, origy, FALSE))
|
||||
origx, origy))
|
||||
cellDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
|
||||
DBFreePaintPlane(cellDef->cd_planes[pNum]);
|
||||
TiFreePlane(cellDef->cd_planes[pNum]);
|
||||
|
|
@ -2295,7 +2272,7 @@ donecell:
|
|||
DBMovePoint(&cellDef->cd_extended.r_ur, origx, origy);
|
||||
|
||||
/* Check all properties for ones with keys beginning with "MASKHINTS_"
|
||||
* or the key "FIXED_BBOX", and move them by the same amount as all
|
||||
* or ending with "_BBOX", and move them by the same amount as all
|
||||
* the geometry.
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -76,12 +76,9 @@ DBDescendSubcell(use, xMask)
|
|||
|
||||
case CU_DESCEND_NO_SUBCKT:
|
||||
if ((use->cu_def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (use->cu_def->cd_flags & CDDEREFERENCE) ?
|
||||
TRUE : FALSE;
|
||||
if (!DBCellRead(use->cu_def, (char *) NULL, TRUE, dereference, NULL))
|
||||
if (!DBCellRead(use->cu_def, TRUE, TRUE, NULL))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return (DBIsSubcircuit(use->cu_def)) ? FALSE : TRUE;
|
||||
|
||||
case CU_DESCEND_NO_LOCK:
|
||||
|
|
@ -221,8 +218,10 @@ DBCellClearDef(cellDef)
|
|||
cellDef->cd_bbox.r_xtop = cellDef->cd_bbox.r_ytop = 1;
|
||||
cellDef->cd_extended.r_xbot = cellDef->cd_extended.r_ybot = 0;
|
||||
cellDef->cd_extended.r_xtop = cellDef->cd_extended.r_ytop = 1;
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
|
||||
freeMagic((char *) lab);
|
||||
freeMagic1(&mm1, (char *) lab);
|
||||
freeMagic1_end(&mm1);
|
||||
cellDef->cd_labels = (Label *) NULL;
|
||||
cellDef->cd_lastLabel = (Label *) NULL;
|
||||
|
||||
|
|
@ -265,7 +264,7 @@ DBClearPaintPlane(plane)
|
|||
|
||||
/* Allocate a new central space tile */
|
||||
newCenterTile = TiAlloc();
|
||||
plane->pl_hint = newCenterTile;
|
||||
PlaneSetHint(plane, newCenterTile);
|
||||
TiSetBody(newCenterTile, TT_SPACE);
|
||||
dbSetPlaneTile(plane, newCenterTile);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@ DBInvTransformDiagonal(oldtype, trans)
|
|||
return dinfo;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -198,9 +197,7 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
|
|||
{
|
||||
struct conSrArg csa;
|
||||
int startPlane, result;
|
||||
Tile *startTile; /* Starting tile for search. */
|
||||
extern int dbSrConnectFunc(); /* Forward declaration. */
|
||||
extern int dbSrConnectStartFunc();
|
||||
TileAndDinfo start_tad; /* Starting tile and split information */
|
||||
|
||||
result = 0;
|
||||
csa.csa_def = def;
|
||||
|
|
@ -211,26 +208,28 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
|
|||
* the tile address and returns.
|
||||
*/
|
||||
|
||||
startTile = NULL;
|
||||
start_tad.tad_tile = NULL;
|
||||
start_tad.tad_next = NULL; /* unused */
|
||||
for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++)
|
||||
{
|
||||
csa.csa_pNum = startPlane;
|
||||
if (DBSrPaintArea((Tile *) NULL,
|
||||
def->cd_planes[startPlane], startArea, mask,
|
||||
dbSrConnectStartFunc, (ClientData) &startTile) != 0) break;
|
||||
dbSrConnectStartFunc, PTR2CD(&start_tad)) != 0) break;
|
||||
}
|
||||
if (startTile == NULL) return 0;
|
||||
if (start_tad.tad_tile == NULL) return 0;
|
||||
/* The following lets us call DBSrConnect recursively */
|
||||
else if (startTile->ti_client == (ClientData)1) return 0;
|
||||
|
||||
else if (start_tad.tad_tile->ti_client == (ClientData)1) return 0;
|
||||
|
||||
/* Pass 1. During this pass the client function gets called. */
|
||||
|
||||
csa.csa_clientFunc = func;
|
||||
csa.csa_clientData = clientData;
|
||||
csa.csa_clientDefault = CLIENTDEFAULT;
|
||||
csa.csa_clear = FALSE;
|
||||
csa.csa_connect = connect;
|
||||
if (dbSrConnectFunc(startTile, &csa) != 0) result = 1;
|
||||
if (dbSrConnectFunc(start_tad.tad_tile, start_tad.tad_dinfo,
|
||||
PTR2CD(&csa)) != 0) result = 1;
|
||||
|
||||
/* Pass 2. Don't call any client function, just clear the marks.
|
||||
* Don't allow any interruptions.
|
||||
|
|
@ -239,18 +238,22 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
|
|||
SigDisableInterrupts();
|
||||
csa.csa_clientFunc = NULL;
|
||||
csa.csa_clear = TRUE;
|
||||
(void) dbSrConnectFunc(startTile, &csa);
|
||||
(void) dbSrConnectFunc(start_tad.tad_tile, start_tad.tad_dinfo, PTR2CD(&csa));
|
||||
SigEnableInterrupts();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @typedef cb_database_srpaintarea_t */
|
||||
int
|
||||
dbSrConnectStartFunc(tile, pTile)
|
||||
Tile *tile; /* This will be the starting tile. */
|
||||
Tile **pTile; /* We store tile's address here. */
|
||||
dbSrConnectStartFunc(
|
||||
Tile *tile, /* This will be the starting tile. */
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData cdata) /* We store tile and split info here. */
|
||||
{
|
||||
*pTile = tile;
|
||||
TileAndDinfo *tad = (TileAndDinfo *)CD2PTR(cdata);
|
||||
tad->tad_tile = tile;
|
||||
tad->tad_dinfo = dinfo;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -288,9 +291,7 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
|
|||
{
|
||||
struct conSrArg csa;
|
||||
int startPlane, result;
|
||||
Tile *startTile; /* Starting tile for search. */
|
||||
extern int dbSrConnectFunc(); /* Forward declaration. */
|
||||
extern int dbSrConnectStartFunc();
|
||||
TileAndDinfo tad;
|
||||
|
||||
result = 0;
|
||||
csa.csa_def = def;
|
||||
|
|
@ -301,26 +302,27 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
|
|||
* the tile address and returns.
|
||||
*/
|
||||
|
||||
startTile = NULL;
|
||||
tad.tad_tile = NULL;
|
||||
tad.tad_next = NULL; /* unused */
|
||||
for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++)
|
||||
{
|
||||
csa.csa_pNum = startPlane;
|
||||
if (DBSrPaintArea((Tile *) NULL,
|
||||
def->cd_planes[startPlane], startArea, mask,
|
||||
dbSrConnectStartFunc, (ClientData) &startTile) != 0) break;
|
||||
dbSrConnectStartFunc, PTR2CD(&tad)) != 0) break;
|
||||
}
|
||||
if (startTile == NULL) return 0;
|
||||
if (tad.tad_tile == NULL) return 0;
|
||||
/* The following lets us call DBSrConnect recursively */
|
||||
else if (startTile->ti_client == (ClientData)1) return 0;
|
||||
|
||||
else if (tad.tad_tile->ti_client == (ClientData)1) return 0;
|
||||
|
||||
/* Pass 1. During this pass the client function gets called. */
|
||||
|
||||
csa.csa_clientFunc = func;
|
||||
csa.csa_clientData = clientData;
|
||||
csa.csa_clientDefault = CLIENTDEFAULT;
|
||||
csa.csa_clear = FALSE;
|
||||
csa.csa_connect = connect;
|
||||
if (dbSrConnectFunc(startTile, &csa) != 0) result = 1;
|
||||
if (dbSrConnectFunc(tad.tad_tile, tad.tad_dinfo, PTR2CD(&csa)) != 0) result = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -343,12 +345,15 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
|
|||
*/
|
||||
|
||||
int
|
||||
dbcFindTileFunc(tile, arg)
|
||||
dbcFindTileFunc(tile, dinfo, arg)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
ClientData arg;
|
||||
{
|
||||
Tile **tptr = (Tile **)arg;
|
||||
*tptr = tile;
|
||||
TileAndDinfo *tad = (TileAndDinfo *)arg;
|
||||
|
||||
tad->tad_tile = tile;
|
||||
tad->tad_dinfo = dinfo;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -386,15 +391,19 @@ dbcFindTileFunc(tile, arg)
|
|||
*/
|
||||
|
||||
int
|
||||
dbSrConnectFunc(tile, csa)
|
||||
Tile *tile; /* Tile that is connected. */
|
||||
struct conSrArg *csa; /* Contains information about the search. */
|
||||
dbSrConnectFunc(
|
||||
Tile *tile, /* Tile that is connected. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
ClientData cdata) /* Contains information about the search. */
|
||||
/* (struct conSrArg *csa) */
|
||||
{
|
||||
struct conSrArg *csa = (struct conSrArg *)CD2PTR(cdata);
|
||||
Tile *t2;
|
||||
Rect tileArea;
|
||||
int i, pNum;
|
||||
int result = 0;
|
||||
TileTypeBitMask *connectMask;
|
||||
bool callClient;
|
||||
const TileTypeBitMask *connectMask;
|
||||
TileType loctype, checktype;
|
||||
PlaneMask planes;
|
||||
|
||||
|
|
@ -403,13 +412,15 @@ dbSrConnectFunc(tile, csa)
|
|||
|
||||
/* Drop the first entry on the stack */
|
||||
pNum = csa->csa_pNum;
|
||||
STACKPUSH((ClientData)tile, dbConnectStack);
|
||||
STACKPUSH((ClientData)pNum, dbConnectStack);
|
||||
STACKPUSH(INT2CD(tile), dbConnectStack);
|
||||
STACKPUSH(INT2CD(dinfo), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
|
||||
while (!StackEmpty(dbConnectStack))
|
||||
{
|
||||
pNum = (int)STACKPOP(dbConnectStack);
|
||||
tile = (Tile *)STACKPOP(dbConnectStack);
|
||||
pNum = (int)CD2INT(STACKPOP(dbConnectStack));
|
||||
dinfo = (int)CD2INT(STACKPOP(dbConnectStack));
|
||||
tile = (Tile *)CD2INT(STACKPOP(dbConnectStack));
|
||||
if (result == 1) continue;
|
||||
|
||||
TiToRect(tile, &tileArea);
|
||||
|
|
@ -422,22 +433,27 @@ dbSrConnectFunc(tile, csa)
|
|||
* visited.
|
||||
*/
|
||||
|
||||
callClient = TRUE;
|
||||
if (csa->csa_clear)
|
||||
{
|
||||
if (tile->ti_client == (ClientData) CLIENTDEFAULT) continue;
|
||||
tile->ti_client = (ClientData) CLIENTDEFAULT;
|
||||
if (tile->ti_client == csa->csa_clientDefault) continue;
|
||||
tile->ti_client = csa->csa_clientDefault;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tile->ti_client != (ClientData) CLIENTDEFAULT) continue;
|
||||
if (tile->ti_client == (ClientData) 1) continue;
|
||||
|
||||
/* Allow a process to mark tiles for skipping the client function */
|
||||
if (tile->ti_client != csa->csa_clientDefault)
|
||||
callClient = FALSE;
|
||||
tile->ti_client = (ClientData) 1;
|
||||
}
|
||||
|
||||
/* Call the client function, if there is one. */
|
||||
|
||||
if (csa->csa_clientFunc != NULL)
|
||||
if (callClient && (csa->csa_clientFunc != NULL))
|
||||
{
|
||||
if ((*csa->csa_clientFunc)(tile, pNum, csa->csa_clientData) != 0)
|
||||
if ((*csa->csa_clientFunc)(tile, dinfo, pNum, csa->csa_clientData) != 0)
|
||||
{
|
||||
result = 1;
|
||||
continue;
|
||||
|
|
@ -451,7 +467,7 @@ dbSrConnectFunc(tile, csa)
|
|||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
if (SplitSide(tile))
|
||||
if (dinfo & TT_SIDE)
|
||||
loctype = SplitRightType(tile);
|
||||
else
|
||||
loctype = SplitLeftType(tile);
|
||||
|
|
@ -462,7 +478,7 @@ dbSrConnectFunc(tile, csa)
|
|||
|
||||
/* Left side: */
|
||||
|
||||
if (IsSplit(tile) && SplitSide(tile)) goto bottomside;
|
||||
if (IsSplit(tile) && (dinfo & TT_SIDE)) goto bottomside;
|
||||
|
||||
for (t2 = BL(tile); BOTTOM(t2) < tileArea.r_ytop; t2 = RT(t2))
|
||||
{
|
||||
|
|
@ -476,20 +492,22 @@ dbSrConnectFunc(tile, csa)
|
|||
{
|
||||
if (csa->csa_clear)
|
||||
{
|
||||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) continue;
|
||||
if (t2->ti_client == csa->csa_clientDefault) continue;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) continue;
|
||||
else if (t2->ti_client == (ClientData) 1) continue;
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
if (IsSplit(t2))
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body | TT_SIDE)); /* bit set */
|
||||
STACKPUSH((ClientData)t2, dbConnectStack);
|
||||
STACKPUSH((ClientData)pNum, dbConnectStack);
|
||||
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack);
|
||||
else
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
}
|
||||
|
||||
/* Bottom side: */
|
||||
|
||||
bottomside:
|
||||
if (IsSplit(tile) && (!(SplitSide(tile) ^ SplitDirection(tile))))
|
||||
if (IsSplit(tile) && ((!((dinfo & TT_SIDE) ? 1 : 0)) ^ SplitDirection(tile)))
|
||||
goto rightside;
|
||||
|
||||
for (t2 = LB(tile); LEFT(t2) < tileArea.r_xtop; t2 = TR(t2))
|
||||
|
|
@ -504,27 +522,28 @@ bottomside:
|
|||
{
|
||||
if (csa->csa_clear)
|
||||
{
|
||||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) continue;
|
||||
if (t2->ti_client == csa->csa_clientDefault) continue;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) continue;
|
||||
else if (t2->ti_client == (ClientData) 1) continue;
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
if (IsSplit(t2))
|
||||
{
|
||||
if (SplitDirection(t2))
|
||||
/* bit set */
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body | TT_SIDE));
|
||||
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack);
|
||||
else
|
||||
/* bit clear */
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body & ~TT_SIDE));
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
}
|
||||
STACKPUSH((ClientData)t2, dbConnectStack);
|
||||
STACKPUSH((ClientData)pNum, dbConnectStack);
|
||||
else
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
}
|
||||
|
||||
/* Right side: */
|
||||
|
||||
rightside:
|
||||
if (IsSplit(tile) && !SplitSide(tile)) goto topside;
|
||||
if (IsSplit(tile) && !(dinfo & TT_SIDE)) goto topside;
|
||||
|
||||
for (t2 = TR(tile); ; t2 = LB(t2))
|
||||
{
|
||||
|
|
@ -538,13 +557,12 @@ rightside:
|
|||
{
|
||||
if (csa->csa_clear)
|
||||
{
|
||||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) goto nextRight;
|
||||
if (t2->ti_client == csa->csa_clientDefault) goto nextRight;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) goto nextRight;
|
||||
if (IsSplit(t2))
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body & ~TT_SIDE)); /* bit clear */
|
||||
STACKPUSH((ClientData)t2, dbConnectStack);
|
||||
STACKPUSH((ClientData)pNum, dbConnectStack);
|
||||
else if (t2->ti_client == (ClientData) 1) goto nextRight;
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
nextRight: if (BOTTOM(t2) <= tileArea.r_ybot) break;
|
||||
}
|
||||
|
|
@ -552,7 +570,8 @@ rightside:
|
|||
/* Top side: */
|
||||
topside:
|
||||
|
||||
if (IsSplit(tile) && (SplitSide(tile) ^ SplitDirection(tile))) goto donesides;
|
||||
if (IsSplit(tile) && (((dinfo & TT_SIDE) ? 1 : 0) ^ SplitDirection(tile)))
|
||||
goto donesides;
|
||||
|
||||
for (t2 = RT(tile); ; t2 = BL(t2))
|
||||
{
|
||||
|
|
@ -566,25 +585,28 @@ topside:
|
|||
{
|
||||
if (csa->csa_clear)
|
||||
{
|
||||
if (t2->ti_client == (ClientData) CLIENTDEFAULT) goto nextTop;
|
||||
if (t2->ti_client == csa->csa_clientDefault) goto nextTop;
|
||||
}
|
||||
else if (t2->ti_client != (ClientData) CLIENTDEFAULT) goto nextTop;
|
||||
else if (t2->ti_client == (ClientData) 1) goto nextTop;
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
if (IsSplit(t2))
|
||||
{
|
||||
if (SplitDirection(t2))
|
||||
/* bit clear */
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body & ~TT_SIDE));
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
else
|
||||
/* bit set */
|
||||
TiSetBody(t2, (ClientData)(t2->ti_body | TT_SIDE));
|
||||
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack);
|
||||
}
|
||||
STACKPUSH((ClientData)t2, dbConnectStack);
|
||||
STACKPUSH((ClientData)pNum, dbConnectStack);
|
||||
else
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
nextTop: if (LEFT(t2) <= tileArea.r_xbot) break;
|
||||
}
|
||||
|
||||
donesides:
|
||||
if (pNum < 0) continue; /* Used for single-plane search */
|
||||
|
||||
/* Lastly, check to see if this tile connects to anything on
|
||||
* other planes. If so, search those planes.
|
||||
|
|
@ -596,6 +618,7 @@ donesides:
|
|||
{
|
||||
Rect newArea;
|
||||
GEO_EXPAND(&tileArea, 1, &newArea);
|
||||
TileAndDinfo tad;
|
||||
|
||||
for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++)
|
||||
{
|
||||
|
|
@ -603,19 +626,21 @@ donesides:
|
|||
if (IsSplit(tile))
|
||||
{
|
||||
if (DBSrPaintNMArea((Tile *) NULL, csa->csa_def->cd_planes[i],
|
||||
TiGetTypeExact(tile), &newArea, connectMask,
|
||||
dbcFindTileFunc, (ClientData)&t2) != 0)
|
||||
TiGetTypeExact(tile) | dinfo, &newArea, connectMask,
|
||||
dbcFindTileFunc, (ClientData)&tad) != 0)
|
||||
{
|
||||
STACKPUSH((ClientData)t2, dbConnectStack);
|
||||
STACKPUSH((ClientData)i, dbConnectStack);
|
||||
STACKPUSH(PTR2CD(tad.tad_tile), dbConnectStack);
|
||||
STACKPUSH(INT2CD(tad.tad_dinfo), dbConnectStack);
|
||||
STACKPUSH(INT2CD(i), dbConnectStack);
|
||||
}
|
||||
}
|
||||
else if (DBSrPaintArea((Tile *) NULL, csa->csa_def->cd_planes[i],
|
||||
&newArea, connectMask, dbcFindTileFunc,
|
||||
(ClientData)&t2) != 0)
|
||||
(ClientData)&tad) != 0)
|
||||
{
|
||||
STACKPUSH((ClientData)t2, dbConnectStack);
|
||||
STACKPUSH((ClientData)i, dbConnectStack);
|
||||
STACKPUSH(PTR2CD(tad.tad_tile), dbConnectStack);
|
||||
STACKPUSH(INT2CD(tad.tad_dinfo), dbConnectStack);
|
||||
STACKPUSH(INT2CD(i), dbConnectStack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -645,10 +670,13 @@ donesides:
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** @typedef cb_database_srpaintnmarea_t */
|
||||
/** @typedef cb_database_srpaintarea_t */
|
||||
int
|
||||
dbcUnconnectFunc(tile, clientData)
|
||||
dbcUnconnectFunc(tile, dinfo, clientData)
|
||||
Tile *tile; /* Current tile */
|
||||
ClientData clientData; /* Unused. */
|
||||
TileType dinfo; /* Split tile information, unused */
|
||||
ClientData clientData; /* Unused. */
|
||||
|
||||
{
|
||||
return 1;
|
||||
|
|
@ -740,7 +768,8 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
|
|||
CellDef *orig_def = scx->scx_use->cu_def;
|
||||
Label *slab;
|
||||
int lidx = lab->lab_port;
|
||||
TileTypeBitMask *connectMask;
|
||||
bool foundOne;
|
||||
const TileTypeBitMask *connectMask;
|
||||
|
||||
/* Check for equivalent ports. For any found, call */
|
||||
/* DBTreeSrTiles recursively on the type and area */
|
||||
|
|
@ -751,6 +780,7 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
|
|||
/* are more equivalent ports, they will be found when */
|
||||
/* processing this label's area. */
|
||||
|
||||
foundOne = FALSE;
|
||||
for (slab = orig_def->cd_labels; slab != NULL; slab = slab->lab_next)
|
||||
if ((slab->lab_flags & PORT_DIR_MASK) && (slab != lab))
|
||||
if (slab->lab_port == lidx)
|
||||
|
|
@ -769,10 +799,13 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
|
|||
connectMask = &csa2->csa2_connect[slab->lab_type];
|
||||
|
||||
pNum = DBPlane(slab->lab_type);
|
||||
if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum],
|
||||
|
||||
// Do *not* run this check on zero area labels
|
||||
if (!GEO_RECTNULL(&newarea))
|
||||
if (DBSrPaintArea((Tile *) NULL, def->cd_planes[pNum],
|
||||
&newarea, connectMask, dbcUnconnectFunc,
|
||||
(ClientData) NULL) == 1)
|
||||
continue;
|
||||
continue;
|
||||
|
||||
newarea.r_xbot--;
|
||||
newarea.r_xtop++;
|
||||
|
|
@ -808,6 +841,20 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
|
|||
csa2->csa2_list[csa2->csa2_top].connectMask = connectMask;
|
||||
csa2->csa2_list[csa2->csa2_top].dinfo = 0;
|
||||
|
||||
#if 0
|
||||
/* This warning is useful but currently is generating
|
||||
* multiple messages per instance and so its more of
|
||||
* an annoyance than an aid.
|
||||
*/
|
||||
|
||||
if (foundOne == FALSE)
|
||||
TxError("Warning: Port %s at location (%d %d) connects"
|
||||
" a net across multiple disconnected areas!\n",
|
||||
lab->lab_text, lab->lab_rect.r_xbot,
|
||||
lab->lab_rect.r_ybot);
|
||||
#endif
|
||||
foundOne = TRUE;
|
||||
|
||||
/* See above: Process only one equivalent port at a time */
|
||||
break;
|
||||
}
|
||||
|
|
@ -842,8 +889,9 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
|
|||
*/
|
||||
|
||||
int
|
||||
dbcConnectFunc(tile, cx)
|
||||
dbcConnectFunc(tile, dinfo, cx)
|
||||
Tile *tile; /* Tile found. */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TreeContext *cx; /* Describes context of search. The client
|
||||
* data is a pointer to a conSrArg2 record
|
||||
* containing various required information.
|
||||
|
|
@ -851,12 +899,13 @@ dbcConnectFunc(tile, cx)
|
|||
{
|
||||
struct conSrArg2 *csa2;
|
||||
Rect tileArea, newarea;
|
||||
TileTypeBitMask *connectMask, notConnectMask;
|
||||
const TileTypeBitMask *connectMask;
|
||||
TileTypeBitMask notConnectMask;
|
||||
Rect *srArea;
|
||||
SearchContext *scx = cx->tc_scx;
|
||||
SearchContext scx2;
|
||||
TileType loctype = TiGetTypeExact(tile);
|
||||
TileType dinfo = 0;
|
||||
TileType loctype = TiGetTypeExact(tile) | dinfo;
|
||||
TileType newdinfo = 0;
|
||||
int retval, i, pNum = cx->tc_plane;
|
||||
CellDef *def;
|
||||
|
||||
|
|
@ -888,8 +937,8 @@ dbcConnectFunc(tile, cx)
|
|||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
dinfo = DBTransformDiagonal(loctype, &scx->scx_trans);
|
||||
loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
newdinfo = DBTransformDiagonal(loctype, &scx->scx_trans);
|
||||
loctype = ((dinfo & TT_SIDE)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
}
|
||||
|
||||
/* See if the destination cell contains stuff over the whole
|
||||
|
|
@ -927,7 +976,7 @@ dbcConnectFunc(tile, cx)
|
|||
def = csa2->csa2_use->cu_def;
|
||||
retval = 1;
|
||||
if (DBSrPaintNMArea((Tile *) NULL, def->cd_planes[pNum],
|
||||
dinfo, &newarea, ¬ConnectMask, dbcUnconnectFunc,
|
||||
newdinfo, &newarea, ¬ConnectMask, dbcUnconnectFunc,
|
||||
(ClientData) NULL) == 0)
|
||||
retval = 0;
|
||||
|
||||
|
|
@ -936,8 +985,7 @@ dbcConnectFunc(tile, cx)
|
|||
* the storage for the current list element.
|
||||
*/
|
||||
|
||||
if ((retval == 1) || DBIsContact(loctype))
|
||||
DBNMPaintPlane(def->cd_planes[pNum], dinfo,
|
||||
DBNMPaintPlane(def->cd_planes[pNum], newdinfo,
|
||||
&newarea, DBStdPaintTbl(loctype, pNum),
|
||||
(PaintUndoInfo *) NULL);
|
||||
|
||||
|
|
@ -954,14 +1002,14 @@ dbcConnectFunc(tile, cx)
|
|||
|
||||
/* Only extend those sides bordering the diagonal tile */
|
||||
|
||||
if (dinfo & TT_DIAGONAL)
|
||||
if (newdinfo & TT_DIAGONAL)
|
||||
{
|
||||
if (dinfo & TT_SIDE) /* right */
|
||||
if (newdinfo & TT_SIDE) /* right */
|
||||
newarea.r_xtop += 1;
|
||||
else /* left */
|
||||
newarea.r_xbot -= 1;
|
||||
if (((dinfo & TT_SIDE) >> 1)
|
||||
== (dinfo & TT_DIRECTION)) /* top */
|
||||
if (((newdinfo & TT_SIDE) >> 1)
|
||||
== (newdinfo & TT_DIRECTION)) /* top */
|
||||
newarea.r_ytop += 1;
|
||||
else /* bottom */
|
||||
newarea.r_ybot -= 1;
|
||||
|
|
@ -1001,7 +1049,7 @@ dbcConnectFunc(tile, cx)
|
|||
|
||||
csa2->csa2_list[csa2->csa2_top].area = newarea;
|
||||
csa2->csa2_list[csa2->csa2_top].connectMask = connectMask;
|
||||
csa2->csa2_list[csa2->csa2_top].dinfo = dinfo;
|
||||
csa2->csa2_list[csa2->csa2_top].dinfo = newdinfo;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1067,7 +1115,7 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, doLabels, destUse)
|
|||
*/
|
||||
{
|
||||
struct conSrArg2 csa2;
|
||||
TileTypeBitMask *newmask;
|
||||
const TileTypeBitMask *newmask;
|
||||
TileType newtype;
|
||||
unsigned char searchtype;
|
||||
|
||||
|
|
@ -1156,7 +1204,8 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, doLabels, destUse)
|
|||
if (DBTreeSrLabels(scx, newmask, xMask, &tpath, searchtype,
|
||||
dbcConnectLabelFunc, (ClientData) &csa2) != 0)
|
||||
{
|
||||
TxError("Connection search hit memory limit and stopped.\n");
|
||||
TxError("Connection search was interrupted or hit "
|
||||
"memory limit and stopped.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,12 +50,13 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
* cell graph; if it returns 0 then the subcells of 'def' are visited;
|
||||
* if it returns 1 then the subcells are not visited.
|
||||
*
|
||||
* int
|
||||
* void
|
||||
* hiercount(parent, uses, child, cdata)
|
||||
* CellDef *parent, *child;
|
||||
* CellDef *parent;
|
||||
* int uses; /# Scale factor: number of times child
|
||||
* # is used by parent
|
||||
* #/
|
||||
* CellDef *child;
|
||||
* ClientData cdata;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -103,7 +104,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
struct countArg
|
||||
{
|
||||
int (*ca_count)();
|
||||
int (*ca_hiercount)();
|
||||
void (*ca_hiercount)();
|
||||
ClientData ca_cdata;
|
||||
};
|
||||
|
||||
|
|
@ -111,7 +112,7 @@ void
|
|||
DBTreeCountPaint(def, count, hiercount, cleanup, cdata)
|
||||
CellDef *def;
|
||||
int (*count)();
|
||||
int (*hiercount)();
|
||||
void (*hiercount)();
|
||||
int (*cleanup)();
|
||||
ClientData cdata;
|
||||
{
|
||||
|
|
|
|||
|
|
@ -82,8 +82,7 @@ DBExpand(cellUse, expandMask, expandFlag)
|
|||
def = cellUse->cu_def;
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (!DBCellRead(def, (char *) NULL, TRUE, dereference, NULL))
|
||||
if (!DBCellRead(def, TRUE, TRUE, NULL))
|
||||
return;
|
||||
/* Note: we don't have to recompute the bbox here, because
|
||||
* if it changed, then a timestamp violation must have occurred
|
||||
|
|
@ -144,13 +143,9 @@ DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg)
|
|||
int dbExpandFunc(), dbUnexpandFunc();
|
||||
SearchContext scontext;
|
||||
struct expandArg arg;
|
||||
bool dereference = (rootUse->cu_def->cd_flags & CDDEREFERENCE) ?
|
||||
TRUE : FALSE;
|
||||
|
||||
if ((rootUse->cu_def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
(void) DBCellRead(rootUse->cu_def, (char *) NULL, TRUE, dereference, NULL);
|
||||
}
|
||||
(void) DBCellRead(rootUse->cu_def, TRUE, TRUE, NULL);
|
||||
|
||||
/*
|
||||
* Walk through the area and set the expansion state
|
||||
|
|
@ -160,7 +155,7 @@ DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg)
|
|||
arg.ea_xmask = expandMask;
|
||||
arg.ea_func = func;
|
||||
arg.ea_arg = cdarg;
|
||||
arg.ea_deref = dereference;
|
||||
arg.ea_deref = (rootUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
|
||||
scontext.scx_use = rootUse;
|
||||
scontext.scx_trans = GeoIdentityTransform;
|
||||
|
|
@ -200,12 +195,16 @@ dbExpandFunc(scx, arg)
|
|||
/* If the cell is unavailable, then don't expand it.
|
||||
*/
|
||||
if ((childUse->cu_def->cd_flags & CDAVAILABLE) == 0)
|
||||
if(!DBCellRead(childUse->cu_def, (char *) NULL, TRUE, arg->ea_deref, NULL))
|
||||
{
|
||||
/* If the parent is dereferenced, then the child should be, too */
|
||||
if (arg->ea_deref) childUse->cu_def->cd_flags |= CDDEREFERENCE;
|
||||
if(!DBCellRead(childUse->cu_def, TRUE, TRUE, NULL))
|
||||
{
|
||||
TxError("Cell %s is unavailable. It could not be expanded.\n",
|
||||
childUse->cu_def->cd_name);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
childUse->cu_expandMask |= arg->ea_xmask;
|
||||
if (arg->ea_func != NULL)
|
||||
|
|
@ -275,8 +274,8 @@ dbUnexpandFunc(scx, arg)
|
|||
* the given rectangle.
|
||||
*
|
||||
* Results:
|
||||
* If "halt_on_error" is TRUE, then return 1 if any subcell could not
|
||||
* be read. Otherwise, return 0.
|
||||
* If "halt_on_error" is TRUE, then return a pointer to the first
|
||||
* subcell that could not be read. Otherwise, return NULL.
|
||||
*
|
||||
* Side effects:
|
||||
* May make new cells known to the database. Sets the CDAVAILABLE
|
||||
|
|
@ -285,7 +284,7 @@ dbUnexpandFunc(scx, arg)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
CellDef *
|
||||
DBCellReadArea(rootUse, rootRect, halt_on_error)
|
||||
CellUse *rootUse; /* Root cell use from which search begins */
|
||||
Rect *rootRect; /* Area to be read, in root coordinates */
|
||||
|
|
@ -293,33 +292,44 @@ DBCellReadArea(rootUse, rootRect, halt_on_error)
|
|||
{
|
||||
int dbReadAreaFunc();
|
||||
SearchContext scontext;
|
||||
CellDef *err_def = NULL;
|
||||
|
||||
scontext.scx_use = rootUse;
|
||||
scontext.scx_trans = GeoIdentityTransform;
|
||||
scontext.scx_area = *rootRect;
|
||||
if (dbReadAreaFunc(&scontext, halt_on_error) == 1)
|
||||
return 1;
|
||||
if (dbReadAreaFunc(&scontext, ((halt_on_error == TRUE) ? &err_def : NULL)) == 1)
|
||||
return err_def;
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
dbReadAreaFunc(scx, halt_on_error)
|
||||
dbReadAreaFunc(scx, err_ptr)
|
||||
SearchContext *scx; /* Pointer to context specifying
|
||||
* the cell use to be read in, and
|
||||
* an area to be recursively read in
|
||||
* coordinates of the cell use's def.
|
||||
*/
|
||||
bool halt_on_error; /* If TURE, failure to find a cell causes a halt */
|
||||
CellDef **err_ptr; /* If non-NULL, failure to find a cell causes a halt
|
||||
* and the CellDef in error is returned in err_def.
|
||||
* If NULL, failure to find a cell still causes a
|
||||
* halt but no information is passed back to the
|
||||
* calling routine.
|
||||
*/
|
||||
{
|
||||
CellDef *def = scx->scx_use->cu_def;
|
||||
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
if (DBCellRead(def, (char *)NULL, TRUE, dereference, NULL) == FALSE)
|
||||
if (halt_on_error)
|
||||
if (DBCellRead(def, TRUE, TRUE, NULL) == FALSE)
|
||||
{
|
||||
if (err_ptr != NULL) {
|
||||
*err_ptr = def;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Note: we don't have to invoke DBReComputeBbox here because
|
||||
* if the bbox changed then there was a timestamp mismatch and
|
||||
|
|
@ -327,9 +337,8 @@ dbReadAreaFunc(scx, halt_on_error)
|
|||
*/
|
||||
}
|
||||
|
||||
if (DBCellSrArea(scx, dbReadAreaFunc, (ClientData)halt_on_error))
|
||||
if (halt_on_error)
|
||||
return 1;
|
||||
if (DBCellSrArea(scx, dbReadAreaFunc, (ClientData)err_ptr))
|
||||
return 1;
|
||||
|
||||
/* Be clever about handling arrays: if the search area covers this
|
||||
* whole definition, then there's no need to look at any other
|
||||
|
|
|
|||
1420
database/DBio.c
1420
database/DBio.c
File diff suppressed because it is too large
Load Diff
|
|
@ -24,6 +24,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <math.h> /* For sin(), cos(), and round() functions */
|
||||
#include <ctype.h>
|
||||
|
||||
|
|
@ -36,12 +37,13 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "database/database.h"
|
||||
#include "database/fonts.h"
|
||||
#include "database/databaseInt.h"
|
||||
#include "extract/extractInt.h" /* for ExtCurStyle */
|
||||
#include "windows/windows.h"
|
||||
#include "dbwind/dbwind.h"
|
||||
#include "commands/commands.h"
|
||||
#include "textio/textio.h"
|
||||
|
||||
static TileType DBPickLabelLayer(/* CellDef *def, Label *lab, int noreconnect */);
|
||||
static TileType DBPickLabelLayer(/* CellDef *def, Label *lab, bool doCalma */);
|
||||
|
||||
/* Globally-accessible font information */
|
||||
|
||||
|
|
@ -278,6 +280,7 @@ DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
|
|||
bool erasedAny = FALSE;
|
||||
TileType newType;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
labPrev = NULL;
|
||||
lab = cellDef->cd_labels;
|
||||
while (lab != NULL)
|
||||
|
|
@ -292,7 +295,7 @@ DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
|
|||
*/
|
||||
if (!(lab->lab_type == TT_SPACE))
|
||||
{
|
||||
newType = DBPickLabelLayer(cellDef, lab, 0);
|
||||
newType = DBPickLabelLayer(cellDef, lab, FALSE);
|
||||
if (DBConnectsTo(newType, lab->lab_type)) goto nextLab;
|
||||
}
|
||||
}
|
||||
|
|
@ -311,7 +314,7 @@ DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
|
|||
if ((lab->lab_font >= 0) && areaReturn)
|
||||
GeoInclude(&lab->lab_bbox, areaReturn);
|
||||
|
||||
freeMagic((char *) lab);
|
||||
freeMagic1(&mm1, (char *) lab);
|
||||
lab = lab->lab_next;
|
||||
erasedAny = TRUE;
|
||||
continue;
|
||||
|
|
@ -319,6 +322,7 @@ DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
|
|||
nextLab: labPrev = lab;
|
||||
lab = lab->lab_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
if (erasedAny)
|
||||
cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
|
||||
|
|
@ -440,6 +444,7 @@ DBEraseLabelsByContent(def, rect, type, text)
|
|||
{
|
||||
Label *lab, *labPrev;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (labPrev = NULL, lab = def->cd_labels;
|
||||
lab != NULL;
|
||||
labPrev = lab, lab = lab->lab_next)
|
||||
|
|
@ -455,7 +460,7 @@ DBEraseLabelsByContent(def, rect, type, text)
|
|||
else labPrev->lab_next = lab->lab_next;
|
||||
if (def->cd_lastLabel == lab)
|
||||
def->cd_lastLabel = labPrev;
|
||||
freeMagic((char *) lab);
|
||||
freeMagic1(&mm1, (char *) lab);
|
||||
|
||||
/* Don't iterate through loop, since this will skip a label:
|
||||
* just go back to top. This is tricky!
|
||||
|
|
@ -465,6 +470,7 @@ DBEraseLabelsByContent(def, rect, type, text)
|
|||
if (lab == NULL) break;
|
||||
else goto nextCheck;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -493,6 +499,7 @@ DBRemoveLabel(def, refLab)
|
|||
{
|
||||
Label *lab, *labPrev;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (labPrev = NULL, lab = def->cd_labels;
|
||||
lab != NULL;
|
||||
labPrev = lab, lab = lab->lab_next)
|
||||
|
|
@ -506,7 +513,7 @@ DBRemoveLabel(def, refLab)
|
|||
else labPrev->lab_next = lab->lab_next;
|
||||
if (def->cd_lastLabel == lab)
|
||||
def->cd_lastLabel = labPrev;
|
||||
freeMagic((char *) lab);
|
||||
freeMagic1(&mm1, (char *) lab);
|
||||
|
||||
/* Don't iterate through loop, since this will skip a label:
|
||||
* just go back to top. This is tricky!
|
||||
|
|
@ -516,6 +523,7 @@ DBRemoveLabel(def, refLab)
|
|||
if (lab == NULL) break;
|
||||
else goto nextCheck;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -560,6 +568,42 @@ DBReOrientLabel(cellDef, area, newPos)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbGetLabelArea ---
|
||||
*
|
||||
* Callback function used by DBAdjustLabels. Find all material under a label
|
||||
* that is *not* the label type, and return the
|
||||
*
|
||||
* Note: This clips in a regular order, and does not consider what is the
|
||||
* largest rectangular area outside the area that has been clipped out.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbGetLabelArea(tile, dinfo, area)
|
||||
Tile *tile; /* Tile found. */
|
||||
TileType dinfo; /* Split tile information (unused) */
|
||||
Rect *area; /* Area to be modified. */
|
||||
{
|
||||
Rect r;
|
||||
|
||||
TiToRect(tile, &r);
|
||||
|
||||
if (r.r_xbot > area->r_xbot)
|
||||
area->r_xtop = r.r_xbot;
|
||||
else if (r.r_xtop < area->r_xtop)
|
||||
area->r_xbot = r.r_xtop;
|
||||
else if (r.r_ybot > area->r_ybot)
|
||||
area->r_ytop = r.r_ybot;
|
||||
else if (r.r_ytop < area->r_ytop)
|
||||
area->r_ybot = r.r_ytop;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -589,7 +633,7 @@ DBAdjustLabels(def, area)
|
|||
{
|
||||
Label *lab;
|
||||
TileType newType;
|
||||
bool modified = FALSE;
|
||||
bool modified = FALSE, adjusted = FALSE;
|
||||
|
||||
/* First, find each label that crosses the area we're
|
||||
* interested in.
|
||||
|
|
@ -598,18 +642,63 @@ DBAdjustLabels(def, area)
|
|||
for (lab = def->cd_labels; lab != NULL; lab = lab->lab_next)
|
||||
{
|
||||
if (!GEO_TOUCH(&lab->lab_rect, area)) continue;
|
||||
newType = DBPickLabelLayer(def, lab, 0);
|
||||
newType = DBPickLabelLayer(def, lab, FALSE);
|
||||
if (newType == lab->lab_type) continue;
|
||||
if (lab->lab_flags & LABEL_STICKY) continue;
|
||||
if (DBVerbose && ((def->cd_flags & CDINTERNAL) == 0)) {
|
||||
TxPrintf("Moving label \"%s\" from %s to %s in cell %s.\n",
|
||||
lab->lab_text, DBTypeLongName(lab->lab_type),
|
||||
DBTypeLongName(newType), def->cd_name);
|
||||
};
|
||||
DBUndoEraseLabel(def, lab);
|
||||
lab->lab_type = newType;
|
||||
DBUndoPutLabel(def, lab);
|
||||
modified = TRUE;
|
||||
|
||||
/* New behavior (5/2024) (idea from Philipp Guhring)---If the new
|
||||
* type is space, then instead of immediately casting the label off
|
||||
* of its material, find the amount of the label that is still
|
||||
* covered by the material. If the material covers more than half
|
||||
* the label area, then adjust the label area to match the material.
|
||||
*/
|
||||
|
||||
adjusted = FALSE;
|
||||
if (newType == TT_SPACE)
|
||||
{
|
||||
Rect r;
|
||||
TileTypeBitMask lmask;
|
||||
|
||||
TTMaskSetOnlyType(&lmask, lab->lab_type);
|
||||
/* To do: Add compatible types (contact, residue) */
|
||||
TTMaskCom(&lmask);
|
||||
|
||||
r = lab->lab_rect;
|
||||
DBSrPaintArea((Tile *) NULL, def->cd_planes[DBPlane(lab->lab_type)],
|
||||
&lab->lab_rect, &lmask, dbGetLabelArea, (ClientData) &r);
|
||||
|
||||
if (!GEO_RECTNULL(&r))
|
||||
{
|
||||
if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
|
||||
{
|
||||
TxPrintf("Adjusting size of label \"%s\" in cell %s.\n",
|
||||
lab->lab_text, def->cd_name);
|
||||
}
|
||||
|
||||
DBUndoEraseLabel(def, lab);
|
||||
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
|
||||
lab->lab_rect = r;
|
||||
DBFontLabelSetBBox(lab);
|
||||
DBUndoPutLabel(def, lab);
|
||||
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
|
||||
modified = TRUE;
|
||||
adjusted = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!adjusted)
|
||||
{
|
||||
if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
|
||||
{
|
||||
TxPrintf("Moving label \"%s\" from %s to %s in cell %s.\n",
|
||||
lab->lab_text, DBTypeLongName(lab->lab_type),
|
||||
DBTypeLongName(newType), def->cd_name);
|
||||
}
|
||||
DBUndoEraseLabel(def, lab);
|
||||
lab->lab_type = newType;
|
||||
DBUndoPutLabel(def, lab);
|
||||
modified = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (modified) DBCellSetModified(def, TRUE);
|
||||
|
|
@ -617,16 +706,32 @@ DBAdjustLabels(def, area)
|
|||
|
||||
|
||||
/*
|
||||
* Extended version of DBAdjustLabels. If noreconnect==0,
|
||||
* this is supposed to be the same as DBAdjustlabels() above.
|
||||
*---------------------------------------------------------------
|
||||
*
|
||||
* DBAdjustLabelsNew--
|
||||
*
|
||||
* Modified version of DBAdjustLabels, used with reading
|
||||
* GDS and LEF files. Since those files use GDS layers and
|
||||
* not magic layers, there is no exact relationship between
|
||||
* the two. Instead, the cifinput rules are used to set an
|
||||
* initial type only. The rules for label adjustment are
|
||||
* different from DBAdjustLabels(), and so a different
|
||||
* routine is called.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The layer attachments of labels may change. For each
|
||||
* such change, a message is output.
|
||||
*
|
||||
*---------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DBAdjustLabelsNew(def, area, noreconnect)
|
||||
DBAdjustLabelsNew(def, area)
|
||||
CellDef *def; /* Cell whose paint was changed. */
|
||||
Rect *area; /* Area where paint was modified. */
|
||||
int noreconnect; /* if 1, don't move label to a type that doesn't
|
||||
* connect to the original type, delete instead
|
||||
*/
|
||||
{
|
||||
Label *lab, *labPrev;
|
||||
TileType newType;
|
||||
|
|
@ -640,46 +745,59 @@ DBAdjustLabelsNew(def, area, noreconnect)
|
|||
lab = def->cd_labels;
|
||||
while (lab != NULL)
|
||||
{
|
||||
int locnoreconnect = noreconnect;
|
||||
if (!GEO_TOUCH(&lab->lab_rect, area)) {
|
||||
goto nextLab;
|
||||
}
|
||||
if (lab->lab_type == TT_SPACE) locnoreconnect = FALSE;
|
||||
newType = DBPickLabelLayer(def, lab, locnoreconnect);
|
||||
if (newType == lab->lab_type) {
|
||||
goto nextLab;
|
||||
}
|
||||
if(newType < 0 && !(lab->lab_flags & LABEL_STICKY)) {
|
||||
TxPrintf("Deleting ambiguous-layer label \"%s\" from %s in cell %s.\n",
|
||||
lab->lab_text, DBTypeLongName(lab->lab_type),
|
||||
def->cd_name);
|
||||
bool doCalma = TRUE;
|
||||
if (!GEO_TOUCH(&lab->lab_rect, area)) goto nextLab;
|
||||
if (lab->lab_type == TT_SPACE) doCalma = FALSE;
|
||||
newType = DBPickLabelLayer(def, lab, doCalma);
|
||||
if (newType == lab->lab_type)
|
||||
goto nextLab;
|
||||
|
||||
if (labPrev == NULL)
|
||||
def->cd_labels = lab->lab_next;
|
||||
else
|
||||
labPrev->lab_next = lab->lab_next;
|
||||
if (def->cd_lastLabel == lab)
|
||||
def->cd_lastLabel = labPrev;
|
||||
DBUndoEraseLabel(def, lab);
|
||||
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
|
||||
freeMagic((char *) lab);
|
||||
lab = lab->lab_next;
|
||||
modified = TRUE;
|
||||
continue;
|
||||
} else if (!(lab->lab_flags & LABEL_STICKY)) {
|
||||
if (DBVerbose && ((def->cd_flags & CDINTERNAL) == 0)) {
|
||||
TxPrintf("Moving label \"%s\" from %s to %s in cell %s.\n",
|
||||
lab->lab_text, DBTypeLongName(lab->lab_type),
|
||||
DBTypeLongName(newType), def->cd_name);
|
||||
}
|
||||
DBUndoEraseLabel(def, lab);
|
||||
lab->lab_type = newType;
|
||||
DBUndoPutLabel(def, lab);
|
||||
modified = TRUE;
|
||||
if (((newType < 0) || (newType == TT_SPACE)) && !(lab->lab_flags & LABEL_STICKY))
|
||||
{
|
||||
if (lab->lab_type == TT_SPACE)
|
||||
{
|
||||
TxPrintf("Deleting unattached label \"%s\" in cell %s.\n",
|
||||
lab->lab_text, def->cd_name);
|
||||
|
||||
if (labPrev == NULL)
|
||||
def->cd_labels = lab->lab_next;
|
||||
else
|
||||
labPrev->lab_next = lab->lab_next;
|
||||
if (def->cd_lastLabel == lab)
|
||||
def->cd_lastLabel = labPrev;
|
||||
DBUndoEraseLabel(def, lab);
|
||||
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, (char *) lab);
|
||||
lab = lab->lab_next;
|
||||
freeMagic1_end(&mm1);
|
||||
modified = TRUE;
|
||||
continue;
|
||||
}
|
||||
nextLab:
|
||||
labPrev = lab;
|
||||
lab = lab->lab_next;
|
||||
else
|
||||
{
|
||||
TxPrintf("Making label \"%s\" on type %s in cell %s sticky.\n",
|
||||
lab->lab_text, DBTypeLongName(lab->lab_type),
|
||||
def->cd_name);
|
||||
lab->lab_flags |= LABEL_STICKY;
|
||||
}
|
||||
}
|
||||
else if (!(lab->lab_flags & LABEL_STICKY))
|
||||
{
|
||||
if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
|
||||
{
|
||||
TxPrintf("Moving label \"%s\" from %s to %s in cell %s.\n",
|
||||
lab->lab_text, DBTypeLongName(lab->lab_type),
|
||||
DBTypeLongName(newType), def->cd_name);
|
||||
}
|
||||
DBUndoEraseLabel(def, lab);
|
||||
lab->lab_type = newType;
|
||||
DBUndoPutLabel(def, lab);
|
||||
modified = TRUE;
|
||||
}
|
||||
nextLab:
|
||||
labPrev = lab;
|
||||
lab = lab->lab_next;
|
||||
}
|
||||
|
||||
if (modified) DBCellSetModified(def, TRUE);
|
||||
|
|
@ -715,10 +833,10 @@ TileTypeBitMask *dbAdjustPlaneTypes; /* Mask of all types in current
|
|||
* plane being searched.
|
||||
*/
|
||||
TileType
|
||||
DBPickLabelLayer(def, lab, noreconnect)
|
||||
DBPickLabelLayer(def, lab, doCalma)
|
||||
CellDef *def; /* Cell definition containing label. */
|
||||
Label *lab; /* Label for which a home must be found. */
|
||||
int noreconnect; /* if 1, return -1 if rule 5 or 6 would succeed */
|
||||
bool doCalma; /* if TRUE, use rules for GDS and LEF */
|
||||
{
|
||||
TileTypeBitMask types[3], types2[3];
|
||||
Rect check1, check2;
|
||||
|
|
@ -819,112 +937,147 @@ DBPickLabelLayer(def, lab, noreconnect)
|
|||
}
|
||||
|
||||
/* If the label's layer covers the label's area, use it.
|
||||
* Otherwise, look for a layer in the following order:
|
||||
* 1. A layer on the same plane as the original layer and that
|
||||
* covers the label and connects to its original layer.
|
||||
* 2. A layer on the same plane as the original layer and that
|
||||
* is a component of material that covers the label and
|
||||
* connects to its original layer.
|
||||
* 3. A layer that covers the label and connects to the
|
||||
* old layer.
|
||||
* 4. A layer that is a component of material that covers
|
||||
* the label and connects to the old layer.
|
||||
* 5. A layer that covers the label.
|
||||
* 6. A layer that is a component of material that covers the label.
|
||||
* 7. Space.
|
||||
* Otherwise, look for a layer in the following order
|
||||
* (Note: "covers" means covers the area of the label if the
|
||||
* label has area or touches the entire label if it doesn't.):
|
||||
*
|
||||
* If "doCalma" is TRUE, then:
|
||||
* 1. A layer on the same plane as the original layer and that
|
||||
* covers the label and is not a device type.
|
||||
* 2. A layer on the same plane as the original layer and that
|
||||
* covers the label.
|
||||
* 3. A layer on the same plane as the original layer and that
|
||||
* is a component of material that covers the label.
|
||||
* 4. -1
|
||||
*
|
||||
* If "doCalma" is FALSE, then:
|
||||
* 1. A layer on the same plane as the original layer and that
|
||||
* covers the label and connects to its original layer.
|
||||
* 2. A layer on the same plane as the original layer and that
|
||||
* is a component of material that covers the label and
|
||||
* connects to its original layer.
|
||||
* 3. A layer that covers the label and connects to the old layer.
|
||||
* 4. A layer that is a component of material that covers the
|
||||
* label and connects to the old layer.
|
||||
* 5. A layer that covers the label and is on the same plane as the
|
||||
* label.
|
||||
* 6. A layer that is a component of material that covers the label
|
||||
* and is on the same plane as the label.
|
||||
* 7. Space.
|
||||
*
|
||||
* All searches are done from the lowest to highest plane, so that
|
||||
* the label connects to material on the highest plane that matches
|
||||
* the criteria above. This avoids weirdnesses caused by declaring
|
||||
* types out of order in the techfile.
|
||||
*
|
||||
* Note that when the "label" command is used with no type given,
|
||||
* then lab_type is TT_SPACE and "same plane as the label" is all
|
||||
* planes. This should never be true when called during GDS or
|
||||
* LEF reads, so only needs to be checked when "doCalma" is FALSE.
|
||||
*/
|
||||
|
||||
if (TTMaskHasType(&types[0], lab->lab_type)) return lab->lab_type;
|
||||
plane = DBPlane(lab->lab_type);
|
||||
choice1 = choice2 = choice3 = choice4 = choice5 = choice6 = TT_SPACE;
|
||||
|
||||
for (j = PL_SELECTBASE; j < DBNumPlanes; j++)
|
||||
if (doCalma)
|
||||
{
|
||||
choice1 = choice2 = choice3 = -1;
|
||||
|
||||
for (i = TT_SELECTBASE; i < DBNumUserLayers; i += 1)
|
||||
{
|
||||
if (!TTMaskHasType(&DBPlaneTypes[j], i)) continue;
|
||||
if (!TTMaskHasType(&DBPlaneTypes[plane], i)) continue;
|
||||
|
||||
if (DBConnectsTo(i, lab->lab_type))
|
||||
if (TTMaskHasType(&types[0], i) && (ExtCurStyle != NULL))
|
||||
{
|
||||
if (DBPlane(i) == plane)
|
||||
{
|
||||
if (TTMaskHasType(&types[0], i))
|
||||
{
|
||||
choice1 = i;
|
||||
continue;
|
||||
}
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
{
|
||||
choice2 = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (TTMaskHasType(&types[0], i))
|
||||
{
|
||||
choice3 = i;
|
||||
continue;
|
||||
}
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
{
|
||||
choice4 = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (TTMaskHasType(&types[0], i))
|
||||
{
|
||||
/* A type that connects to more than itself is preferred */
|
||||
if (choice5 == TT_SPACE)
|
||||
choice5 = i;
|
||||
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, i))
|
||||
choice2 = i;
|
||||
else
|
||||
{
|
||||
TileTypeBitMask ctest;
|
||||
TTMaskZero(&ctest);
|
||||
TTMaskSetMask(&ctest, &DBConnectTbl[i]);
|
||||
TTMaskClearType(&ctest, i);
|
||||
if (!TTMaskIsZero(&ctest))
|
||||
choice5 = i;
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
choice6 = i;
|
||||
}
|
||||
choice1 = i;
|
||||
continue;
|
||||
}
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
{
|
||||
choice6 = i;
|
||||
choice3 = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (choice1 != TT_SPACE) return choice1;
|
||||
else if (choice2 != TT_SPACE) return choice2;
|
||||
else if (choice3 != TT_SPACE) return choice3;
|
||||
else if (choice4 != TT_SPACE) return choice4;
|
||||
else if (noreconnect) {
|
||||
#ifdef notdef
|
||||
TxPrintf("DBPickLabelLayer \"%s\" (on %s at %d,%d) choice4=%s choice5=%s choice6=%s.\n",
|
||||
lab->lab_text,
|
||||
DBTypeLongName(lab->lab_type),
|
||||
lab->lab_rect.r_xbot,
|
||||
lab->lab_rect.r_ytop,
|
||||
DBTypeLongName(choice4),
|
||||
DBTypeLongName(choice5),
|
||||
DBTypeLongName(choice6));
|
||||
#endif
|
||||
/* If the flag is set, don't cause a netlist change by moving a
|
||||
the label. So unless there's only space here, delete the label */
|
||||
if(choice5 == TT_SPACE && choice6 == TT_SPACE)
|
||||
return TT_SPACE;
|
||||
else
|
||||
return -1;
|
||||
if (choice1 != -1) return choice1;
|
||||
else if (choice2 != -1) return choice2;
|
||||
else return choice3;
|
||||
}
|
||||
else
|
||||
{
|
||||
choice1 = choice2 = choice3 = choice4 = choice5 = choice6 = TT_SPACE;
|
||||
|
||||
for (j = PL_SELECTBASE; j < DBNumPlanes; j++)
|
||||
{
|
||||
for (i = TT_SELECTBASE; i < DBNumUserLayers; i += 1)
|
||||
{
|
||||
if (!TTMaskHasType(&DBPlaneTypes[j], i)) continue;
|
||||
|
||||
if (DBConnectsTo(i, lab->lab_type))
|
||||
{
|
||||
if (DBPlane(i) == plane)
|
||||
{
|
||||
if (TTMaskHasType(&types[0], i))
|
||||
{
|
||||
choice1 = i;
|
||||
continue;
|
||||
}
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
{
|
||||
choice2 = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (TTMaskHasType(&types[0], i))
|
||||
{
|
||||
choice3 = i;
|
||||
continue;
|
||||
}
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
{
|
||||
choice4 = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if ((DBPlane(i) == plane) || (lab->lab_type == TT_SPACE))
|
||||
{
|
||||
if (TTMaskHasType(&types[0], i))
|
||||
{
|
||||
/* A type that connects to more than itself is preferred */
|
||||
if (choice5 == TT_SPACE)
|
||||
choice5 = i;
|
||||
else
|
||||
{
|
||||
TileTypeBitMask ctest;
|
||||
TTMaskZero(&ctest);
|
||||
TTMaskSetMask(&ctest, &DBConnectTbl[i]);
|
||||
TTMaskClearType(&ctest, i);
|
||||
if (!TTMaskIsZero(&ctest))
|
||||
choice5 = i;
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
choice6 = i;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (TTMaskHasType(&types[1], i))
|
||||
{
|
||||
choice6 = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (choice1 != TT_SPACE) return choice1;
|
||||
else if (choice2 != TT_SPACE) return choice2;
|
||||
else if (choice3 != TT_SPACE) return choice3;
|
||||
else if (choice4 != TT_SPACE) return choice4;
|
||||
else if (choice5 != TT_SPACE) return choice5;
|
||||
else return choice6;
|
||||
}
|
||||
else if (choice5 != TT_SPACE) return choice5;
|
||||
else return choice6;
|
||||
}
|
||||
|
||||
/* Search function for DBPickLabelLayer: just OR in the type of
|
||||
|
|
@ -933,14 +1086,15 @@ DBPickLabelLayer(def, lab, noreconnect)
|
|||
*/
|
||||
|
||||
int
|
||||
dbPickFunc1(tile, mask)
|
||||
dbPickFunc1(tile, dinfo, mask)
|
||||
Tile *tile; /* Tile found. */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TileTypeBitMask *mask; /* Mask to be modified. */
|
||||
{
|
||||
TileType type;
|
||||
|
||||
if (IsSplit(tile))
|
||||
type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
else
|
||||
type = TiGetType(tile);
|
||||
|
||||
|
|
@ -959,15 +1113,16 @@ dbPickFunc1(tile, mask)
|
|||
*/
|
||||
|
||||
int
|
||||
dbPickFunc2(tile, mask)
|
||||
dbPickFunc2(tile, dinfo, mask)
|
||||
Tile *tile; /* Tile found. */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TileTypeBitMask *mask; /* Mask to be modified. */
|
||||
{
|
||||
TileType type;
|
||||
TileTypeBitMask tmp, *rMask;
|
||||
|
||||
if (IsSplit(tile))
|
||||
type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
|
||||
else
|
||||
type = TiGetType(tile);
|
||||
|
||||
|
|
@ -1405,7 +1560,7 @@ DBLoadFont(fontfile, scale)
|
|||
float scale;
|
||||
{
|
||||
FILE *ff;
|
||||
char *ascii_names[] = {
|
||||
const char * const ascii_names[] = {
|
||||
"space", "exclam", "quotedbl", "numbersign", "dollar",
|
||||
"percent", "ampersand", "quoteright", "parenleft", "parenright",
|
||||
"asterisk", "plus", "comma", "hyphen", "period", "slash", "zero",
|
||||
|
|
@ -1510,7 +1665,7 @@ DBLoadFont(fontfile, scale)
|
|||
{
|
||||
if (psname != NULL)
|
||||
{
|
||||
asciiidx = LookupStructFull(psname, ascii_names, sizeof(char *));
|
||||
asciiidx = LookupStructFull(psname, ascii_names, sizeof(const char *));
|
||||
if (asciiidx >= 0)
|
||||
chardef = 2;
|
||||
}
|
||||
|
|
@ -1600,8 +1755,10 @@ DBLoadFont(fontfile, scale)
|
|||
}
|
||||
|
||||
/* Remove the pointlist */
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (newPath = pathStart; newPath != NULL; newPath = newPath->fp_next)
|
||||
freeMagic(newPath);
|
||||
freeMagic1(&mm1, newPath);
|
||||
freeMagic1_end(&mm1);
|
||||
pathStart = NULL;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ DBSrLabelLoc(rootUse, name, func, cdarg)
|
|||
char csave;
|
||||
Rect r;
|
||||
|
||||
if (cp = strrchr(name, '/'))
|
||||
if ((cp = strrchr(name, '/')))
|
||||
{
|
||||
csave = *cp;
|
||||
*cp = '\0';
|
||||
|
|
@ -294,10 +294,7 @@ DBTreeFindUse(name, use, scx)
|
|||
* is read in from disk.
|
||||
*/
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
(void) DBCellRead(def, (char *) NULL, TRUE, dereference, NULL);
|
||||
}
|
||||
(void) DBCellRead(def, TRUE, TRUE, NULL);
|
||||
|
||||
cp = name;
|
||||
he = HashLookOnly(&def->cd_idHash, name);
|
||||
|
|
@ -346,10 +343,7 @@ DBTreeFindUse(name, use, scx)
|
|||
/* Ensure that the leaf cell is read in */
|
||||
def = use->cu_def;
|
||||
if ((def->cd_flags & CDAVAILABLE) == 0)
|
||||
{
|
||||
bool dereference = (def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
(void) DBCellRead(def, (char *) NULL, TRUE, dereference, NULL);
|
||||
}
|
||||
DBCellRead(def, TRUE, TRUE, NULL);
|
||||
|
||||
scx->scx_use = use;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ Tile *TiNMMergeRight();
|
|||
Tile *TiNMMergeLeft();
|
||||
|
||||
#ifdef PAINTDEBUG
|
||||
void dbPaintShowTile(Tile *tile, PaintUndoInfo *undo, char *str);
|
||||
|
||||
int dbPaintDebug = 0;
|
||||
#endif /* PAINTDEBUG */
|
||||
|
||||
|
|
@ -240,7 +242,7 @@ int
|
|||
DBPaintPlane0(plane, area, resultTbl, undo, method)
|
||||
Plane *plane; /* Plane whose paint is to be modified */
|
||||
Rect *area; /* Area to be changed */
|
||||
PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
const PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
* present in the plane, giving the type to
|
||||
* which the existing tile must change as a
|
||||
* result of this paint operation.
|
||||
|
|
@ -271,9 +273,10 @@ DBPaintPlane0(plane, area, resultTbl, undo, method)
|
|||
* search.
|
||||
*/
|
||||
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
start.p_x = area->r_xbot;
|
||||
start.p_y = area->r_ytop - 1;
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -310,6 +313,11 @@ enumerate:
|
|||
* Set up the directions in which we will have to
|
||||
* merge initially. Clipping can cause some of these
|
||||
* to be turned off.
|
||||
*
|
||||
* The search runs from left to right, top to bottom.
|
||||
* Therefore always merge left and up, but never right
|
||||
* and down, unless at or beyond the each of the search
|
||||
* area.
|
||||
*/
|
||||
mergeFlags = MRG_TOP | MRG_LEFT;
|
||||
if (RIGHT(tile) >= area->r_xtop) mergeFlags |= MRG_RIGHT;
|
||||
|
|
@ -339,6 +347,7 @@ enumerate:
|
|||
* Merging is only necessary if we clip to the left or to
|
||||
* the right, and then only to the top or the bottom.
|
||||
* We do the merge in-line for efficiency.
|
||||
* Clipping of split tiles is more complicated.
|
||||
*/
|
||||
|
||||
/* Clip up */
|
||||
|
|
@ -353,13 +362,17 @@ enumerate:
|
|||
newType = (method == (unsigned char)PAINT_XOR) ?
|
||||
*resultTbl : resultTbl[oldType];
|
||||
|
||||
tile = TiNMMergeLeft(tile, plane);
|
||||
TiNMMergeRight(TR(newtile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
tile = TiNMMergeLeft(tile, plane);
|
||||
if ((mergeFlags & MRG_RIGHT) || SplitDirection(newtile) == 1)
|
||||
TiNMMergeRight(TR(newtile), plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
TiNMMergeLeft(newtile, plane);
|
||||
TiNMMergeRight(TR(tile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
TiNMMergeLeft(newtile, plane);
|
||||
if ((mergeFlags & MRG_RIGHT) || SplitDirection(tile) == 1)
|
||||
TiNMMergeRight(TR(tile), plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -388,13 +401,17 @@ enumerate:
|
|||
newType = (method == (unsigned char)PAINT_XOR) ?
|
||||
*resultTbl : resultTbl[oldType];
|
||||
|
||||
tile = TiNMMergeLeft(tile, plane);
|
||||
TiNMMergeRight(TR(newtile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
tile = TiNMMergeLeft(tile, plane);
|
||||
if ((mergeFlags & MRG_RIGHT) || SplitDirection(newtile) == 0)
|
||||
TiNMMergeRight(TR(newtile), plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
TiNMMergeLeft(newtile, plane);
|
||||
TiNMMergeRight(TR(tile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
TiNMMergeLeft(newtile, plane);
|
||||
if ((mergeFlags & MRG_RIGHT) || SplitDirection(tile) == 0)
|
||||
TiNMMergeRight(TR(tile), plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -423,13 +440,17 @@ enumerate:
|
|||
newType = (method == (unsigned char)PAINT_XOR) ?
|
||||
*resultTbl : resultTbl[oldType];
|
||||
|
||||
tile = TiNMMergeLeft(tile, plane);
|
||||
TiNMMergeRight(LB(newtile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
tile = TiNMMergeLeft(tile, plane);
|
||||
if (mergeFlags & MRG_RIGHT)
|
||||
TiNMMergeRight(LB(newtile), plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
TiNMMergeRight(newtile, plane);
|
||||
TiNMMergeLeft(LB(tile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
TiNMMergeRight(newtile, plane);
|
||||
if (mergeFlags & MRG_RIGHT)
|
||||
TiNMMergeLeft(LB(tile), plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -439,11 +460,11 @@ enumerate:
|
|||
|
||||
/* Merge the outside tile to its top */
|
||||
tp = RT(newtile);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane);
|
||||
|
||||
/* Merge the outside tile to its bottom */
|
||||
tp = LB(newtile);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
mergeFlags &= ~MRG_RIGHT;
|
||||
}
|
||||
|
|
@ -466,13 +487,13 @@ enumerate:
|
|||
newType = (method == (unsigned char)PAINT_XOR) ?
|
||||
*resultTbl : resultTbl[oldType];
|
||||
|
||||
// tile = TiNMMergeRight(tile, plane);
|
||||
TiNMMergeLeft(LB(newtile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
TiNMMergeLeft(LB(newtile), plane);
|
||||
}
|
||||
else
|
||||
{
|
||||
TiNMMergeLeft(newtile, plane);
|
||||
// TiNMMergeRight(LB(tile), plane);
|
||||
if (mergeFlags & MRG_LEFT)
|
||||
TiNMMergeLeft(newtile, plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -483,11 +504,11 @@ enumerate:
|
|||
|
||||
/* Merge the outside tile to its top */
|
||||
tp = RT(newtile);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane);
|
||||
|
||||
/* Merge the outside tile to its bottom */
|
||||
tp = LB(newtile);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
|
||||
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
mergeFlags &= ~MRG_LEFT;
|
||||
}
|
||||
|
|
@ -579,7 +600,7 @@ clipdone:
|
|||
if (mergeFlags & MRG_TOP)
|
||||
{
|
||||
tp = RT(tile);
|
||||
if (CANMERGE_Y(tile, tp)) TiJoinY(tile, tp, plane);
|
||||
if (CANMERGE_Y(tile, tp)) TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "merged up (CHEAP)");
|
||||
|
|
@ -588,7 +609,7 @@ clipdone:
|
|||
if (mergeFlags & MRG_BOTTOM)
|
||||
{
|
||||
tp = LB(tile);
|
||||
if (CANMERGE_Y(tile, tp)) TiJoinY(tile, tp, plane);
|
||||
if (CANMERGE_Y(tile, tp)) TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "merged down (CHEAP)");
|
||||
|
|
@ -648,7 +669,7 @@ done:
|
|||
start.p_x = area->r_xbot;
|
||||
start.p_y = area->r_ytop - 1;
|
||||
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &start);
|
||||
|
||||
while (TOP(tile) > area->r_ybot)
|
||||
|
|
@ -696,7 +717,8 @@ enum2:
|
|||
}
|
||||
|
||||
done2:
|
||||
plane->pl_hint = tile;
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -719,7 +741,7 @@ DBSplitTile(plane, point, splitx)
|
|||
int splitx;
|
||||
{
|
||||
Tile *tile, *newtile, *tp;
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, point);
|
||||
|
||||
if (IsSplit(tile)) /* This should always be true */
|
||||
|
|
@ -766,7 +788,7 @@ void
|
|||
DBFracturePlane(plane, area, resultTbl, undo)
|
||||
Plane *plane; /* Plane whose paint is to be modified */
|
||||
Rect *area; /* Area to be changed */
|
||||
PaintResultType *resultTbl; /* Paint table, to pinpoint those tiles
|
||||
const PaintResultType *resultTbl; /* Paint table, to pinpoint those tiles
|
||||
* that interact with the paint type.
|
||||
*/
|
||||
PaintUndoInfo *undo; /* Record containing everything needed to
|
||||
|
|
@ -793,7 +815,7 @@ DBFracturePlane(plane, area, resultTbl, undo)
|
|||
|
||||
start.p_x = area->r_xbot;
|
||||
start.p_y = area->r_ytop - 1;
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -990,7 +1012,7 @@ paintdone:
|
|||
}
|
||||
|
||||
done:
|
||||
plane->pl_hint = tile;
|
||||
PlaneSetHint(plane, tile);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1032,11 +1054,12 @@ DBMergeNMTiles0(plane, area, undo, mergeOnce)
|
|||
int clipTop;
|
||||
Tile *tile, *tp, *tp2, *newtile, *tpnew;
|
||||
int aspecta, aspectb;
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
TileType ttype, ltype, rtype;
|
||||
|
||||
start.p_x = area->r_xbot;
|
||||
start.p_y = area->r_ytop - 1;
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -1121,23 +1144,23 @@ nmenum:
|
|||
newtile = TiSplitY(tp2, TOP(tile));
|
||||
TiSetBody(newtile, ltype);
|
||||
if (CANMERGE_X(newtile, BL(newtile)))
|
||||
TiJoinX(newtile, BL(newtile), plane);
|
||||
TiJoinX1(&delayed, newtile, BL(newtile), plane);
|
||||
if (CANMERGE_X(newtile, TR(newtile)))
|
||||
TiJoinX(newtile, TR(newtile), plane);
|
||||
TiJoinX1(&delayed, newtile, TR(newtile), plane);
|
||||
if (CANMERGE_Y(newtile, RT(newtile)))
|
||||
TiJoinY(newtile, RT(newtile), plane);
|
||||
TiJoinY1(&delayed, newtile, RT(newtile), plane);
|
||||
}
|
||||
if (LEFT(tp2) < LEFT(tp))
|
||||
{
|
||||
newtile = TiSplitX(tp2, LEFT(tp));
|
||||
TiSetBody(newtile, ltype);
|
||||
if (CANMERGE_Y(tp2, LB(tp2)))
|
||||
TiJoinY(tp2, LB(tp2), plane);
|
||||
TiJoinY1(&delayed, tp2, LB(tp2), plane);
|
||||
if (CANMERGE_Y(tp2, RT(tp2)))
|
||||
TiJoinY(tp2, RT(tp2), plane);
|
||||
TiJoinY1(&delayed, tp2, RT(tp2), plane);
|
||||
tp2 = newtile;
|
||||
}
|
||||
TiJoinY(tp2, tp, plane);
|
||||
TiJoinY1(&delayed, tp2, tp, plane);
|
||||
tp = tp2;
|
||||
tp2 = RT(tp2);
|
||||
}
|
||||
|
|
@ -1151,11 +1174,11 @@ nmenum:
|
|||
newtile = TiSplitY(tp2, BOTTOM(tp));
|
||||
TiSetBody(newtile, rtype);
|
||||
if (CANMERGE_X(tp2, BL(tp2)))
|
||||
TiJoinX(tp2, BL(tp2), plane);
|
||||
TiJoinX1(&delayed, tp2, BL(tp2), plane);
|
||||
if (CANMERGE_X(tp2, TR(tp2)))
|
||||
TiJoinX(tp2, TR(tp2), plane);
|
||||
TiJoinX1(&delayed, tp2, TR(tp2), plane);
|
||||
if (CANMERGE_Y(tp2, LB(tp2)))
|
||||
TiJoinY(tp2, LB(tp2), plane);
|
||||
TiJoinY1(&delayed, tp2, LB(tp2), plane);
|
||||
tp2 = newtile;
|
||||
}
|
||||
if (RIGHT(tp2) > RIGHT(tile))
|
||||
|
|
@ -1163,16 +1186,16 @@ nmenum:
|
|||
newtile = TiSplitX(tp2, RIGHT(tile));
|
||||
TiSetBody(newtile, rtype);
|
||||
if (CANMERGE_Y(newtile, LB(newtile)))
|
||||
TiJoinY(newtile, LB(newtile), plane);
|
||||
TiJoinY1(&delayed, newtile, LB(newtile), plane);
|
||||
if (CANMERGE_Y(newtile, RT(newtile)))
|
||||
TiJoinY(newtile, RT(newtile), plane);
|
||||
TiJoinY1(&delayed, newtile, RT(newtile), plane);
|
||||
}
|
||||
TiJoinY(tp2, tile, plane);
|
||||
TiJoinY1(&delayed, tp2, tile, plane);
|
||||
tile = tp2;
|
||||
tp2 = LB(tp2);
|
||||
}
|
||||
/* Merge tp and tile */
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
TiSetBody(tile, ttype);
|
||||
}
|
||||
else /* split direction 1 */
|
||||
|
|
@ -1213,11 +1236,11 @@ nmenum:
|
|||
newtile = TiSplitY(tp2, BOTTOM(tp));
|
||||
TiSetBody(newtile, ltype);
|
||||
if (CANMERGE_X(tp2, BL(tp2)))
|
||||
TiJoinX(tp2, BL(tp2), plane);
|
||||
TiJoinX1(&delayed, tp2, BL(tp2), plane);
|
||||
if (CANMERGE_X(tp2, TR(tp2)))
|
||||
TiJoinX(tp2, TR(tp2), plane);
|
||||
TiJoinX1(&delayed, tp2, TR(tp2), plane);
|
||||
if (CANMERGE_Y(tp2, LB(tp2)))
|
||||
TiJoinY(tp2, LB(tp2), plane);
|
||||
TiJoinY1(&delayed, tp2, LB(tp2), plane);
|
||||
tp2 = newtile;
|
||||
}
|
||||
if (LEFT(tp2) < LEFT(tile))
|
||||
|
|
@ -1225,12 +1248,12 @@ nmenum:
|
|||
newtile = TiSplitX(tp2, LEFT(tile));
|
||||
TiSetBody(newtile, ltype);
|
||||
if (CANMERGE_Y(tp2, LB(tp2)))
|
||||
TiJoinY(tp2, LB(tp2), plane);
|
||||
TiJoinY1(&delayed, tp2, LB(tp2), plane);
|
||||
if (CANMERGE_Y(tp2, RT(tp2)))
|
||||
TiJoinY(tp2, RT(tp2), plane);
|
||||
TiJoinY1(&delayed, tp2, RT(tp2), plane);
|
||||
tp2 = newtile;
|
||||
}
|
||||
TiJoinY(tp2, tile, plane);
|
||||
TiJoinY1(&delayed, tp2, tile, plane);
|
||||
tile = tp2;
|
||||
tp2 = LB(tp2);
|
||||
}
|
||||
|
|
@ -1245,27 +1268,27 @@ nmenum:
|
|||
newtile = TiSplitY(tp2, TOP(tile));
|
||||
TiSetBody(newtile, rtype);
|
||||
if (CANMERGE_X(newtile, BL(newtile)))
|
||||
TiJoinX(newtile, BL(newtile), plane);
|
||||
TiJoinX1(&delayed, newtile, BL(newtile), plane);
|
||||
if (CANMERGE_X(newtile, TR(newtile)))
|
||||
TiJoinX(newtile, TR(newtile), plane);
|
||||
TiJoinX1(&delayed, newtile, TR(newtile), plane);
|
||||
if (CANMERGE_Y(newtile, RT(newtile)))
|
||||
TiJoinY(newtile, RT(newtile), plane);
|
||||
TiJoinY1(&delayed, newtile, RT(newtile), plane);
|
||||
}
|
||||
if (RIGHT(tp2) > RIGHT(tp))
|
||||
{
|
||||
newtile = TiSplitX(tp2, RIGHT(tp));
|
||||
TiSetBody(newtile, rtype);
|
||||
if (CANMERGE_Y(newtile, LB(newtile)))
|
||||
TiJoinY(newtile, LB(newtile), plane);
|
||||
TiJoinY1(&delayed, newtile, LB(newtile), plane);
|
||||
if (CANMERGE_Y(newtile, RT(newtile)))
|
||||
TiJoinY(newtile, RT(newtile), plane);
|
||||
TiJoinY1(&delayed, newtile, RT(newtile), plane);
|
||||
}
|
||||
TiJoinY(tp2, tp, plane);
|
||||
TiJoinY1(&delayed, tp2, tp, plane);
|
||||
tp = tp2;
|
||||
tp2 = RT(tp2);
|
||||
}
|
||||
/* Merge tp and tile */
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
TiSetBody(tile, ttype);
|
||||
}
|
||||
/* Now repeat until no more merging is possible */
|
||||
|
|
@ -1306,7 +1329,8 @@ nmenum:
|
|||
}
|
||||
|
||||
nmdone:
|
||||
plane->pl_hint = tile;
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1315,7 +1339,7 @@ nmdone:
|
|||
* DBDiagonalProc(type) --
|
||||
*
|
||||
* Return the result type of a diagonal tile painted on oldtype;
|
||||
* Argument "cdata", gives direction and side of diagonal, and the
|
||||
* Argument "dinfo", gives direction and side of diagonal, and the
|
||||
* paint result table for the given diagonal side.
|
||||
*
|
||||
* If the result cannot be described with a single tile, then
|
||||
|
|
@ -1333,15 +1357,14 @@ nmdone:
|
|||
*/
|
||||
|
||||
int
|
||||
DBDiagonalProc(oldtype, cdata)
|
||||
DBDiagonalProc(oldtype, dinfo)
|
||||
TileType oldtype;
|
||||
ClientData cdata;
|
||||
DiagInfo *dinfo;
|
||||
{
|
||||
TileType old_n, old_s, old_e, old_w;
|
||||
TileType new_n, new_s, new_e, new_w;
|
||||
TileType newtype;
|
||||
DiagInfo *dinfo = (DiagInfo *)cdata;
|
||||
PaintResultType *resultTbl = dinfo->resultTbl;
|
||||
const PaintResultType *resultTbl = dinfo->resultTbl;
|
||||
|
||||
/* Disassemble old and new types into four quadrants, find the */
|
||||
/* paint result for each quadrant, then reassemble the result. */
|
||||
|
|
@ -1412,10 +1435,6 @@ DBDiagonalProc(oldtype, cdata)
|
|||
else
|
||||
return -1;
|
||||
|
||||
/* For purposes of "undo" recording, record which side we just painted */
|
||||
if (dinfo->side)
|
||||
newtype |= TT_SIDE;
|
||||
|
||||
return newtype;
|
||||
}
|
||||
|
||||
|
|
@ -1458,7 +1477,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
|
|||
Plane *plane; /* Plane whose paint is to be modified */
|
||||
TileType exacttype; /* diagonal info for tile to be changed */
|
||||
Rect *area; /* Area to be changed */
|
||||
PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
const PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
* present in the plane, giving the type to
|
||||
* which the existing tile must change as a
|
||||
* result of this paint operation.
|
||||
|
|
@ -1500,7 +1519,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
|
|||
/* linked list out of them. */
|
||||
|
||||
lhead = NULL;
|
||||
DBSrPaintArea(plane->pl_hint, plane, area, &DBAllTypeBits,
|
||||
DBSrPaintArea(PlaneGetHint(plane), plane, area, &DBAllTypeBits,
|
||||
dbNMEnumFunc, (ClientData) &lhead);
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
|
|
@ -1520,7 +1539,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
|
|||
GeoClip(&lhead->r_r, area);
|
||||
start.p_x = area->r_xbot;
|
||||
start.p_y = area->r_ytop - 1;
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &start);
|
||||
|
||||
/* Ignore tiles that don't interact. This has */
|
||||
|
|
@ -1609,7 +1628,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
|
|||
{
|
||||
result = DBPaintPlane(plane, &(lr->r_r), DBSpecialPaintTbl,
|
||||
(PaintUndoInfo *)NULL);
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &(lr->r_r.r_ll));
|
||||
if (undo && UndoIsEnabled())
|
||||
{
|
||||
|
|
@ -1769,12 +1788,14 @@ nextrect:
|
|||
lr = lr->r_next;
|
||||
}
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
lr = lhead;
|
||||
while (lr != NULL)
|
||||
{
|
||||
freeMagic((char *) lr);
|
||||
freeMagic1(&mm1, (char *) lr);
|
||||
lr = lr->r_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
else
|
||||
result = DBPaintPlane0(plane, area, resultTbl, undo, (method == PAINT_MARK) ?
|
||||
|
|
@ -1795,14 +1816,15 @@ nextrect:
|
|||
*/
|
||||
|
||||
int
|
||||
dbNMEnumFunc(tile, arg)
|
||||
dbNMEnumFunc(tile, dinfo, arg)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
LinkedRect **arg;
|
||||
{
|
||||
LinkedRect *lr;
|
||||
|
||||
/* Ignore the second call to any diagonal---only count once! */
|
||||
if (IsSplit(tile) && SplitSide(tile)) return 0;
|
||||
if (IsSplit(tile) && (dinfo & TT_SIDE)) return 0;
|
||||
|
||||
lr = (LinkedRect *) mallocMagic(sizeof(LinkedRect));
|
||||
TiToRect(tile, &lr->r_r);
|
||||
|
|
@ -1886,6 +1908,7 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
|
|||
PaintUndoInfo *undo; /* See DBPaintPlane() above */
|
||||
bool mark; /* Mark tiles that were processed */
|
||||
{
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
Tile *tp, *tpLast;
|
||||
int ysplit;
|
||||
|
||||
|
|
@ -1992,7 +2015,7 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
|
|||
if (mark) dbMarkClient(tile, area);
|
||||
}
|
||||
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged left");
|
||||
|
|
@ -2008,7 +2031,7 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
|
|||
if (mark) dbMarkClient(tile, area);
|
||||
}
|
||||
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged right");
|
||||
|
|
@ -2017,7 +2040,7 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
|
|||
if (mergeFlags&MRG_TOP)
|
||||
{
|
||||
tp = RT(tile);
|
||||
if (CANMERGE_Y(tp, tile)) TiJoinY(tile, tp, plane);
|
||||
if (CANMERGE_Y(tp, tile)) TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged up");
|
||||
|
|
@ -2026,13 +2049,14 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
|
|||
if (mergeFlags&MRG_BOTTOM)
|
||||
{
|
||||
tp = LB(tile);
|
||||
if (CANMERGE_Y(tp, tile)) TiJoinY(tile, tp, plane);
|
||||
if (CANMERGE_Y(tp, tile)) TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged down");
|
||||
#endif /* PAINTDEBUG */
|
||||
}
|
||||
|
||||
TiFreeIf(delayed);
|
||||
return (tile);
|
||||
}
|
||||
|
||||
|
|
@ -2065,7 +2089,7 @@ void
|
|||
DBPaintType(plane, area, resultTbl, client, undo, tileMask)
|
||||
Plane *plane; /* Plane whose paint is to be modified */
|
||||
Rect *area; /* Area to be changed */
|
||||
PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
const PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
* present in the plane, giving the type to
|
||||
* which the existing tile must change as a
|
||||
* result of this paint operation.
|
||||
|
|
@ -2095,9 +2119,10 @@ DBPaintType(plane, area, resultTbl, client, undo, tileMask)
|
|||
* search.
|
||||
*/
|
||||
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
start.p_x = area->r_xbot;
|
||||
start.p_y = area->r_ytop - 1;
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -2187,14 +2212,14 @@ enumerate:
|
|||
if (CANMERGE_Y(newtile, tp) &&
|
||||
( (TiGetClient(tp) == TiGetClient(newtile)) ||
|
||||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
|
||||
TiJoinY(newtile, tp, plane);
|
||||
TiJoinY1(&delayed, newtile, tp, plane);
|
||||
|
||||
/* Merge the outside tile to its bottom */
|
||||
tp = LB(newtile);
|
||||
if (CANMERGE_Y(newtile, tp) &&
|
||||
( (TiGetClient(tp) == TiGetClient(newtile)) ||
|
||||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
|
||||
TiJoinY(newtile, tp, plane);
|
||||
TiJoinY1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
|
||||
/* Clip left */
|
||||
|
|
@ -2211,14 +2236,14 @@ enumerate:
|
|||
if (CANMERGE_Y(newtile, tp) &&
|
||||
( (TiGetClient(tp) == TiGetClient(newtile)) ||
|
||||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
|
||||
TiJoinY(newtile, tp, plane);
|
||||
TiJoinY1(&delayed, newtile, tp, plane);
|
||||
|
||||
/* Merge the outside tile to its bottom */
|
||||
tp = LB(newtile);
|
||||
if (CANMERGE_Y(newtile, tp) &&
|
||||
( (TiGetClient(tp) == TiGetClient(newtile)) ||
|
||||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
|
||||
TiJoinY(newtile, tp, plane);
|
||||
TiJoinY1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
|
||||
#ifdef PAINTDEBUG
|
||||
|
|
@ -2277,7 +2302,7 @@ enumerate:
|
|||
{
|
||||
tp = RT(tile);
|
||||
if (CANMERGE_Y(tile, tp) && (tp->ti_client == client))
|
||||
TiJoinY(tile, tp, plane);
|
||||
TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "merged up (CHEAP)");
|
||||
|
|
@ -2287,7 +2312,7 @@ enumerate:
|
|||
{
|
||||
tp = LB(tile);
|
||||
if (CANMERGE_Y(tile, tp) && (tp->ti_client == client))
|
||||
TiJoinY(tile, tp, plane);
|
||||
TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "merged down (CHEAP)");
|
||||
|
|
@ -2334,7 +2359,8 @@ paintdone:
|
|||
}
|
||||
|
||||
done:
|
||||
plane->pl_hint = tile;
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2381,6 +2407,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
|
|||
PaintUndoInfo *undo; /* See DBPaintPlane() above */
|
||||
ClientData client;
|
||||
{
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
Tile *tp, *tpLast;
|
||||
int ysplit;
|
||||
|
||||
|
|
@ -2482,7 +2509,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
|
|||
TiSetClient(tpLast, client);
|
||||
}
|
||||
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged left");
|
||||
|
|
@ -2498,7 +2525,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
|
|||
TiSetClient(tpLast, client);
|
||||
}
|
||||
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged right");
|
||||
|
|
@ -2507,7 +2534,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
|
|||
if (mergeFlags&MRG_TOP)
|
||||
{
|
||||
tp = RT(tile);
|
||||
if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY(tile, tp, plane);
|
||||
if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged up");
|
||||
|
|
@ -2516,13 +2543,14 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
|
|||
if (mergeFlags&MRG_BOTTOM)
|
||||
{
|
||||
tp = LB(tile);
|
||||
if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY(tile, tp, plane);
|
||||
if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged down");
|
||||
#endif /* PAINTDEBUG */
|
||||
}
|
||||
|
||||
TiFreeIf(delayed);
|
||||
return (tile);
|
||||
}
|
||||
|
||||
|
|
@ -2556,7 +2584,7 @@ int
|
|||
DBPaintPlaneVert(plane, area, resultTbl, undo)
|
||||
Plane *plane; /* Plane whose paint is to be modified */
|
||||
Rect *area; /* Area to be changed */
|
||||
PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
const PaintResultType *resultTbl; /* Table, indexed by the type of tile already
|
||||
* present in the plane, giving the type to
|
||||
* which the existing tile must change as a
|
||||
* result of this paint operation.
|
||||
|
|
@ -2582,9 +2610,10 @@ DBPaintPlaneVert(plane, area, resultTbl, undo)
|
|||
* search.
|
||||
*/
|
||||
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
start.p_x = area->r_xbot;
|
||||
start.p_y = area->r_ytop - 1;
|
||||
tile = plane->pl_hint;
|
||||
tile = PlaneGetHint(plane);
|
||||
GOTOPOINT(tile, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -2663,11 +2692,11 @@ enumerate:
|
|||
|
||||
/* Merge the outside tile to its left */
|
||||
tp = BL(newtile);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane);
|
||||
|
||||
/* Merge the outside tile to its right */
|
||||
tp = TR(newtile);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
|
||||
/* Clip down */
|
||||
|
|
@ -2679,11 +2708,11 @@ enumerate:
|
|||
|
||||
/* Merge the outside tile to its left */
|
||||
tp = BL(newtile);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane);
|
||||
|
||||
/* Merge the outside tile to its right */
|
||||
tp = TR(newtile);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
|
||||
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
|
||||
#ifdef PAINTDEBUG
|
||||
|
|
@ -2741,7 +2770,7 @@ enumerate:
|
|||
if (mergeFlags & MRG_LEFT)
|
||||
{
|
||||
tp = BL(tile);
|
||||
if (CANMERGE_X(tile, tp)) TiJoinX(tile, tp, plane);
|
||||
if (CANMERGE_X(tile, tp)) TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "merged left (CHEAP)");
|
||||
|
|
@ -2750,7 +2779,7 @@ enumerate:
|
|||
if (mergeFlags & MRG_RIGHT)
|
||||
{
|
||||
tp = TR(tile);
|
||||
if (CANMERGE_X(tile, tp)) TiJoinX(tile, tp, plane);
|
||||
if (CANMERGE_X(tile, tp)) TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "merged right (CHEAP)");
|
||||
|
|
@ -2797,7 +2826,8 @@ paintdone:
|
|||
}
|
||||
|
||||
done:
|
||||
plane->pl_hint = tile;
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2850,6 +2880,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
|
|||
int mergeFlags; /* Specify which directions to merge */
|
||||
PaintUndoInfo *undo; /* See DBPaintPlane() above */
|
||||
{
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
Tile *tp, *tpLast;
|
||||
int xsplit;
|
||||
|
||||
|
|
@ -2944,7 +2975,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
|
|||
if (LEFT(tp) < LEFT(tile)) tp = TiSplitX(tp, LEFT(tile));
|
||||
if (RIGHT(tp) > RIGHT(tile))
|
||||
tpLast = TiSplitX(tp, RIGHT(tile)), TiSetBody(tpLast, newType);
|
||||
TiJoinY(tile, tp, plane);
|
||||
TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged up");
|
||||
|
|
@ -2957,7 +2988,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
|
|||
if (LEFT(tp) < LEFT(tile)) tp = TiSplitX(tp, LEFT(tile));
|
||||
if (RIGHT(tp) > RIGHT(tile))
|
||||
tpLast = TiSplitX(tp, RIGHT(tile)), TiSetBody(tpLast, newType);
|
||||
TiJoinY(tile, tp, plane);
|
||||
TiJoinY1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged down");
|
||||
|
|
@ -2967,7 +2998,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
|
|||
if (mergeFlags&MRG_LEFT)
|
||||
{
|
||||
tp = BL(tile);
|
||||
if (CANMERGE_X(tp, tile)) TiJoinX(tile, tp, plane);
|
||||
if (CANMERGE_X(tp, tile)) TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged left");
|
||||
|
|
@ -2976,13 +3007,14 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
|
|||
if (mergeFlags&MRG_RIGHT)
|
||||
{
|
||||
tp = TR(tile);
|
||||
if (CANMERGE_X(tp, tile)) TiJoinX(tile, tp, plane);
|
||||
if (CANMERGE_X(tp, tile)) TiJoinX1(&delayed, tile, tp, plane);
|
||||
#ifdef PAINTDEBUG
|
||||
if (dbPaintDebug)
|
||||
dbPaintShowTile(tile, undo, "(DBMERGE) merged right");
|
||||
#endif /* PAINTDEBUG */
|
||||
}
|
||||
|
||||
TiFreeIf(delayed);
|
||||
return (tile);
|
||||
}
|
||||
|
||||
|
|
@ -3005,7 +3037,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "styles.h"
|
||||
#include "utils/styles.h"
|
||||
|
||||
void
|
||||
dbPaintShowTile(tile, undo, str)
|
||||
|
|
@ -3028,6 +3060,16 @@ dbPaintShowTile(tile, undo, str)
|
|||
TxPrintf("%s --more--", str); fflush(stdout);
|
||||
(void) TxGetLine(answer, sizeof answer);
|
||||
DBWFeedbackClear(NULL);
|
||||
|
||||
/* To debug tile operations that happen away from the active layout
|
||||
* window, it may be advantageous to replace the display code above
|
||||
* with the print statement below.
|
||||
*/
|
||||
/*
|
||||
TxPrintf("Debug %s: Tile (%d %d) to (%d %d) type %d\n",
|
||||
str, LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile),
|
||||
TiGetBody(tile));
|
||||
*/
|
||||
}
|
||||
#endif /* PAINTDEBUG */
|
||||
|
||||
|
|
@ -3317,6 +3359,7 @@ TiNMMergeRight(tile, plane)
|
|||
Tile *tile;
|
||||
Plane *plane;
|
||||
{
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
TileType ttype = TiGetTypeExact(tile);
|
||||
Tile *tp, *tp2, *newtile;
|
||||
|
||||
|
|
@ -3348,7 +3391,7 @@ TiNMMergeRight(tile, plane)
|
|||
else
|
||||
newtile = tile;
|
||||
// Join tp to newtile
|
||||
TiJoinX(newtile, tp, plane);
|
||||
TiJoinX1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
tp = tp2;
|
||||
}
|
||||
|
|
@ -3365,11 +3408,13 @@ TiNMMergeRight(tile, plane)
|
|||
newtile = TiSplitY(tp, BOTTOM(tile));
|
||||
TiSetBody(newtile, ttype);
|
||||
// join newtile to tile
|
||||
TiJoinX(tile, newtile, plane);
|
||||
TiJoinX1(&delayed, tile, newtile, plane);
|
||||
// merge up if possible
|
||||
if (CANMERGE_Y(tile, RT(tile))) TiJoinY(tile, RT(tile), plane);
|
||||
if (CANMERGE_Y(tile, RT(tile))) TiJoinY1(&delayed, tile, RT(tile), plane);
|
||||
}
|
||||
}
|
||||
|
||||
TiFreeIf(delayed);
|
||||
return tile;
|
||||
}
|
||||
|
||||
|
|
@ -3397,6 +3442,7 @@ TiNMMergeLeft(tile, plane)
|
|||
Tile *tile;
|
||||
Plane *plane;
|
||||
{
|
||||
Tile *delayed = NULL; /* delayed free to extend lifetime */
|
||||
TileType ttype = TiGetTypeExact(tile);
|
||||
Tile *tp, *tp2, *newtile;
|
||||
|
||||
|
|
@ -3429,7 +3475,7 @@ TiNMMergeLeft(tile, plane)
|
|||
else
|
||||
newtile = tile;
|
||||
// Join tp to tile
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
tile = newtile;
|
||||
}
|
||||
tp = tp2;
|
||||
|
|
@ -3447,14 +3493,16 @@ TiNMMergeLeft(tile, plane)
|
|||
newtile = TiSplitY(tp, TOP(tile));
|
||||
TiSetBody(newtile, ttype);
|
||||
// join tp to tile
|
||||
TiJoinX(tile, tp, plane);
|
||||
TiJoinX1(&delayed, tile, tp, plane);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Merge up if possible
|
||||
if (CANMERGE_Y(tile, tp)) TiJoinY(tile, tp, plane);
|
||||
if (CANMERGE_Y(tile, tp)) TiJoinY1(&delayed, tile, tp, plane);
|
||||
}
|
||||
|
||||
TiFreeIf(delayed);
|
||||
return tile;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,8 +119,9 @@ DBPaint (cellDef, rect, type)
|
|||
*/
|
||||
|
||||
int
|
||||
dbResolveImages(tile, cellDef)
|
||||
dbResolveImages(tile, dinfo, cellDef)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
CellDef *cellDef;
|
||||
{
|
||||
Rect rect;
|
||||
|
|
@ -130,7 +131,7 @@ dbResolveImages(tile, cellDef)
|
|||
/* Recursive call back to DBPaint---this will ensure that */
|
||||
/* all of the planes of the image type are painted. */
|
||||
|
||||
DBPaint(cellDef, &rect, TiGetTypeExact(tile));
|
||||
DBPaint(cellDef, &rect, TiGetTypeExact(tile) | dinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -283,6 +284,7 @@ DBPaintValid(cellDef, rect, mask, dinfo)
|
|||
|
||||
for (t = TT_SELECTBASE; t < DBNumUserLayers; t++)
|
||||
if (TTMaskHasType(&mmask, t))
|
||||
{
|
||||
if (DBIsContact(t))
|
||||
{
|
||||
tMask = DBResidueMask(t);
|
||||
|
|
@ -310,6 +312,7 @@ DBPaintValid(cellDef, rect, mask, dinfo)
|
|||
(t << 14) : t) : t);
|
||||
DBPaint(cellDef, rect, tloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -382,6 +385,7 @@ DBEraseValid(cellDef, rect, mask, dinfo)
|
|||
|
||||
for (t = TT_SELECTBASE; t < DBNumUserLayers; t++)
|
||||
if (TTMaskHasType(&mmask, t))
|
||||
{
|
||||
if (DBIsContact(t))
|
||||
{
|
||||
tMask = DBResidueMask(t);
|
||||
|
|
@ -409,4 +413,5 @@ DBEraseValid(cellDef, rect, mask, dinfo)
|
|||
(t << 14) : t) : t);
|
||||
DBErase(cellDef, rect, tloc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -895,6 +895,24 @@ DBIsContact(type)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBLayerPlanes --
|
||||
*
|
||||
* Like LayerPlaneMask(), except as a subroutine, not a macro. For export
|
||||
* to other routines.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
PlaneMask
|
||||
DBLayerPlanes(type)
|
||||
TileType type;
|
||||
{
|
||||
return LayerPlaneMask(type);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ DBTechSetVersion(sectionName, argc, argv)
|
|||
major = minor = rev = 0;
|
||||
rmajor = rminor = rrev = 0;
|
||||
|
||||
if (sscanf(vstring, "%d.%d.%d", &rmajor, &rminor, &rrev) == 0)
|
||||
if (sscanf(vstring, "%d.%d.%d", &rmajor, &rminor, &rrev) != 3)
|
||||
{
|
||||
TechError("Badly formed magic version string, should be major.minor.rev\n");
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -327,11 +327,11 @@ DBTechNoisyNamePlane(planename)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
DBTypeShortName(type)
|
||||
TileType type;
|
||||
const char *
|
||||
DBTypeShortName(
|
||||
TileType type)
|
||||
{
|
||||
NameList *tbl;
|
||||
const NameList *tbl;
|
||||
|
||||
for (tbl = dbTypeNameLists.sn_next;
|
||||
tbl != &dbTypeNameLists;
|
||||
|
|
@ -347,11 +347,11 @@ DBTypeShortName(type)
|
|||
return ("???");
|
||||
}
|
||||
|
||||
char *
|
||||
DBPlaneShortName(pNum)
|
||||
int pNum;
|
||||
const char *
|
||||
DBPlaneShortName(
|
||||
int pNum)
|
||||
{
|
||||
NameList *tbl;
|
||||
const NameList *tbl;
|
||||
|
||||
for (tbl = dbPlaneNameLists.sn_next;
|
||||
tbl != &dbPlaneNameLists;
|
||||
|
|
@ -478,7 +478,7 @@ DBTechPrintTypes(mask, dolist)
|
|||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_AppendResult(magicinterp, " ", (char *)NULL);
|
||||
#else
|
||||
TxPrintf(" ", keepname);
|
||||
TxPrintf(" ");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -530,7 +530,7 @@ DBTechPrintTypes(mask, dolist)
|
|||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_AppendResult(magicinterp, " ", (char *)NULL);
|
||||
#else
|
||||
TxPrintf(" ", keepname);
|
||||
TxPrintf(" ");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,14 +38,14 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
/* Types and their names */
|
||||
int DBNumTypes;
|
||||
char *DBTypeLongNameTbl[NT];
|
||||
const char *DBTypeLongNameTbl[NT];
|
||||
int DBTypePlaneTbl[NT]; /* Normally accessed as macro "DBPlane(x)" */
|
||||
NameList dbTypeNameLists = {NULL, NULL, NULL, (ClientData)0, FALSE};
|
||||
HashTable DBTypeAliasTable;
|
||||
|
||||
/* Planes and their names */
|
||||
int DBNumPlanes;
|
||||
char *DBPlaneLongNameTbl[PL_MAXTYPES];
|
||||
const char *DBPlaneLongNameTbl[PL_MAXTYPES];
|
||||
NameList dbPlaneNameLists = {NULL, NULL, NULL, (ClientData)0, FALSE};
|
||||
|
||||
|
||||
|
|
@ -70,28 +70,28 @@ TileTypeBitMask DBTechActiveLayerBits; /* Layers marked locked in the techfile *
|
|||
/* Table of default, builtin planes */
|
||||
DefaultPlane dbTechDefaultPlanes[] =
|
||||
{
|
||||
PL_ROUTER, "router",
|
||||
PL_DRC_ERROR, "designRuleError",
|
||||
PL_DRC_CHECK, "designRuleCheck",
|
||||
PL_M_HINT, "mhint",
|
||||
PL_F_HINT, "fhint",
|
||||
PL_R_HINT, "rhint",
|
||||
0, 0, 0
|
||||
{PL_ROUTER, "router"},
|
||||
{PL_DRC_ERROR, "designRuleError"},
|
||||
{PL_DRC_CHECK, "designRuleCheck"},
|
||||
{PL_M_HINT, "mhint"},
|
||||
{PL_F_HINT, "fhint"},
|
||||
{PL_R_HINT, "rhint"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
/* Table of default, builtin types */
|
||||
DefaultType dbTechDefaultTypes[] =
|
||||
{
|
||||
TT_SPACE, -1, "space", FALSE,
|
||||
TT_CHECKPAINT, PL_DRC_CHECK, "checkpaint,CP", FALSE,
|
||||
TT_CHECKSUBCELL, PL_DRC_CHECK, "checksubcell,CS", FALSE,
|
||||
TT_ERROR_P, PL_DRC_ERROR, "error_p,EP", FALSE,
|
||||
TT_ERROR_S, PL_DRC_ERROR, "error_s,ES", FALSE,
|
||||
TT_ERROR_PS, PL_DRC_ERROR, "error_ps,EPS", FALSE,
|
||||
TT_MAGNET, PL_M_HINT, "magnet,mag", TRUE,
|
||||
TT_FENCE, PL_F_HINT, "fence,f", TRUE,
|
||||
TT_ROTATE, PL_R_HINT, "rotate,r", TRUE,
|
||||
0, 0, NULL, 0
|
||||
{TT_SPACE, -1, "space", FALSE},
|
||||
{TT_CHECKPAINT, PL_DRC_CHECK, "checkpaint,CP", FALSE},
|
||||
{TT_CHECKSUBCELL, PL_DRC_CHECK, "checksubcell,CS", FALSE},
|
||||
{TT_ERROR_P, PL_DRC_ERROR, "error_p,EP", FALSE},
|
||||
{TT_ERROR_S, PL_DRC_ERROR, "error_s,ES", FALSE},
|
||||
{TT_ERROR_PS, PL_DRC_ERROR, "error_ps,EPS", FALSE},
|
||||
{TT_MAGNET, PL_M_HINT, "magnet,mag", TRUE},
|
||||
{TT_FENCE, PL_F_HINT, "fence,f", TRUE},
|
||||
{TT_ROTATE, PL_R_HINT, "rotate,r", TRUE},
|
||||
{0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/* Forward declarations */
|
||||
|
|
@ -116,22 +116,24 @@ NameList *dbTechNameAddOne();
|
|||
*/
|
||||
|
||||
void
|
||||
DBTechInitPlane()
|
||||
DBTechInitPlane(void)
|
||||
{
|
||||
DefaultPlane *dpp;
|
||||
char *cp;
|
||||
const char *cp;
|
||||
|
||||
/* Clear out any old information */
|
||||
if (dbPlaneNameLists.sn_next != NULL)
|
||||
{
|
||||
NameList *tbl;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (tbl = dbPlaneNameLists.sn_next; tbl != &dbPlaneNameLists;
|
||||
tbl = tbl->sn_next)
|
||||
{
|
||||
freeMagic(tbl->sn_name);
|
||||
freeMagic(tbl);
|
||||
freeMagic1(&mm1, tbl);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
/* Tables of short names */
|
||||
|
|
@ -140,7 +142,7 @@ DBTechInitPlane()
|
|||
|
||||
for (dpp = dbTechDefaultPlanes; dpp->dp_names; dpp++)
|
||||
{
|
||||
cp = dbTechNameAdd(dpp->dp_names, (ClientData) dpp->dp_plane,
|
||||
cp = dbTechNameAdd(dpp->dp_names, INT2CD(dpp->dp_plane),
|
||||
&dbPlaneNameLists, FALSE);
|
||||
if (cp == NULL)
|
||||
{
|
||||
|
|
@ -205,12 +207,14 @@ DBTechInitType()
|
|||
{
|
||||
NameList *tbl;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (tbl = dbTypeNameLists.sn_next; tbl != &dbTypeNameLists;
|
||||
tbl = tbl->sn_next)
|
||||
{
|
||||
freeMagic(tbl->sn_name);
|
||||
freeMagic(tbl);
|
||||
freeMagic1(&mm1, tbl);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
/* Tables of short names */
|
||||
|
|
@ -223,7 +227,7 @@ DBTechInitType()
|
|||
*/
|
||||
for (dtp = dbTechDefaultTypes; dtp->dt_names; dtp++)
|
||||
{
|
||||
cp = dbTechNameAdd(dtp->dt_names, (ClientData) dtp->dt_type,
|
||||
cp = dbTechNameAdd(dtp->dt_names, INT2CD(dtp->dt_type),
|
||||
&dbTypeNameLists, FALSE);
|
||||
if (cp == NULL)
|
||||
{
|
||||
|
|
@ -264,12 +268,12 @@ DBTechInitType()
|
|||
|
||||
/*ARGSUSED*/
|
||||
bool
|
||||
DBTechAddPlane(sectionName, argc, argv)
|
||||
char *sectionName;
|
||||
int argc;
|
||||
char *argv[];
|
||||
DBTechAddPlane(
|
||||
const char *sectionName,
|
||||
int argc,
|
||||
char *argv[])
|
||||
{
|
||||
char *cp;
|
||||
const char *cp;
|
||||
|
||||
if (DBNumPlanes >= PL_MAXTYPES)
|
||||
{
|
||||
|
|
@ -283,7 +287,7 @@ DBTechAddPlane(sectionName, argc, argv)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
cp = dbTechNameAdd(argv[0], (ClientData) DBNumPlanes, &dbPlaneNameLists, FALSE);
|
||||
cp = dbTechNameAdd(argv[0], INT2CD(DBNumPlanes), &dbPlaneNameLists, FALSE);
|
||||
if (cp == NULL)
|
||||
return FALSE;
|
||||
DBPlaneLongNameTbl[DBNumPlanes++] = cp;
|
||||
|
|
@ -315,7 +319,7 @@ DBTechAddNameToType(newname, ttype, canonical)
|
|||
{
|
||||
char *cp;
|
||||
|
||||
cp = dbTechNameAdd(newname, (ClientData) ttype, &dbTypeNameLists, TRUE);
|
||||
cp = dbTechNameAdd(newname, INT2CD(ttype), &dbTypeNameLists, TRUE);
|
||||
if (canonical)
|
||||
DBTypeLongNameTbl[ttype] = cp;
|
||||
}
|
||||
|
|
@ -455,7 +459,7 @@ DBTechAddType(sectionName, argc, argv)
|
|||
}
|
||||
else
|
||||
{
|
||||
cp = dbTechNameAdd(argv[1], (ClientData) DBNumTypes, &dbTypeNameLists, FALSE);
|
||||
cp = dbTechNameAdd(argv[1], INT2CD(DBNumTypes), &dbTypeNameLists, FALSE);
|
||||
if (cp == NULL)
|
||||
return FALSE;
|
||||
|
||||
|
|
@ -513,7 +517,7 @@ dbTechNewStackedType(type1, type2)
|
|||
}
|
||||
|
||||
sprintf(buf, "%s+%s", DBTypeShortName(type1), DBTypeShortName(type2));
|
||||
cp = dbTechNameAdd(buf, (ClientData) DBNumTypes, &dbTypeNameLists, FALSE);
|
||||
cp = dbTechNameAdd(buf, INT2CD(DBNumTypes), &dbTypeNameLists, FALSE);
|
||||
if (cp == NULL)
|
||||
{
|
||||
TechError("Couldn't generate new stacking type %s\n", buf);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,296 @@ struct dbCheck
|
|||
|
||||
int dbCheckMaxHFunc(), dbCheckMaxVFunc();
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* dbEvalCorner --
|
||||
*
|
||||
* Used by DBTestNMInteract() to determine whether two non-
|
||||
* Manhattan areas have crossing diagonals by evaluating the
|
||||
* corner points of the area of intersection between the two
|
||||
* tiles. This routine finds the distance from a point in
|
||||
* the second triangle to the diagonal of the first, in both
|
||||
* x and y. If the point is below or to the left, the
|
||||
* distance is negative; otherwise the distance is positive.
|
||||
*
|
||||
* Results:
|
||||
* 1 for a positive result, -1 for a negative result, and 0
|
||||
* for the same result (point touches the diagonal).
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbEvalCorner(Point *p, // Point to evaluate
|
||||
Rect *rect, // Triangular area bounding rectangle
|
||||
TileType di) // Diagonal information for split rect
|
||||
{
|
||||
dlong D;
|
||||
|
||||
/* D is the distance from a point to the diagonal of the rectangle.
|
||||
* The magnitude is not important. It only matters what the sign
|
||||
* is, so return 1 for positive, -1 for negative, or 0.
|
||||
*/
|
||||
|
||||
if (di & TT_DIRECTION)
|
||||
D = (p->p_y - rect->r_ybot) * (rect->r_xtop - rect->r_xbot) -
|
||||
(rect->r_xtop - p->p_x) * (rect->r_ytop - rect->r_ybot);
|
||||
else
|
||||
D = (p->p_y - rect->r_ybot) * (rect->r_xtop - rect->r_xbot) -
|
||||
(p->p_x - rect->r_xbot) * (rect->r_ytop - rect->r_ybot);
|
||||
|
||||
if (D > 0) return 1;
|
||||
if (D < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* DBTestNMInteract --
|
||||
*
|
||||
* Determine if a tile (t2) interacts with (touches or overlaps)
|
||||
* a triangular area (rect1, with diagonal split information in
|
||||
* di1). Tile t2 may or may not be a split tile. If t2 is
|
||||
* split, then diagonal split information is in di2.
|
||||
*
|
||||
* There are two distinct cases: DBSrPaintNMArea() looks for
|
||||
* tiles that overlap the area of rect1, but extTestNMInteract()
|
||||
* looks for tiles that both overlap or touch (indicating
|
||||
* electrical connectivity between the two). "overlap_only"
|
||||
* distinguishes between the two use cases. Set "overlap_only"
|
||||
* to TRUE for overlap searches, and FALSE for interaction
|
||||
* searches.
|
||||
*
|
||||
* Results:
|
||||
*
|
||||
* If overlap_only is TRUE:
|
||||
* Return TRUE if the indicated areas overlap, FALSE if not.
|
||||
* If overlap_only is FALSE:
|
||||
* Return TRUE if the indicated areas touch or overlap, FALSE if not.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool
|
||||
DBTestNMInteract(Rect *rect1,
|
||||
TileType tt1,
|
||||
Tile *t2,
|
||||
TileType di2,
|
||||
bool overlap_only)
|
||||
{
|
||||
Rect rect2, r;
|
||||
Point p;
|
||||
int rheight, rwidth, rmax;
|
||||
dlong f1, f2, f3, f4;
|
||||
TileType tt2;
|
||||
int pos, neg, touch, sign;
|
||||
|
||||
TiToRect(t2, &rect2);
|
||||
|
||||
/* Assuming that rect1 is a split area, then check if any part of t2
|
||||
* overlaps the split side of interest in rect1, regardless of whether
|
||||
* t2 is split or not. If there is no overlap, then return FALSE.
|
||||
*/
|
||||
|
||||
rheight = rect1->r_ytop - rect1->r_ybot;
|
||||
rwidth = rect1->r_xtop - rect1->r_xbot;
|
||||
rmax = MAX(rheight, rwidth);
|
||||
|
||||
f1 = (rect2.r_ybot > MINFINITY + 2) ?
|
||||
((dlong)(rect1->r_ytop - rect2.r_ybot) * rwidth) : DLONG_MAX;
|
||||
f2 = (rect2.r_ytop < INFINITY - 2) ?
|
||||
((dlong)(rect2.r_ytop - rect1->r_ybot) * rwidth) : DLONG_MAX;
|
||||
|
||||
if (tt1 & TT_SIDE)
|
||||
{
|
||||
/* Outside-of-triangle check---ignore sub-integer slivers */
|
||||
if (rect2.r_xtop < INFINITY - 2)
|
||||
{
|
||||
f3 = (dlong)(rect1->r_xtop - rect2.r_xtop) * rheight;
|
||||
f3 += rmax;
|
||||
}
|
||||
else
|
||||
f3 = DLONG_MIN;
|
||||
if ((tt1 & TT_DIRECTION) ? (f2 < f3) : (f1 < f3))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Outside-of-triangle check---ignore sub-integer slivers */
|
||||
if (rect2.r_xbot > MINFINITY + 2)
|
||||
{
|
||||
f4 = (dlong)(rect2.r_xbot - rect1->r_xbot) * rheight;
|
||||
f4 += rmax;
|
||||
}
|
||||
else
|
||||
f4 = DLONG_MIN;
|
||||
if ((tt1 & TT_DIRECTION) ? (f1 < f4) : (f2 < f4))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If t2 is not split, or its diagonal is the opposite of t1,
|
||||
* or its side is the same as that of t1, then they overlap.
|
||||
*/
|
||||
if (!IsSplit(t2)) return TRUE;
|
||||
|
||||
tt2 = TiGetTypeExact(t2) | di2;
|
||||
|
||||
if ((tt1 & TT_DIRECTION) != (tt2 & TT_DIRECTION)) return TRUE;
|
||||
// if ((tt1 & TT_SIDE) == (tt2 & TT_SIDE)) return TRUE;
|
||||
|
||||
/* Hard case: Same diagonal direction, opposite sides. To determine
|
||||
* overlap, count which of the three points of triangle t2 land on
|
||||
* one side or the other of the rect1 split diagonal. From those
|
||||
* counts, determine if the triangles are overlapping, touching,
|
||||
* or disjoint.
|
||||
*/
|
||||
|
||||
/* Evaluate the three corners of the rect2 triangle */
|
||||
|
||||
pos = neg = touch = 0;
|
||||
if (!(tt2 & TT_DIRECTION) || !(tt2 & TT_SIDE))
|
||||
{
|
||||
/* Evaluate the lower left corner */
|
||||
sign = dbEvalCorner(&rect2.r_ll, rect1, tt1);
|
||||
if (sign == 1)
|
||||
pos++;
|
||||
else if (sign == -1)
|
||||
neg++;
|
||||
else
|
||||
touch++;
|
||||
}
|
||||
|
||||
if (!(tt2 & TT_DIRECTION) || (tt2 & TT_SIDE))
|
||||
{
|
||||
/* Evaluate the upper right corner */
|
||||
sign = dbEvalCorner(&rect2.r_ur, rect1, tt1);
|
||||
if (sign == 1)
|
||||
pos++;
|
||||
else if (sign == -1)
|
||||
neg++;
|
||||
else
|
||||
touch++;
|
||||
}
|
||||
|
||||
if ((tt2 & TT_DIRECTION) || !(tt2 & TT_SIDE))
|
||||
{
|
||||
/* Evaluate the upper left corner */
|
||||
p.p_x = rect2.r_xbot;
|
||||
p.p_y = rect2.r_ytop;
|
||||
sign = dbEvalCorner(&p, rect1, tt1);
|
||||
if (sign == 1)
|
||||
pos++;
|
||||
else if (sign == -1)
|
||||
neg++;
|
||||
else
|
||||
touch++;
|
||||
}
|
||||
|
||||
if ((tt2 & TT_DIRECTION) || (tt2 & TT_SIDE))
|
||||
{
|
||||
/* Evaluate the lower right corner */
|
||||
p.p_x = rect2.r_xtop;
|
||||
p.p_y = rect2.r_ybot;
|
||||
sign = dbEvalCorner(&p, rect1, tt1);
|
||||
if (sign == 1)
|
||||
pos++;
|
||||
else if (sign == -1)
|
||||
neg++;
|
||||
else
|
||||
touch++;
|
||||
}
|
||||
|
||||
/* If side and direction match, then pos and neg need to be swapped */
|
||||
if (((tt1 & TT_SIDE) && (tt1 & TT_DIRECTION)) ||
|
||||
(!(tt1 & TT_SIDE) && !(tt1 & TT_DIRECTION)))
|
||||
{
|
||||
int temp = neg;
|
||||
neg = pos;
|
||||
pos = temp;
|
||||
}
|
||||
|
||||
/* Return TRUE or FALSE depending on the values of pos, neg, and
|
||||
* touch, and depending on whether overlap_only is set or not.
|
||||
*/
|
||||
if (pos == 3)
|
||||
return FALSE; /* Fully disjoint */
|
||||
else if (neg == 3)
|
||||
{
|
||||
if ((tt1 & TT_SIDE) != (tt2 & TT_SIDE))
|
||||
return TRUE; /* Fully enclosed */
|
||||
else
|
||||
{
|
||||
/* This is a trickier situation. Both triangles have
|
||||
* the same TT_SIDE bit, but the triangular area of t2
|
||||
* could still be outside of rect1. Need to check where
|
||||
* the inside corner of rect1 lands with respect to the
|
||||
* t2 diagonal.
|
||||
*/
|
||||
if (((tt1 & TT_SIDE) == 0) && ((tt1 & TT_DIRECTION) != 0))
|
||||
{
|
||||
sign = dbEvalCorner(&rect1->r_ll, &rect2, tt2);
|
||||
}
|
||||
else if (((tt1 & TT_SIDE) == 0) && ((tt1 & TT_DIRECTION) == 0))
|
||||
{
|
||||
p.p_x = rect1->r_ll.p_x;
|
||||
p.p_y = rect1->r_ur.p_y;
|
||||
sign = dbEvalCorner(&p, &rect2, tt2);
|
||||
}
|
||||
else if (((tt1 & TT_SIDE) != 0) && ((tt1 & TT_DIRECTION) == 0))
|
||||
{
|
||||
p.p_x = rect1->r_ur.p_x;
|
||||
p.p_y = rect1->r_ll.p_y;
|
||||
sign = dbEvalCorner(&p, &rect2, tt2);
|
||||
}
|
||||
else /* if (((tt1 & TT_SIDE) != 0) && ((tt1 & TT_DIRECTION) != 0)) */
|
||||
{
|
||||
sign = dbEvalCorner(&rect1->r_ur, &rect2, tt2);
|
||||
}
|
||||
|
||||
/* Again, if side and direction match, then sign is backwards
|
||||
*/
|
||||
if (((tt2 & TT_SIDE) && (tt2 & TT_DIRECTION)) ||
|
||||
(!(tt2 & TT_SIDE) && !(tt2 & TT_DIRECTION)))
|
||||
sign = -sign;
|
||||
|
||||
if (sign == 1)
|
||||
return FALSE; /* Fully disjoint */
|
||||
else if (sign == -1)
|
||||
return TRUE; /* Fully overlapping */
|
||||
else if (overlap_only)
|
||||
return FALSE; /* Touching but not overlapping */
|
||||
else
|
||||
return TRUE; /* Touching but not overlapping */
|
||||
}
|
||||
}
|
||||
else if (overlap_only)
|
||||
{
|
||||
if ((touch > 0) && (neg + touch == 3))
|
||||
return TRUE; /* Enclosed and touching */
|
||||
else if ((touch > 0) && (pos + touch == 3))
|
||||
return FALSE; /* Unenclosed but touching */
|
||||
else
|
||||
return TRUE; /* Partially overlapping */
|
||||
}
|
||||
else /* overlap_only == FALSE */
|
||||
{
|
||||
if ((touch > 0) && (neg + touch == 3))
|
||||
return TRUE; /* Enclosed and touching */
|
||||
else if ((touch > 0) && (pos + touch == 3))
|
||||
return TRUE; /* Unenclosed but touching */
|
||||
else
|
||||
return TRUE; /* Partially overlapping */
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -56,6 +346,7 @@ int dbCheckMaxHFunc(), dbCheckMaxVFunc();
|
|||
* int
|
||||
* func(tile, cdata)
|
||||
* Tile *tile;
|
||||
* TileType dinfo;
|
||||
* ClientData cdata;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -92,7 +383,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
|
|||
* provide a hint tile in case hintTile == NULL.
|
||||
* The hint tile in the plane is updated to be
|
||||
* the last tile visited in the area
|
||||
* enumeration.
|
||||
* enumeration, if plane is non-NULL.
|
||||
*/
|
||||
TileType ttype; /* Information about the non-manhattan area to
|
||||
* search; zero if area is manhattan.
|
||||
|
|
@ -111,7 +402,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
|
|||
TileType tpt;
|
||||
int rheight, rwidth, rmax;
|
||||
dlong f1, f2, f3, f4;
|
||||
bool ignore_sides;
|
||||
int ignore_sides;
|
||||
|
||||
/* If the search area is not diagonal, return the result of the */
|
||||
/* standard (manhattan) search function. */
|
||||
|
|
@ -121,7 +412,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
|
|||
|
||||
start.p_x = rect->r_xbot;
|
||||
start.p_y = rect->r_ytop - 1;
|
||||
tp = hintTile ? hintTile : plane->pl_hint;
|
||||
tp = hintTile ? hintTile : PlaneGetHint(plane);
|
||||
GOTOPOINT(tp, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -129,7 +420,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
|
|||
{
|
||||
/* Each iteration enumerates another tile */
|
||||
nm_enum:
|
||||
plane->pl_hint = tp;
|
||||
if (plane != (Plane *)NULL) PlaneSetHint(plane, tp);
|
||||
if (SigInterruptPending)
|
||||
return (1);
|
||||
|
||||
|
|
@ -137,147 +428,26 @@ nm_enum:
|
|||
/* the tile enumeration if it is not. */
|
||||
/* Watch for calculations involving (M)INFINITY in tile (tp)! */
|
||||
|
||||
rheight = rect->r_ytop - rect->r_ybot;
|
||||
rwidth = rect->r_xtop - rect->r_xbot;
|
||||
rmax = MAX(rheight, rwidth);
|
||||
f1 = (BOTTOM(tp) > MINFINITY + 2) ?
|
||||
((dlong)(rect->r_ytop - BOTTOM(tp)) * rwidth) : DLONG_MAX;
|
||||
f2 = (TOP(tp) < INFINITY - 2) ?
|
||||
((dlong)(TOP(tp) - rect->r_ybot) * rwidth) : DLONG_MAX;
|
||||
|
||||
if (ttype & TT_SIDE)
|
||||
{
|
||||
/* Outside-of-triangle check---ignore sub-integer slivers */
|
||||
if (RIGHT(tp) < INFINITY - 2)
|
||||
{
|
||||
f3 = (dlong)(rect->r_xtop - RIGHT(tp)) * rheight;
|
||||
f3 += rmax;
|
||||
}
|
||||
else
|
||||
f3 = DLONG_MIN;
|
||||
if ((ttype & TT_DIRECTION) ? (f2 < f3) : (f1 < f3))
|
||||
goto enum_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Outside-of-triangle check---ignore sub-integer slivers */
|
||||
if (LEFT(tp) > MINFINITY + 2)
|
||||
{
|
||||
f4 = (dlong)(LEFT(tp) - rect->r_xbot) * rheight;
|
||||
f4 += rmax;
|
||||
}
|
||||
else
|
||||
f4 = DLONG_MIN;
|
||||
if ((ttype & TT_DIRECTION) ? (f1 < f4) : (f2 < f4))
|
||||
goto enum_next;
|
||||
}
|
||||
|
||||
/* Secondary checks---if tile is also non-Manhattan, is */
|
||||
/* either side of it outside the area? If so, restrict it. */
|
||||
/* This check is only necessary if the split directions are */
|
||||
/* the same, so we have to see if either of the neighboring */
|
||||
/* points is also inside the search triangle. */
|
||||
|
||||
ignore_sides = 0;
|
||||
|
||||
if (IsSplit(tp))
|
||||
{
|
||||
if (!TTMaskHasType(mask, SplitLeftType(tp)))
|
||||
ignore_sides |= IGNORE_LEFT;
|
||||
if (!TTMaskHasType(mask, SplitRightType(tp)))
|
||||
ignore_sides |= IGNORE_RIGHT;
|
||||
TileType tpdi = TiGetTypeExact(tp);
|
||||
|
||||
tpt = TiGetTypeExact(tp);
|
||||
if ((tpt & TT_DIRECTION) == (ttype & TT_DIRECTION))
|
||||
{
|
||||
f3 = (LEFT(tp) > MINFINITY + 2) ?
|
||||
((dlong)(rect->r_xtop - LEFT(tp)) * rheight) : DLONG_MAX;
|
||||
f4 = (RIGHT(tp) < INFINITY - 2) ?
|
||||
((dlong)(RIGHT(tp) - rect->r_xbot) * rheight) : DLONG_MAX;
|
||||
|
||||
if (ttype & TT_SIDE)
|
||||
{
|
||||
/* Ignore sub-integer slivers */
|
||||
if (f4 != DLONG_MAX) f4 -= rmax;
|
||||
if (f3 != DLONG_MAX) f3 += rmax;
|
||||
|
||||
if (ttype & TT_DIRECTION)
|
||||
{
|
||||
if ((f2 < f3) && (f1 > f4))
|
||||
/* Tile bottom left is outside search area */
|
||||
ignore_sides |= IGNORE_LEFT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((f1 < f3) && (f2 > f4))
|
||||
/* Tile top left is outside search area */
|
||||
ignore_sides |= IGNORE_LEFT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Ignore sub-integer slivers */
|
||||
if (f4 != DLONG_MAX) f4 += rmax;
|
||||
if (f3 != DLONG_MAX) f3 -= rmax;
|
||||
|
||||
if (ttype & TT_DIRECTION)
|
||||
{
|
||||
if ((f2 > f3) && (f1 < f4))
|
||||
/* Tile top right is outside search area */
|
||||
ignore_sides |= IGNORE_RIGHT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((f1 > f3) && (f2 < f4))
|
||||
/* Tile bottom right is outside search area */
|
||||
ignore_sides |= IGNORE_RIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If the tile is larger than the search area or overlaps */
|
||||
/* the search area, we need to check if one of the sides */
|
||||
/* of the tile is disjoint from the search area. */
|
||||
|
||||
rheight = TOP(tp) - BOTTOM(tp);
|
||||
rwidth = RIGHT(tp) - LEFT(tp);
|
||||
rmax = MAX(rheight, rwidth);
|
||||
f1 = (TOP(tp) < INFINITY - 2) ?
|
||||
((dlong)(TOP(tp) - rect->r_ybot) * rwidth) : DLONG_MAX;
|
||||
f2 = (BOTTOM(tp) > MINFINITY + 2) ?
|
||||
((dlong)(rect->r_ytop - BOTTOM(tp)) * rwidth) : DLONG_MAX;
|
||||
f3 = (RIGHT(tp) < INFINITY - 2) ?
|
||||
((dlong)(RIGHT(tp) - rect->r_xtop) * rheight) : DLONG_MAX;
|
||||
f4 = (LEFT(tp) > MINFINITY + 2) ?
|
||||
((dlong)(rect->r_xbot - LEFT(tp)) * rheight) : DLONG_MAX;
|
||||
|
||||
/* ignore sub-integer slivers */
|
||||
if (f4 < DLONG_MAX) f4 += rmax;
|
||||
if (f3 < DLONG_MAX) f3 += rmax;
|
||||
|
||||
if (SplitDirection(tp) ? (f1 < f4) : (f2 < f4))
|
||||
ignore_sides |= IGNORE_LEFT;
|
||||
|
||||
if (SplitDirection(tp) ? (f2 < f3) : (f1 < f3))
|
||||
ignore_sides |= IGNORE_RIGHT;
|
||||
|
||||
/* May call function twice to paint both sides of */
|
||||
/* the split tile, if necessary. */
|
||||
|
||||
if (!(ignore_sides & IGNORE_LEFT))
|
||||
{
|
||||
TiSetBody(tp, (ClientData)(tpt & ~TT_SIDE)); /* bit clear */
|
||||
if ((*func)(tp, arg)) return (1);
|
||||
}
|
||||
if (!(ignore_sides & IGNORE_RIGHT))
|
||||
{
|
||||
TiSetBody(tp, (ClientData)(tpt | TT_SIDE)); /* bit set */
|
||||
if ((*func)(tp, arg)) return (1);
|
||||
}
|
||||
}
|
||||
if (TTMaskHasType(mask, SplitLeftType(tp)))
|
||||
if (DBTestNMInteract(rect, ttype, tp, tpdi, TRUE))
|
||||
if ((*func)(tp, (TileType)TT_DIAGONAL, arg))
|
||||
return 1;
|
||||
if (TTMaskHasType(mask, SplitRightType(tp)))
|
||||
if (DBTestNMInteract(rect, ttype, tp, tpdi | TT_SIDE, TRUE))
|
||||
if ((*func)(tp, (TileType)TT_DIAGONAL | TT_SIDE, arg))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
if (TTMaskHasType(mask, TiGetType(tp)) && (*func)(tp, arg))
|
||||
return (1);
|
||||
{
|
||||
if (TTMaskHasType(mask, TiGetType(tp)))
|
||||
if (DBTestNMInteract(rect, ttype, tp, (TileType)0, TRUE))
|
||||
if ((*func)(tp, (TileType)0, arg))
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum_next:
|
||||
tpnew = TR(tp);
|
||||
|
|
@ -325,6 +495,7 @@ enum_next:
|
|||
* int
|
||||
* func(tile, cdata)
|
||||
* Tile *tile;
|
||||
* TileType dinfo;
|
||||
* ClientData cdata;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -372,7 +543,7 @@ DBSrPaintArea(hintTile, plane, rect, mask, func, arg)
|
|||
|
||||
start.p_x = rect->r_xbot;
|
||||
start.p_y = rect->r_ytop - 1;
|
||||
tp = hintTile ? hintTile : plane->pl_hint;
|
||||
tp = hintTile ? hintTile : PlaneGetHint(plane);
|
||||
GOTOPOINT(tp, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -380,7 +551,7 @@ DBSrPaintArea(hintTile, plane, rect, mask, func, arg)
|
|||
{
|
||||
/* Each iteration enumerates another tile */
|
||||
enumerate:
|
||||
plane->pl_hint = tp;
|
||||
PlaneSetHint(plane, tp);
|
||||
if (SigInterruptPending)
|
||||
return (1);
|
||||
|
||||
|
|
@ -416,9 +587,7 @@ enumerate:
|
|||
(dlong)(rect->r_xbot - LEFT(tp)) * theight : DLONG_MIN;
|
||||
if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4))
|
||||
{
|
||||
TiSetBody(tp, (ClientData)((TileType)TiGetBody(tp)
|
||||
& ~TT_SIDE)); /* bit clear */
|
||||
if ((*func)(tp, arg)) return (1);
|
||||
if ((*func)(tp, (TileType)TT_DIAGONAL, arg)) return (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -429,14 +598,12 @@ enumerate:
|
|||
(dlong)(RIGHT(tp) - rect->r_xtop) * theight : DLONG_MIN;
|
||||
if (SplitDirection(tp) ? (f2 > f3) : (f1 > f3))
|
||||
{
|
||||
TiSetBody(tp, (ClientData)((TileType)TiGetBody(tp)
|
||||
| TT_SIDE)); /* bit set */
|
||||
if ((*func)(tp, arg)) return (1);
|
||||
if ((*func)(tp, (TileType)TT_DIAGONAL | TT_SIDE, arg)) return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (TTMaskHasType(mask, TiGetType(tp)) && (*func)(tp, arg))
|
||||
if (TTMaskHasType(mask, TiGetType(tp)) && (*func)(tp, (TileType)0, arg))
|
||||
return (1);
|
||||
|
||||
tpnew = TR(tp);
|
||||
|
|
@ -485,6 +652,7 @@ enumerate:
|
|||
* int
|
||||
* func(tile, cdata)
|
||||
* Tile *tile;
|
||||
* TileType dinfo;
|
||||
* ClientData cdata;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -532,7 +700,7 @@ DBSrPaintClient(hintTile, plane, rect, mask, client, func, arg)
|
|||
|
||||
start.p_x = rect->r_xbot;
|
||||
start.p_y = rect->r_ytop - 1;
|
||||
tp = hintTile ? hintTile : plane->pl_hint;
|
||||
tp = hintTile ? hintTile : PlaneGetHint(plane);
|
||||
GOTOPOINT(tp, &start);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
|
|
@ -540,7 +708,7 @@ DBSrPaintClient(hintTile, plane, rect, mask, client, func, arg)
|
|||
{
|
||||
/* Each iteration enumerates another tile */
|
||||
enumerate:
|
||||
plane->pl_hint = tp;
|
||||
PlaneSetHint(plane, tp);
|
||||
if (SigInterruptPending)
|
||||
return (1);
|
||||
|
||||
|
|
@ -565,20 +733,18 @@ enumerate:
|
|||
theight = TOP(tp) - BOTTOM(tp);
|
||||
twidth = RIGHT(tp) - LEFT(tp);
|
||||
f1 = (rect->r_ybot > MINFINITY + 2) ?
|
||||
(TOP(tp) - rect->r_ybot) * twidth : DLONG_MAX;
|
||||
(dlong)(TOP(tp) - rect->r_ybot) * (dlong)twidth : DLONG_MAX;
|
||||
f2 = (rect->r_ytop < INFINITY - 2) ?
|
||||
(rect->r_ytop - BOTTOM(tp)) * twidth : DLONG_MAX;
|
||||
(dlong)(rect->r_ytop - BOTTOM(tp)) * (dlong)twidth : DLONG_MAX;
|
||||
|
||||
if (TTMaskHasType(mask, SplitLeftType(tp)))
|
||||
{
|
||||
/* !Outside-of-triangle check */
|
||||
f4 = (rect->r_xbot > MINFINITY + 2) ?
|
||||
(rect->r_xbot - LEFT(tp)) * theight : DLONG_MIN;
|
||||
(dlong)(rect->r_xbot - LEFT(tp)) * (dlong)theight : DLONG_MIN;
|
||||
if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4))
|
||||
{
|
||||
TiSetBody(tp, (ClientData)((TileType)TiGetBody(tp)
|
||||
& ~TT_SIDE)); /* bit clear */
|
||||
if ((tp->ti_client == client) && (*func)(tp, arg))
|
||||
if ((tp->ti_client == client) && (*func)(tp, (TileType)TT_DIAGONAL, arg))
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
|
@ -587,19 +753,18 @@ enumerate:
|
|||
{
|
||||
/* !Outside-of-triangle check */
|
||||
f3 = (rect->r_xtop < INFINITY - 2) ?
|
||||
(RIGHT(tp) - rect->r_xtop) * theight : DLONG_MIN;
|
||||
(dlong)(RIGHT(tp) - rect->r_xtop) * (dlong)theight : DLONG_MIN;
|
||||
if (SplitDirection(tp) ? (f2 > f3) : (f1 > f3))
|
||||
{
|
||||
TiSetBody(tp, (ClientData)((TileType)TiGetBody(tp)
|
||||
| TT_SIDE)); /* bit set */
|
||||
if ((tp->ti_client == client) && (*func)(tp, arg))
|
||||
if ((tp->ti_client == client) && (*func)(tp, (TileType)TT_DIAGONAL
|
||||
| TT_SIDE, arg))
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if (TTMaskHasType(mask, TiGetType(tp)) && tp->ti_client == client
|
||||
&& (*func)(tp, arg))
|
||||
&& (*func)(tp, (TileType)0, arg))
|
||||
return (1);
|
||||
|
||||
tpnew = TR(tp);
|
||||
|
|
@ -657,7 +822,7 @@ DBResetTilePlane(plane, cdata)
|
|||
ClientData cdata;
|
||||
{
|
||||
Tile *tp, *tpnew;
|
||||
Rect *rect = &TiPlaneRect;
|
||||
const Rect *rect = &TiPlaneRect;
|
||||
|
||||
/* Start with the leftmost non-infinity tile in the plane */
|
||||
tp = TR(plane->pl_left);
|
||||
|
|
@ -665,7 +830,7 @@ DBResetTilePlane(plane, cdata)
|
|||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
while (TOP(tp) > rect->r_ybot)
|
||||
{
|
||||
/* Each iteration frees another tile */
|
||||
/* Each iteration resets another tile */
|
||||
enumerate:
|
||||
tp->ti_client = cdata;
|
||||
|
||||
|
|
@ -701,6 +866,88 @@ enumerate:
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
* DBResetTilePlaneSpecial --
|
||||
*
|
||||
* This routine works like DBResetTilePlane(), but is designed
|
||||
* specifically to be run after extFindNodes() or ExtFindRegions()
|
||||
* to check for split tiles that have an allocated ExtSplitRegion
|
||||
* structure in the ClientData; this needs to be freed before
|
||||
* resetting the ClientData value to "cdata". It is not necessary
|
||||
* to know anything about the ExtSplitRegion structure other than
|
||||
* the condition under which it can be expected to be present,
|
||||
* which is a split tile with neither side having type TT_SPACE.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* Resets the ti_client fields of all tiles.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
DBResetTilePlaneSpecial(plane, cdata)
|
||||
Plane *plane; /* Plane whose tiles are to be reset */
|
||||
ClientData cdata;
|
||||
{
|
||||
Tile *tp, *tpnew;
|
||||
const Rect *rect = &TiPlaneRect;
|
||||
|
||||
/* Start with the leftmost non-infinity tile in the plane */
|
||||
tp = TR(plane->pl_left);
|
||||
|
||||
/* Each iteration visits another tile on the LHS of the search area */
|
||||
while (TOP(tp) > rect->r_ybot)
|
||||
{
|
||||
/* Each iteration resets another tile */
|
||||
enumerate:
|
||||
if (IsSplit(tp))
|
||||
if ((TiGetLeftType(tp) != TT_SPACE) && (TiGetRightType(tp) != TT_SPACE))
|
||||
if (tp->ti_client != cdata)
|
||||
{
|
||||
ASSERT(TiGetBody((Tile *)tp->ti_client) == CLIENTDEFAULT,
|
||||
"DBResetTilePlaneSpecial");
|
||||
freeMagic(tp->ti_client);
|
||||
}
|
||||
|
||||
tp->ti_client = cdata;
|
||||
|
||||
/* Move along to the next tile */
|
||||
tpnew = TR(tp);
|
||||
if (LEFT(tpnew) < rect->r_xtop)
|
||||
{
|
||||
while (BOTTOM(tpnew) >= rect->r_ytop) tpnew = LB(tpnew);
|
||||
if (BOTTOM(tpnew) >= BOTTOM(tp) || BOTTOM(tp) <= rect->r_ybot)
|
||||
{
|
||||
tp = tpnew;
|
||||
goto enumerate;
|
||||
}
|
||||
}
|
||||
|
||||
/* Each iteration returns one tile further to the left */
|
||||
while (LEFT(tp) > rect->r_xbot)
|
||||
{
|
||||
if (BOTTOM(tp) <= rect->r_ybot)
|
||||
return;
|
||||
tpnew = LB(tp);
|
||||
tp = BL(tp);
|
||||
if (BOTTOM(tpnew) >= BOTTOM(tp) || BOTTOM(tp) <= rect->r_ybot)
|
||||
{
|
||||
tp = tpnew;
|
||||
goto enumerate;
|
||||
}
|
||||
}
|
||||
|
||||
/* At left edge -- walk down to next tile along the left edge */
|
||||
for (tp = LB(tp); RIGHT(tp) <= rect->r_xbot; tp = TR(tp))
|
||||
/* Nothing */;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -723,9 +970,7 @@ enumerate:
|
|||
*
|
||||
* This procedure uses a carfully constructed non-recursive area
|
||||
* enumeration algorithm. Care is taken to not access a tile that has
|
||||
* been deallocated. The only exception is for a tile that has just been
|
||||
* passed to free(), but no more calls to free() or malloc() have been made.
|
||||
* Magic's malloc allows this.
|
||||
* been deallocated.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -735,11 +980,12 @@ DBFreePaintPlane(plane)
|
|||
Plane *plane; /* Plane whose storage is to be freed */
|
||||
{
|
||||
Tile *tp, *tpnew;
|
||||
Rect *rect = &TiPlaneRect;
|
||||
const Rect *rect = &TiPlaneRect;
|
||||
|
||||
/* Start with the bottom-right non-infinity tile in the plane */
|
||||
tp = BL(plane->pl_right);
|
||||
|
||||
Tile *delayed = NULL;
|
||||
/* Each iteration visits another tile on the RHS of the search area */
|
||||
while (BOTTOM(tp) < rect->r_ytop)
|
||||
{
|
||||
|
|
@ -762,9 +1008,9 @@ enumerate:
|
|||
/* Each iteration returns one tile further to the right */
|
||||
while (RIGHT(tp) < rect->r_xtop)
|
||||
{
|
||||
TiFree(tp);
|
||||
tpnew = RT(tp);
|
||||
tp = TR(tp);
|
||||
TiFree1(&delayed, tp);
|
||||
tpnew = RT(tp); /* deref of delayed */
|
||||
tp = TR(tp); /* deref of delayed */
|
||||
if (CLIP_TOP(tpnew) <= CLIP_TOP(tp) && BOTTOM(tpnew) < rect->r_ytop)
|
||||
{
|
||||
tp = tpnew;
|
||||
|
|
@ -772,13 +1018,14 @@ enumerate:
|
|||
}
|
||||
}
|
||||
|
||||
TiFree(tp);
|
||||
TiFree1(&delayed, tp);
|
||||
/* At right edge -- walk up to next tile along the right edge */
|
||||
tp = RT(tp);
|
||||
tp = RT(tp); /* deref of delayed */
|
||||
if (BOTTOM(tp) < rect->r_ytop) {
|
||||
while(LEFT(tp) >= rect->r_xtop) tp = BL(tp);
|
||||
}
|
||||
}
|
||||
TiFreeIf(delayed);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -918,8 +1165,9 @@ DBCheckMaxHStrips(plane, area, proc, cdata)
|
|||
*/
|
||||
|
||||
int
|
||||
dbCheckMaxHFunc(tile, dbc)
|
||||
dbCheckMaxHFunc(tile, dinfo, dbc)
|
||||
Tile *tile;
|
||||
TileType dinfo; /* (unused) */
|
||||
struct dbCheck *dbc;
|
||||
{
|
||||
Tile *tp;
|
||||
|
|
@ -1010,8 +1258,9 @@ DBCheckMaxVStrips(plane, area, proc, cdata)
|
|||
*/
|
||||
|
||||
int
|
||||
dbCheckMaxVFunc(tile, dbc)
|
||||
dbCheckMaxVFunc(tile, dinfo, dbc)
|
||||
Tile *tile;
|
||||
TileType dinfo; /* (unused) */
|
||||
struct dbCheck *dbc;
|
||||
{
|
||||
Tile *tp;
|
||||
|
|
|
|||
|
|
@ -84,6 +84,10 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
|
||||
int timestamp;
|
||||
|
||||
typedef struct _celllist {
|
||||
CellDef *cl_cell;
|
||||
struct _celllist *cl_next;
|
||||
} CellList;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -107,9 +111,9 @@ DBFixMismatch()
|
|||
{
|
||||
CellDef *cellDef;
|
||||
CellUse *parentUse;
|
||||
CellList *cl = NULL, *clnew;
|
||||
Rect oldArea, parentArea, tmp;
|
||||
int redisplay;
|
||||
int firstOne = TRUE;
|
||||
Mismatch *tmpm;
|
||||
|
||||
/* It's very important to disable interrupts during this section!
|
||||
|
|
@ -118,7 +122,7 @@ DBFixMismatch()
|
|||
|
||||
redisplay = FALSE;
|
||||
if (mismatch == NULL) return;
|
||||
TxPrintf("Processing timestamp mismatches:");
|
||||
TxPrintf("Processing timestamp mismatches.\n");
|
||||
SigDisableInterrupts();
|
||||
|
||||
for (tmpm = mismatch; tmpm; tmpm = tmpm->mm_next)
|
||||
|
|
@ -126,8 +130,6 @@ DBFixMismatch()
|
|||
|
||||
while (mismatch != NULL)
|
||||
{
|
||||
bool dereference;
|
||||
|
||||
/* Be careful to remove the front element from the mismatch
|
||||
* list before processing it, because while processing it we
|
||||
* may add new elements to the list.
|
||||
|
|
@ -135,12 +137,13 @@ DBFixMismatch()
|
|||
|
||||
cellDef = mismatch->mm_cellDef;
|
||||
oldArea = mismatch->mm_oldArea;
|
||||
freeMagic((char *) mismatch);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, (char *) mismatch);
|
||||
mismatch = mismatch->mm_next;
|
||||
freeMagic1_end(&mm1);
|
||||
if (cellDef->cd_flags & CDPROCESSED) continue;
|
||||
|
||||
dereference = (cellDef->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
|
||||
(void) DBCellRead(cellDef, (char *) NULL, TRUE, dereference, NULL);
|
||||
(void) DBCellRead(cellDef, TRUE, TRUE, NULL);
|
||||
|
||||
/* Jimmy up the cell's current bounding box, so the following
|
||||
* procedure call will absolutely and positively know that
|
||||
|
|
@ -174,15 +177,22 @@ DBFixMismatch()
|
|||
redisplay = TRUE;
|
||||
}
|
||||
cellDef->cd_flags |= CDPROCESSED;
|
||||
if (firstOne)
|
||||
{
|
||||
TxPrintf(" %s", cellDef->cd_name);
|
||||
firstOne = FALSE;
|
||||
}
|
||||
else TxPrintf(", %s", cellDef->cd_name);
|
||||
TxFlush(); /* This is needed to prevent _doprnt screwups */
|
||||
clnew = (CellList *)mallocMagic(sizeof(CellList));
|
||||
clnew->cl_cell = cellDef;
|
||||
clnew->cl_next = cl;
|
||||
cl = clnew;
|
||||
}
|
||||
SigEnableInterrupts();
|
||||
TxPrintf("Timestamp mismatches found in these cells: ");
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (cl != NULL)
|
||||
{
|
||||
TxPrintf("%s", cl->cl_cell->cd_name);
|
||||
if (cl->cl_next != NULL) TxPrintf(", ");
|
||||
freeMagic1(&mm1, cl);
|
||||
cl = cl->cl_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
TxPrintf(".\n");
|
||||
TxFlush();
|
||||
if (redisplay) WindAreaChanged((MagWindow *) NULL, (Rect *) NULL);
|
||||
|
|
@ -221,7 +231,7 @@ DBUpdateStamps(def)
|
|||
|
||||
else if (def->cd_flags & CDGETNEWSTAMP)
|
||||
{
|
||||
if (def->cd_flags & CDFIXEDSTAMP)
|
||||
if (def->cd_flags & (CDNOEDIT | CDFIXEDSTAMP))
|
||||
def->cd_flags &= ~CDGETNEWSTAMP;
|
||||
else
|
||||
dbStampFunc(def);
|
||||
|
|
@ -241,6 +251,26 @@ dbStampFunc(cellDef)
|
|||
|
||||
if (cellDef->cd_timestamp == timestamp) return 0;
|
||||
|
||||
/* Non-editable cells should not try to update timestamps, as the
|
||||
* new timestamp cannot be written back to the file. This is
|
||||
* basically a hack solution for the problem that running DRC on
|
||||
* all cells causes all cells, including non-editable ones, to be
|
||||
* marked as modified, even if there were no DRC changes in the
|
||||
* cell. It is possible to get into trouble this way by modifying
|
||||
* a cell and then marking it as non-editable
|
||||
*/
|
||||
|
||||
if (cellDef->cd_flags & CDNOEDIT)
|
||||
{
|
||||
cellDef->cd_flags &= ~CDGETNEWSTAMP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not force a non-edit cell or a cell with a fixed timestamp
|
||||
* to update its timestamp, as it cannot or should not. Just clear
|
||||
* any flag suggesting that it needs a new timestamp.
|
||||
*/
|
||||
if (!(cellDef->cd_flags & CDFIXEDSTAMP))
|
||||
cellDef->cd_timestamp = timestamp;
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue