Compare commits
333 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
0cbed6078a | |
|
|
9760ef6d1d | |
|
|
bd13febb72 | |
|
|
81436b75ed | |
|
|
8822f8dce2 | |
|
|
f03003b79f | |
|
|
802c31d16a | |
|
|
308224109f | |
|
|
4d9c7fd7d7 | |
|
|
a55ec49434 | |
|
|
c0dbb2067b | |
|
|
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 |
|
|
@ -1,28 +0,0 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
name: CI-appimage
|
||||
|
||||
jobs:
|
||||
build_appimage:
|
||||
name: Build AppImage
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
- 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}}
|
||||
|
|
@ -12,37 +12,35 @@ jobs:
|
|||
strategy:
|
||||
max-parallel: 3
|
||||
matrix:
|
||||
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
|
||||
os: [ubuntu-24.04, ubuntu-22.04]
|
||||
# Configure Options
|
||||
pkgs: [all, none, no_tk_tcl_rl, no_rl, no_zlib, no_gc_gl_gu, no_gc_gu]
|
||||
# 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] gcc-10
|
||||
# ubuntu-22.04 [gcc-11] gcc-12
|
||||
# ubuntu-24.04 [gcc-13] gcc-14
|
||||
tc: [default, gcc-10, gcc-12, gcc-14, clang-17, clang-18]
|
||||
# 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-20.04
|
||||
tc: gcc-12
|
||||
- os: ubuntu-20.04
|
||||
tc: gcc-14
|
||||
- os: ubuntu-20.04
|
||||
tc: clang-17
|
||||
- os: ubuntu-20.04
|
||||
tc: clang-18
|
||||
|
||||
- os: ubuntu-22.04
|
||||
tc: gcc-10
|
||||
tc: gcc-13
|
||||
- os: ubuntu-22.04
|
||||
tc: gcc-14
|
||||
- os: ubuntu-22.04
|
||||
tc: clang-17
|
||||
- os: ubuntu-22.04
|
||||
- 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-12
|
||||
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:
|
||||
|
|
@ -69,16 +67,19 @@ jobs:
|
|||
# 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
|
||||
# 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
|
||||
|
|
@ -111,6 +112,8 @@ jobs:
|
|||
_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
|
||||
|
|
@ -203,6 +206,7 @@ jobs:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -10,8 +10,8 @@ on:
|
|||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
jobs:
|
||||
simple_build_macos13:
|
||||
runs-on: macos-13
|
||||
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
|
||||
|
|
@ -22,8 +22,8 @@ jobs:
|
|||
run: |
|
||||
brew install --cask xquartz
|
||||
PACKAGE_LIST="xquartz"
|
||||
brew install cairo tcl-tk@8 tcsh
|
||||
_package_list="cairo tcl-tk@8 tcsh"
|
||||
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"
|
||||
|
|
@ -54,6 +54,7 @@ jobs:
|
|||
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 ""
|
||||
|
|
@ -234,10 +235,10 @@ jobs:
|
|||
cp *.mak dist/BUILD-INFO/
|
||||
cp *.LOG dist/BUILD-INFO/
|
||||
|
||||
- name: Upload archive magic-macos13
|
||||
- name: Upload archive magic-macos15
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: magic-macos13
|
||||
name: magic-macos15
|
||||
path: |
|
||||
${{ github.workspace }}/dist
|
||||
|
||||
|
|
@ -253,8 +254,8 @@ jobs:
|
|||
run: |
|
||||
brew install --cask xquartz
|
||||
PACKAGE_LIST="xquartz"
|
||||
brew install cairo tcl-tk@8 tcsh
|
||||
_package_list="cairo tcl-tk@8 tcsh"
|
||||
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"
|
||||
|
|
@ -285,6 +286,7 @@ jobs:
|
|||
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 ""
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ jobs:
|
|||
- 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@v4
|
||||
- name: Get Dependencies
|
||||
|
|
@ -36,7 +36,7 @@ jobs:
|
|||
make database/database.h
|
||||
make -j$(nproc)
|
||||
simple_build_wasm:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Get Dependencies
|
||||
|
|
@ -49,6 +49,9 @@ jobs:
|
|||
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
|
||||
|
|
|
|||
|
|
@ -3,11 +3,10 @@
|
|||
Get [Homebrew](https://brew.sh).
|
||||
|
||||
```sh
|
||||
# TCL9 should be supported soon (Q2 2025)
|
||||
brew install cairo tcl-tk@8 python3
|
||||
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 TCL8 was selected.
|
||||
# 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
|
||||
|
|
|
|||
103
Makefile
103
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,24 +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
|
||||
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)
|
||||
|
||||
|
|
@ -95,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
|
||||
|
||||
|
|
@ -105,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 \
|
||||
|
|
@ -133,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 |
|
||||
|
|
@ -13,21 +13,24 @@ RUN ls -l /etc/yum.repos.d/ \
|
|||
&& yum -y update \
|
||||
&& rm -f /tmp/CentOS-Base.repo.old
|
||||
|
||||
# Build Dependencies
|
||||
RUN yum install -y cairo-devel freeglut-devel gcc make tcsh
|
||||
# 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
|
||||
# Tcl/Tk
|
||||
WORKDIR /tcl
|
||||
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl8.6.12-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
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.12-src.tar.gz | tar --strip-components=1 -xzC . \
|
||||
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\
|
||||
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib \
|
||||
&& make \
|
||||
&& make install
|
||||
|
||||
|
|
@ -49,7 +52,17 @@ RUN ./configure \
|
|||
&& 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"]
|
||||
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,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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@
|
|||
//
|
||||
// ************************************************************************
|
||||
|
||||
#ifndef _BPENUM_H
|
||||
#define _BPENUM_H
|
||||
#ifndef _MAGIC__BPLANE__BPENUM_H
|
||||
#define _MAGIC__BPLANE__BPENUM_H
|
||||
|
||||
/* bpEnum.h --
|
||||
*
|
||||
|
|
@ -534,4 +534,4 @@ static __inline__ void *BPEnumNext(BPEnum *bpe)
|
|||
}
|
||||
}
|
||||
|
||||
#endif /* _BPENUM_H */
|
||||
#endif /* _MAGIC__BPLANE__BPENUM_H */
|
||||
|
|
|
|||
|
|
@ -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 --
|
||||
|
|
@ -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 --
|
||||
|
|
@ -232,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 */
|
||||
|
|
|
|||
|
|
@ -245,7 +245,9 @@ calmaExact(void)
|
|||
int pNum;
|
||||
Plane *newplane;
|
||||
Plane **parray;
|
||||
int gdsCopyPaintFunc(Tile *tile, GDSCopyRec *gdsCopyRec); /* Forward reference */
|
||||
|
||||
/* Forward reference */
|
||||
int gdsCopyPaintFunc(Tile *tile, TileType dinfo, GDSCopyRec *gdsCopyRec);
|
||||
|
||||
parray = (Plane **)mallocMagic(MAXCIFRLAYERS * sizeof(Plane *));
|
||||
|
||||
|
|
@ -387,6 +389,15 @@ calmaParseStructure(
|
|||
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 */
|
||||
|
|
@ -396,6 +407,7 @@ calmaParseStructure(
|
|||
|
||||
if (!CalmaPostOrder && !CalmaRewound)
|
||||
{
|
||||
cifReadCellDef = def;
|
||||
CalmaReadError("Cell \"%s\" was already defined in this file.\n",
|
||||
strname);
|
||||
CalmaReadError("Ignoring duplicate definition\n");
|
||||
|
|
@ -407,6 +419,7 @@ calmaParseStructure(
|
|||
{
|
||||
char *newname;
|
||||
|
||||
cifReadCellDef = def;
|
||||
CalmaReadError("Cell \"%s\" was already defined in this file.\n",
|
||||
strname);
|
||||
newname = (char *)mallocMagic(strlen(strname) + 20);
|
||||
|
|
@ -740,6 +753,7 @@ calmaParseElement(
|
|||
int
|
||||
calmaEnumFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
int *plane)
|
||||
{
|
||||
return 1;
|
||||
|
|
@ -773,16 +787,18 @@ calmaElementSref(
|
|||
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(Tile *tile, GDSCopyRec *gdsCopyRec); /* Forward reference */
|
||||
int gdsHasUses(CellUse *use, ClientData clientdata); /* 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);
|
||||
|
||||
|
|
@ -798,7 +814,38 @@ calmaElementSref(
|
|||
*/
|
||||
|
||||
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
|
||||
|
|
@ -832,6 +879,7 @@ calmaElementSref(
|
|||
FSEEK(calmaInputFile, originalFilePos, SEEK_SET);
|
||||
cifReadCellDef = calmaLookCell(currentSname);
|
||||
def = calmaLookCell(sname);
|
||||
def->cd_flags |= CDPRELOADED;
|
||||
cifCurReadPlanes = savePlanes;
|
||||
calmaLayerHash = OrigCalmaLayerHash;
|
||||
if (crsMultiplier != cifCurReadStyle->crs_multiplier)
|
||||
|
|
@ -1245,27 +1293,28 @@ gdsHasUses(
|
|||
int
|
||||
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;
|
||||
|
|
@ -1384,13 +1433,18 @@ calmaFindCell(
|
|||
}
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ extern int CalmaPathCount;
|
|||
extern HashTable calmaDefInitHash;
|
||||
|
||||
extern void calmaLayerError(char *mesg, int layer, int dt);
|
||||
bool calmaReadPath(CIFPath **pathheadpp, int iscale);
|
||||
CIFPath *calmaReadPath(int iscale);
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -213,7 +213,7 @@ calmaElementBoundary(void)
|
|||
LinkedRect *rp;
|
||||
Plane *plane;
|
||||
CellUse *use;
|
||||
CellDef *savedef, *newdef = NULL;
|
||||
CellDef *savedef = NULL, *newdef = NULL;
|
||||
|
||||
/* Skip CALMA_ELFLAGS, CALMA_PLEX */
|
||||
calmaSkipSet(calmaElementIgnore);
|
||||
|
|
@ -237,7 +237,8 @@ calmaElementBoundary(void)
|
|||
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");
|
||||
|
|
@ -257,7 +258,7 @@ calmaElementBoundary(void)
|
|||
if ((CalmaSubcellPolygons != CALMA_POLYGON_NONE) && (calmaNonManhattan > 0))
|
||||
{
|
||||
/* Place the polygon in its own subcell */
|
||||
char newname[16];
|
||||
char newname[20];
|
||||
HashEntry *he;
|
||||
|
||||
savedef = cifReadCellDef;
|
||||
|
|
@ -359,12 +360,14 @@ calmaElementBoundary(void)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
|
|
@ -512,7 +515,7 @@ calmaElementPath(void)
|
|||
Plane *plane;
|
||||
int first,last;
|
||||
CellUse *use;
|
||||
CellDef *savedef, *newdef = NULL;
|
||||
CellDef *savedef = NULL, *newdef = NULL;
|
||||
|
||||
/* Skip CALMA_ELFLAGS, CALMA_PLEX */
|
||||
calmaSkipSet(calmaElementIgnore);
|
||||
|
|
@ -595,7 +598,8 @@ calmaElementPath(void)
|
|||
|
||||
/* Read the points in the path */
|
||||
savescale = calmaReadScale1;
|
||||
if (!calmaReadPath(&pathheadp, 2))
|
||||
pathheadp = calmaReadPath(2);
|
||||
if (pathheadp == NULL)
|
||||
{
|
||||
CalmaReadError("Improper path; ignored.\n");
|
||||
return;
|
||||
|
|
@ -1098,26 +1102,24 @@ calmaElementText(void)
|
|||
* 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
|
||||
CIFPath *
|
||||
calmaReadPath(
|
||||
CIFPath **pathheadpp,
|
||||
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;
|
||||
|
||||
|
|
@ -1126,12 +1128,12 @@ calmaReadPath(
|
|||
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) */
|
||||
|
|
@ -1142,7 +1144,7 @@ calmaReadPath(
|
|||
calmaReadPoint(&path.cifp_point, iscale);
|
||||
if (savescale != calmaReadScale1)
|
||||
{
|
||||
CIFPath *phead = *pathheadpp;
|
||||
CIFPath *phead = pathheadp;
|
||||
int newscale = calmaReadScale1 / savescale;
|
||||
while (phead != NULL)
|
||||
{
|
||||
|
|
@ -1157,8 +1159,8 @@ calmaReadPath(
|
|||
}
|
||||
if (FEOF(calmaInputFile))
|
||||
{
|
||||
CIFFreePath(*pathheadpp);
|
||||
return (FALSE);
|
||||
CIFFreePath(pathheadp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (iscale != 0)
|
||||
|
|
@ -1166,7 +1168,7 @@ calmaReadPath(
|
|||
newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath)));
|
||||
*newpathp = path;
|
||||
|
||||
if (*pathheadpp)
|
||||
if (pathheadp)
|
||||
{
|
||||
/*
|
||||
* Check that this segment is Manhattan. If not, remember the
|
||||
|
|
@ -1187,11 +1189,11 @@ calmaReadPath(
|
|||
}
|
||||
pathtailp->cifp_next = newpathp;
|
||||
}
|
||||
else *pathheadpp = newpathp;
|
||||
else pathheadp = newpathp;
|
||||
pathtailp = newpathp;
|
||||
}
|
||||
}
|
||||
return (*pathheadpp != NULL);
|
||||
return (pathheadp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -613,20 +613,23 @@ CalmaTechInit(void)
|
|||
ASSERT(sizeof(FourByteInt)==4, "definition in calmaInt.h");
|
||||
ASSERT(sizeof(TwoByteInt)==2, "definition in calmaInt.h");
|
||||
|
||||
/* NOTE: Enable the code below when CalmaContactArrays */
|
||||
/* behaves like the non-arrayed function and can be enabled */
|
||||
/* by default. */
|
||||
#if 0
|
||||
/* 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 */
|
||||
/* "$$*$$" to match the name style used by the contact */
|
||||
/* array cell generation. This can be overridden by the */
|
||||
/* "gds flatglob none" command option. */
|
||||
/* "*_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, "$$*$$");
|
||||
*CalmaFlattenUsesByName = StrDup((char **)NULL, "*_CDNS_*");
|
||||
*(CalmaFlattenUsesByName + 1) = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,9 +28,15 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
|
|||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h> /* for htons() */
|
||||
#include <time.h> /* since C89 */
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "utils/magic.h"
|
||||
|
|
@ -38,6 +44,7 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
|
|||
#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"
|
||||
|
|
@ -90,10 +97,10 @@ typedef struct {
|
|||
|
||||
/* Forward declarations */
|
||||
extern int calmaWriteInitFunc(CellDef *def);
|
||||
extern int calmaWritePaintFunc(Tile *tile, calmaOutputStruct *cos);
|
||||
extern int calmaMergePaintFunc(Tile *tile, calmaOutputStruct *cos);
|
||||
extern int calmaWritePaintFunc(Tile *tile, TileType dinfo, calmaOutputStruct *cos);
|
||||
extern int calmaMergePaintFunc(Tile *tile, TileType dinfo, calmaOutputStruct *cos);
|
||||
extern int calmaWriteUseFunc(CellUse *use, FILE *f);
|
||||
extern int calmaPaintLabelFunc(Tile *tile, calmaOutputStruct *cos);
|
||||
extern int calmaPaintLabelFunc(Tile *tile, TileType dinfo, calmaOutputStruct *cos);
|
||||
extern void calmaWriteContacts(FILE *f);
|
||||
extern void calmaDelContacts(void);
|
||||
extern void calmaOutFunc(CellDef *def, FILE *f, const Rect *cliprect);
|
||||
|
|
@ -1393,8 +1400,10 @@ calmaOutFunc(
|
|||
{
|
||||
pllist[i].pl_label = ll->ll_label;
|
||||
pllist[i].pl_port = (unsigned int)ll->ll_attr;
|
||||
freeMagic(ll);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, ll);
|
||||
ll = ll->ll_next;
|
||||
freeMagic1_end(&mm1);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
@ -2415,19 +2424,27 @@ calmaProcessBoundary(
|
|||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2447,6 +2464,7 @@ calmaProcessBoundary(
|
|||
int
|
||||
calmaMergePaintFunc(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
calmaOutputStruct *cos) /* Information needed by algorithm */
|
||||
{
|
||||
FILE *f = cos->f;
|
||||
|
|
@ -2477,11 +2495,10 @@ calmaMergePaintFunc(
|
|||
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;
|
||||
|
|
@ -2493,8 +2510,10 @@ calmaMergePaintFunc(
|
|||
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
|
||||
|
|
@ -2702,7 +2721,9 @@ right_search:
|
|||
done_searches:
|
||||
if (intedges == 0)
|
||||
{
|
||||
calmaWritePaintFunc(t, cos);
|
||||
calmaWritePaintFunc(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 */
|
||||
|
|
@ -2713,11 +2734,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))
|
||||
|
|
@ -2770,6 +2793,7 @@ done_searches:
|
|||
int
|
||||
calmaWritePaintFunc(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
calmaOutputStruct *cos) /* File for output and clipping area */
|
||||
{
|
||||
FILE *f = cos->f;
|
||||
|
|
@ -2805,7 +2829,7 @@ calmaWritePaintFunc(
|
|||
/* Coordinates */
|
||||
calmaOutRH(36, CALMA_XY, CALMA_I4, f);
|
||||
|
||||
switch ((SplitSide(tile) << 1) | SplitDirection(tile))
|
||||
switch (((dinfo & TT_SIDE) ? 2 : 0) | SplitDirection(tile))
|
||||
{
|
||||
case 0x0:
|
||||
calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f);
|
||||
|
|
@ -3046,6 +3070,7 @@ calmaWriteLabelFunc(
|
|||
int
|
||||
calmaPaintLabelFunc(
|
||||
Tile *tile, /* Tile contains area for label. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
calmaOutputStruct *cos) /* File for output and clipping area */
|
||||
{
|
||||
FILE *f = cos->f;
|
||||
|
|
|
|||
|
|
@ -38,10 +38,15 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
|
|||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h> /* for htons() */
|
||||
#if defined(SYSV) || defined(EMSCRIPTEN)
|
||||
#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"
|
||||
|
|
@ -49,6 +54,7 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
|
|||
#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"
|
||||
|
|
@ -101,10 +107,10 @@ typedef struct {
|
|||
} calmaOutputStructZ;
|
||||
|
||||
/* Forward declarations */
|
||||
extern int calmaWritePaintFuncZ(Tile *tile, calmaOutputStructZ *cos);
|
||||
extern int calmaMergePaintFuncZ(Tile *tile, calmaOutputStructZ *cos);
|
||||
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, calmaOutputStructZ *cos);
|
||||
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);
|
||||
|
|
@ -1318,8 +1324,10 @@ calmaOutFuncZ(
|
|||
{
|
||||
pllist[i].pl_label = ll->ll_label;
|
||||
pllist[i].pl_port = (unsigned int)ll->ll_attr;
|
||||
freeMagic(ll);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, ll);
|
||||
ll = ll->ll_next;
|
||||
freeMagic1_end(&mm1);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
|
@ -1851,19 +1859,27 @@ calmaProcessBoundaryZ(
|
|||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1883,6 +1899,7 @@ calmaProcessBoundaryZ(
|
|||
int
|
||||
calmaMergePaintFuncZ(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
calmaOutputStructZ *cos) /* Information needed by algorithm */
|
||||
{
|
||||
gzFile f = cos->f;
|
||||
|
|
@ -1913,11 +1930,10 @@ calmaMergePaintFuncZ(
|
|||
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;
|
||||
|
|
@ -1929,8 +1945,10 @@ calmaMergePaintFuncZ(
|
|||
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
|
||||
|
|
@ -2138,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 */
|
||||
|
|
@ -2149,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))
|
||||
|
|
@ -2206,6 +2228,7 @@ done_searches:
|
|||
int
|
||||
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;
|
||||
|
|
@ -2241,7 +2264,7 @@ calmaWritePaintFuncZ(
|
|||
/* 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);
|
||||
|
|
@ -2482,6 +2505,7 @@ calmaWriteLabelFuncZ(
|
|||
int
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
* 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"
|
||||
|
||||
|
|
@ -97,4 +97,4 @@ 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"
|
||||
|
|
@ -274,4 +274,4 @@ extern Plane **cifCurReadPlanes;
|
|||
extern HashTable CifCellTable;
|
||||
extern Plane *cifEditCellPlanes[];
|
||||
|
||||
#endif /* _CALMAINT_H */
|
||||
#endif /* _MAGIC__CALMA__CALMAINT_H */
|
||||
|
|
|
|||
394
cif/CIFgen.c
394
cif/CIFgen.c
File diff suppressed because it is too large
Load Diff
|
|
@ -433,15 +433,16 @@ cifHierCopyMaskHints(
|
|||
int
|
||||
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. */
|
||||
|
|
@ -457,8 +458,8 @@ cifHierCopyFunc(
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
@ -473,7 +474,7 @@ cifHierCopyFunc(
|
|||
{
|
||||
if (DBPaintOnPlane(type, pNum))
|
||||
{
|
||||
DBNMPaintPlane(def->cd_planes[pNum], dinfo, &targetRect,
|
||||
DBNMPaintPlane(def->cd_planes[pNum], newdinfo, &targetRect,
|
||||
DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -562,9 +563,11 @@ cifHierCellFunc(
|
|||
int
|
||||
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);
|
||||
|
||||
|
|
@ -572,8 +575,8 @@ cifHierErrorFunc(
|
|||
* 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);
|
||||
|
|
@ -604,6 +607,7 @@ cifHierErrorFunc(
|
|||
int
|
||||
cifHierCheckFunc(
|
||||
Tile *tile, /* Tile containing CIF. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
Plane *plane) /* Plane to check against and modify. */
|
||||
{
|
||||
Rect area;
|
||||
|
|
@ -612,10 +616,10 @@ cifHierCheckFunc(
|
|||
|
||||
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
|
||||
|
|
@ -651,6 +655,7 @@ cifHierCheckFunc(
|
|||
int
|
||||
cifHierTempCheckFunc(
|
||||
Tile *tile, /* Tile containing CIF. */
|
||||
TileType dinfo, /* Information about split tiles */
|
||||
Plane *plane) /* Plane to check against and modify. */
|
||||
{
|
||||
Rect area;
|
||||
|
|
@ -658,7 +663,7 @@ cifHierTempCheckFunc(
|
|||
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);
|
||||
|
|
@ -686,6 +691,7 @@ cifHierTempCheckFunc(
|
|||
int
|
||||
cifHierPaintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* Information about split tiles */
|
||||
Plane *plane) /* Plane in which to paint CIF over tile's
|
||||
* area.
|
||||
*/
|
||||
|
|
@ -693,9 +699,9 @@ cifHierPaintFunc(
|
|||
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);
|
||||
|
|
@ -1067,6 +1073,7 @@ cifHierElementFunc(
|
|||
int
|
||||
cifGrowSliver(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* Split tile information, needs to be handled */
|
||||
Rect *area)
|
||||
{
|
||||
int height, width, expand_up, expand_side;
|
||||
|
|
@ -1127,22 +1134,24 @@ cifGrowSliver(
|
|||
|
||||
int
|
||||
cifHierPaintArrayFunc(
|
||||
Tile *tile)
|
||||
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;
|
||||
}
|
||||
|
|
|
|||
13
cif/CIFint.h
13
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"
|
||||
|
||||
|
|
@ -335,7 +335,7 @@ 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, TreeContext *cxp);
|
||||
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);
|
||||
|
|
@ -346,7 +346,7 @@ 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, Rect *area);
|
||||
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);
|
||||
|
|
@ -367,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,
|
||||
|
|
@ -396,4 +399,4 @@ extern void CIFError(Rect *area, char *message);
|
|||
#define CIF_SOLIDTYPE 1
|
||||
extern TileTypeBitMask CIFSolidBits;
|
||||
|
||||
#endif /* _CIFINT_H */
|
||||
#endif /* _MAGIC__CIF__CIFINT_H */
|
||||
|
|
|
|||
|
|
@ -505,6 +505,7 @@ CIFParseStart(void)
|
|||
|
||||
int cifCheckPaintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData clientData)
|
||||
{
|
||||
return 1;
|
||||
|
|
@ -515,27 +516,28 @@ int cifCheckPaintFunc(
|
|||
int
|
||||
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;
|
||||
|
|
@ -561,6 +563,7 @@ cifCopyPaintFunc(
|
|||
int
|
||||
cifMaskHintFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* Unused, do not support non-manhattan hints */
|
||||
LinkedRect **lrecp)
|
||||
{
|
||||
Rect r;
|
||||
|
|
@ -597,8 +600,9 @@ int
|
|||
CIFPaintCurrent(
|
||||
int filetype)
|
||||
{
|
||||
extern int cifMakeBoundaryFunc(Tile *tile, ClientData clientdata); /* Forward declaration. */
|
||||
extern int cifPaintCurrentFunc(Tile *tile, TileType type); /* 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;
|
||||
|
|
@ -851,9 +855,11 @@ CIFPaintCurrent(
|
|||
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.
|
||||
*/
|
||||
|
|
@ -889,6 +895,7 @@ CIFPaintCurrent(
|
|||
int
|
||||
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. */
|
||||
|
|
@ -968,6 +975,7 @@ cifMakeBoundaryFunc(
|
|||
int
|
||||
cifPaintCurrentFunc(
|
||||
Tile *tile, /* Tile of CIF information. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
TileType type) /* Magic type to be painted. */
|
||||
{
|
||||
Rect area;
|
||||
|
|
@ -1017,7 +1025,7 @@ cifPaintCurrentFunc(
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -338,18 +338,20 @@ CIFPaintWirePath(
|
|||
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(
|
|||
/* 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(
|
|||
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;
|
||||
}
|
||||
|
|
@ -484,11 +488,13 @@ CIFPaintWirePath(
|
|||
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
|
||||
|
|
@ -586,11 +592,13 @@ PaintPolygon(
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
@ -687,7 +695,8 @@ CIFParseWire(void)
|
|||
|
||||
width /= cifReadScale2;
|
||||
savescale = cifReadScale1;
|
||||
if (!CIFParsePath(&pathheadp, 2))
|
||||
pathheadp = CIFParsePath(2);
|
||||
if (pathheadp == NULL)
|
||||
{
|
||||
CIFReadError("wire, but improper path; ignored.\n");
|
||||
CIFSkipToSemi();
|
||||
|
|
@ -797,7 +806,8 @@ CIFParsePoly(void)
|
|||
CIFSkipToSemi();
|
||||
return FALSE;
|
||||
}
|
||||
if (!CIFParsePath(&pathheadp, 1))
|
||||
pathheadp = CIFParsePath(1);
|
||||
if (pathheadp == NULL)
|
||||
{
|
||||
CIFReadError("polygon, but improper path; ignored.\n");
|
||||
CIFSkipToSemi();
|
||||
|
|
@ -817,11 +827,13 @@ CIFParsePoly(void)
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -329,8 +329,10 @@ cifNewReadStyle(void)
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -408,11 +410,13 @@ CIFReadTechInit(void)
|
|||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -276,8 +276,10 @@ CIFScaleCoord(
|
|||
PlowAfterTech();
|
||||
ExtTechScale(1, denom);
|
||||
WireTechScale(1, denom);
|
||||
#ifdef ROUTE_MODULE
|
||||
MZAfterTech();
|
||||
IRAfterTech();
|
||||
#endif
|
||||
#ifdef LEF_MODULE
|
||||
LefTechScale(1, denom);
|
||||
#endif
|
||||
|
|
@ -649,12 +651,11 @@ CIFParsePoint(
|
|||
* 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(
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool
|
||||
CIFPath *
|
||||
CIFParsePath(
|
||||
CIFPath **pathheadpp,
|
||||
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(
|
|||
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(
|
|||
}
|
||||
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(
|
|||
}
|
||||
pathtailp->cifp_next = newpathp;
|
||||
}
|
||||
else *pathheadpp = newpathp;
|
||||
else pathheadp = newpathp;
|
||||
pathtailp = newpathp;
|
||||
}
|
||||
return (*pathheadpp != NULL);
|
||||
return pathheadp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1338,11 +1338,13 @@ void
|
|||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
@ -166,7 +166,7 @@ extern bool CIFParseUser(void);
|
|||
extern bool CIFParseCall(void);
|
||||
extern bool CIFParseTransform(Transform *transformp);
|
||||
extern bool CIFParseInteger(int *valuep);
|
||||
extern bool CIFParsePath(CIFPath **pathheadpp, int iscale);
|
||||
extern CIFPath *CIFParsePath(int iscale);
|
||||
extern bool CIFParsePoint(Point *pointp, int iscale);
|
||||
extern bool CIFParseSInteger(int *valuep);
|
||||
extern void CIFSkipToSemi(void);
|
||||
|
|
@ -221,4 +221,4 @@ extern int cifParseLaChar;
|
|||
? (cifParseLaAvail = FALSE, cifParseLaChar) \
|
||||
: (cifParseLaChar = getc(cifInputFile)))
|
||||
|
||||
#endif /* _CIFREAD_H */
|
||||
#endif /* _MAGIC__CIF__CIFREAD_H */
|
||||
|
|
|
|||
15
cif/CIFsee.c
15
cif/CIFsee.c
|
|
@ -78,6 +78,7 @@ typedef struct {
|
|||
int
|
||||
cifPaintDBFunc(
|
||||
Tile *tile, /* Tile of CIF information. */
|
||||
TileType dinfo,
|
||||
PaintLayerData *pld)
|
||||
{
|
||||
Rect area;
|
||||
|
|
@ -106,7 +107,7 @@ cifPaintDBFunc(
|
|||
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);
|
||||
}
|
||||
|
||||
|
|
@ -219,6 +220,7 @@ CIFPaintLayer(
|
|||
int
|
||||
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(
|
|||
(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;
|
||||
}
|
||||
|
||||
|
|
@ -438,9 +440,11 @@ CIFCoverageLayer(
|
|||
SearchContext scx;
|
||||
TileTypeBitMask mask, depend;
|
||||
float fcover;
|
||||
int cifCoverageFunc(Tile *tile, ClientData *arg);
|
||||
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;
|
||||
|
|
@ -512,6 +516,7 @@ CIFCoverageLayer(
|
|||
int
|
||||
cifCoverageFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData *arg)
|
||||
{
|
||||
coverstats *cstats = (coverstats *)arg;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ cifTechFreeStyle(void)
|
|||
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)
|
||||
|
|
@ -120,8 +121,9 @@ cifTechFreeStyle(void)
|
|||
break;
|
||||
}
|
||||
}
|
||||
freeMagic((char *)op);
|
||||
freeMagic1(&mm1, (char *)op);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
freeMagic((char *)layer);
|
||||
}
|
||||
}
|
||||
|
|
@ -234,7 +236,7 @@ cifParseLayers(
|
|||
*/
|
||||
{
|
||||
TileTypeBitMask curCifMask, curPaintMask;
|
||||
char curLayer[40], *p, *cp;
|
||||
char curLayer[512], *p, *cp;
|
||||
TileType paintType;
|
||||
int i;
|
||||
bool allResidues;
|
||||
|
|
@ -246,6 +248,10 @@ cifParseLayers(
|
|||
{
|
||||
p = curLayer;
|
||||
|
||||
if (*string == '(')
|
||||
while ((*string != ')') && (*string != 0))
|
||||
*p++ = *string++;
|
||||
|
||||
if (*string == '*')
|
||||
{
|
||||
allResidues = TRUE;
|
||||
|
|
@ -263,7 +269,22 @@ cifParseLayers(
|
|||
|
||||
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;
|
||||
|
|
@ -299,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");
|
||||
|
|
@ -369,11 +390,13 @@ CIFTechInit(void)
|
|||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
@ -794,7 +817,7 @@ CIFTechLine(
|
|||
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;
|
||||
|
|
@ -1758,7 +1781,8 @@ cifComputeHalo(
|
|||
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",
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
|||
/* Forward declarations */
|
||||
extern int cifWriteInitFunc(CellDef *def);
|
||||
extern int cifWriteMarkFunc(CellUse *use);
|
||||
extern int cifWritePaintFunc(Tile *tile, FILE *f);
|
||||
extern int cifWriteLabelFunc(Tile *tile, FILE *f);
|
||||
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);
|
||||
|
|
@ -584,6 +584,7 @@ cifWriteUseFunc(
|
|||
int
|
||||
cifWriteLabelFunc(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
FILE *f) /* File in which to write. */
|
||||
{
|
||||
Rect r;
|
||||
|
|
@ -643,7 +644,8 @@ cifWriteLabelFunc(
|
|||
int
|
||||
cifWritePaintFunc(
|
||||
Tile *tile, /* Tile to be written out. */
|
||||
FILE *f) /* File in which to write. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
FILE *f) /* File in which to write. */
|
||||
{
|
||||
Rect r;
|
||||
|
||||
|
|
@ -662,7 +664,7 @@ cifWritePaintFunc(
|
|||
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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
@ -95,4 +95,4 @@ extern LinkedRect *PaintPolygon(Point *pointlist, int number, Plane *plane, Pain
|
|||
/* C99 compat */
|
||||
extern int CIFGetContactSize(TileType type, int *edge, int *spacing, int *border);
|
||||
|
||||
#endif /* _CIF_H */
|
||||
#endif /* _MAGIC__CIF__CIF_H */
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
@ -81,4 +81,4 @@ extern bool CMWCheckWritten(void);
|
|||
extern void CMWinit(void);
|
||||
|
||||
|
||||
#endif /* _CMWIND_H */
|
||||
#endif /* _MAGIC__CMWIND__CMWIND_H */
|
||||
|
|
|
|||
222
commands/CmdAB.c
222
commands/CmdAB.c
|
|
@ -81,6 +81,70 @@ CmdAddPath(
|
|||
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 */
|
||||
|
||||
|
|
@ -274,14 +338,17 @@ CmdArray(
|
|||
case ARRAY_WIDTH:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *xsepvalue;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
xsepvalue = DBWPrintValue(la->arrayInfo.ar_xsep,
|
||||
w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_xsep));
|
||||
Tcl_NewStringObj(xsepvalue, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -291,7 +358,7 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("x separation %d\n", la->arrayInfo.ar_xsep);
|
||||
TxPrintf("x separation %s\n", xsepvalue);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -310,14 +377,17 @@ CmdArray(
|
|||
case ARRAY_HEIGHT:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *ysepvalue;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
ysepvalue = DBWPrintValue(la->arrayInfo.ar_ysep,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_ysep));
|
||||
Tcl_NewStringObj(ysepvalue, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -327,7 +397,7 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("y separation %d\n", la->arrayInfo.ar_ysep);
|
||||
TxPrintf("y separation %s\n", ysepvalue);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -346,16 +416,21 @@ CmdArray(
|
|||
case ARRAY_PITCH:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *xpitch, *ypitch;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
xpitch = DBWPrintValue(la->arrayInfo.ar_xsep,
|
||||
w, TRUE);
|
||||
ypitch = DBWPrintValue(la->arrayInfo.ar_ysep,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_xsep));
|
||||
Tcl_NewStringObj(xpitch, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->arrayInfo.ar_ysep));
|
||||
Tcl_NewStringObj(ypitch, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -365,8 +440,8 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("x separation %d ", la->arrayInfo.ar_xsep);
|
||||
TxPrintf("y separation %d\n", la->arrayInfo.ar_ysep);
|
||||
TxPrintf("x separation %s ", xpitch);
|
||||
TxPrintf("y separation %s\n", ypitch);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -386,16 +461,21 @@ CmdArray(
|
|||
case ARRAY_POSITION:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *xpos, *ypos;
|
||||
for (la = lahead; la != NULL; la = la->ar_next)
|
||||
{
|
||||
xpos = DBWPrintValue(la->cellUse->cu_bbox.r_xbot,
|
||||
w, TRUE);
|
||||
ypos = DBWPrintValue(la->cellUse->cu_bbox.r_ybot,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (doList)
|
||||
{
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->cellUse->cu_bbox.r_xbot));
|
||||
Tcl_NewStringObj(xpos, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewIntObj(la->cellUse->cu_bbox.r_ybot));
|
||||
Tcl_NewStringObj(ypos, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
}
|
||||
else
|
||||
|
|
@ -405,8 +485,8 @@ CmdArray(
|
|||
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
|
||||
else
|
||||
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
|
||||
TxPrintf("x=%d ", la->cellUse->cu_bbox.r_xbot);
|
||||
TxPrintf("y=%d\n", la->cellUse->cu_bbox.r_ybot);
|
||||
TxPrintf("x=%s ", xpos);
|
||||
TxPrintf("y=%s\n", ypos);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
}
|
||||
#endif
|
||||
|
|
@ -466,11 +546,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;
|
||||
}
|
||||
|
|
@ -806,13 +890,16 @@ CmdBox(
|
|||
TxRebuildCommand(cmd);
|
||||
return;
|
||||
}
|
||||
else if (DBWSnapToGrid != DBW_SNAP_USER)
|
||||
else if (DBWUnits != DBW_UNITS_USER)
|
||||
{
|
||||
distancex = cmdParseCoord(w, cmd->tx_argv[3], TRUE, FALSE);
|
||||
distancey = distancex;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* For user units, the distance may be different in the X and Y
|
||||
* directions for a given value.
|
||||
*/
|
||||
switch (direction)
|
||||
{
|
||||
case GEO_EAST: case GEO_WEST:
|
||||
|
|
@ -840,15 +927,14 @@ CmdBox(
|
|||
case BOX_WIDTH:
|
||||
if (argc == 2)
|
||||
{
|
||||
char *boxvalues;
|
||||
boxvalues = DBWPrintValue(boxptr->r_xtop - boxptr->r_xbot,
|
||||
w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d",
|
||||
boxptr->r_xtop - boxptr->r_xbot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(boxvalues, -1));
|
||||
#else
|
||||
TxPrintf("%s box width is %d\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xtop - boxptr->r_xbot);
|
||||
TxPrintf("%s box width is %s\n", (refEdit) ? "Edit" : "Root",
|
||||
boxvalues);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -860,15 +946,14 @@ CmdBox(
|
|||
case BOX_HEIGHT:
|
||||
if (argc == 2)
|
||||
{
|
||||
char *boxvalues;
|
||||
boxvalues = DBWPrintValue(boxptr->r_ytop - boxptr->r_ybot,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d",
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(boxvalues, -1));
|
||||
#else
|
||||
TxPrintf("%s box height is %d\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
TxPrintf("%s box height is %s\n", (refEdit) ? "Edit" : "Root",
|
||||
boxvalues);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -881,16 +966,24 @@ CmdBox(
|
|||
if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d %d",
|
||||
boxptr->r_xtop - boxptr->r_xbot,
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
char *boxvaluex, *boxvaluey;
|
||||
boxvaluex = DBWPrintValue(boxptr->r_xtop - boxptr->r_xbot,
|
||||
w, TRUE);
|
||||
boxvaluey = DBWPrintValue(boxptr->r_ytop - boxptr->r_ybot,
|
||||
w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluex, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluey, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s box size is %d x %d\n",
|
||||
TxPrintf("%s box size is %s x %s\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xtop - boxptr->r_xbot,
|
||||
boxptr->r_ytop - boxptr->r_ybot);
|
||||
boxvaluex, boxvaluey);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -905,14 +998,22 @@ CmdBox(
|
|||
if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d %d",
|
||||
boxptr->r_xbot, boxptr->r_ybot);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
char *boxvaluex, *boxvaluey;
|
||||
boxvaluex = DBWPrintValue(boxptr->r_xbot, w, TRUE);
|
||||
boxvaluey = DBWPrintValue(boxptr->r_ybot, w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluex, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluey, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s box lower-left corner at (%d, %d)\n",
|
||||
TxPrintf("%s box lower-left corner at (%s, %s)\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xbot, boxptr->r_ybot);
|
||||
boxvaluex, boxvaluey);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -944,16 +1045,31 @@ CmdBox(
|
|||
if (argc == 2)
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *boxvalues = (char *)Tcl_Alloc(50);
|
||||
sprintf(boxvalues, "%d %d %d %d",
|
||||
boxptr->r_xbot, boxptr->r_ybot,
|
||||
boxptr->r_xtop, boxptr->r_ytop);
|
||||
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
|
||||
Tcl_Obj *tobj;
|
||||
#endif
|
||||
char *boxvaluellx, *boxvaluelly;
|
||||
char *boxvalueurx, *boxvalueury;
|
||||
|
||||
boxvaluellx = DBWPrintValue(boxptr->r_xbot, w, TRUE);
|
||||
boxvaluelly = DBWPrintValue(boxptr->r_ybot, w, FALSE);
|
||||
boxvalueurx = DBWPrintValue(boxptr->r_xtop, w, TRUE);
|
||||
boxvalueury = DBWPrintValue(boxptr->r_ytop, w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluellx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvaluelly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvalueurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj(boxvalueury, -1));
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s box coordinates (%d, %d) to (%d, %d)\n",
|
||||
TxPrintf("%s box coordinates (%s, %s) to (%s, %s)\n",
|
||||
(refEdit) ? "Edit" : "Root",
|
||||
boxptr->r_xbot, boxptr->r_ybot,
|
||||
boxptr->r_xtop, boxptr->r_ytop);
|
||||
boxvaluellx, boxvaluelly, boxvalueurx, boxvalueury);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
373
commands/CmdCD.c
373
commands/CmdCD.c
|
|
@ -24,6 +24,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tcltk/tclmagic.h"
|
||||
#include "utils/magic.h"
|
||||
|
|
@ -36,6 +37,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
|||
#include "utils/main.h"
|
||||
#include "commands/commands.h"
|
||||
#include "utils/utils.h"
|
||||
#include "utils/magic_zlib.h"
|
||||
#include "textio/textio.h"
|
||||
#include "drc/drc.h"
|
||||
#include "graphics/graphics.h"
|
||||
|
|
@ -429,7 +431,7 @@ CmdCalma(
|
|||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewDoubleObj((double)CalmaMagScale));
|
||||
#else
|
||||
TxPrintf("Text magnification 1.0 = %g microns.\n");
|
||||
TxPrintf("Text magnification 1.0 = %g microns.\n", (double)CalmaMagScale);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -742,7 +744,7 @@ CmdCalma(
|
|||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaNoDuplicates));
|
||||
#else
|
||||
TxPrintf("Cell defs that exist before reading GDS will not be paresd.\n",
|
||||
TxPrintf("Cell defs that exist before reading GDS will %sbe parsed.\n",
|
||||
(CalmaNoDuplicates) ? "not " : "");
|
||||
#endif
|
||||
return;
|
||||
|
|
@ -762,7 +764,7 @@ CmdCalma(
|
|||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaUnique));
|
||||
#else
|
||||
TxPrintf("Cell defs that exist before reading GDS will be renamed.\n",
|
||||
TxPrintf("Cell defs that exist before reading GDS will %sbe renamed.\n",
|
||||
(CalmaUnique) ? "not " : "");
|
||||
#endif
|
||||
return;
|
||||
|
|
@ -2394,8 +2396,10 @@ CmdContact(
|
|||
CCStruct ccs;
|
||||
Rect area;
|
||||
LinkedRect *lr = NULL;
|
||||
int cmdContactFunc(Tile *tile, CCStruct *ccs); /* Forward declaration */
|
||||
int cmdContactEraseFunc(Tile *tile, LinkedRect **lr); /* Forward declaration */
|
||||
|
||||
/* Forward declarations */
|
||||
int cmdContactFunc(Tile *tile, TileType dinfo, CCStruct *ccs);
|
||||
int cmdContactEraseFunc(Tile *tile, TileType dinfo, LinkedRect **lr);
|
||||
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID))
|
||||
|
|
@ -2453,6 +2457,7 @@ CmdContact(
|
|||
|
||||
rmask = DBResidueMask(type);
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (lr != NULL)
|
||||
{
|
||||
GeoClip(&lr->r_r, &area);
|
||||
|
|
@ -2463,9 +2468,10 @@ CmdContact(
|
|||
if (TTMaskHasType(rmask, rtype))
|
||||
DBPaint(EditCellUse->cu_def, &lr->r_r, rtype);
|
||||
|
||||
freeMagic(lr);
|
||||
freeMagic1(&mm1, lr);
|
||||
lr = lr->r_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
/* Refresh the layout drawing */
|
||||
DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask);
|
||||
|
|
@ -2502,14 +2508,16 @@ CmdContact(
|
|||
DBSrPaintArea((Tile *) NULL, EditCellUse->cu_def->cd_planes[DBPlane(rtype)],
|
||||
&area, &smask, cmdContactFunc, (ClientData) &ccs);
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (ccs.lhead != NULL)
|
||||
{
|
||||
TTMaskSetOnlyType(&smask, type);
|
||||
TTMaskAndMask(&smask, &DBActiveLayerBits);
|
||||
DBPaintMask(EditCellUse->cu_def, &ccs.lhead->r_r, &smask);
|
||||
freeMagic(ccs.lhead);
|
||||
freeMagic1(&mm1, ccs.lhead);
|
||||
ccs.lhead = ccs.lhead->r_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
/* Refresh the layout drawing */
|
||||
DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask);
|
||||
|
|
@ -2525,11 +2533,14 @@ CmdContact(
|
|||
int
|
||||
cmdContactFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
CCStruct *ccs)
|
||||
{
|
||||
TileType stype;
|
||||
TileTypeBitMask smask;
|
||||
int cmdContactFunc2(Tile *tile, CCStruct *ccs); /* Forward declaration */
|
||||
|
||||
/* Forward declaration */
|
||||
int cmdContactFunc2(Tile *tile, TileType dinfo, CCStruct *ccs);
|
||||
|
||||
TiToRect(tile, &ccs->area);
|
||||
GeoClip(&ccs->area, &ccs->clip);
|
||||
|
|
@ -2539,14 +2550,16 @@ cmdContactFunc(
|
|||
break;
|
||||
|
||||
TTMaskSetOnlyType(&smask, stype);
|
||||
DBSrPaintArea((Tile *) NULL, ccs->rootDef->cd_planes[DBPlane(stype)],
|
||||
&ccs->area, &smask, cmdContactFunc2, (ClientData)ccs);
|
||||
DBSrPaintNMArea((Tile *)NULL, ccs->rootDef->cd_planes[DBPlane(stype)],
|
||||
TiGetTypeExact(tile) | dinfo, &ccs->area, &smask,
|
||||
cmdContactFunc2, (ClientData)ccs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
cmdContactFunc2(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* (unused) */
|
||||
CCStruct *ccs)
|
||||
{
|
||||
LinkedRect *newlr;
|
||||
|
|
@ -2569,6 +2582,7 @@ cmdContactFunc2(
|
|||
int
|
||||
cmdContactEraseFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* (unused) */
|
||||
LinkedRect **lr)
|
||||
{
|
||||
LinkedRect *newlr;
|
||||
|
|
@ -2822,14 +2836,15 @@ CmdCorner(
|
|||
TileTypeBitMask maskBits;
|
||||
Rect editBox;
|
||||
SearchContext scx;
|
||||
extern int cmdCornerFunc(Tile *tile, TreeContext *cxp);
|
||||
bool hasErr = FALSE;
|
||||
int locargc = cmd->tx_argc;
|
||||
|
||||
extern int cmdBevelFunc(Tile *tile, TreeContext *cxp);
|
||||
bool dobevel = FALSE;
|
||||
NMCornerPath cmdPathList;
|
||||
|
||||
/* Forward declarations */
|
||||
extern int cmdCornerFunc(Tile *tile, TileType dinfo, TreeContext *cxp);
|
||||
extern int cmdBevelFunc(Tile *tile, TileType dinfo, TreeContext *cxp);
|
||||
|
||||
if (cmd->tx_argc < 3 || cmd->tx_argc > 5)
|
||||
{
|
||||
TxError("Usage: %s direction1 direction2 [layers]\n",
|
||||
|
|
@ -2950,14 +2965,22 @@ CmdCorner(
|
|||
|
||||
rectp = CIFPolyToRects(cmdPathList.pathlist->pathhead, plane,
|
||||
resultTbl, &ui, FALSE);
|
||||
for (; rectp != NULL; rectp = rectp->r_next)
|
||||
{
|
||||
DBPaintPlane(plane, &rectp->r_r, resultTbl, &ui);
|
||||
freeMagic((char *)rectp);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (; rectp != NULL; rectp = rectp->r_next)
|
||||
{
|
||||
DBPaintPlane(plane, &rectp->r_r, resultTbl, &ui);
|
||||
freeMagic1(&mm1, (char *)rectp);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
CIFFreePath(cmdPathList.pathlist->pathhead);
|
||||
freeMagic((char *)cmdPathList.pathlist);
|
||||
cmdPathList.pathlist = cmdPathList.pathlist->cpl_next;
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, (char *)cmdPathList.pathlist);
|
||||
cmdPathList.pathlist = cmdPathList.pathlist->cpl_next;
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2975,14 +2998,16 @@ CmdCorner(
|
|||
/* 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 (cmdCornerList != NULL)
|
||||
{
|
||||
DBPaint(EditCellUse->cu_def, &cmdCornerList->cca_area,
|
||||
cmdCornerList->cca_type);
|
||||
freeMagic((char *) cmdCornerList);
|
||||
freeMagic1(&mm1, (char *) cmdCornerList);
|
||||
cmdCornerList = cmdCornerList->cca_next;
|
||||
}
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
SelectClear();
|
||||
DBAdjustLabels(EditCellUse->cu_def, &editBox);
|
||||
|
|
@ -3014,6 +3039,7 @@ CmdCorner(
|
|||
int
|
||||
cmdCornerFunc(
|
||||
Tile *tile, /* Tile to fill with. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
TreeContext *cxp) /* Describes state of search. */
|
||||
{
|
||||
Rect r1, r2, r3;
|
||||
|
|
@ -3180,6 +3206,7 @@ AddNewPoint(
|
|||
int
|
||||
cmdBevelFunc(
|
||||
Tile *tile, /* Tile to fill with. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
TreeContext *cxp) /* Describes state of search. */
|
||||
{
|
||||
Rect r1, r2, r3;
|
||||
|
|
@ -3641,8 +3668,10 @@ cmdBevelFunc(
|
|||
GeoClip(&r3, &cmdCornerRootBox);
|
||||
if (GEO_RECTNULL(&r2) || GEO_RECTNULL(&r3))
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (pptr = pathhead; pptr != NULL; pptr = pptr->cifp_next)
|
||||
freeMagic((char *)pptr);
|
||||
freeMagic1(&mm1, (char *)pptr);
|
||||
freeMagic1_end(&mm1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3676,7 +3705,7 @@ cmdBevelFunc(
|
|||
* Save cells to or recover cells from a crash backup file
|
||||
*
|
||||
* Usage:
|
||||
* crash save|recover [file]
|
||||
* crash save|recover|archive|read [file]
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -3711,7 +3740,7 @@ CmdCrash(
|
|||
|
||||
switch(option) {
|
||||
case 0: /* save */
|
||||
DBWriteBackup(filename);
|
||||
DBWriteBackup(filename, FALSE, FALSE);
|
||||
break;
|
||||
case 1: /* recover */
|
||||
DBFileRecovery(filename);
|
||||
|
|
@ -4152,6 +4181,7 @@ CmdDrc(
|
|||
|
||||
rootUse = (CellUse *) window->w_surfaceID;
|
||||
dcl = DRCCount(rootUse, &rootArea, doforall);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (dcl != NULL)
|
||||
{
|
||||
if (count_total >= 0)
|
||||
|
|
@ -4181,9 +4211,10 @@ CmdDrc(
|
|||
}
|
||||
#endif
|
||||
}
|
||||
freeMagic((char *)dcl);
|
||||
freeMagic1(&mm1, (char *)dcl);
|
||||
dcl = dcl->dcl_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if ((count_total >= 0) || (!dolist))
|
||||
|
|
@ -4306,6 +4337,8 @@ CmdDrc(
|
|||
#endif
|
||||
TxPrintf("Error area #%d:\n", result);
|
||||
if (DRCWhy(dolist, rootUse, &area, findonly)) break;
|
||||
/* Check for interrupt or this will go into an infinite loop */
|
||||
else if (SigInterruptPending) break;
|
||||
drc_nth++;
|
||||
}
|
||||
else if (result < 0)
|
||||
|
|
@ -4332,12 +4365,14 @@ CmdDrc(
|
|||
}
|
||||
if (findonly)
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
/* Delete temporary rules */
|
||||
while (DRCIgnoreRules != NULL)
|
||||
{
|
||||
freeMagic(DRCIgnoreRules);
|
||||
freeMagic1(&mm1, DRCIgnoreRules);
|
||||
DRCIgnoreRules = DRCIgnoreRules->li_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
/* Replace temporary set of rules */
|
||||
DRCIgnoreRules = DRCSaveRules;
|
||||
}
|
||||
|
|
@ -4420,8 +4455,10 @@ CmdDrc(
|
|||
{
|
||||
while (DRCIgnoreRules != NULL)
|
||||
{
|
||||
freeMagic(DRCIgnoreRules);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, DRCIgnoreRules);
|
||||
DRCIgnoreRules = DRCIgnoreRules->li_next;
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -4559,6 +4596,7 @@ CmdDrc(
|
|||
int
|
||||
cmdDropPaintCell(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
TreeContext *cxp)
|
||||
{
|
||||
CellDef *cellDef = cxp->tc_scx->scx_use->cu_def;
|
||||
|
|
@ -4567,7 +4605,7 @@ cmdDropPaintCell(
|
|||
TileType type;
|
||||
Rect area;
|
||||
|
||||
if (SplitSide(tile))
|
||||
if (dinfo & TT_SIDE)
|
||||
type = SplitRightType(tile);
|
||||
else
|
||||
type = SplitLeftType(tile);
|
||||
|
|
@ -4600,6 +4638,7 @@ cmdDropPaintCell(
|
|||
int
|
||||
cmdDropFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData clientData)
|
||||
{
|
||||
TileTypeBitMask tMask, *lMask = (TileTypeBitMask *)clientData;
|
||||
|
|
@ -4610,7 +4649,7 @@ cmdDropFunc(
|
|||
scx.scx_use = EditCellUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
|
||||
if (SplitSide(tile))
|
||||
if (dinfo & TT_SIDE)
|
||||
type = SplitRightType(tile);
|
||||
else
|
||||
type = SplitLeftType(tile);
|
||||
|
|
@ -4763,9 +4802,10 @@ CmdDrop(
|
|||
* Usage:
|
||||
* dump cellName [child refPointChild] [parent refPointParent]
|
||||
*
|
||||
* where the refPoints are either a label name, e.g., SOCKET_A, or an x-y
|
||||
* pair of integers, e.g., 100 200. The words "child" and "parent" are
|
||||
* keywords, and may be abbreviated.
|
||||
* where the refPoints are either "label" and a label name, e.g.,
|
||||
* "label SOCKET_A", a corner position, e.g., "ur", or an x-y pair of
|
||||
* coordinates, e.g., "100 200", or "1um 5um". The words "child",
|
||||
* "parent", and "label" are keywords, and may be abbreviated.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
|
|
@ -4971,18 +5011,40 @@ cmdDumpParseArgs(
|
|||
* points weren't provided. (Lower-left of the box tool is interpreted
|
||||
* in root coordinates).
|
||||
*/
|
||||
// getcell cellname child 0 0 parent ll v 0 0
|
||||
|
||||
/*
|
||||
* Examples: getcell cellname v child 0 0 parent ll
|
||||
* getcell cellname child 0 0 parent 1um 1um
|
||||
* getcell cellname child 0 0
|
||||
* getcell cellname 90v child label VDD
|
||||
* etc.
|
||||
*/
|
||||
|
||||
av = &cmd->tx_argv[2];
|
||||
ac = cmd->tx_argc - 2;
|
||||
hasChild = hasRoot = hasTrans = FALSE;
|
||||
while (ac > 0)
|
||||
{
|
||||
static const char * const kwdNames[] = { "child", "parent", "0", "90", "180", "270",
|
||||
"v", "0v", "90v", "180v", "270v",
|
||||
"h", "0h", "90h", "180h", "270h", 0 };
|
||||
static const char * const refPointNames[] = { "ll", "lr", "ul", "ur", 0 };
|
||||
static const char * const kwdNames[] = { "child", "parent",
|
||||
"0", "90", "180", "270",
|
||||
"v", "0v", "90v", "180v", "270v",
|
||||
"h", "0h", "90h", "180h", "270h", 0 };
|
||||
typedef enum {
|
||||
IDX_CHILD, IDX_PARENT,
|
||||
IDX_ZERO, IDX_90, IDX_180, IDX_270,
|
||||
IDX_VERT, IDX_ZERO_VERT, IDX_90_VERT, IDX_180_VERT, IDX_270_VERT,
|
||||
IDX_HORZ, IDX_ZERO_HORZ, IDX_90_HORZ, IDX_180_HORZ, IDX_270_HORZ
|
||||
} optionType;
|
||||
|
||||
static const char * const refPointNames[] = {
|
||||
"ll", "lr", "ul", "ur", "label", 0 };
|
||||
typedef enum {
|
||||
IDX_LL, IDX_LR, IDX_UL, IDX_UR, IDX_LABEL
|
||||
} refPointType;
|
||||
|
||||
Label *lab;
|
||||
int n,p;
|
||||
int n, p;
|
||||
Point locp;
|
||||
|
||||
n = Lookup(av[0], kwdNames);
|
||||
if (n < 0)
|
||||
|
|
@ -4992,130 +5054,143 @@ cmdDumpParseArgs(
|
|||
}
|
||||
switch (n)
|
||||
{
|
||||
case 0: /* Child */
|
||||
case IDX_CHILD: /* "child" */
|
||||
if (ac < 2)
|
||||
{
|
||||
TxError("Keyword must be followed by a reference point\n");
|
||||
goto usage;
|
||||
}
|
||||
//else if (ac == 3) # error case: getcell cellname child 0 0 parent ll -> (ac > 3) -> read 0 as label
|
||||
else if (ac >= 3 && StrIsInt(av[1]) && StrIsInt(av[2]))
|
||||
{
|
||||
childPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE);
|
||||
childPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE);
|
||||
av += 3;
|
||||
ac -= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = Lookup(av[1], refPointNames);
|
||||
if (p == 0) /* lower left */
|
||||
if (p == IDX_LL) /* lower left */
|
||||
{
|
||||
childPoint.p_x = bbox.r_ll.p_x;
|
||||
childPoint.p_y = bbox.r_ll.p_y;
|
||||
}
|
||||
else if (p == 1) /* lower right */
|
||||
else if (p == IDX_LR) /* lower right */
|
||||
{
|
||||
childPoint.p_x = bbox.r_ur.p_x;
|
||||
childPoint.p_y = bbox.r_ll.p_y;
|
||||
}
|
||||
else if (p == 2) /* upper left */
|
||||
else if (p == IDX_UL) /* upper left */
|
||||
{
|
||||
childPoint.p_x = bbox.r_ll.p_x;
|
||||
childPoint.p_y = bbox.r_ur.p_y;
|
||||
}
|
||||
else if (p == 3) /* upper right */
|
||||
else if (p == IDX_UR) /* upper right */
|
||||
{
|
||||
childPoint.p_x = bbox.r_ur.p_x;
|
||||
childPoint.p_y = bbox.r_ur.p_y;
|
||||
}
|
||||
else
|
||||
else if ((p == IDX_LABEL) && (ac >= 3)) /* label */
|
||||
{
|
||||
childPoint = TiPlaneRect.r_ur;
|
||||
(void) DBSrLabelLoc(dummy, av[1], cmdDumpFunc,
|
||||
(void) DBSrLabelLoc(dummy, av[2], cmdDumpFunc,
|
||||
&childPoint);
|
||||
if (childPoint.p_x == TiPlaneRect.r_xtop &&
|
||||
childPoint.p_y == TiPlaneRect.r_ytop)
|
||||
{
|
||||
TxError("Couldn't find label \"%s\" in cell \"%s\".\n",
|
||||
av[1], cmd->tx_argv[1]);
|
||||
av[2], cmd->tx_argv[1]);
|
||||
return FALSE;
|
||||
}
|
||||
av += 1;
|
||||
ac -= 1;
|
||||
}
|
||||
else if (ac >= 3) /* Coordinate pair */
|
||||
{
|
||||
childPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE);
|
||||
childPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE);
|
||||
av += 1;
|
||||
ac -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
TxError("Must provide two valid coordinates\n");
|
||||
goto usage;
|
||||
}
|
||||
av += 2;
|
||||
ac -= 2;
|
||||
}
|
||||
hasChild = TRUE;
|
||||
break;
|
||||
case 1: /* Parent */
|
||||
|
||||
case IDX_PARENT: /* "parent" */
|
||||
if (ac < 2)
|
||||
{
|
||||
TxError("Keyword must be followed by a reference point\n");
|
||||
goto usage;
|
||||
}
|
||||
//else if (ac == 3) # error case: getcell cellname child 0 0 parent ll v 0 0 -> (ac > 3) -> read 0 as label
|
||||
else if (ac >= 3 && StrIsInt(av[1]) && StrIsInt(av[2]))
|
||||
{
|
||||
editPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE);
|
||||
editPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE);
|
||||
av += 3;
|
||||
ac -= 3;
|
||||
GeoTransPoint(&EditToRootTransform, &editPoint,
|
||||
&rootPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
p = Lookup(av[1], refPointNames);
|
||||
if (p == 0) /* lower left */
|
||||
if (p == IDX_LL) /* lower left */
|
||||
{
|
||||
if (!ToolGetBox(&rootDef, &rootBox) ||
|
||||
(rootDef != EditRootDef)) goto box_error;
|
||||
rootPoint.p_x = rootBox.r_ll.p_x;
|
||||
rootPoint.p_y = rootBox.r_ll.p_y;
|
||||
}
|
||||
else if (p == 1) /* lower right */
|
||||
else if (p == IDX_LR) /* lower right */
|
||||
{
|
||||
if (!ToolGetBox(&rootDef, &rootBox) ||
|
||||
(rootDef != EditRootDef)) goto box_error;
|
||||
rootPoint.p_x = rootBox.r_ur.p_x;
|
||||
rootPoint.p_y = rootBox.r_ll.p_y;
|
||||
}
|
||||
else if (p == 2) /* upper left */
|
||||
else if (p == IDX_UL) /* upper left */
|
||||
{
|
||||
if (!ToolGetBox(&rootDef, &rootBox) ||
|
||||
(rootDef != EditRootDef)) goto box_error;
|
||||
rootPoint.p_x = rootBox.r_ll.p_x;
|
||||
rootPoint.p_y = rootBox.r_ur.p_y;
|
||||
}
|
||||
else if (p == 3) /* upper right */
|
||||
else if (p == IDX_UR) /* upper right */
|
||||
{
|
||||
if (!ToolGetBox(&rootDef, &rootBox) ||
|
||||
(rootDef != EditRootDef)) goto box_error;
|
||||
rootPoint.p_x = rootBox.r_ur.p_x;
|
||||
rootPoint.p_y = rootBox.r_ur.p_y;
|
||||
}
|
||||
else
|
||||
else if ((p == IDX_LABEL) && (ac >= 3)) /* label */
|
||||
{
|
||||
for (lab = editDef->cd_labels; lab; lab = lab->lab_next)
|
||||
if (strcmp(lab->lab_text, av[1]) == 0)
|
||||
if (strcmp(lab->lab_text, av[2]) == 0)
|
||||
break;
|
||||
|
||||
if (lab == NULL)
|
||||
{
|
||||
TxError("Couldn't find label \"%s\" in edit cell.\n",
|
||||
av[1]);
|
||||
av[2]);
|
||||
return FALSE;
|
||||
}
|
||||
editPoint = lab->lab_rect.r_ll;
|
||||
GeoTransPoint(&EditToRootTransform, &editPoint,
|
||||
&rootPoint);
|
||||
av += 1;
|
||||
ac -= 1;
|
||||
}
|
||||
else if (ac >= 3) /* Coordinate pair */
|
||||
{
|
||||
editPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE);
|
||||
editPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE);
|
||||
av += 1;
|
||||
ac -= 1;
|
||||
GeoTransPoint(&EditToRootTransform, &editPoint,
|
||||
&rootPoint);
|
||||
}
|
||||
else
|
||||
{
|
||||
TxError("Must provide two valid coordinates\n");
|
||||
goto usage;
|
||||
}
|
||||
av += 2;
|
||||
ac -= 2;
|
||||
}
|
||||
hasRoot = TRUE;
|
||||
break;
|
||||
case 2: /* 0 */
|
||||
case IDX_ZERO: /* "0" */
|
||||
tx_cell = &GeoIdentityTransform;
|
||||
transform_cell:
|
||||
if (ac < 2 )
|
||||
|
|
@ -5131,109 +5206,117 @@ default_action:
|
|||
}
|
||||
av += 1;
|
||||
ac -= 1;
|
||||
}
|
||||
// error case: getcell cellname v 0 0 -> read 0 in kwdNames -> goto default transform
|
||||
// av[1] = "0", "90", "180", "270" case -> av[1] must mean editpoint coordinate
|
||||
else if (Lookup(av[1], kwdNames)>=0 && Lookup(av[1], kwdNames)!= 2 && strcmp(av[1],"90") && strcmp(av[1],"180") && strcmp(av[1],"270"))
|
||||
}
|
||||
|
||||
/*
|
||||
* Error case:
|
||||
* getcell cellname v 0 0 ->
|
||||
* read 0 in kwdNames
|
||||
* goto default transform
|
||||
* av[1] = "0", "90", "180", "270" case ->
|
||||
* av[1] must mean editpoint coordinate
|
||||
*/
|
||||
|
||||
else if (Lookup(av[1], kwdNames) >= 0 &&
|
||||
Lookup(av[1], kwdNames) != 2 &&
|
||||
strcmp(av[1], "90") &&
|
||||
strcmp(av[1], "180") &&
|
||||
strcmp(av[1], "270"))
|
||||
{
|
||||
goto default_action;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (StrIsInt(av[1]))
|
||||
p = Lookup(av[1], refPointNames);
|
||||
if (p == IDX_LL) /* lower left */
|
||||
{
|
||||
editPoint.p_x = atoi(av[1]);
|
||||
if (ac < 3 || !StrIsInt(av[2]))
|
||||
editPoint.p_x = bbox.r_ll.p_x;
|
||||
editPoint.p_y = bbox.r_ll.p_y;
|
||||
}
|
||||
else if (p == IDX_LR) /* lower right */
|
||||
{
|
||||
editPoint.p_x = bbox.r_ur.p_x;
|
||||
editPoint.p_y = bbox.r_ll.p_y;
|
||||
}
|
||||
else if (p == IDX_UL) /* upper left */
|
||||
{
|
||||
editPoint.p_x = bbox.r_ll.p_x;
|
||||
editPoint.p_y = bbox.r_ur.p_y;
|
||||
}
|
||||
else if (p == IDX_UR) /* upper right */
|
||||
{
|
||||
editPoint.p_x = bbox.r_ur.p_x;
|
||||
editPoint.p_y = bbox.r_ur.p_y;
|
||||
}
|
||||
else if ((p == IDX_LABEL) && (ac >= 3)) /* label */
|
||||
{
|
||||
editPoint = TiPlaneRect.r_ur;
|
||||
(void) DBSrLabelLoc(dummy, av[1], cmdDumpFunc, &editPoint);
|
||||
if (editPoint.p_x == TiPlaneRect.r_xtop &&
|
||||
editPoint.p_y == TiPlaneRect.r_ytop)
|
||||
{
|
||||
TxError("Must provide two coordinates\n");
|
||||
goto usage;
|
||||
TxError("Couldn't find label \"%s\" in cell \"%s\".\n",
|
||||
av[1], cmd->tx_argv[1]);
|
||||
return FALSE;
|
||||
}
|
||||
editPoint.p_y = atoi(av[2]);
|
||||
av += 3;
|
||||
ac -= 3;
|
||||
av += 1;
|
||||
ac -= 1;
|
||||
}
|
||||
else if (ac >= 3) /* Coordinate pair */
|
||||
{
|
||||
editPoint.p_x = cmdParseCoord(w, av[1], TRUE, TRUE);
|
||||
editPoint.p_y = cmdParseCoord(w, av[2], TRUE, FALSE);
|
||||
av += 1;
|
||||
ac -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = Lookup(av[1], refPointNames);
|
||||
if (p == 0) /* lower left */
|
||||
{
|
||||
editPoint.p_x = bbox.r_ll.p_x;
|
||||
editPoint.p_y = bbox.r_ll.p_y;
|
||||
}
|
||||
else if (p == 1) /* lower right */
|
||||
{
|
||||
editPoint.p_x = bbox.r_ur.p_x;
|
||||
editPoint.p_y = bbox.r_ll.p_y;
|
||||
}
|
||||
else if (p == 2) /* upper left */
|
||||
{
|
||||
editPoint.p_x = bbox.r_ll.p_x;
|
||||
editPoint.p_y = bbox.r_ur.p_y;
|
||||
}
|
||||
else if (p == 3) /* upper right */
|
||||
{
|
||||
editPoint.p_x = bbox.r_ur.p_x;
|
||||
editPoint.p_y = bbox.r_ur.p_y;
|
||||
}
|
||||
else
|
||||
{
|
||||
editPoint = TiPlaneRect.r_ur;
|
||||
(void) DBSrLabelLoc(dummy, av[1], cmdDumpFunc,
|
||||
&editPoint);
|
||||
if (editPoint.p_x == TiPlaneRect.r_xtop &&
|
||||
editPoint.p_y == TiPlaneRect.r_ytop)
|
||||
{
|
||||
TxError("Couldn't find label \"%s\" in cell \"%s\".\n",
|
||||
av[1], cmd->tx_argv[1]);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
av += 2;
|
||||
ac -= 2;
|
||||
TxError("Must provide two valid coordinates\n");
|
||||
goto usage;
|
||||
}
|
||||
{
|
||||
Point p;
|
||||
av += 2;
|
||||
ac -= 2;
|
||||
|
||||
GeoTransPoint(tx_cell, &editPoint, &p);
|
||||
GeoTranslateTrans(tx_cell, editPoint.p_x - p.p_x,
|
||||
editPoint.p_y - p.p_y, &trans_cell);
|
||||
}
|
||||
GeoTransPoint(tx_cell, &editPoint, &locp);
|
||||
GeoTranslateTrans(tx_cell, editPoint.p_x - locp.p_x,
|
||||
editPoint.p_y - locp.p_y,
|
||||
&trans_cell);
|
||||
}
|
||||
hasTrans = TRUE;
|
||||
break;
|
||||
case 3: /* 90 */
|
||||
case IDX_90: /* "90" */
|
||||
tx_cell = &Geo90Transform;
|
||||
goto transform_cell;
|
||||
case 4: /* 180 */
|
||||
case IDX_180: /* "180" */
|
||||
tx_cell = &Geo180Transform;
|
||||
goto transform_cell;
|
||||
case 5: /* 270 */
|
||||
case IDX_270: /* "270" */
|
||||
tx_cell = &Geo270Transform;
|
||||
goto transform_cell;
|
||||
case 6: /* v */
|
||||
case 7: /* 0v */
|
||||
case IDX_VERT: /* "v" */
|
||||
case IDX_ZERO_VERT: /* "0v" */
|
||||
tx_cell = &GeoUpsideDownTransform;
|
||||
goto transform_cell;
|
||||
case 8: /* 90v */
|
||||
case IDX_90_VERT: /* "90v" */
|
||||
tx_cell = &GeoRef45Transform;
|
||||
goto transform_cell;
|
||||
case 9: /* 180v */
|
||||
case IDX_180_VERT: /* "180v" */
|
||||
tx_cell = &GeoSidewaysTransform;
|
||||
goto transform_cell;
|
||||
case 10: /* 270v */
|
||||
case IDX_270_VERT: /* "270v" */
|
||||
tx_cell = &GeoRef135Transform;
|
||||
goto transform_cell;
|
||||
case 11: /* h */
|
||||
case 12: /* 0h */
|
||||
case IDX_HORZ: /* "h" */
|
||||
case IDX_ZERO_HORZ: /* "0h" */
|
||||
tx_cell = &GeoSidewaysTransform;
|
||||
goto transform_cell;
|
||||
case 13: /* 90h */
|
||||
case IDX_90_HORZ: /* "90h" */
|
||||
tx_cell = &GeoRef135Transform;
|
||||
goto transform_cell;
|
||||
case 14: /* 180h */
|
||||
case IDX_180_HORZ: /* "180h" */
|
||||
tx_cell = &GeoUpsideDownTransform;
|
||||
goto transform_cell;
|
||||
case 15: /* 270h */
|
||||
case IDX_270_HORZ: /* "270h" */
|
||||
tx_cell = &GeoRef45Transform;
|
||||
goto transform_cell;
|
||||
}
|
||||
|
|
@ -5293,15 +5376,17 @@ usage:
|
|||
"Usage: %s cellName [child refPointChild] [parent refPointParent]\n",
|
||||
cmdName);
|
||||
TxError(" [transform [refPointTrans]],\n");
|
||||
TxError(" where the refPoints are either a single label name,\n");
|
||||
TxError(" where the refPoints are one of:\n");
|
||||
TxError(
|
||||
" or ll for lower left corner, or lr for lower right corner\n");
|
||||
" 'label' followed by a single label name,\n");
|
||||
TxError(
|
||||
" or ul for upper left corner, or ur for upper right corner\n");
|
||||
" or 'll' for lower left corner, 'lr' for lower right corner,\n");
|
||||
TxError(
|
||||
" or a pair of integer coordinates, and the transform is one of\n");
|
||||
" 'ul' for upper left corner, 'ur' for upper right corner,\n");
|
||||
TxError(
|
||||
" 90, 180, 270, v, 90v, 180v, 270v, h, 90h, 180h, 270h.\n");
|
||||
" or a pair of coordinates. The transform is one of:\n");
|
||||
TxError(
|
||||
" 90, 180, 270, v, 90v, 180v, 270v, h, 90h, 180h, or 270h.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -930,6 +930,7 @@ cmdExpandFunc(
|
|||
#define DORESISTANCE 6
|
||||
#define DOLABELCHECK 7
|
||||
#define DOALIASES 8
|
||||
#define DOUNIQUE 9
|
||||
|
||||
#define LENCLEAR 0
|
||||
#define LENDRIVER 1
|
||||
|
|
@ -977,6 +978,7 @@ CmdExtract(
|
|||
"resistance estimate resistance",
|
||||
"labelcheck check for connections through sticky labels",
|
||||
"aliases output all net name aliases",
|
||||
"unique ensure unique node names during extraction",
|
||||
NULL
|
||||
};
|
||||
static const char * const cmdExtLength[] =
|
||||
|
|
@ -1120,12 +1122,13 @@ CmdExtract(
|
|||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
char *halodisp;
|
||||
halodisp = DBWPrintValue(ExtCurStyle->exts_sideCoupleHalo,
|
||||
w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewIntObj(ExtCurStyle->exts_sideCoupleHalo);
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(halodisp, -1));
|
||||
#else
|
||||
TxPrintf("Side overlap halo is %d\n", ExtCurStyle->exts_sideCoupleHalo);
|
||||
TxPrintf("Side overlap halo is %s\n", halodisp);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -1150,12 +1153,12 @@ CmdExtract(
|
|||
}
|
||||
else if (argc == 2)
|
||||
{
|
||||
char *stepdisp;
|
||||
stepdisp = DBWPrintValue(ExtCurStyle->exts_stepSize, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewIntObj(ExtCurStyle->exts_stepSize);
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(stepdisp, -1));
|
||||
#else
|
||||
TxPrintf("Extraction step size is %d\n", ExtCurStyle->exts_stepSize);
|
||||
TxPrintf("Extraction step size is %s\n", stepdisp);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -1280,6 +1283,7 @@ CmdExtract(
|
|||
TxPrintf("%s resistance\n", OPTSET(EXT_DORESISTANCE));
|
||||
TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK));
|
||||
TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES));
|
||||
TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE));
|
||||
return;
|
||||
#undef OPTSET
|
||||
}
|
||||
|
|
@ -1309,6 +1313,7 @@ CmdExtract(
|
|||
case DORESISTANCE: option = EXT_DORESISTANCE; break;
|
||||
case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
|
||||
case DOALIASES: option = EXT_DOALIASES; break;
|
||||
case DOUNIQUE: option = EXT_DOUNIQUE; break;
|
||||
case DOLOCAL:
|
||||
/* "extract do local" and "extract no local" are kept for
|
||||
* backwards compatibility, but now effectively implement
|
||||
|
|
|
|||
|
|
@ -102,15 +102,17 @@ struct cmdFPArg
|
|||
int
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -507,13 +509,15 @@ struct cmdFillArea *cmdFillList; /* List of areas to fill. */
|
|||
|
||||
void
|
||||
CmdFill(
|
||||
MagWindow *w, /* Window in which command was invoked. */
|
||||
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(Tile *tile, TreeContext *cxp);
|
||||
|
||||
/* Forward declaration */
|
||||
extern int cmdFillFunc(Tile *tile, TileType dinfo, TreeContext *cxp);
|
||||
|
||||
if (cmd->tx_argc < 2 || cmd->tx_argc > 3)
|
||||
{
|
||||
|
|
@ -581,13 +585,15 @@ CmdFill(
|
|||
/* 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);
|
||||
|
|
@ -601,11 +607,16 @@ CmdFill(
|
|||
* 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 *tile, /* Tile to fill with. */
|
||||
TileType dinfo, /* Split tile information (unused) */
|
||||
TreeContext *cxp) /* Describes state of search. */
|
||||
{
|
||||
Rect r1, r2;
|
||||
|
|
@ -841,7 +852,7 @@ CmdFindLabel(
|
|||
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;
|
||||
|
||||
|
|
@ -1208,7 +1219,7 @@ CmdGetnode(
|
|||
TxError("Put the cursor in a layout window\n");
|
||||
return;
|
||||
}
|
||||
if( is_fast == TRUE )
|
||||
if (is_fast == TRUE)
|
||||
{
|
||||
SimRecomputeSel = TRUE;
|
||||
SimGetsnode();
|
||||
|
|
@ -1216,7 +1227,8 @@ CmdGetnode(
|
|||
else
|
||||
SimGetnode();
|
||||
|
||||
if (SimGetnodeAlias) { /* "erase" the hash table */
|
||||
if (SimGetnodeAlias) /* "erase" the hash table */
|
||||
{
|
||||
HashKill(&SimGNAliasTbl);
|
||||
HashInit(&SimGNAliasTbl, 120, STRINGS);
|
||||
}
|
||||
|
|
@ -1602,7 +1614,7 @@ CmdFindNetProc(
|
|||
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;
|
||||
|
|
@ -1640,6 +1652,7 @@ CmdFindNetProc(
|
|||
|
||||
if ((xstr = strchr(s, '_')) != NULL)
|
||||
{
|
||||
char *hashpos;
|
||||
bool isNeg = FALSE;
|
||||
|
||||
/* The characters up to the leading '_' should match one of the */
|
||||
|
|
@ -1683,6 +1696,17 @@ CmdFindNetProc(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1705,17 +1729,23 @@ checklocal:
|
|||
|
||||
if (locvalid == TRUE)
|
||||
{
|
||||
int findTile(Tile *tile, TileType *rtype);
|
||||
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
|
||||
{
|
||||
|
|
@ -1783,7 +1813,7 @@ CmdGoto(
|
|||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
char *s, *nodename = cmd->tx_argv[1];
|
||||
char *nodename = cmd->tx_argv[1];
|
||||
Rect rect;
|
||||
CellUse *use;
|
||||
int locargc;
|
||||
|
|
@ -1824,9 +1854,9 @@ CmdGoto(
|
|||
/* 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
|
||||
}
|
||||
|
||||
|
|
@ -1839,20 +1869,31 @@ CmdGoto(
|
|||
int
|
||||
findTile(
|
||||
Tile *tile,
|
||||
TileType *rtype)
|
||||
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 */
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2176,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2431,14 +2435,14 @@ printPropertiesFunc(
|
|||
}
|
||||
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 */
|
||||
|
|
|
|||
126
commands/CmdRS.c
126
commands/CmdRS.c
|
|
@ -99,7 +99,7 @@ CmdRandom(
|
|||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(random()));
|
||||
#else
|
||||
TxPrintf("%d", random());
|
||||
TxPrintf("%ld", random());
|
||||
#endif
|
||||
}
|
||||
else if ((cmd->tx_argc >= 2) && (!strcmp(cmd->tx_argv[1], "seed")))
|
||||
|
|
@ -220,8 +220,6 @@ CmdSave(
|
|||
DBUpdateStamps(locDef);
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
char *fileName;
|
||||
|
||||
if (CmdIllegalChars(cmd->tx_argv[1], "[],", "Cell name"))
|
||||
return;
|
||||
|
||||
|
|
@ -1086,25 +1084,33 @@ CmdSelect(
|
|||
*/
|
||||
|
||||
case SEL_BBOX:
|
||||
{
|
||||
char *selllx, *sellly, *selurx, *selury;
|
||||
|
||||
GeoTransRect(&SelectUse->cu_transform, &SelectDef->cd_bbox, &selarea);
|
||||
|
||||
selllx = DBWPrintValue(selarea.r_xbot, w, TRUE);
|
||||
sellly = DBWPrintValue(selarea.r_ybot, w, FALSE);
|
||||
selurx = DBWPrintValue(selarea.r_xtop, w, TRUE);
|
||||
selury = DBWPrintValue(selarea.r_ytop, w, FALSE);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_xbot));
|
||||
Tcl_NewStringObj(selllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_ybot));
|
||||
Tcl_NewStringObj(sellly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_xtop));
|
||||
Tcl_NewStringObj(selurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(selarea.r_ytop));
|
||||
Tcl_NewStringObj(selury, -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("Select bounding box: %d %d %d %d\n",
|
||||
selarea.r_xbot, selarea.r_ybot,
|
||||
selarea.r_xtop, selarea.r_ytop);
|
||||
TxPrintf("Select bounding box: %s %s %s %s\n",
|
||||
selllx, sellly, selurx, selury);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* Make a copy of the selection at its present loction but do not
|
||||
|
|
@ -1121,14 +1127,36 @@ CmdSelect(
|
|||
|
||||
/*--------------------------------------------------------------------
|
||||
* Move the selection relative to the cell def
|
||||
* With two additional arguments: Arguments are X and Y position
|
||||
* With no additional arugments: X and Y position taken from pointer.
|
||||
*--------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
case SEL_MOVE:
|
||||
if ((more) || (less) || (primargs != 4)) goto usageError;
|
||||
if ((more) || (less) || ((primargs != 4) && (primargs != 2)))
|
||||
goto usageError;
|
||||
|
||||
p.p_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
|
||||
p.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
|
||||
if (primargs == 2)
|
||||
{
|
||||
MagWindow *window;
|
||||
Rect rootBox;
|
||||
|
||||
window = ToolGetPoint(&p, (Rect *)NULL);
|
||||
if ((window == NULL) ||
|
||||
!ToolGetBox(&SelectRootDef, &rootBox) ||
|
||||
(EditRootDef != ((CellUse *) window->w_surfaceID)->cu_def))
|
||||
{
|
||||
TxError("Error: Pointer is not in the edit cell.\n");
|
||||
return;
|
||||
}
|
||||
p.p_x -= rootBox.r_xbot;
|
||||
p.p_y -= rootBox.r_ybot;
|
||||
}
|
||||
else
|
||||
{
|
||||
p.p_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
|
||||
p.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
|
||||
}
|
||||
|
||||
/* Erase first, then recompute the transform */
|
||||
GeoTransRect(&SelectUse->cu_transform, &SelectDef->cd_bbox, &selarea);
|
||||
|
|
@ -1236,15 +1264,17 @@ CmdSelect(
|
|||
/* of rlist) */
|
||||
SelectClear();
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
while (rlist != NULL)
|
||||
{
|
||||
/* Paint rlist back into SelectDef */
|
||||
DBPaint(SelectDef, &rlist->r_r, rlist->r_type);
|
||||
|
||||
/* cleanup as we go */
|
||||
freeMagic(rlist);
|
||||
freeMagic1(&mm1, rlist);
|
||||
rlist = rlist->r_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
/* Force erase and redraw of the selection */
|
||||
DBReComputeBbox(SelectDef);
|
||||
|
|
@ -1963,23 +1993,25 @@ cmdLabelRectFunc(
|
|||
|
||||
if (rect == NULL)
|
||||
{
|
||||
char *labllx, *lablly, *laburx, *labury;
|
||||
|
||||
/* Note: Ideally, the MagWindow pointer should be passed to this function */
|
||||
labllx = DBWPrintValue(label->lab_rect.r_xbot, (MagWindow *)NULL, TRUE);
|
||||
lablly = DBWPrintValue(label->lab_rect.r_ybot, (MagWindow *)NULL, FALSE);
|
||||
laburx = DBWPrintValue(label->lab_rect.r_xtop, (MagWindow *)NULL, TRUE);
|
||||
labury = DBWPrintValue(label->lab_rect.r_ytop, (MagWindow *)NULL, FALSE);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_GetObjResult(magicinterp);
|
||||
pobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj, pobj);
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_xbot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_ybot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_xtop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj,
|
||||
Tcl_NewIntObj((double)label->lab_rect.r_ytop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(labllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(lablly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(laburx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(labury, -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("%d %d %d %d\n",
|
||||
label->lab_rect.r_xbot, label->lab_rect.r_ybot,
|
||||
label->lab_rect.r_xtop, label->lab_rect.r_ytop);
|
||||
TxPrintf("%s %s %s %s\n", labllx, lablly, laburx,labury);
|
||||
#endif
|
||||
}
|
||||
else if (!GEO_SAMERECT(label->lab_rect, *rect))
|
||||
|
|
@ -2295,11 +2327,13 @@ CmdSetLabel(
|
|||
{
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *labsize;
|
||||
|
||||
labsize = DBWPrintValue(DefaultLabel->lab_size, w, FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp,
|
||||
Tcl_NewIntObj(DefaultLabel->lab_size));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(labsize, -1));
|
||||
#else
|
||||
TxPrintf("%d\n", DefaultLabel->lab_size);
|
||||
TxPrintf("%s\n", labsize);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
@ -2338,16 +2372,20 @@ CmdSetLabel(
|
|||
{
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *laboffx, *laboffy;
|
||||
laboffx = DBWPrintValue(DefaultLabel->lab_offset.p_x, w,
|
||||
TRUE);
|
||||
laboffy = DBWPrintValue(DefaultLabel->lab_offset.p_y, w,
|
||||
FALSE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(DefaultLabel->lab_offset.p_x));
|
||||
Tcl_NewStringObj(laboffx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(DefaultLabel->lab_offset.p_y));
|
||||
Tcl_NewStringObj(laboffy, -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("%d %d\n", DefaultLabel->lab_offset.p_x,
|
||||
DefaultLabel->lab_offset.p_y);
|
||||
TxPrintf("%s %s\n", laboffx, laboffy);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
@ -2514,7 +2552,7 @@ CmdSetLabel(
|
|||
else
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetResult(magicinterp,
|
||||
DBTypeLongNameTbl[DefaultLabel->lab_type],
|
||||
(char*)DBTypeLongNameTbl[DefaultLabel->lab_type], /* Tcl treats as const */
|
||||
TCL_VOLATILE);
|
||||
#else
|
||||
TxPrintf("%s\n", DBTypeLongNameTbl[DefaultLabel->lab_type]);
|
||||
|
|
@ -2764,7 +2802,7 @@ CmdSimCmd(
|
|||
{
|
||||
static char cmdbuf[200];
|
||||
char *strptr;
|
||||
char *nodeCmd;
|
||||
const char *nodeCmd;
|
||||
int i;
|
||||
|
||||
if (!SimRsimRunning) {
|
||||
|
|
@ -2865,13 +2903,13 @@ CmdSnap(
|
|||
switch (n)
|
||||
{
|
||||
case SNAP_OFF: case SNAP_INTERNAL:
|
||||
DBWSnapToGrid = DBW_SNAP_INTERNAL;
|
||||
DBWSnapToGrid = DBW_UNITS_INTERNAL;
|
||||
return;
|
||||
case SNAP_LAMBDA:
|
||||
DBWSnapToGrid = DBW_SNAP_LAMBDA;
|
||||
DBWSnapToGrid = DBW_UNITS_LAMBDA;
|
||||
return;
|
||||
case SNAP_GRID: case SNAP_USER: case SNAP_ON:
|
||||
DBWSnapToGrid = DBW_SNAP_USER;
|
||||
DBWSnapToGrid = DBW_UNITS_USER;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2879,21 +2917,19 @@ printit:
|
|||
if (n == SNAP_LIST) /* list */
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetResult(magicinterp,
|
||||
(DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"),
|
||||
(DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user"),
|
||||
TCL_VOLATILE);
|
||||
#else
|
||||
TxPrintf("%s\n", (DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"));
|
||||
TxPrintf("%s\n", (DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user"));
|
||||
#endif
|
||||
else
|
||||
TxPrintf("Box is aligned to %s grid\n",
|
||||
(DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"));
|
||||
(DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" :
|
||||
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -73,9 +73,22 @@ TileTypeBitMask CmdYMAllButSpace;
|
|||
* lambda, a suffix of "g" indicates the user grid, and a suffix in metric
|
||||
* notation ("nm", "um", "mm", "cm") indicates natural units. Other valid
|
||||
* units are "cu" or "centimicrons" for centimicrons, or "microns" for um.
|
||||
* Units without any suffix are assumed to be in lambda if "snap"
|
||||
* (DBWSnapToGrid) is set to lambda, grid units if "snap" is set to the
|
||||
* user grid, and internal units otherwise.
|
||||
* Traditional (backwards-compatible) behavior: Units without any suffix
|
||||
* are assumed to be in lambda if "snap" (DBWSnapToGrid) is set to lambda,
|
||||
* grid units if "snap" is set to the user grid, and internal units otherwise.
|
||||
* Current behavior: Use of the "units" command to set the units to
|
||||
* any value other than "default" causes cmdScaleCoord() to parse any
|
||||
* units provided without an identifying suffix as the units indicted by
|
||||
* the "units" command. Once the "units" command has been issued, the
|
||||
* values are dependent on DBWUnits and not on DBWSnapToGrid.
|
||||
*
|
||||
* Additional behavior from magic version 8.3.596: A single command
|
||||
* option can use simple expressions using '+', '-', '*', and '/'. These
|
||||
* can be passed as a single token, without spaces, or within a string
|
||||
* token deliniated by quotes or braces, per usual Tcl syntax. Unlike
|
||||
* the Tcl "expr" command, this can solve arithmetic expressions of
|
||||
* suffixed values, evaluated independently such that different suffixes
|
||||
* may be used (e.g., "1g + 3um" meaning 1 grid pitch plus 3 microns).
|
||||
*
|
||||
* MagWindow argument w is used only with grid-based snapping, to find
|
||||
* the value of the grid for the given window. In this case, because the
|
||||
|
|
@ -99,6 +112,13 @@ TileTypeBitMask CmdYMAllButSpace;
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define PARSEOP_NONE 0
|
||||
#define PARSEOP_ADD 1
|
||||
#define PARSEOP_SUB 2
|
||||
#define PARSEOP_MUL 3
|
||||
#define PARSEOP_DIV 4
|
||||
#define PARSEOP_END 5
|
||||
|
||||
int
|
||||
cmdScaleCoord(
|
||||
MagWindow *w,
|
||||
|
|
@ -109,107 +129,184 @@ cmdScaleCoord(
|
|||
{
|
||||
char *endptr;
|
||||
double dval = 0;
|
||||
int mscale = 1;
|
||||
int mscale = 1, curunits;
|
||||
int retval, curval, parseop;
|
||||
DBWclientRec *crec;
|
||||
|
||||
if (*arg == '{') arg++;
|
||||
while (isspace(*arg)) arg++;
|
||||
if (*arg == '{' || *arg == '"') arg++;
|
||||
while (isspace(*arg) && (*arg != '\0')) arg++;
|
||||
|
||||
dval = strtod(arg, &endptr);
|
||||
dval *= (double)scale;
|
||||
parseop = PARSEOP_NONE;
|
||||
retval = 0;
|
||||
while (*arg != '\0')
|
||||
{
|
||||
dval = strtod(arg, &endptr);
|
||||
dval *= (double)scale;
|
||||
mscale = -1;
|
||||
|
||||
if (endptr == arg)
|
||||
{
|
||||
/* strtod() error condition */
|
||||
TxError("Coordinate value cannot be parsed: assuming 0\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
else if ((*endptr == 'l')
|
||||
|| ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_LAMBDA)))
|
||||
{
|
||||
/* lambda or default units */
|
||||
dval *= (double)DBLambda[1];
|
||||
dval /= (double)DBLambda[0];
|
||||
return round(dval);
|
||||
}
|
||||
else if ((*endptr == 'i')
|
||||
|| ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_INTERNAL)))
|
||||
{
|
||||
/* internal units */
|
||||
return round(dval);
|
||||
}
|
||||
else if ((*endptr == 'g')
|
||||
|| ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_USER)))
|
||||
{
|
||||
/* grid units */
|
||||
if (w == (MagWindow *)NULL)
|
||||
if (endptr == arg)
|
||||
{
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
if (w == (MagWindow *)NULL)
|
||||
return round(dval); /* Default, if window is unknown */
|
||||
/* strtod() error condition */
|
||||
TxError("Coordinate value cannot be parsed: assuming 0\n");
|
||||
curval = 0;
|
||||
break;
|
||||
}
|
||||
crec = (DBWclientRec *) w->w_clientData;
|
||||
if (is_x)
|
||||
|
||||
/* Original behavior was to accept un-suffixed values according to the
|
||||
* "snap" setting. This behavior remains in effect until the "units"
|
||||
* command is used, in which case units follow the selected units
|
||||
* value indepedendently of the snap setting.
|
||||
*/
|
||||
if (DBWUnits == DBW_UNITS_DEFAULT)
|
||||
curunits = DBWSnapToGrid;
|
||||
else
|
||||
curunits = DBWUnits & DBW_UNITS_TYPE_MASK;
|
||||
|
||||
if ((*endptr == 'l')
|
||||
|| ((*endptr == '\0') && (curunits == DBW_UNITS_LAMBDA)))
|
||||
{
|
||||
dval *= (double)(crec->dbw_gridRect.r_xtop
|
||||
/* lambda or default units */
|
||||
dval *= (double)DBLambda[1];
|
||||
dval /= (double)DBLambda[0];
|
||||
}
|
||||
else if ((*endptr == 'i')
|
||||
|| ((*endptr == '\0') && (curunits == DBW_UNITS_INTERNAL)))
|
||||
{
|
||||
/* internal units */
|
||||
}
|
||||
else if ((*endptr == 'g')
|
||||
|| ((*endptr == '\0') && (curunits == DBW_UNITS_USER)))
|
||||
{
|
||||
/* grid units */
|
||||
if (w == (MagWindow *)NULL)
|
||||
{
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
if (w == (MagWindow *)NULL)
|
||||
{
|
||||
curval = round(dval); /* Default, if window is unknown */
|
||||
break;
|
||||
}
|
||||
}
|
||||
crec = (DBWclientRec *) w->w_clientData;
|
||||
if (is_x)
|
||||
{
|
||||
dval *= (double)(crec->dbw_gridRect.r_xtop
|
||||
- crec->dbw_gridRect.r_xbot);
|
||||
if (!is_relative)
|
||||
dval += (double)crec->dbw_gridRect.r_xbot;
|
||||
if (!is_relative)
|
||||
dval += (double)crec->dbw_gridRect.r_xbot;
|
||||
}
|
||||
else
|
||||
{
|
||||
dval *= (double)(crec->dbw_gridRect.r_ytop
|
||||
- crec->dbw_gridRect.r_ybot);
|
||||
if (!is_relative)
|
||||
dval += (double)crec->dbw_gridRect.r_ybot;
|
||||
}
|
||||
}
|
||||
else if (*endptr == '\0' && (curunits == DBW_UNITS_MICRONS))
|
||||
{
|
||||
mscale = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
dval *= (double)(crec->dbw_gridRect.r_ytop
|
||||
- crec->dbw_gridRect.r_ybot);
|
||||
if (!is_relative)
|
||||
dval += (double)crec->dbw_gridRect.r_ybot;
|
||||
/* natural units referred to the current cifoutput style */
|
||||
if (*(endptr + 1) == 'm')
|
||||
{
|
||||
switch (*endptr)
|
||||
{
|
||||
case 'n':
|
||||
mscale = 1;
|
||||
break;
|
||||
case 'u':
|
||||
mscale = 1000;
|
||||
break;
|
||||
case 'm':
|
||||
mscale = 1000000;
|
||||
break;
|
||||
case 'c':
|
||||
mscale = 10000000;
|
||||
break;
|
||||
default:
|
||||
TxError("Unknown metric prefix \"%cm\"; assuming "
|
||||
"internal units\n", *endptr);
|
||||
mscale = -1;
|
||||
}
|
||||
}
|
||||
else if ((*endptr == 'u') && !isalnum(*(endptr + 1)))
|
||||
/* 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"))
|
||||
mscale = 10;
|
||||
else if (!isspace(*endptr) && (*endptr != '+') && (*endptr != '-') &&
|
||||
(*endptr != '*') && (*endptr != '/'))
|
||||
{
|
||||
TxError("Unknown coordinate type at \"%s\"; assuming internal units\n",
|
||||
endptr);
|
||||
mscale = -1;
|
||||
}
|
||||
}
|
||||
return round(dval);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* natural units referred to the current cifoutput style */
|
||||
if (*(endptr + 1) == 'm')
|
||||
if ((mscale != -1) && !isspace(*endptr))
|
||||
dval /= CIFGetOutputScale(mscale);
|
||||
curval = round(dval);
|
||||
|
||||
switch (parseop)
|
||||
{
|
||||
case PARSEOP_NONE:
|
||||
retval = curval;
|
||||
break;
|
||||
case PARSEOP_ADD:
|
||||
retval += curval;
|
||||
break;
|
||||
case PARSEOP_SUB:
|
||||
retval -= curval;
|
||||
break;
|
||||
case PARSEOP_MUL:
|
||||
retval *= curval;
|
||||
break;
|
||||
case PARSEOP_DIV:
|
||||
retval /= curval;
|
||||
break;
|
||||
}
|
||||
|
||||
parseop = PARSEOP_NONE;
|
||||
while (*endptr != '\0')
|
||||
{
|
||||
switch (*endptr)
|
||||
{
|
||||
case 'n':
|
||||
mscale = 1;
|
||||
case '}':
|
||||
case '"':
|
||||
parseop = PARSEOP_END;
|
||||
break;
|
||||
case 'u':
|
||||
mscale = 1000;
|
||||
case '+':
|
||||
parseop = PARSEOP_ADD;
|
||||
endptr++;
|
||||
break;
|
||||
case 'm':
|
||||
mscale = 1000000;
|
||||
case '-':
|
||||
parseop = PARSEOP_SUB;
|
||||
endptr++;
|
||||
break;
|
||||
case 'c':
|
||||
mscale = 10000000;
|
||||
case '*':
|
||||
parseop = PARSEOP_MUL;
|
||||
endptr++;
|
||||
break;
|
||||
case '/':
|
||||
parseop = PARSEOP_DIV;
|
||||
endptr++;
|
||||
break;
|
||||
default:
|
||||
TxError("Unknown metric prefix \"%cm\"; assuming internal units\n",
|
||||
*endptr);
|
||||
return round(dval);
|
||||
endptr++;
|
||||
break;
|
||||
}
|
||||
if (parseop != PARSEOP_NONE) break;
|
||||
}
|
||||
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"))
|
||||
mscale = 10;
|
||||
else if (!isspace(*endptr))
|
||||
{
|
||||
TxError("Unknown coordinate type \"%s\"; assuming internal units\n",
|
||||
endptr);
|
||||
return round(dval);
|
||||
}
|
||||
arg = endptr;
|
||||
while (isspace(*arg) && (*arg != '\0')) arg++;
|
||||
}
|
||||
if (!isspace(*endptr))
|
||||
dval /= CIFGetOutputScale(mscale);
|
||||
return round(dval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1196,6 +1293,17 @@ cmdGetSelFunc(
|
|||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -1228,7 +1336,7 @@ CmdIllegalChars(
|
|||
|
||||
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++)
|
||||
{
|
||||
|
|
@ -1237,7 +1345,7 @@ CmdIllegalChars(
|
|||
continue;
|
||||
|
||||
error:
|
||||
if (!isascii(*p) || iscntrl(*p))
|
||||
if (!magic_isascii(*p) || iscntrl(*p))
|
||||
{
|
||||
TxError("%s contains illegal control character 0x%x\n",
|
||||
msg, *p);
|
||||
|
|
|
|||
244
commands/CmdTZ.c
244
commands/CmdTZ.c
|
|
@ -61,7 +61,9 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
|||
|
||||
int
|
||||
existFunc(
|
||||
Tile *tile)
|
||||
Tile *tile, /* (unused) */
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -453,15 +455,18 @@ CmdTech(
|
|||
}
|
||||
if (!strncmp(cmd->tx_argv[2], "width", 5))
|
||||
{
|
||||
char *techwidth;
|
||||
tresult = DRCGetDefaultLayerWidth(t1);
|
||||
techwidth = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techwidth, -1));
|
||||
#else
|
||||
TxPrintf("Minimum width is %d\n", tresult);
|
||||
TxPrintf("Minimum width is %s\n", techwidth);
|
||||
#endif
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[2], "spac", 4))
|
||||
{
|
||||
char *techspace;
|
||||
if (cmd->tx_argc >= 5)
|
||||
{
|
||||
t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
|
||||
|
|
@ -473,14 +478,16 @@ CmdTech(
|
|||
else
|
||||
t2 = t1;
|
||||
tresult = DRCGetDefaultLayerSpacing(t1, t2);
|
||||
techspace = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techspace, -1));
|
||||
#else
|
||||
TxPrintf("Minimum spacing is %d\n", tresult);
|
||||
TxPrintf("Minimum spacing is %s\n", techspace);
|
||||
#endif
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[2], "surr", 4))
|
||||
{
|
||||
char *techsurround;
|
||||
if (cmd->tx_argc >= 5)
|
||||
{
|
||||
t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
|
||||
|
|
@ -496,14 +503,17 @@ CmdTech(
|
|||
}
|
||||
|
||||
tresult = DRCGetDefaultLayerSurround(t1, t2);
|
||||
techsurround = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techsurround, -1));
|
||||
#else
|
||||
TxPrintf("Minimum surround is %d\n", tresult);
|
||||
TxPrintf("Minimum surround is %s\n", techsurround);
|
||||
#endif
|
||||
}
|
||||
else if (!strncmp(cmd->tx_argv[2], "direc", 5))
|
||||
{
|
||||
char *techdirec;
|
||||
|
||||
if (cmd->tx_argc >= 5)
|
||||
{
|
||||
t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
|
||||
|
|
@ -519,10 +529,11 @@ CmdTech(
|
|||
}
|
||||
|
||||
tresult = DRCGetDirectionalLayerSurround(t1, t2);
|
||||
techdirec = DBWPrintValue(tresult, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
|
||||
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techdirec, -1));
|
||||
#else
|
||||
TxPrintf("Minimum surround (in one orientation) is %d\n", tresult);
|
||||
TxPrintf("Minimum surround (in one orientation) is %s\n", techdirec);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -671,6 +682,15 @@ CmdTool(
|
|||
|
||||
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]);
|
||||
}
|
||||
|
||||
|
|
@ -743,6 +763,182 @@ cmdUnexpandFunc(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* CmdUnits --
|
||||
*
|
||||
* Implement the "units" command.
|
||||
*
|
||||
* Usage:
|
||||
* units [value] [print|noprint]
|
||||
*
|
||||
* where "value" may be one of "default", "internal", "lambda",
|
||||
* "user" (equivalently "grid"), or "microns".
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The global variable DBWUnits may be changed, which changes the
|
||||
* behavior of magic when interpreting un-suffixed values or
|
||||
* displaying values.
|
||||
*
|
||||
* Notes:
|
||||
* The units behavior was previously dependent on what command was
|
||||
* issued, with results usually being given in internal units, and
|
||||
* with un-suffixed values following the snap behavior. Backwards-
|
||||
* compatible behavior is used on startup or at any time by setting
|
||||
* the units to "default". Otherwise, unit display follows the
|
||||
* given "units" setting.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#define UNITS_DEFAULT 0
|
||||
#define UNITS_INTERNAL 1
|
||||
#define UNITS_LAMBDA 2
|
||||
#define UNITS_GRID 3
|
||||
#define UNITS_USER 4
|
||||
#define UNITS_MICRONS 5
|
||||
#define UNITS_LIST 6
|
||||
#define UNITS_PRINT 7
|
||||
#define UNITS_NOPRINT 8
|
||||
|
||||
void
|
||||
CmdUnits(
|
||||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
static const char * const names[] = { "default", "internal", "lambda",
|
||||
"grid", "user", "microns", "list", "print", "noprint", 0 };
|
||||
int idx, n = UNITS_LIST, n2, saveflag;
|
||||
DBWclientRec *crec;
|
||||
|
||||
if (cmd->tx_argc >= 2)
|
||||
{
|
||||
n = Lookup(cmd->tx_argv[1], names);
|
||||
if (n < 0)
|
||||
{
|
||||
TxPrintf("Usage: units [default | internal | lambda | microns"
|
||||
" | user] [print]\n");
|
||||
return;
|
||||
}
|
||||
if (DBWUnits != DBW_UNITS_DEFAULT)
|
||||
saveflag = DBWUnits & DBW_UNITS_PRINT_FLAG;
|
||||
else
|
||||
saveflag = -1;
|
||||
|
||||
switch (n)
|
||||
{
|
||||
case UNITS_DEFAULT:
|
||||
DBWUnits = DBW_UNITS_DEFAULT;
|
||||
break;
|
||||
case UNITS_INTERNAL:
|
||||
DBWUnits = DBW_UNITS_INTERNAL;
|
||||
break;
|
||||
case UNITS_LAMBDA:
|
||||
DBWUnits = DBW_UNITS_LAMBDA;
|
||||
break;
|
||||
case UNITS_USER:
|
||||
case UNITS_GRID:
|
||||
DBWUnits = DBW_UNITS_USER;
|
||||
break;
|
||||
case UNITS_MICRONS:
|
||||
DBWUnits = DBW_UNITS_MICRONS;
|
||||
break;
|
||||
case UNITS_PRINT:
|
||||
saveflag = DBW_UNITS_PRINT_FLAG;
|
||||
break;
|
||||
case UNITS_NOPRINT:
|
||||
saveflag = 0;
|
||||
break;
|
||||
}
|
||||
if (n < 0)
|
||||
{
|
||||
TxError("Unrecognized units option %s\n.", cmd->tx_argv[1]);
|
||||
return;
|
||||
}
|
||||
if (n != UNITS_LIST)
|
||||
{
|
||||
if ((cmd->tx_argc == 3) && (n != UNITS_DEFAULT))
|
||||
{
|
||||
n2 = Lookup(cmd->tx_argv[2], names);
|
||||
switch (n2)
|
||||
{
|
||||
case UNITS_PRINT:
|
||||
DBWUnits |= DBW_UNITS_PRINT_FLAG;
|
||||
break;
|
||||
case UNITS_NOPRINT:
|
||||
DBWUnits &= DBW_UNITS_TYPE_MASK;
|
||||
break;
|
||||
default:
|
||||
TxError("Unrecognized units option %s\n.", cmd->tx_argv[2]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ((n != UNITS_DEFAULT) && (saveflag != -1))
|
||||
{
|
||||
/* Preserve the previous value of the print/noprint flag */
|
||||
DBWUnits &= DBW_UNITS_TYPE_MASK;
|
||||
DBWUnits |= saveflag;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (DBWUnits == DBW_UNITS_DEFAULT)
|
||||
idx = UNITS_DEFAULT;
|
||||
else
|
||||
switch (DBWUnits & DBW_UNITS_TYPE_MASK)
|
||||
{
|
||||
case DBW_UNITS_INTERNAL:
|
||||
idx = UNITS_INTERNAL;
|
||||
break;
|
||||
case DBW_UNITS_LAMBDA:
|
||||
idx = UNITS_LAMBDA;
|
||||
break;
|
||||
case DBW_UNITS_USER:
|
||||
idx = UNITS_USER;
|
||||
break;
|
||||
case DBW_UNITS_MICRONS:
|
||||
idx = UNITS_MICRONS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == UNITS_LIST) /* list */
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
Tcl_Obj *tobj;
|
||||
tobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj((char *)names[idx], -1));
|
||||
if (idx != UNITS_DEFAULT)
|
||||
{
|
||||
if (DBWUnits & DBW_UNITS_PRINT_FLAG)
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj("print", 5));
|
||||
else
|
||||
Tcl_ListObjAppendElement(magicinterp, tobj,
|
||||
Tcl_NewStringObj("noprint", 7));
|
||||
}
|
||||
Tcl_SetObjResult(magicinterp, tobj);
|
||||
#else
|
||||
TxPrintf("%s", names[idx]);
|
||||
if (idx != UNITS_DEFAULT)
|
||||
if (DBWUnits & DBW_UNITS_PRINT_FLAG)
|
||||
TxPrintf(" print");
|
||||
TxPrintf("\n");
|
||||
#endif
|
||||
}
|
||||
else if (idx == UNITS_DEFAULT)
|
||||
TxPrintf("Reported units follow the snap setting.\n");
|
||||
else if (DBWUnits & DBW_UNITS_PRINT_FLAG)
|
||||
TxPrintf("Values are reported as %s, along with the units.\n", names[idx]);
|
||||
else
|
||||
TxPrintf("Values are reported as %s\n", names[idx]);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -830,7 +1026,8 @@ struct linked_id {
|
|||
|
||||
int
|
||||
cmdWhatPrintCell(
|
||||
Tile *tile,
|
||||
Tile *tile, /* (unused) */
|
||||
TileType dinfo, /* (unused) */
|
||||
TreeContext *cxp)
|
||||
{
|
||||
struct linked_id **lid = (struct linked_id **)cxp->tc_filter->tf_arg;
|
||||
|
|
@ -885,6 +1082,7 @@ static LabelStore *labelBlockTop, *labelEntry;
|
|||
int
|
||||
cmdFindWhatTileFunc(
|
||||
Tile *tile,
|
||||
TileType dinfo,
|
||||
ClientData clientData)
|
||||
{
|
||||
struct linked_id **lid = (struct linked_id **)clientData;
|
||||
|
|
@ -896,7 +1094,7 @@ cmdFindWhatTileFunc(
|
|||
scx.scx_use = EditCellUse;
|
||||
scx.scx_trans = GeoIdentityTransform;
|
||||
|
||||
if (SplitSide(tile))
|
||||
if (dinfo & TT_SIDE)
|
||||
type = SplitRightType(tile);
|
||||
else
|
||||
type = SplitLeftType(tile);
|
||||
|
|
@ -1094,11 +1292,13 @@ CmdWhat(
|
|||
}
|
||||
#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,
|
||||
|
|
@ -1681,18 +1881,20 @@ CmdWire(
|
|||
case VALUES:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *wdisp;
|
||||
width = WireGetWidth();
|
||||
type = WireGetType();
|
||||
wdisp = DBWPrintValue(width, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewIntObj(width));
|
||||
Tcl_NewStringObj(wdisp, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, lobj,
|
||||
Tcl_NewStringObj(DBTypeLongNameTbl[type], -1));
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("Wire layer %s, width %d\n",
|
||||
DBTypeLongNameTbl[type], width);
|
||||
TxPrintf("Wire layer %s, width %s\n",
|
||||
DBTypeLongNameTbl[type], wdisp);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
|
@ -1717,12 +1919,14 @@ CmdWire(
|
|||
case WIDTH:
|
||||
if (locargc == 2)
|
||||
{
|
||||
char *wdisp;
|
||||
width = WireGetWidth();
|
||||
wdisp = DBWPrintValue(width, w, TRUE);
|
||||
#ifdef MAGIC_WRAPPER
|
||||
lobj = Tcl_NewIntObj(width);
|
||||
lobj = Tcl_NewStringObj(wdisp, -1);
|
||||
Tcl_SetObjResult(magicinterp, lobj);
|
||||
#else
|
||||
TxPrintf("Wire width is %d\n", width);
|
||||
TxPrintf("Wire width is %s\n", wdisp);
|
||||
#endif
|
||||
}
|
||||
else if (locargc != 3)
|
||||
|
|
@ -1945,7 +2149,7 @@ CmdWriteall(
|
|||
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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
|
|||
#include "utils/utils.h"
|
||||
#include "textio/txcommands.h"
|
||||
|
||||
/* For diagnostics */
|
||||
#include "cif/CIFint.h"
|
||||
#include "database/databaseInt.h"
|
||||
|
||||
/* C99 compat */
|
||||
#include "extract/extract.h"
|
||||
|
||||
|
|
@ -189,6 +193,234 @@ CmdExtractTest(
|
|||
}
|
||||
#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);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
|
|
@ -232,7 +464,7 @@ showTech(
|
|||
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);
|
||||
|
|
@ -569,11 +801,13 @@ cmdStatsCount(
|
|||
CellDef *def,
|
||||
struct countClient *cc)
|
||||
{
|
||||
int cmdStatsCountTile(Tile *tile, struct cellInfo *ci);
|
||||
int pNum;
|
||||
struct cellInfo *ci;
|
||||
TileType t;
|
||||
|
||||
/* Forward declaration */
|
||||
int cmdStatsCountTile(Tile *tile, TileType dinfo, struct cellInfo *ci);
|
||||
|
||||
if (def->cd_client)
|
||||
return (1);
|
||||
|
||||
|
|
@ -598,6 +832,7 @@ cmdStatsCount(
|
|||
int
|
||||
cmdStatsCountTile(
|
||||
Tile *tile,
|
||||
TileType dinfo, /* (unused) */
|
||||
struct cellInfo *ci)
|
||||
{
|
||||
TileType type = TiGetType(tile);
|
||||
|
|
@ -868,17 +1103,18 @@ CmdTsearch(
|
|||
MagWindow *w,
|
||||
TxCommand *cmd)
|
||||
{
|
||||
int cmdTsrFunc(Tile *tp);
|
||||
char *RunStats(int flags, struct tms *lastt, struct tms *deltat);
|
||||
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");
|
||||
|
|
@ -978,10 +1214,12 @@ CmdTsearch(
|
|||
|
||||
int
|
||||
cmdTsrFunc(
|
||||
Tile *tp)
|
||||
Tile *tp,
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
if (cmdTsearchDebug)
|
||||
TxPrintf("%lx\n", (intmax_t) tp);
|
||||
TxPrintf("%lx\n", (intptr_t) tp);
|
||||
numTilesFound++;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1047,7 +1285,7 @@ CmdWatch(
|
|||
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++) {
|
||||
|
|
|
|||
|
|
@ -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,8 +20,8 @@
|
|||
* 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"
|
||||
|
|
@ -75,4 +75,4 @@ extern void CmdInit(void);
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -108,16 +108,55 @@ DBCellFindDup(use, parent)
|
|||
"DBCellFindDup");
|
||||
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.
|
||||
* an insufficient measure of exact overlap. Also, array
|
||||
* counts and separation must match for arrayed devices
|
||||
*/
|
||||
if ((dupUse->cu_transform.t_a == use->cu_transform.t_a) &&
|
||||
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))
|
||||
(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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -967,14 +967,15 @@ DBCellGenerateSimpleSubstrate(scx, subType, notSubMask, 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 */
|
||||
|
||||
|
|
@ -983,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);
|
||||
|
|
@ -998,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);
|
||||
}
|
||||
|
||||
|
|
@ -1010,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 */
|
||||
|
||||
|
|
@ -1026,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);
|
||||
|
|
@ -1041,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);
|
||||
}
|
||||
|
||||
|
|
@ -1054,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;
|
||||
|
||||
|
|
@ -1072,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);
|
||||
|
|
@ -1086,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);
|
||||
}
|
||||
|
||||
|
|
@ -1098,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;
|
||||
|
|
@ -1109,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
|
||||
|
|
@ -1433,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;
|
||||
|
|
@ -1480,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;
|
||||
|
|
@ -1489,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;
|
||||
|
|
@ -1502,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);
|
||||
}
|
||||
|
||||
|
|
@ -1568,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);
|
||||
|
|
@ -1597,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 */
|
||||
{
|
||||
|
|
@ -1654,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 */
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
@ -312,6 +320,7 @@ DBCellDelete(cellname, force)
|
|||
/* 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)
|
||||
{
|
||||
|
|
@ -320,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);
|
||||
|
|
@ -1611,6 +1621,7 @@ dbAbutmentUseFunc(selUse, use, transform, data)
|
|||
Rect bbox, refbox;
|
||||
Transform *trans;
|
||||
char *propvalue;
|
||||
char *refllx, *reflly, *refurx, *refury;
|
||||
bool found;
|
||||
bool *dolist = (bool *)data;
|
||||
|
||||
|
|
@ -1643,21 +1654,25 @@ dbAbutmentUseFunc(selUse, use, transform, data)
|
|||
}
|
||||
GeoTransRect(trans, &bbox, &refbox);
|
||||
|
||||
/* NOTE: Ideally, the MagWindow pointer should get passed to this routine */
|
||||
refllx = DBWPrintValue(refbox.r_xbot, (MagWindow *)NULL, TRUE);
|
||||
reflly = DBWPrintValue(refbox.r_ybot, (MagWindow *)NULL, FALSE);
|
||||
refurx = DBWPrintValue(refbox.r_xtop, (MagWindow *)NULL, TRUE);
|
||||
refury = DBWPrintValue(refbox.r_ytop, (MagWindow *)NULL, FALSE);
|
||||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
if (*dolist)
|
||||
{
|
||||
pobj = Tcl_NewListObj(0, NULL);
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_xbot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_ybot));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_xtop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_ytop));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refllx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(reflly, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refurx, -1));
|
||||
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refury, -1));
|
||||
Tcl_SetObjResult(magicinterp, pobj);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
TxPrintf("Abutment box: %d %d %d %d\n", refbox.r_xbot, refbox.r_ybot,
|
||||
refbox.r_xtop, refbox.r_ytop);
|
||||
|
||||
TxPrintf("Abutment box: %s %s %s %s\n", refllx, reflly, refurx, refury);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1936,6 +1951,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);
|
||||
|
||||
|
|
@ -1997,8 +2013,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);
|
||||
|
||||
|
|
|
|||
|
|
@ -85,11 +85,13 @@ struct seeTypesArg
|
|||
int
|
||||
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)))
|
||||
|
|
@ -102,7 +104,7 @@ DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg
|
|||
}
|
||||
|
||||
BPEnumTerm(bpe);
|
||||
freeMagic(bpe);
|
||||
/* freeMagic(bpe); */
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
|
@ -118,6 +120,7 @@ DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg
|
|||
* int
|
||||
* func(tile, cxp)
|
||||
* Tile *tile;
|
||||
* TileType dinfo;
|
||||
* TreeContext *cxp;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -414,6 +417,7 @@ dbCellUniqueTileSrFunc(scx, fp)
|
|||
* int
|
||||
* func(tile, cxp)
|
||||
* Tile *tile;
|
||||
* TileType dinfo;
|
||||
* TreeContext *cxp;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -912,8 +916,9 @@ DBSeeTypesAll(rootUse, rootRect, xMask, mask)
|
|||
*/
|
||||
|
||||
int
|
||||
dbSeeTypesAllSrFunc(tile, cxp)
|
||||
dbSeeTypesAllSrFunc(tile, dinfo, cxp)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
TreeContext *cxp;
|
||||
{
|
||||
Rect tileRect;
|
||||
|
|
@ -924,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));
|
||||
|
|
@ -1514,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);
|
||||
|
|
@ -1602,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;
|
||||
|
|
@ -1626,12 +1635,15 @@ dbTileScaleFunc(tile, scvals)
|
|||
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;
|
||||
|
|
@ -1681,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;
|
||||
|
|
@ -1695,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);
|
||||
|
|
@ -1762,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;
|
||||
}
|
||||
|
||||
|
|
@ -1995,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. */
|
||||
|
|
@ -2203,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. */
|
||||
|
|
|
|||
|
|
@ -218,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -128,85 +128,6 @@ DBInvTransformDiagonal(oldtype, trans)
|
|||
return dinfo;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBSrConnectOnePlane --
|
||||
*
|
||||
* Search from a starting tile to find all paint that is electrically
|
||||
* connected to that tile in the same plane.
|
||||
*
|
||||
* Results:
|
||||
* 0 is returned if the search finished normally. 1 is returned
|
||||
* if the search was aborted.
|
||||
*
|
||||
* Side effects:
|
||||
* For every paint tile that is electrically connected to the initial
|
||||
* tile, func is called. Func should have the following form:
|
||||
*
|
||||
* int
|
||||
* func(tile, clientData)
|
||||
* Tile *tile;
|
||||
* ClientData clientData;
|
||||
* {
|
||||
* }
|
||||
*
|
||||
* The clientData passed to func is the same one that was passed
|
||||
* to us. Func returns 0 under normal conditions; if it returns
|
||||
* 1 then the search is aborted.
|
||||
*
|
||||
* *** WARNING ***
|
||||
*
|
||||
* Func should not modify any paint during the search, since this
|
||||
* will mess up pointers kept by these procedures and likely cause
|
||||
* a core-dump.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
DBSrConnectOnePlane(startTile, connect, func, clientData)
|
||||
Tile *startTile; /* Starting tile for search */
|
||||
TileTypeBitMask *connect; /* Pointer to a table indicating what tile
|
||||
* types connect to what other tile types.
|
||||
* Each entry gives a mask of types that
|
||||
* connect to tiles of a given type.
|
||||
*/
|
||||
int (*func)(); /* Function to apply at each connected tile. */
|
||||
ClientData clientData; /* Client data for above function. */
|
||||
|
||||
{
|
||||
struct conSrArg csa;
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
csa.csa_def = (CellDef *)NULL;
|
||||
csa.csa_bounds = TiPlaneRect;
|
||||
|
||||
/* Pass 1. During this pass the client function gets called. */
|
||||
|
||||
csa.csa_clientFunc = func;
|
||||
csa.csa_clientData = clientData;
|
||||
csa.csa_clientDefault = startTile->ti_client;
|
||||
csa.csa_clear = FALSE;
|
||||
csa.csa_connect = connect;
|
||||
csa.csa_pNum = -1;
|
||||
if (dbSrConnectFunc(startTile, PTR2CD(&csa)) != 0) result = 1;
|
||||
|
||||
/* Pass 2. Don't call any client function, just clear the marks.
|
||||
* Don't allow any interruptions.
|
||||
*/
|
||||
|
||||
SigDisableInterrupts();
|
||||
csa.csa_clientFunc = NULL;
|
||||
csa.csa_clear = TRUE;
|
||||
(void) dbSrConnectFunc(startTile, PTR2CD(&csa));
|
||||
SigEnableInterrupts();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -276,7 +197,7 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
|
|||
{
|
||||
struct conSrArg csa;
|
||||
int startPlane, result;
|
||||
Tile *startTile; /* Starting tile for search. */
|
||||
TileAndDinfo start_tad; /* Starting tile and split information */
|
||||
|
||||
result = 0;
|
||||
csa.csa_def = def;
|
||||
|
|
@ -287,17 +208,18 @@ 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, PTR2CD(&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. */
|
||||
|
||||
|
|
@ -306,7 +228,8 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
|
|||
csa.csa_clientDefault = CLIENTDEFAULT;
|
||||
csa.csa_clear = FALSE;
|
||||
csa.csa_connect = connect;
|
||||
if (dbSrConnectFunc(startTile, PTR2CD(&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.
|
||||
|
|
@ -315,7 +238,7 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
|
|||
SigDisableInterrupts();
|
||||
csa.csa_clientFunc = NULL;
|
||||
csa.csa_clear = TRUE;
|
||||
(void) dbSrConnectFunc(startTile, PTR2CD(&csa));
|
||||
(void) dbSrConnectFunc(start_tad.tad_tile, start_tad.tad_dinfo, PTR2CD(&csa));
|
||||
SigEnableInterrupts();
|
||||
|
||||
return result;
|
||||
|
|
@ -325,11 +248,12 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
|
|||
int
|
||||
dbSrConnectStartFunc(
|
||||
Tile *tile, /* This will be the starting tile. */
|
||||
ClientData cdata) /* We store tile's address here. */
|
||||
/* (Tile **pTile) */
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData cdata) /* We store tile and split info here. */
|
||||
{
|
||||
Tile **pTile = (Tile **)CD2PTR(cdata);
|
||||
*pTile = tile;
|
||||
TileAndDinfo *tad = (TileAndDinfo *)CD2PTR(cdata);
|
||||
tad->tad_tile = tile;
|
||||
tad->tad_dinfo = dinfo;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -367,7 +291,7 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
|
|||
{
|
||||
struct conSrArg csa;
|
||||
int startPlane, result;
|
||||
Tile *startTile; /* Starting tile for search. */
|
||||
TileAndDinfo tad;
|
||||
|
||||
result = 0;
|
||||
csa.csa_def = def;
|
||||
|
|
@ -378,17 +302,18 @@ 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, PTR2CD(&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. */
|
||||
|
||||
|
|
@ -397,7 +322,7 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
|
|||
csa.csa_clientDefault = CLIENTDEFAULT;
|
||||
csa.csa_clear = FALSE;
|
||||
csa.csa_connect = connect;
|
||||
if (dbSrConnectFunc(startTile, PTR2CD(&csa)) != 0) result = 1;
|
||||
if (dbSrConnectFunc(tad.tad_tile, tad.tad_dinfo, PTR2CD(&csa)) != 0) result = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -420,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;
|
||||
}
|
||||
|
||||
|
|
@ -465,6 +393,7 @@ dbcFindTileFunc(tile, arg)
|
|||
int
|
||||
dbSrConnectFunc(
|
||||
Tile *tile, /* Tile that is connected. */
|
||||
TileType dinfo, /* Split tile information */
|
||||
ClientData cdata) /* Contains information about the search. */
|
||||
/* (struct conSrArg *csa) */
|
||||
{
|
||||
|
|
@ -484,11 +413,13 @@ dbSrConnectFunc(
|
|||
/* Drop the first entry on the stack */
|
||||
pNum = csa->csa_pNum;
|
||||
STACKPUSH(INT2CD(tile), dbConnectStack);
|
||||
STACKPUSH(INT2CD(dinfo), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
|
||||
while (!StackEmpty(dbConnectStack))
|
||||
{
|
||||
pNum = (int)CD2INT(STACKPOP(dbConnectStack));
|
||||
dinfo = (int)CD2INT(STACKPOP(dbConnectStack));
|
||||
tile = (Tile *)CD2INT(STACKPOP(dbConnectStack));
|
||||
if (result == 1) continue;
|
||||
|
||||
|
|
@ -522,7 +453,7 @@ dbSrConnectFunc(
|
|||
|
||||
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;
|
||||
|
|
@ -536,7 +467,7 @@ dbSrConnectFunc(
|
|||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
if (SplitSide(tile))
|
||||
if (dinfo & TT_SIDE)
|
||||
loctype = SplitRightType(tile);
|
||||
else
|
||||
loctype = SplitLeftType(tile);
|
||||
|
|
@ -547,7 +478,7 @@ dbSrConnectFunc(
|
|||
|
||||
/* 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))
|
||||
{
|
||||
|
|
@ -564,9 +495,11 @@ dbSrConnectFunc(
|
|||
if (t2->ti_client == csa->csa_clientDefault) continue;
|
||||
}
|
||||
else if (t2->ti_client == (ClientData) 1) continue;
|
||||
if (IsSplit(t2))
|
||||
TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) | TT_SIDE)); /* bit set */
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
if (IsSplit(t2))
|
||||
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack);
|
||||
else
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
}
|
||||
|
|
@ -574,7 +507,7 @@ dbSrConnectFunc(
|
|||
/* 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))
|
||||
|
|
@ -592,16 +525,17 @@ bottomside:
|
|||
if (t2->ti_client == csa->csa_clientDefault) continue;
|
||||
}
|
||||
else if (t2->ti_client == (ClientData) 1) continue;
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
if (IsSplit(t2))
|
||||
{
|
||||
if (SplitDirection(t2))
|
||||
/* bit set */
|
||||
TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) | TT_SIDE));
|
||||
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack);
|
||||
else
|
||||
/* bit clear */
|
||||
TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) & ~TT_SIDE));
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
}
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
else
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
}
|
||||
|
|
@ -609,7 +543,7 @@ bottomside:
|
|||
/* 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))
|
||||
{
|
||||
|
|
@ -626,9 +560,8 @@ rightside:
|
|||
if (t2->ti_client == csa->csa_clientDefault) goto nextRight;
|
||||
}
|
||||
else if (t2->ti_client == (ClientData) 1) goto nextRight;
|
||||
if (IsSplit(t2))
|
||||
TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) & ~TT_SIDE)); /* bit clear */
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
nextRight: if (BOTTOM(t2) <= tileArea.r_ybot) break;
|
||||
|
|
@ -637,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))
|
||||
{
|
||||
|
|
@ -654,16 +588,18 @@ topside:
|
|||
if (t2->ti_client == csa->csa_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, INT2CD(CD2INT(t2->ti_body) & ~TT_SIDE));
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
else
|
||||
/* bit set */
|
||||
TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) | TT_SIDE));
|
||||
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack);
|
||||
}
|
||||
STACKPUSH(INT2CD(t2), dbConnectStack);
|
||||
else
|
||||
STACKPUSH(INT2CD(0), dbConnectStack);
|
||||
STACKPUSH(INT2CD(pNum), dbConnectStack);
|
||||
}
|
||||
nextTop: if (LEFT(t2) <= tileArea.r_xbot) break;
|
||||
|
|
@ -682,6 +618,7 @@ donesides:
|
|||
{
|
||||
Rect newArea;
|
||||
GEO_EXPAND(&tileArea, 1, &newArea);
|
||||
TileAndDinfo tad;
|
||||
|
||||
for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++)
|
||||
{
|
||||
|
|
@ -689,18 +626,20 @@ 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(INT2CD(t2), 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(INT2CD(t2), dbConnectStack);
|
||||
STACKPUSH(PTR2CD(tad.tad_tile), dbConnectStack);
|
||||
STACKPUSH(INT2CD(tad.tad_dinfo), dbConnectStack);
|
||||
STACKPUSH(INT2CD(i), dbConnectStack);
|
||||
}
|
||||
}
|
||||
|
|
@ -734,9 +673,10 @@ 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;
|
||||
|
|
@ -828,6 +768,7 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
|
|||
CellDef *orig_def = scx->scx_use->cu_def;
|
||||
Label *slab;
|
||||
int lidx = lab->lab_port;
|
||||
bool foundOne;
|
||||
const TileTypeBitMask *connectMask;
|
||||
|
||||
/* Check for equivalent ports. For any found, call */
|
||||
|
|
@ -839,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)
|
||||
|
|
@ -899,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;
|
||||
}
|
||||
|
|
@ -933,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.
|
||||
|
|
@ -947,8 +904,8 @@ dbcConnectFunc(tile, cx)
|
|||
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;
|
||||
|
||||
|
|
@ -980,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
|
||||
|
|
@ -1019,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;
|
||||
|
||||
|
|
@ -1028,7 +985,7 @@ dbcConnectFunc(tile, cx)
|
|||
* the storage for the current list element.
|
||||
*/
|
||||
|
||||
DBNMPaintPlane(def->cd_planes[pNum], dinfo,
|
||||
DBNMPaintPlane(def->cd_planes[pNum], newdinfo,
|
||||
&newarea, DBStdPaintTbl(loctype, pNum),
|
||||
(PaintUndoInfo *) NULL);
|
||||
|
||||
|
|
@ -1045,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;
|
||||
|
|
@ -1092,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;
|
||||
}
|
||||
|
|
@ -1247,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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
674
database/DBio.c
674
database/DBio.c
|
|
@ -40,8 +40,16 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#endif
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PATHS_H
|
||||
#include <paths.h>
|
||||
|
|
@ -52,6 +60,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#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"
|
||||
|
|
@ -89,6 +98,9 @@ extern bool FileLocking;
|
|||
|
||||
/* Suffix for all Magic files */
|
||||
char *DBSuffix = ".mag";
|
||||
#ifdef HAVE_ZLIB
|
||||
char *DBZSuffix = ".mag.gz";
|
||||
#endif
|
||||
|
||||
/* Magic units per lambda (2 integers, representing (n / d) */
|
||||
int DBLambda[2] = {1, 1};
|
||||
|
|
@ -158,6 +170,24 @@ file_is_not_writeable(name)
|
|||
return(0);
|
||||
}
|
||||
|
||||
static int
|
||||
path_is_dir(const char *dirname, const char *filename)
|
||||
{
|
||||
struct stat statbuf;
|
||||
char path[PATH_MAX];
|
||||
const char *sep = filename ? "/" : "";
|
||||
if (!filename)
|
||||
filename = "";
|
||||
size_t n = snprintf(path, sizeof(path), "%s%s%s", dirname, sep, filename);
|
||||
ASSERT(n < sizeof(path), "path");
|
||||
if (n >= sizeof(path))
|
||||
return -1;
|
||||
int err = stat(path, &statbuf);
|
||||
if (err != 0)
|
||||
return 0;
|
||||
return S_ISDIR(statbuf.st_mode) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Linked string record used to hold directory contents */
|
||||
|
||||
typedef struct _linkedDirent {
|
||||
|
|
@ -243,13 +273,20 @@ DBSearchForTech(techname, techroot, pathroot, level)
|
|||
for (ld = dlist; ld; ld = ld->ld_next)
|
||||
{
|
||||
tdent = ld->ld_dirent;
|
||||
if (tdent->d_type != DT_DIR)
|
||||
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
|
||||
int is_dir = tdent->d_type == DT_DIR;
|
||||
#else
|
||||
int is_dir = path_is_dir(pathroot, tdent->d_name) > 0; /* treat error as false */
|
||||
#endif
|
||||
if (!is_dir)
|
||||
{
|
||||
if (!strcmp(tdent->d_name, techname))
|
||||
{
|
||||
closedir(tdir);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (ld = dlist; ld; ld = ld->ld_next)
|
||||
freeMagic(ld);
|
||||
freeMagic1(&mm1, ld);
|
||||
freeMagic1_end(&mm1);
|
||||
return pathroot;
|
||||
}
|
||||
}
|
||||
|
|
@ -262,8 +299,10 @@ DBSearchForTech(techname, techroot, pathroot, level)
|
|||
if (found)
|
||||
{
|
||||
closedir(tdir);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (ld = dlist; ld; ld = ld->ld_next)
|
||||
freeMagic(ld);
|
||||
freeMagic1(&mm1, ld);
|
||||
freeMagic1_end(&mm1);
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
|
@ -271,8 +310,12 @@ DBSearchForTech(techname, techroot, pathroot, level)
|
|||
closedir(tdir);
|
||||
}
|
||||
|
||||
for (ld = dlist; ld; ld = ld->ld_next)
|
||||
freeMagic(ld);
|
||||
{
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (ld = dlist; ld; ld = ld->ld_next)
|
||||
freeMagic1(&mm1, ld);
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -315,7 +358,12 @@ DBAddStandardCellPaths(pathptr, level)
|
|||
|
||||
while ((tdent = readdir(tdir)) != NULL)
|
||||
{
|
||||
if ((tdent->d_type == DT_DIR) &&
|
||||
#ifdef HAVE_STRUCT_DIRENT_D_TYPE
|
||||
int is_dir = tdent->d_type == DT_DIR;
|
||||
#else
|
||||
int is_dir = path_is_dir(pathptr, tdent->d_name) > 0; /* treat error as false */
|
||||
#endif
|
||||
if (is_dir &&
|
||||
(strcmp(tdent->d_name, ".") && strcmp(tdent->d_name, "..")))
|
||||
{
|
||||
/* Scan the directory contents of tdir for more subdirectories */
|
||||
|
|
@ -324,7 +372,7 @@ DBAddStandardCellPaths(pathptr, level)
|
|||
paths += DBAddStandardCellPaths(newpath, level + 1);
|
||||
freeMagic(newpath);
|
||||
}
|
||||
else if (tdent->d_type != DT_DIR)
|
||||
else if (!is_dir)
|
||||
{
|
||||
/* Scan the directory contents of tdir for .mag files */
|
||||
if (!strcmp(tdent->d_name + strlen(tdent->d_name) - 4, ".mag"))
|
||||
|
|
@ -1149,7 +1197,7 @@ DBFileRecovery(filename)
|
|||
switch(action)
|
||||
{
|
||||
case 0: /* Read */
|
||||
if (DBReadBackup(DBbackupFile) == TRUE)
|
||||
if (DBReadBackup(DBbackupFile, FALSE, TRUE) == TRUE)
|
||||
DBRemoveBackup();
|
||||
break;
|
||||
case 1: /* Cancel */
|
||||
|
|
@ -1185,24 +1233,38 @@ DBFileRecovery(filename)
|
|||
*/
|
||||
|
||||
bool
|
||||
DBReadBackup(name)
|
||||
DBReadBackup(name, archive, usederef)
|
||||
char *name; /* Name of the backup file */
|
||||
bool archive; /* TRUE if this is an archive file */
|
||||
bool usederef; /* If TRUE, then dereference all cells */
|
||||
{
|
||||
FILETYPE f;
|
||||
char *filename, *rootname, *chrptr;
|
||||
static const char *filetypes[] = {"archive", "backup", 0};
|
||||
char *filename, *rootname, *chrptr, *suffix, *filetype;
|
||||
char line[256];
|
||||
CellDef *cellDef;
|
||||
bool result = TRUE;
|
||||
|
||||
if ((f = PaZOpen(name, "r", NULL, "", NULL, NULL)) == NULL)
|
||||
if (archive)
|
||||
{
|
||||
TxError("Cannot open backup file \"%s\"\n", name);
|
||||
suffix = DBSuffix;
|
||||
filetype = (char *)filetypes[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
suffix = NULL;
|
||||
filetype = (char *)filetypes[1];
|
||||
}
|
||||
|
||||
if ((f = PaZOpen(name, "r", suffix, Path, NULL, NULL)) == NULL)
|
||||
{
|
||||
TxError("Cannot open %s file \"%s\"\n", filetype, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (dbFgets(line, sizeof(line), f) == NULL)
|
||||
{
|
||||
TxError("Bad backup file %s; can't restore!\n", name);
|
||||
TxError("Bad %s file %s; can't read!\n", filetype, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1236,22 +1298,26 @@ DBReadBackup(name)
|
|||
cellDef->cd_flags &= ~CDNOTFOUND;
|
||||
cellDef->cd_flags |= CDAVAILABLE;
|
||||
|
||||
if (dbCellReadDef(f, cellDef, TRUE, FALSE) == FALSE)
|
||||
if (dbCellReadDef(f, cellDef, TRUE, usederef) == FALSE)
|
||||
return FALSE;
|
||||
|
||||
if (dbFgets(line, sizeof(line), f) == NULL)
|
||||
{
|
||||
TxError("Error in backup file %s; partial restore only!\n",
|
||||
name);
|
||||
TxError("Error in %s file %s; partial restore only!\n",
|
||||
filetype, name);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update timestamp flags from dbCellReadDef() */
|
||||
DBFlagMismatches(cellDef);
|
||||
|
||||
/* Update bounding boxes */
|
||||
DBReComputeBbox(cellDef);
|
||||
}
|
||||
else
|
||||
{
|
||||
TxError("Error in backup file %s; expected keyword"
|
||||
" \"file\", got \"%s\"!\n", name, line);
|
||||
TxError("Error in %s file %s; expected keyword"
|
||||
" \"file\", got \"%s\"!\n", filetype, name, line);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1262,6 +1328,7 @@ DBReadBackup(name)
|
|||
*chrptr = '\0';
|
||||
DBWreload(line + 4);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -1427,15 +1494,28 @@ dbReadOpen(cellDef, setFileName, dereference, errptr)
|
|||
|
||||
/* If dereferencing, then use search paths first */
|
||||
if (!dereference)
|
||||
{
|
||||
f = PaLockZOpen(cellDef->cd_file, "r", DBSuffix, ".",
|
||||
(char *) NULL, &filename, &is_locked, &fd);
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
if (f == NULL)
|
||||
f = PaLockZOpen(cellDef->cd_file, "r", DBZSuffix, ".",
|
||||
(char *) NULL, &filename, &is_locked, &fd);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Fall back on the original method of using search paths. */
|
||||
|
||||
if (f == NULL)
|
||||
{
|
||||
f = PaLockZOpen(cellDef->cd_name, "r", DBSuffix, Path,
|
||||
CellLibPath, &filename, &is_locked, &fd);
|
||||
#ifdef HAVE_ZLIB
|
||||
if (f == NULL)
|
||||
f = PaLockZOpen(cellDef->cd_file, "r", DBZSuffix, Path,
|
||||
CellLibPath, &filename, &is_locked, &fd);
|
||||
#endif
|
||||
|
||||
if (f != NULL)
|
||||
{
|
||||
|
|
@ -1468,6 +1548,11 @@ dbReadOpen(cellDef, setFileName, dereference, errptr)
|
|||
{
|
||||
f = PaLockZOpen(cellDef->cd_file, "r", DBSuffix, ".",
|
||||
(char *) NULL, &filename, &is_locked, &fd);
|
||||
#ifdef HAVE_ZLIB
|
||||
if (f == NULL)
|
||||
f = PaLockZOpen(cellDef->cd_file, "r", DBZSuffix, ".",
|
||||
(char *) NULL, &filename, &is_locked, &fd);
|
||||
#endif
|
||||
if (f != NULL)
|
||||
if (DBVerbose)
|
||||
TxError("Warning: Dereferenced cell \"%s\" not "
|
||||
|
|
@ -1485,6 +1570,11 @@ dbReadOpen(cellDef, setFileName, dereference, errptr)
|
|||
{
|
||||
f = PaLockZOpen(cellDef->cd_name, "r", DBSuffix, Path,
|
||||
CellLibPath, &filename, &is_locked, &fd);
|
||||
#ifdef HAVE_ZLIB
|
||||
if (f == NULL)
|
||||
f = PaLockZOpen(cellDef->cd_name, "r", DBZSuffix, Path,
|
||||
CellLibPath, &filename, &is_locked, &fd);
|
||||
#endif
|
||||
if (errptr != NULL) *errptr = errno;
|
||||
}
|
||||
|
||||
|
|
@ -3080,7 +3170,7 @@ int
|
|||
DBCellFindScale(cellDef)
|
||||
CellDef *cellDef;
|
||||
{
|
||||
int dbFindGCFFunc(), dbFindCellGCFFunc();
|
||||
int dbFindGCFFunc(), dbFindCellGCFFunc(), dbFindPropGCFFunc();
|
||||
TileType type;
|
||||
TileTypeBitMask typeMask;
|
||||
int pNum;
|
||||
|
|
@ -3124,8 +3214,13 @@ DBCellFindScale(cellDef)
|
|||
}
|
||||
}
|
||||
|
||||
/* Finally, cell uses */
|
||||
/* Properties, where they are coordinates. This includes
|
||||
* FIXED_BBOX and MASKHINTS_*
|
||||
*/
|
||||
if (DBPropEnum(cellDef, dbFindPropGCFFunc, (ClientData)&ggcf))
|
||||
return 1;
|
||||
|
||||
/* Finally, cell uses */
|
||||
if (DBCellEnum(cellDef, dbFindCellGCFFunc, (ClientData) &ggcf))
|
||||
return 1;
|
||||
|
||||
|
|
@ -3133,8 +3228,9 @@ DBCellFindScale(cellDef)
|
|||
}
|
||||
|
||||
int
|
||||
dbFindGCFFunc(tile, ggcf)
|
||||
dbFindGCFFunc(tile, dinfo, ggcf)
|
||||
Tile *tile;
|
||||
TileType dinfo; /* (unused) */
|
||||
int *ggcf;
|
||||
{
|
||||
Rect r;
|
||||
|
|
@ -3193,6 +3289,73 @@ dbFindCellGCFFunc(cellUse, ggcf)
|
|||
return (*ggcf == 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
dbFindPropGCFFunc(key, value, ggcf)
|
||||
char *key;
|
||||
ClientData value;
|
||||
int *ggcf; /* Client data */
|
||||
{
|
||||
Rect bbox;
|
||||
char *vptr = value, *sptr;
|
||||
int numvals, n;
|
||||
|
||||
if (!strcmp(key, "FIXED_BBOX"))
|
||||
{
|
||||
if (sscanf(value, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
|
||||
&bbox.r_xtop, &bbox.r_ytop) == 4)
|
||||
{
|
||||
/* Check bounding box */
|
||||
if (bbox.r_xtop % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_xtop, *ggcf);
|
||||
if (bbox.r_xbot % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_xbot, *ggcf);
|
||||
if (bbox.r_ytop % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_ytop, *ggcf);
|
||||
if (bbox.r_ybot % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_ybot, *ggcf);
|
||||
}
|
||||
else
|
||||
TxError("Error: Cannot parse FIXED_BBOX property value!\n");
|
||||
}
|
||||
else if (!strncmp(key, "MASKHINTS_", 10))
|
||||
{
|
||||
while (TRUE)
|
||||
{
|
||||
numvals = sscanf(vptr, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
|
||||
&bbox.r_xtop, &bbox.r_ytop);
|
||||
if (numvals <= 0)
|
||||
break;
|
||||
else if (numvals != 4)
|
||||
{
|
||||
TxError("Error: Cannot parse %s property value at \"%s\"!\n",
|
||||
key, vptr);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check bounding box */
|
||||
if (bbox.r_xtop % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_xtop, *ggcf);
|
||||
if (bbox.r_xbot % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_xbot, *ggcf);
|
||||
if (bbox.r_ytop % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_ytop, *ggcf);
|
||||
if (bbox.r_ybot % (*ggcf) != 0)
|
||||
*ggcf = FindGCF(bbox.r_ybot, *ggcf);
|
||||
}
|
||||
|
||||
/* Skip forward four values in value */
|
||||
for (n = 0; n < 4; n++)
|
||||
{
|
||||
while (!isspace(*vptr) && (*vptr != '\0')) vptr++;
|
||||
while (isspace(*vptr) && (*vptr != '\0')) vptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (*ggcf == 1) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -3822,6 +3985,361 @@ dbWritePropFunc(key, value, cdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBCellWriteCommandFile --
|
||||
*
|
||||
* Write out the contents of a cell to the specified file as a sequence
|
||||
* of magic commands. Sourcing the resulting file will regenerate the
|
||||
* cell.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the cell could be written successfully, FALSE otherwise.
|
||||
*
|
||||
* Side effects:
|
||||
* Writes a file to disk.
|
||||
* Does NOT close the file 'f', but does fflush(f) before returning.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
bool
|
||||
DBCellWriteCommandFile(cellDef, f)
|
||||
CellDef *cellDef; /* Pointer to definition of cell to be written out */
|
||||
FILE *f; /* The FILE to write to */
|
||||
{
|
||||
int dbWritePaintCommandsFunc();
|
||||
int dbWriteUseCommandsFunc();
|
||||
int dbWritePropCommandsFunc();
|
||||
|
||||
Label *lab;
|
||||
struct writeArg arg;
|
||||
int pNum;
|
||||
TileType type, stype;
|
||||
TileTypeBitMask typeMask, *sMask;
|
||||
static const char *directionNames[] = {"c", "n", "ne", "e", "se",
|
||||
"s", "sw", "w", "nw", 0};
|
||||
|
||||
if (f == NULL) return FALSE;
|
||||
|
||||
SigDisableInterrupts();
|
||||
|
||||
/* Write a descriptive header */
|
||||
fprintf(f, "# Command script for generating cell %s\n", cellDef->cd_name);
|
||||
fprintf(f, "\n");
|
||||
fprintf(f, "suspendall\n");
|
||||
fprintf(f, "tech unlock *\n");
|
||||
fprintf(f, "snap internal\n");
|
||||
fprintf(f, "load %s -silent\n", cellDef->cd_name);
|
||||
fprintf(f, "box values 0 0 0 0\n");
|
||||
|
||||
/* These routines only need the file stream pointer */
|
||||
arg.wa_name = NULL;
|
||||
arg.wa_file = f;
|
||||
arg.wa_reducer = 1;
|
||||
|
||||
for (type = TT_PAINTBASE; type < DBNumUserLayers; type++)
|
||||
{
|
||||
if ((pNum = DBPlane(type)) < 0)
|
||||
continue;
|
||||
arg.wa_found = FALSE;
|
||||
arg.wa_type = type;
|
||||
arg.wa_plane = pNum;
|
||||
TTMaskSetOnlyType(&typeMask, type);
|
||||
|
||||
/* Add to the mask all generated (stacking) types which */
|
||||
/* have this type as a residue. */
|
||||
|
||||
for (stype = DBNumUserLayers; stype < DBNumTypes; stype++)
|
||||
{
|
||||
sMask = DBResidueMask(stype);
|
||||
if (TTMaskHasType(sMask, type))
|
||||
TTMaskSetType(&typeMask, stype);
|
||||
}
|
||||
|
||||
if (DBSrPaintArea((Tile *) NULL, cellDef->cd_planes[pNum],
|
||||
&TiPlaneRect, &typeMask, dbWritePaintCommandsFunc, (ClientData) &arg))
|
||||
goto ioerror;
|
||||
}
|
||||
|
||||
if (DBCellEnum(cellDef, dbWriteUseCommandsFunc, (ClientData)&arg))
|
||||
goto ioerror;
|
||||
|
||||
/* Now labels */
|
||||
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
|
||||
{
|
||||
if (strlen(lab->lab_text) == 0) continue; // Shouldn't happen
|
||||
|
||||
fprintf(f, "box values %d %d %d %d\n",
|
||||
lab->lab_rect.r_xbot,
|
||||
lab->lab_rect.r_ybot,
|
||||
lab->lab_rect.r_xtop,
|
||||
lab->lab_rect.r_ytop);
|
||||
|
||||
if (lab->lab_font < 0)
|
||||
{
|
||||
fprintf(f, "label %s %s %s\n",
|
||||
lab->lab_text,
|
||||
directionNames[lab->lab_just],
|
||||
DBTypeLongName(lab->lab_type));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(f, "label %s %s %d %d %d %d %s %s\n",
|
||||
lab->lab_text,
|
||||
DBFontList[lab->lab_font]->mf_name,
|
||||
lab->lab_size >> 3,
|
||||
lab->lab_rotate,
|
||||
lab->lab_offset.p_x,
|
||||
lab->lab_offset.p_y,
|
||||
directionNames[lab->lab_just],
|
||||
DBTypeLongName(lab->lab_type));
|
||||
}
|
||||
|
||||
if (lab->lab_flags & LABEL_STICKY)
|
||||
{
|
||||
fprintf(f, "select area label\n");
|
||||
fprintf(f, "setlabel sticky true\n");
|
||||
}
|
||||
|
||||
if (lab->lab_flags & PORT_DIR_MASK)
|
||||
{
|
||||
if (!(lab->lab_flags & LABEL_STICKY))
|
||||
fprintf(f, "select area label\n");
|
||||
|
||||
fprintf(f, "port make %d\n", lab->lab_port);
|
||||
|
||||
if (lab->lab_flags & (PORT_DIR_NORTH | PORT_DIR_SOUTH | PORT_DIR_EAST
|
||||
| PORT_DIR_WEST))
|
||||
fprintf(f, "port connections");
|
||||
if (lab->lab_flags & PORT_DIR_NORTH) fprintf(f, " n");
|
||||
if (lab->lab_flags & PORT_DIR_SOUTH) fprintf(f, " s");
|
||||
if (lab->lab_flags & PORT_DIR_EAST) fprintf(f, " e");
|
||||
if (lab->lab_flags & PORT_DIR_WEST) fprintf(f, " w");
|
||||
fprintf(f, "\n");
|
||||
|
||||
if (lab->lab_flags & PORT_USE_MASK)
|
||||
{
|
||||
fprintf(f, "port %d use ", lab->lab_port);
|
||||
switch (lab->lab_flags & PORT_USE_MASK)
|
||||
{
|
||||
case PORT_USE_SIGNAL:
|
||||
fprintf(f, "signal\n");
|
||||
break;
|
||||
case PORT_USE_ANALOG:
|
||||
fprintf(f, "analog\n");
|
||||
break;
|
||||
case PORT_USE_POWER:
|
||||
fprintf(f, "power\n");
|
||||
break;
|
||||
case PORT_USE_GROUND:
|
||||
fprintf(f, "ground\n");
|
||||
break;
|
||||
case PORT_USE_CLOCK:
|
||||
fprintf(f, "clock\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lab->lab_flags & PORT_CLASS_MASK)
|
||||
{
|
||||
fprintf(f, "port %d class ", lab->lab_port);
|
||||
switch (lab->lab_flags & PORT_CLASS_MASK)
|
||||
{
|
||||
case PORT_CLASS_INPUT:
|
||||
fprintf(f, "input\n");
|
||||
break;
|
||||
case PORT_CLASS_OUTPUT:
|
||||
fprintf(f, "output\n");
|
||||
break;
|
||||
case PORT_CLASS_TRISTATE:
|
||||
fprintf(f, "tristate\n");
|
||||
break;
|
||||
case PORT_CLASS_BIDIRECTIONAL:
|
||||
fprintf(f, "bidirectional\n");
|
||||
break;
|
||||
case PORT_CLASS_FEEDTHROUGH:
|
||||
fprintf(f, "feedthrough\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lab->lab_flags & PORT_SHAPE_MASK)
|
||||
{
|
||||
fprintf(f, "port %d shape ", lab->lab_port);
|
||||
switch (lab->lab_flags & PORT_SHAPE_MASK)
|
||||
{
|
||||
case PORT_SHAPE_ABUT:
|
||||
fprintf(f, "abutment\n");
|
||||
break;
|
||||
case PORT_SHAPE_RING:
|
||||
fprintf(f, "ring\n");
|
||||
break;
|
||||
case PORT_SHAPE_THRU:
|
||||
fprintf(f, "feedthrough\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Note: Persistant elements should be handled (see dbwind/DBWelement.c) */
|
||||
|
||||
/* And any properties */
|
||||
DBPropEnum(cellDef, dbWritePropCommandsFunc, (ClientData)&arg);
|
||||
|
||||
fprintf(f, "select clear\n");
|
||||
fprintf(f, "view\n");
|
||||
fprintf(f, "tech revert\n");
|
||||
fprintf(f, "resumeall\n");
|
||||
|
||||
if (fflush(f) == EOF || ferror(f))
|
||||
{
|
||||
ioerror:
|
||||
TxError("Warning: I/O error in writing file\n");
|
||||
SigEnableInterrupts();
|
||||
return (FALSE);
|
||||
}
|
||||
SigEnableInterrupts();
|
||||
TxPrintf("Saved cell %s as a sequence of magic commands (file %s.tcl).\n",
|
||||
cellDef->cd_name, cellDef->cd_name);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbWritePaintCommandsFunc ---
|
||||
*
|
||||
* Callback function used by DBCellWriteCommandFile() to output
|
||||
* commands corresponding to cell layout geometry.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbWritePaintCommandsFunc(tile, dinfo, cdarg)
|
||||
Tile *tile;
|
||||
TileType dinfo;
|
||||
ClientData cdarg;
|
||||
{
|
||||
char pstring[256];
|
||||
struct writeArg *arg = (struct writeArg *) cdarg;
|
||||
FILE *f = arg->wa_file;
|
||||
|
||||
TileType type = TiGetType(tile);
|
||||
TileTypeBitMask *lMask, *rMask;
|
||||
|
||||
int diridx;
|
||||
static const char *directionNames[] = {"nw", "se", "sw", "ne", 0};
|
||||
|
||||
/* Don't write out error tiles */
|
||||
if ((type == TT_ERROR_P) || (type == TT_ERROR_S) || (type == TT_ERROR_PS))
|
||||
return 0;
|
||||
|
||||
/* This could be refined by merging metal areas across contacts,
|
||||
* but the brute force procedure will do the job.
|
||||
*/
|
||||
|
||||
if (IsSplit(tile))
|
||||
{
|
||||
diridx = (SplitDirection(tile) << 1) + ((dinfo & TT_SIDE) ? 1 : 0);
|
||||
|
||||
fprintf(f, "box values %d %d %d %d\n",
|
||||
LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile));
|
||||
type = TiGetLeftType(tile);
|
||||
if (type != TT_SPACE)
|
||||
{
|
||||
fprintf(f, "splitpaint %s %s\n", directionNames[diridx],
|
||||
DBTypeLongNameTbl[type]);
|
||||
}
|
||||
type = TiGetRightType(tile);
|
||||
if (type != TT_SPACE)
|
||||
{
|
||||
fprintf(f, "splitpaint %s %s\n", directionNames[diridx],
|
||||
DBTypeLongNameTbl[type]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
type = TiGetType(tile);
|
||||
fprintf(f, "box values %d %d %d %d\n",
|
||||
LEFT(tile), BOTTOM(tile), RIGHT(tile), TOP(tile));
|
||||
fprintf(f, "paint %s\n", DBTypeLongNameTbl[type]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbWriteUseCommandsFunc ---
|
||||
*
|
||||
* Callback function used by DBCellWriteCommandFile() to output
|
||||
* commands corresponding to cell uses in the layout.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbWriteUseCommandsFunc(cellUse, cdarg)
|
||||
CellUse *cellUse;
|
||||
ClientData cdarg;
|
||||
{
|
||||
struct writeArg *arg = (struct writeArg *) cdarg;
|
||||
FILE *f = arg->wa_file;
|
||||
|
||||
fprintf(f, "box position %d %d\n", cellUse->cu_bbox.r_ll.p_x,
|
||||
cellUse->cu_bbox.r_ll.p_y);
|
||||
fprintf(f, "getcell %s\n", cellUse->cu_def->cd_name);
|
||||
fprintf(f, "identify %s\n", cellUse->cu_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbWritePropCommandsFunc ---
|
||||
*
|
||||
* Callback function used by DBCellWriteCommandFile() to output
|
||||
* commands corresponding to properties in the layout.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int
|
||||
dbWritePropCommandsFunc(key, value, cdarg)
|
||||
char *key;
|
||||
char *value;
|
||||
ClientData cdarg;
|
||||
{
|
||||
struct writeArg *arg = (struct writeArg *) cdarg;
|
||||
char *escstr, *p, *v;
|
||||
int vallen;
|
||||
FILE *f = arg->wa_file;
|
||||
|
||||
/* Probably need to escape more than just quotes here. */
|
||||
vallen = strlen(value) + 1;
|
||||
for (v = value; *v != '\0'; v++)
|
||||
if (*v == '"') vallen++;
|
||||
|
||||
escstr = (char *)mallocMagic(vallen);
|
||||
p = escstr;
|
||||
for (v = value; *v != '\0'; v++)
|
||||
{
|
||||
if (*v == '"')
|
||||
*p++ = '\\';
|
||||
*p++ = *v;
|
||||
}
|
||||
*p = '\0';
|
||||
fprintf(f, "property %s \"%s\"\n", key, escstr);
|
||||
freeMagic(escstr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -3882,11 +4400,27 @@ DBCellWrite(cellDef, fileName)
|
|||
|
||||
result = FALSE;
|
||||
|
||||
/*
|
||||
* Figure out the name of the file we will eventually write.
|
||||
*/
|
||||
if (!fileName)
|
||||
if (fileName)
|
||||
{
|
||||
/* Feature added 9/4/2025: If the filename ends with ".tcl",
|
||||
* then write the cell as a series of magic commands, and don't
|
||||
* otherwise alter the cell.
|
||||
*/
|
||||
if ((strlen(fileName) > 4) && (!strcmp(fileName + strlen(fileName) - 4, ".tcl")))
|
||||
{
|
||||
if ((realf = fopen(fileName, "w")))
|
||||
{
|
||||
result = DBCellWriteCommandFile(cellDef, realf);
|
||||
fclose(realf);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Figure out the name of the file we will eventually write.
|
||||
*/
|
||||
if (cellDef->cd_file)
|
||||
fileName = cellDef->cd_file;
|
||||
else if (cellDef->cd_name)
|
||||
|
|
@ -4175,8 +4709,9 @@ cleanup:
|
|||
*/
|
||||
|
||||
int
|
||||
dbWritePaintFunc(tile, cdarg)
|
||||
dbWritePaintFunc(tile, dinfo, cdarg)
|
||||
Tile *tile;
|
||||
TileType dinfo; /* (unused) */
|
||||
ClientData cdarg;
|
||||
{
|
||||
char pstring[256];
|
||||
|
|
@ -4238,7 +4773,7 @@ dbWritePaintFunc(tile, cdarg)
|
|||
sprintf(pstring, "rect %d %d %d %d\n",
|
||||
LEFT(tile) / arg->wa_reducer, BOTTOM(tile) / arg->wa_reducer,
|
||||
RIGHT(tile) / arg->wa_reducer, TOP(tile) / arg->wa_reducer);
|
||||
FPUTSR(arg->wa_file,pstring);
|
||||
FPUTSR(arg->wa_file, pstring);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -4507,7 +5042,7 @@ DBGetTech(cellName)
|
|||
static char line[512];
|
||||
char *p;
|
||||
|
||||
f = PaZOpen(cellName, "r", DBSuffix, Path, CellLibPath, (char **) NULL);
|
||||
f = PaZOpen(cellName, "r", DBSuffix, ".", CellLibPath, (char **) NULL);
|
||||
if (f == NULL) return NULL;
|
||||
|
||||
p = (char *) NULL;
|
||||
|
|
@ -4527,6 +5062,15 @@ ret:
|
|||
return (p);
|
||||
}
|
||||
|
||||
/* File and flags record used to hold information for dbWriteBackupFunc()
|
||||
* in DBWriteBackup()
|
||||
*/
|
||||
|
||||
typedef struct _fileAndFlags {
|
||||
FILE *ff_file;
|
||||
int ff_flags;
|
||||
} FileAndFlags;
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
@ -4540,6 +5084,13 @@ ret:
|
|||
* is set to this name, erasing any previous value. If "filename" is
|
||||
* an empty string, then the DBbackupFile reverts to NULL.
|
||||
*
|
||||
* If "archive" is TRUE, then save all read/write files, not just modified
|
||||
* ones, and do not remove the file when magic exits.
|
||||
*
|
||||
* If "doforall" is TRUE, the save all files including read-only PDK
|
||||
* cells. By definition, if "archive" is not chosen, then "doforall"
|
||||
* has no impact, since read-only cells cannot be modified.
|
||||
*
|
||||
* Results:
|
||||
* TRUE if the backup file was created, FALSE if an error was
|
||||
* encountered.
|
||||
|
|
@ -4553,25 +5104,39 @@ ret:
|
|||
*/
|
||||
|
||||
bool
|
||||
DBWriteBackup(filename)
|
||||
DBWriteBackup(filename, archive, doforall)
|
||||
char *filename;
|
||||
bool archive;
|
||||
bool doforall;
|
||||
{
|
||||
FILE *f;
|
||||
int fd, pid;
|
||||
char *tempdir;
|
||||
char *tempdir, *saveName = NULL;
|
||||
MagWindow *mw;
|
||||
FileAndFlags ff;
|
||||
|
||||
int dbWriteBackupFunc(), dbCheckModifiedCellsFunc();
|
||||
int flags = CDMODIFIED;
|
||||
int flags = 0;
|
||||
int result;
|
||||
|
||||
/* First check if there are any modified cells that need to be written */
|
||||
|
||||
result = DBCellSrDefs(flags, dbCheckModifiedCellsFunc, (ClientData)NULL);
|
||||
if (result == 0) return TRUE; /* Nothing to write */
|
||||
if (archive == FALSE)
|
||||
{
|
||||
flags = CDMODIFIED;
|
||||
result = DBCellSrDefs(flags, dbCheckModifiedCellsFunc, (ClientData)NULL);
|
||||
|
||||
/*
|
||||
* Avoid unnecessary backups: If there's nothing modified, then
|
||||
* there's nothing to write.
|
||||
*/
|
||||
if (result == 0) return TRUE;
|
||||
}
|
||||
|
||||
if (filename == NULL)
|
||||
{
|
||||
/* A NULL filename is used by the backup mechanism to save to /tmp/. */
|
||||
|
||||
if (DBbackupFile == (char *)NULL)
|
||||
{
|
||||
char *doslash, *template;
|
||||
|
|
@ -4605,8 +5170,14 @@ DBWriteBackup(filename)
|
|||
StrDup(&DBbackupFile, (char *)NULL);
|
||||
return TRUE;
|
||||
}
|
||||
if (archive == TRUE)
|
||||
{
|
||||
TxPrintf("Created database archive file %s\n", filename);
|
||||
saveName = StrDup((char **)NULL, DBbackupFile);
|
||||
}
|
||||
else
|
||||
TxPrintf("Created database crash recovery file %s\n", DBbackupFile);
|
||||
StrDup(&DBbackupFile, filename);
|
||||
TxPrintf("Created database crash recovery file %s\n", DBbackupFile);
|
||||
}
|
||||
|
||||
f = fopen(filename, "w");
|
||||
|
|
@ -4616,7 +5187,15 @@ DBWriteBackup(filename)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
result = DBCellSrDefs(flags, dbWriteBackupFunc, (ClientData)f);
|
||||
ff.ff_file = f;
|
||||
|
||||
/* Flags for recognizing which cells to ignore. Note that flags
|
||||
* for recognizing which cells to search is in "flags".
|
||||
*/
|
||||
ff.ff_flags = CDINTERNAL | CDNOTFOUND;
|
||||
if (!doforall) ff.ff_flags |= CDNOEDIT;
|
||||
|
||||
result = DBCellSrDefs(flags, dbWriteBackupFunc, (ClientData)&ff);
|
||||
|
||||
/* End by printing the keyword "end" followed by the cell to load */
|
||||
/* into the first available window, so that we don't have a default */
|
||||
|
|
@ -4628,6 +5207,17 @@ DBWriteBackup(filename)
|
|||
else
|
||||
fprintf(f, "end\n");
|
||||
fclose(f);
|
||||
|
||||
/* If archiving, put DBbackupFile back to the name that it contained
|
||||
* prior to doing the archive, so that the archive does not interfere
|
||||
* with the backup mechanism.
|
||||
*/
|
||||
if (archive == TRUE)
|
||||
{
|
||||
StrDup(&DBbackupFile, saveName);
|
||||
if (saveName)
|
||||
freeMagic(saveName);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -4639,14 +5229,18 @@ DBWriteBackup(filename)
|
|||
*/
|
||||
|
||||
int
|
||||
dbWriteBackupFunc(def, f)
|
||||
dbWriteBackupFunc(def, clientData)
|
||||
CellDef *def; /* Pointer to CellDef to be saved */
|
||||
FILE *f; /* File to append to */
|
||||
ClientData clientData;
|
||||
{
|
||||
char *name = def->cd_file;
|
||||
int result, save_flags;
|
||||
FileAndFlags *ff = (FileAndFlags *)clientData;
|
||||
|
||||
if (def->cd_flags & (CDINTERNAL | CDNOEDIT | CDNOTFOUND)) return 0;
|
||||
FILE *f = ff->ff_file;
|
||||
int flags = ff->ff_flags;
|
||||
|
||||
if (def->cd_flags & flags) return 0;
|
||||
else if (!(def->cd_flags & CDAVAILABLE)) return 0;
|
||||
|
||||
if (name == NULL) name = def->cd_name;
|
||||
|
|
|
|||
|
|
@ -280,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)
|
||||
|
|
@ -313,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;
|
||||
|
|
@ -321,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;
|
||||
|
|
@ -442,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)
|
||||
|
|
@ -457,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!
|
||||
|
|
@ -467,6 +470,7 @@ DBEraseLabelsByContent(def, rect, type, text)
|
|||
if (lab == NULL) break;
|
||||
else goto nextCheck;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -495,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)
|
||||
|
|
@ -508,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!
|
||||
|
|
@ -518,6 +523,7 @@ DBRemoveLabel(def, refLab)
|
|||
if (lab == NULL) break;
|
||||
else goto nextCheck;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -577,8 +583,9 @@ DBReOrientLabel(cellDef, area, newPos)
|
|||
*/
|
||||
|
||||
int
|
||||
dbGetLabelArea(tile, area)
|
||||
dbGetLabelArea(tile, dinfo, area)
|
||||
Tile *tile; /* Tile found. */
|
||||
TileType dinfo; /* Split tile information (unused) */
|
||||
Rect *area; /* Area to be modified. */
|
||||
{
|
||||
Rect r;
|
||||
|
|
@ -760,8 +767,10 @@ DBAdjustLabelsNew(def, area)
|
|||
def->cd_lastLabel = labPrev;
|
||||
DBUndoEraseLabel(def, lab);
|
||||
DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
|
||||
freeMagic((char *) lab);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, (char *) lab);
|
||||
lab = lab->lab_next;
|
||||
freeMagic1_end(&mm1);
|
||||
modified = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1077,14 +1086,15 @@ DBPickLabelLayer(def, lab, doCalma)
|
|||
*/
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -1103,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);
|
||||
|
||||
|
|
@ -1744,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
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ Tile *TiNMMergeRight();
|
|||
Tile *TiNMMergeLeft();
|
||||
|
||||
#ifdef PAINTDEBUG
|
||||
void dbPaintShowTile(Tile *tile, PaintUndoInfo *undo, char *str);
|
||||
|
||||
int dbPaintDebug = 0;
|
||||
#endif /* PAINTDEBUG */
|
||||
|
||||
|
|
@ -271,6 +273,7 @@ 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 = PlaneGetHint(plane);
|
||||
|
|
@ -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)");
|
||||
|
|
@ -697,6 +718,7 @@ enum2:
|
|||
|
||||
done2:
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1032,6 +1054,7 @@ 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;
|
||||
|
|
@ -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 */
|
||||
|
|
@ -1307,6 +1330,7 @@ nmenum:
|
|||
|
||||
nmdone:
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1411,10 +1435,6 @@ DBDiagonalProc(oldtype, dinfo)
|
|||
else
|
||||
return -1;
|
||||
|
||||
/* For purposes of "undo" recording, record which side we just painted */
|
||||
if (dinfo->side)
|
||||
newtype |= TT_SIDE;
|
||||
|
||||
return newtype;
|
||||
}
|
||||
|
||||
|
|
@ -1768,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) ?
|
||||
|
|
@ -1794,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);
|
||||
|
|
@ -1885,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;
|
||||
|
||||
|
|
@ -1991,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");
|
||||
|
|
@ -2007,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");
|
||||
|
|
@ -2016,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");
|
||||
|
|
@ -2025,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);
|
||||
}
|
||||
|
||||
|
|
@ -2094,6 +2119,7 @@ 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 = PlaneGetHint(plane);
|
||||
|
|
@ -2186,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 */
|
||||
|
|
@ -2210,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
|
||||
|
|
@ -2276,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)");
|
||||
|
|
@ -2286,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,6 +2360,7 @@ paintdone:
|
|||
|
||||
done:
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -2380,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;
|
||||
|
||||
|
|
@ -2481,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");
|
||||
|
|
@ -2497,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");
|
||||
|
|
@ -2506,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");
|
||||
|
|
@ -2515,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);
|
||||
}
|
||||
|
||||
|
|
@ -2581,6 +2610,7 @@ 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 = PlaneGetHint(plane);
|
||||
|
|
@ -2662,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 */
|
||||
|
|
@ -2678,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
|
||||
|
|
@ -2740,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)");
|
||||
|
|
@ -2749,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,6 +2827,7 @@ paintdone:
|
|||
|
||||
done:
|
||||
PlaneSetHint(plane, tile);
|
||||
TiFreeIf(delayed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2849,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;
|
||||
|
||||
|
|
@ -2943,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");
|
||||
|
|
@ -2956,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");
|
||||
|
|
@ -2966,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");
|
||||
|
|
@ -2975,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);
|
||||
}
|
||||
|
||||
|
|
@ -3004,7 +3037,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
|
|||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "styles.h"
|
||||
#include "utils/styles.h"
|
||||
|
||||
void
|
||||
dbPaintShowTile(tile, undo, str)
|
||||
|
|
@ -3027,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 */
|
||||
|
||||
|
|
@ -3316,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;
|
||||
|
||||
|
|
@ -3347,7 +3391,7 @@ TiNMMergeRight(tile, plane)
|
|||
else
|
||||
newtile = tile;
|
||||
// Join tp to newtile
|
||||
TiJoinX(newtile, tp, plane);
|
||||
TiJoinX1(&delayed, newtile, tp, plane);
|
||||
}
|
||||
tp = tp2;
|
||||
}
|
||||
|
|
@ -3364,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;
|
||||
}
|
||||
|
||||
|
|
@ -3396,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;
|
||||
|
||||
|
|
@ -3428,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;
|
||||
|
|
@ -3446,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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
||||
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
|
@ -129,7 +420,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
|
|||
{
|
||||
/* Each iteration enumerates another tile */
|
||||
nm_enum:
|
||||
PlaneSetHint(plane, 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, INT2CD(tpt & ~TT_SIDE)); /* bit clear */
|
||||
if ((*func)(tp, arg)) return (1);
|
||||
}
|
||||
if (!(ignore_sides & IGNORE_RIGHT))
|
||||
{
|
||||
TiSetBody(tp, INT2CD(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;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -416,9 +587,7 @@ enumerate:
|
|||
(dlong)(rect->r_xbot - LEFT(tp)) * theight : DLONG_MIN;
|
||||
if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4))
|
||||
{
|
||||
TiSetBody(tp, INT2CD((TileType)CD2INT(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, INT2CD((TileType)CD2INT(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;
|
||||
* {
|
||||
* }
|
||||
|
|
@ -576,9 +744,7 @@ enumerate:
|
|||
(dlong)(rect->r_xbot - LEFT(tp)) * (dlong)theight : DLONG_MIN;
|
||||
if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4))
|
||||
{
|
||||
TiSetBody(tp, INT2CD((TileType)CD2INT(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);
|
||||
}
|
||||
}
|
||||
|
|
@ -590,16 +756,15 @@ enumerate:
|
|||
(dlong)(RIGHT(tp) - rect->r_xtop) * (dlong)theight : DLONG_MIN;
|
||||
if (SplitDirection(tp) ? (f2 > f3) : (f1 > f3))
|
||||
{
|
||||
TiSetBody(tp, INT2CD((TileType)CD2INT(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);
|
||||
|
|
@ -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.
|
||||
*
|
||||
* --------------------------------------------------------------------
|
||||
*/
|
||||
|
|
@ -740,6 +985,7 @@ DBFreePaintPlane(plane)
|
|||
/* 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;
|
||||
|
|
|
|||
|
|
@ -137,8 +137,10 @@ 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;
|
||||
|
||||
(void) DBCellRead(cellDef, TRUE, TRUE, NULL);
|
||||
|
|
@ -182,13 +184,15 @@ DBFixMismatch()
|
|||
}
|
||||
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(", ");
|
||||
freeMagic(cl);
|
||||
freeMagic1(&mm1, cl);
|
||||
cl = cl->cl_next;
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
TxPrintf(".\n");
|
||||
TxFlush();
|
||||
if (redisplay) WindAreaChanged((MagWindow *) NULL, (Rect *) NULL);
|
||||
|
|
@ -227,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);
|
||||
|
|
@ -247,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,18 @@ SRCS = DBbound.c DBcell.c DBcellbox.c DBcellcopy.c \
|
|||
include ${MAGICDIR}/defs.mak
|
||||
|
||||
LIB_OBJS += ${MAGICDIR}/tiles/libtiles.o ${MAGICDIR}/utils/libutils.o
|
||||
CLEANS += database.h
|
||||
# database.h is managed by the toplevel Makefile, because it has a build dependency
|
||||
# order affecting multiple modules that need it. Both the creation time and the
|
||||
# removal time (during 'clean') are managed by toplevel Makefile.
|
||||
# if it was additionally removed by this clause here, it only causes bogus errors
|
||||
# to be seen during some make operations due to race conditions caused by the
|
||||
# unexpected removal by this clause in parallel MAKE execution of other modules
|
||||
# that thought the file existed. FWIW database.h should be created first (near the
|
||||
# start of top level build) and removed last (near the end of a top level clean).
|
||||
#CLEANS += database.h
|
||||
|
||||
# This is delegated back to the top level Makefile
|
||||
database.h: ${MAGICDIR}/database/database.h.in
|
||||
${MAKE} -C ${MAGICDIR} database/database.h
|
||||
|
||||
include ${MAGICDIR}/rules.mak
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* arrayinfo.h --
|
||||
*
|
||||
* *********************************************************************
|
||||
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
||||
* * Permission to use, copy, modify, and distribute this *
|
||||
* * software and its documentation for any purpose and without *
|
||||
* * fee is hereby granted, provided that the above copyright *
|
||||
* * notice appear in all copies. The University of California *
|
||||
* * makes no representations about the suitability of this *
|
||||
* * software for any purpose. It is provided "as is" without *
|
||||
* * express or implied warranty. Export of this software outside *
|
||||
* * of the United States of America may require an export license. *
|
||||
* *********************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MAGIC__DATABASE__ARRAYINFO_H
|
||||
#define _MAGIC__DATABASE__ARRAYINFO_H
|
||||
|
||||
/*
|
||||
* Description of an array.
|
||||
* The bounds xlo .. xhi and ylo .. yhi are transformed versions
|
||||
* of the bounds xlo' .. xhi' and ylo' .. yhi' supplied by the
|
||||
* user:
|
||||
*
|
||||
* User supplies:
|
||||
* xlo' index of leftmost array element in root coordinates
|
||||
* xhi' index of rightmost array element in root coordinates
|
||||
* ylo' index of bottommost array element in root coordinates
|
||||
* yhi' index of topmost array element in root coordinates
|
||||
*
|
||||
* There is no constraint on the order of any of these indices; xlo' may
|
||||
* be less than, equal to, or greater than xhi', and similarly for ylo'
|
||||
* and yhi'.
|
||||
*
|
||||
* In addition, the separations xsep and ysep are transformed versions
|
||||
* of the separations xsep' and ysep' supplied by the user:
|
||||
*
|
||||
* User supplies:
|
||||
* xsep' (positive) X spacing between array elements in root coords
|
||||
* ysep' (positive) Y spacing between array elements in root coords
|
||||
*
|
||||
* When the array is made via DBMakeArray, both the indices and the spacings
|
||||
* are transformed down to the coordinates of the CellDef that is the child
|
||||
* of the use containing the ArrayInfo.
|
||||
*
|
||||
* The significance of the various values is as follows: the [xlo, ylo]
|
||||
* element of the array is gotten by transforming the celldef by the
|
||||
* transformation in the celluse. the [x, y] element is gotten by
|
||||
* transforming the celldef by xsep*abs(x-xlo) in x, ysep*abs(y-ylo) in
|
||||
* y, and then transforming by the transformation in the celluse.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ar_xlo, ar_xhi; /* Inclusive low/high X bounds */
|
||||
int ar_ylo, ar_yhi; /* Inclusive low/high Y bounds */
|
||||
int ar_xsep, ar_ysep; /* X,Y sep between array elements */
|
||||
} ArrayInfo;
|
||||
|
||||
#endif /* _MAGIC__DATABASE__ARRAYINFO_H */
|
||||
|
|
@ -22,24 +22,24 @@
|
|||
* rcsid "$Header: /usr/cvsroot/magic-8.0/database/database.h.in,v 1.8 2010/08/25 17:33:55 tim Exp $"
|
||||
*/
|
||||
|
||||
#ifndef _DATABASE_H
|
||||
#define _DATABASE_H
|
||||
#ifndef _MAGIC__DATABASE__DATABASE_H
|
||||
#define _MAGIC__DATABASE__DATABASE_H
|
||||
|
||||
#ifndef _TILES_H
|
||||
#ifndef _MAGIC__TILES__TILE_H
|
||||
#include "tiles/tile.h"
|
||||
#endif /* _TILES_H */
|
||||
#endif
|
||||
|
||||
#ifndef _HASH_H
|
||||
#ifndef _MAGIC__UTILS__HASH_H
|
||||
#include "utils/hash.h"
|
||||
#endif /* _HASH_H */
|
||||
#endif
|
||||
|
||||
#ifndef _STACK_H
|
||||
#ifndef _MAGIC__UTILS__STACK_H
|
||||
#include "utils/stack.h"
|
||||
#endif /* _STACK_H */
|
||||
#endif
|
||||
|
||||
#ifndef _BPLANE_H
|
||||
#ifndef _MAGIC__BPLANE__BPLANE_H
|
||||
#include "bplane/bplane.h"
|
||||
#endif /* _BPLANE_H */
|
||||
#endif
|
||||
|
||||
/* ----------------------- Tunable constants -------------------------- */
|
||||
|
||||
|
|
@ -303,9 +303,14 @@ typedef struct label
|
|||
#define PORT_SHAPE_RING 0x1000 /* Port is a ring shape */
|
||||
#define PORT_SHAPE_THRU 0x1800 /* Port is a feedthrough shape */
|
||||
|
||||
#define PORT_VISITED 0x2000 /* Bit for checking if a port */
|
||||
#define LABEL_STICKY 0x2000 /* Label does not change layers */
|
||||
#define LABEL_UNIQUE 0x4000 /* Temporary unique label */
|
||||
|
||||
/* The last two flags are never used at the same time and so can share
|
||||
* a flag bit.
|
||||
*/
|
||||
#define PORT_VISITED 0x8000 /* Bit for checking if a port */
|
||||
/* has been previously visited. */
|
||||
#define LABEL_STICKY 0x4000 /* Label does not change layers */
|
||||
#define LABEL_GENERATE 0x8000 /* Auto-generated label */
|
||||
|
||||
/*
|
||||
|
|
@ -403,6 +408,9 @@ typedef struct celldef
|
|||
* is added to the magic database. The flag is used to identify
|
||||
* whether the cell has been processed when forcing the GDS
|
||||
* stream data to be read in post-order.
|
||||
* CDPRELOADED is similar to CDPROCESSEDGDS but is used in cases
|
||||
* other than forced post-order reading, such as flattening
|
||||
* or flatten-by-name.
|
||||
* CDVENDORGDS indicates that the cell was read from a GDS stream
|
||||
* with the option "gds readonly true".
|
||||
* CDVISITED indicates that at least one instance of the cell was
|
||||
|
|
@ -434,53 +442,15 @@ typedef struct celldef
|
|||
#define CDFLATGDS 0x00400
|
||||
#define CDFLATTENED 0x00800
|
||||
#define CDPROCESSEDGDS 0x01000
|
||||
#define CDVENDORGDS 0x02000
|
||||
#define CDVISITED 0x04000
|
||||
#define CDDEREFERENCE 0x08000
|
||||
#define CDFIXEDSTAMP 0x10000
|
||||
#define CDNOEXTRACT 0x20000
|
||||
#define CDDONTUSE 0x40000
|
||||
#define CDPRELOADED 0x02000
|
||||
#define CDVENDORGDS 0x04000
|
||||
#define CDVISITED 0x08000
|
||||
#define CDDEREFERENCE 0x10000
|
||||
#define CDFIXEDSTAMP 0x20000
|
||||
#define CDNOEXTRACT 0x40000
|
||||
#define CDDONTUSE 0x80000
|
||||
|
||||
/*
|
||||
* Description of an array.
|
||||
* The bounds xlo .. xhi and ylo .. yhi are transformed versions
|
||||
* of the bounds xlo' .. xhi' and ylo' .. yhi' supplied by the
|
||||
* user:
|
||||
*
|
||||
* User supplies:
|
||||
* xlo' index of leftmost array element in root coordinates
|
||||
* xhi' index of rightmost array element in root coordinates
|
||||
* ylo' index of bottommost array element in root coordinates
|
||||
* yhi' index of topmost array element in root coordinates
|
||||
*
|
||||
* There is no constraint on the order of any of these indices; xlo' may
|
||||
* be less than, equal to, or greater than xhi', and similarly for ylo'
|
||||
* and yhi'.
|
||||
*
|
||||
* In addition, the separations xsep and ysep are transformed versions
|
||||
* of the separations xsep' and ysep' supplied by the user:
|
||||
*
|
||||
* User supplies:
|
||||
* xsep' (positive) X spacing between array elements in root coords
|
||||
* ysep' (positive) Y spacing between array elements in root coords
|
||||
*
|
||||
* When the array is made via DBMakeArray, both the indices and the spacings
|
||||
* are transformed down to the coordinates of the CellDef that is the child
|
||||
* of the use containing the ArrayInfo.
|
||||
*
|
||||
* The significance of the various values is as follows: the [xlo, ylo]
|
||||
* element of the array is gotten by transforming the celldef by the
|
||||
* transformation in the celluse. the [x, y] element is gotten by
|
||||
* transforming the celldef by xsep*abs(x-xlo) in x, ysep*abs(y-ylo) in
|
||||
* y, and then transforming by the transformation in the celluse.
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ar_xlo, ar_xhi; /* Inclusive low/high X bounds */
|
||||
int ar_ylo, ar_yhi; /* Inclusive low/high Y bounds */
|
||||
int ar_xsep, ar_ysep; /* X,Y sep between array elements */
|
||||
} ArrayInfo;
|
||||
#include "database/arrayinfo.h" /* ArrayInfo */
|
||||
|
||||
/*
|
||||
* Since a cell may be used in an orientation different from that
|
||||
|
|
@ -586,6 +556,18 @@ typedef struct diag_info
|
|||
bool side;
|
||||
} DiagInfo;
|
||||
|
||||
/* Where search functions need to return a Tile pointer and tile split */
|
||||
/* information, use this structure. Contains a pointer to its own */
|
||||
/* structure type so that it may also be used to create a linked list */
|
||||
/* of tiles including split side information. */
|
||||
|
||||
typedef struct tile_and_dinfo
|
||||
{
|
||||
struct tile_and_dinfo *tad_next;
|
||||
Tile *tad_tile;
|
||||
TileType tad_dinfo;
|
||||
} TileAndDinfo;
|
||||
|
||||
/* This would normally go in geometry.h except that it uses TileType. */
|
||||
/* Used in selOps.c but also passed back to CmdRS.c for select command. */
|
||||
|
||||
|
|
@ -808,7 +790,7 @@ extern void DBTechInit();
|
|||
extern bool DBTechSetTech();
|
||||
extern void DBTechInitVersion();
|
||||
extern bool DBTechSetVersion();
|
||||
extern bool DBTechAddPlane();
|
||||
extern bool DBTechAddPlane(const char *sectionName, int argc, char *argv[]);
|
||||
extern bool DBTechAddType();
|
||||
extern bool DBTechAddAlias();
|
||||
extern void DBTechFinalType();
|
||||
|
|
@ -820,7 +802,7 @@ extern int DBTechNamePlane(), DBTechNoisyNamePlane();
|
|||
extern PlaneMask DBTechNameMask(), DBTechNoisyNameMask();
|
||||
extern PlaneMask DBTechTypesToPlanes();
|
||||
extern bool DBTechTypesOnPlane();
|
||||
extern void DBTechInitPlane();
|
||||
extern void DBTechInitPlane(void);
|
||||
extern void DBTypeInit();
|
||||
extern void DBTechInitType();
|
||||
extern void DBTechInitCompose();
|
||||
|
|
@ -955,9 +937,10 @@ extern int DBArraySr();
|
|||
extern bool DBNearestLabel();
|
||||
extern int DBSrLabelLoc();
|
||||
extern TileType DBTransformDiagonal();
|
||||
extern int dbcUnconnectFunc(Tile *tile, ClientData clientData); /* (notused) */
|
||||
extern int dbSrConnectFunc(Tile *tile, ClientData clientData); /* (struct conSrArg *csa) */
|
||||
extern int dbSrConnectStartFunc(Tile *tile, ClientData clientData); /* cb_database_srpaintarea_t (Tile **pTile) */
|
||||
extern bool DBTestNMInteract(Rect *rect1, TileType tt1, Tile *t2, TileType di2, bool overlap_only);
|
||||
extern int dbcUnconnectFunc(Tile *tile, TileType dinfo, ClientData clientData); /* (notused) */
|
||||
extern int dbSrConnectFunc(Tile *tile, TileType dinfo, ClientData clientData); /* (struct conSrArg *csa) */
|
||||
extern int dbSrConnectStartFunc(Tile *tile, TileType dinfo, ClientData clientData); /* cb_database_srpaintarea_t (Tile **pTile) */
|
||||
|
||||
/* C99 compat */
|
||||
extern void DBEraseValid();
|
||||
|
|
@ -1004,10 +987,10 @@ extern int dbIsPrimary();
|
|||
extern void dbTechMatchResidues();
|
||||
extern void DBUndoInit();
|
||||
extern void DBResetTilePlane();
|
||||
extern void DBResetTilePlaneSpecial();
|
||||
extern void DBNewYank();
|
||||
extern int DBSrPaintClient();
|
||||
extern int DBSrConnect();
|
||||
extern int DBSrConnectOnePlane();
|
||||
extern char *dbFgets();
|
||||
extern void DBAdjustLabelsNew();
|
||||
extern bool DBScaleValue();
|
||||
|
|
@ -1094,10 +1077,10 @@ extern int DBNumPlanes;
|
|||
extern HashTable DBTypeAliasTable;
|
||||
|
||||
/* Gives the official long name of each plane: */
|
||||
extern char *DBPlaneLongNameTbl[NP];
|
||||
extern const char *DBPlaneLongNameTbl[NP];
|
||||
|
||||
/* Gives a short name for each plane: */
|
||||
extern char *DBPlaneShortName();
|
||||
extern const char *DBPlaneShortName();
|
||||
|
||||
/* Gives for each plane a mask of all tile types stored in that plane: */
|
||||
extern TileTypeBitMask DBPlaneTypes[NP];
|
||||
|
|
@ -1156,10 +1139,10 @@ extern int DBTypePlaneTbl[TT_MAXTYPES];
|
|||
extern PlaneMask DBTypePlaneMaskTbl[TT_MAXTYPES];
|
||||
|
||||
/* Gives the long name for each tile type: */
|
||||
extern char *DBTypeLongNameTbl[TT_MAXTYPES];
|
||||
extern const char *DBTypeLongNameTbl[TT_MAXTYPES];
|
||||
|
||||
/* Gives a short name for a tile type: */
|
||||
extern char *DBTypeShortName();
|
||||
extern const char *DBTypeShortName(TileType type);
|
||||
|
||||
/*
|
||||
* The following give masks of all planes that may be affected
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/database/databaseInt.h,v 1.3 2010/06/24 12:37:15 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DATABASEINT_H
|
||||
#define _DATABASEINT_H
|
||||
#ifndef _MAGIC__DATABASE__DATABASEINT_H
|
||||
#define _MAGIC__DATABASE__DATABASEINT_H
|
||||
|
||||
#include "database/database.h"
|
||||
|
||||
|
|
@ -194,6 +194,8 @@ typedef struct
|
|||
extern int dbNumSavedRules;
|
||||
extern Rule dbSavedRules[];
|
||||
|
||||
extern HashTable dbCellDefTable; /* Exported for diagnostics */
|
||||
|
||||
/* -------------------- Internal procedure headers -------------------- */
|
||||
|
||||
extern void DBUndoPutLabel();
|
||||
|
|
@ -247,4 +249,4 @@ extern TileTypeBitMask dbNotDefaultPaintTbl[];
|
|||
#define ERASEAFFECTS(t, s) \
|
||||
((t) != TT_SPACE && DBStdEraseEntry((t), (s), DBPlane(t)) != (t))
|
||||
|
||||
#endif /* _DATABASEINT_H */
|
||||
#endif /* _MAGIC__DATABASE__DATABASEINT_H */
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@
|
|||
* rcsid "$$"
|
||||
*/
|
||||
|
||||
#ifndef _FONTS_H
|
||||
#define _FONTS_H
|
||||
#ifndef _MAGIC__DATABASE__FONTS_H
|
||||
#define _MAGIC__DATABASE__FONTS_H
|
||||
|
||||
#ifndef _TILES_H
|
||||
#ifndef _MAGIC__TILES__TILE_H
|
||||
#include "tiles/tile.h"
|
||||
#endif /* _TILES_H */
|
||||
#endif
|
||||
|
||||
/* ---------------------------- Fonts --------------------------------- */
|
||||
|
||||
|
|
@ -39,4 +39,4 @@ typedef struct
|
|||
extern MagicFont **DBFontList; /* List of loaded font vectors */
|
||||
extern int DBNumFonts; /* Number of loaded fonts */
|
||||
|
||||
#endif /* _FONTS_H */
|
||||
#endif /* _MAGIC__DATABASE__FONTS_H */
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tcltk/tclmagic.h"
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
#include "tiles/tile.h"
|
||||
|
|
@ -240,6 +241,38 @@ DBWChangeButtonHandler(name)
|
|||
return oldName;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBWGetButtonHandler --
|
||||
*
|
||||
* Return the name of the current button handler. This does the same
|
||||
* thing as DBWChangeButtonHandler(name) with an invalid name, but
|
||||
* without printing the error messages. However, if magic is running
|
||||
* with the Tcl interpreter wrapper, then return the string value of
|
||||
* $Opts(tool), if it exists.
|
||||
*
|
||||
* Results:
|
||||
* A pointer to the name of the current button handler.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
DBWGetButtonHandler()
|
||||
{
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *toolName;
|
||||
toolName = (char *)Tcl_GetVar2(magicinterp, "Opts", "tool", TCL_GLOBAL_ONLY);
|
||||
if (toolName != NULL) return toolName;
|
||||
#endif
|
||||
|
||||
return dbwButtonHandlers[dbwButtonCurrentIndex];
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
* Standard DBWind command set
|
||||
*/
|
||||
|
||||
extern void CmdAddPath(), CmdAntennaCheck(), CmdArray();
|
||||
extern void CmdAddPath(), CmdAntennaCheck(), CmdArchive(), CmdArray();
|
||||
extern void CmdBox(), CmdCellname(), CmdClockwise();
|
||||
extern void CmdContact(), CmdCopy(), CmdCorner();
|
||||
extern void CmdCrash(), CmdCrosshair();
|
||||
|
|
@ -54,7 +54,7 @@ extern void CmdRandom(), CmdSave(), CmdScaleGrid(), CmdSee();
|
|||
extern void CmdSelect(), CmdSetLabel(), CmdSideways();
|
||||
extern void CmdShell(), CmdSnap();
|
||||
extern void CmdStretch(), CmdStraighten();
|
||||
extern void CmdTech(), CmdTool(), CmdUnexpand();
|
||||
extern void CmdTech(), CmdTool(), CmdUnexpand(), CmdUnits();
|
||||
extern void CmdUpsidedown(), CmdWhat(), CmdWire(), CmdWriteall();
|
||||
extern void CmdGoto(), CmdFlatten(), CmdXload(), CmdXor();
|
||||
|
||||
|
|
@ -75,6 +75,7 @@ extern void CmdExtResis();
|
|||
extern void CmdPsearch();
|
||||
extern void CmdPlowTest();
|
||||
extern void CmdShowtech();
|
||||
extern void CmdShowmem();
|
||||
extern void CmdTilestats();
|
||||
extern void CmdTsearch();
|
||||
extern void CmdWatch();
|
||||
|
|
@ -208,6 +209,9 @@ DBWInitCommands()
|
|||
WindAddCommand(DBWclientID,
|
||||
"*psearch plane count invoke point search over box area",
|
||||
CmdPsearch, FALSE);
|
||||
WindAddCommand(DBWclientID,
|
||||
"*showmem [file] print internal memory usage",
|
||||
CmdShowmem, FALSE);
|
||||
WindAddCommand(DBWclientID,
|
||||
"*showtech [file] print internal technology tables",
|
||||
CmdShowtech, FALSE);
|
||||
|
|
@ -223,9 +227,15 @@ DBWInitCommands()
|
|||
WindAddCommand(DBWclientID,
|
||||
"addpath [path] append to current search path",
|
||||
CmdAddPath, FALSE);
|
||||
#ifdef LEF_MODULE
|
||||
WindAddCommand(DBWclientID,
|
||||
"antennacheck [path] check for antenna violations",
|
||||
CmdAntennaCheck, FALSE);
|
||||
#endif
|
||||
WindAddCommand(DBWclientID,
|
||||
"archive write|read file\n"
|
||||
" write or read the archive file \"file\".",
|
||||
CmdArchive, FALSE);
|
||||
WindAddCommand(DBWclientID,
|
||||
"array xsize ysize OR\n"
|
||||
"array xlo xhi ylo yhi\n"
|
||||
|
|
@ -464,6 +474,9 @@ DBWInitCommands()
|
|||
WindAddCommand(DBWclientID,
|
||||
"unexpand unexpand subcells under box",
|
||||
CmdUnexpand, FALSE);
|
||||
WindAddCommand(DBWclientID,
|
||||
"units [type] set type of units parsed and displayed",
|
||||
CmdUnits, FALSE);
|
||||
WindAddCommand(DBWclientID,
|
||||
"upsidedown flip selection and box upside down",
|
||||
CmdUpsidedown, FALSE);
|
||||
|
|
|
|||
|
|
@ -571,8 +571,9 @@ DBWredisplay(w, rootArea, clipArea)
|
|||
*/
|
||||
|
||||
int
|
||||
dbwPaintFunc(tile, cxp)
|
||||
Tile *tile; /* Tile to be redisplayed. */
|
||||
dbwPaintFunc(tile, dinfo, cxp)
|
||||
Tile *tile; /* Tile to be redisplayed. */
|
||||
TileType dinfo; /* Split tile information */
|
||||
TreeContext *cxp; /* From DBTreeSrTiles */
|
||||
{
|
||||
SearchContext *scx = cxp->tc_scx;
|
||||
|
|
@ -652,7 +653,7 @@ dbwPaintFunc(tile, cxp)
|
|||
/* whether to render the outline with a fast rectangle- */
|
||||
/* drawing routine or to render it segment by segment. */
|
||||
|
||||
GrBox(dbwWindow, &scx->scx_trans, tile);
|
||||
GrBox(dbwWindow, &scx->scx_trans, tile, dinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1075,8 +1076,10 @@ dbwBBoxFunc(scx)
|
|||
*/
|
||||
|
||||
int
|
||||
dbwTileFunc(tile)
|
||||
dbwTileFunc(tile, dinfo, clientdata)
|
||||
Tile *tile; /* A tile to be redisplayed. */
|
||||
TileType dinfo; /* Split tile information (unused) */
|
||||
ClientData clientdata; /* (unused) */
|
||||
{
|
||||
Rect r, r2;
|
||||
int xoffset, yoffset;
|
||||
|
|
@ -1113,7 +1116,7 @@ dbwTileFunc(tile)
|
|||
|
||||
if (dbwSeeTypes)
|
||||
{
|
||||
(void) sprintf(string, "%s",DBTypeShortName(TiGetType(tile)));
|
||||
(void) sprintf(string, "%s", DBTypeShortName(TiGetType(tile)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1129,7 +1132,7 @@ dbwTileFunc(tile)
|
|||
|
||||
#define XYOFFSET 12
|
||||
|
||||
for (i=0; i<4; i++)
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
xoffset = 0;
|
||||
yoffset = 0;
|
||||
|
|
@ -1172,13 +1175,13 @@ dbwTileFunc(tile)
|
|||
yoffset = temp;
|
||||
}
|
||||
|
||||
if ( (dbwWatchTrans.t_a < 0) || (dbwWatchTrans.t_b < 0) )
|
||||
if ((dbwWatchTrans.t_a < 0) || (dbwWatchTrans.t_b < 0))
|
||||
{
|
||||
/* mirror in x */
|
||||
xoffset = -xoffset;
|
||||
}
|
||||
|
||||
if ( (dbwWatchTrans.t_d < 0) || (dbwWatchTrans.t_e < 0) )
|
||||
if ((dbwWatchTrans.t_d < 0) || (dbwWatchTrans.t_e < 0))
|
||||
{
|
||||
/* mirror in y */
|
||||
yoffset = -yoffset;
|
||||
|
|
|
|||
|
|
@ -588,10 +588,12 @@ DBWElementDelete(MagWindow *w, char *name)
|
|||
if (elem->flags & DBW_ELEMENT_PERSISTENT)
|
||||
elem->rootDef->cd_flags |= CDMODIFIED;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (stylePtr = elem->stylelist; stylePtr != NULL; stylePtr = stylePtr->next)
|
||||
{
|
||||
freeMagic(stylePtr);
|
||||
freeMagic1(&mm1, stylePtr);
|
||||
}
|
||||
freeMagic1_end(&mm1);
|
||||
if (elem->type == ELEMENT_TEXT)
|
||||
freeMagic(elem->text);
|
||||
|
||||
|
|
@ -1156,8 +1158,10 @@ DBWElementStyle(MagWindow *w, char *ename, int style, bool add)
|
|||
(elem->stylelist->style == style))
|
||||
{
|
||||
dbwElementUndraw(w, elem);
|
||||
freeMagic(elem->stylelist);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, elem->stylelist);
|
||||
elem->stylelist = elem->stylelist->next;
|
||||
freeMagic1_end(&mm1);
|
||||
if (elem->stylelist == NULL)
|
||||
TxPrintf("Warning: Element %s has no styles!\n", ename);
|
||||
}
|
||||
|
|
@ -1169,8 +1173,10 @@ DBWElementStyle(MagWindow *w, char *ename, int style, bool add)
|
|||
else if (sptr->next != NULL)
|
||||
{
|
||||
dbwElementUndraw(w, elem);
|
||||
freeMagic(sptr->next);
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
freeMagic1(&mm1, sptr->next);
|
||||
sptr->next = sptr->next->next;
|
||||
freeMagic1_end(&mm1);
|
||||
}
|
||||
}
|
||||
/* mark element's cell as having been modified */
|
||||
|
|
@ -1279,8 +1285,10 @@ DBWElementClearDef(cellDef)
|
|||
if (!elem) continue;
|
||||
if (elem->rootDef != cellDef) continue;
|
||||
|
||||
free_magic1_t mm1 = freeMagic1_init();
|
||||
for (stylePtr = elem->stylelist; stylePtr != NULL; stylePtr = stylePtr->next)
|
||||
freeMagic(stylePtr);
|
||||
freeMagic1(&mm1, stylePtr);
|
||||
freeMagic1_end(&mm1);
|
||||
|
||||
if (elem->type == ELEMENT_TEXT)
|
||||
freeMagic(elem->text);
|
||||
|
|
|
|||
|
|
@ -249,7 +249,10 @@ DBWFeedbackRedraw(window, plane)
|
|||
}
|
||||
|
||||
int
|
||||
dbwFeedbackAlways1()
|
||||
dbwFeedbackAlways1(
|
||||
Tile *tile, /* (unused) */
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,8 +392,9 @@ DBWHLRedrawWind(window)
|
|||
*/
|
||||
|
||||
int
|
||||
dbwhlEraseFunc(tile, window)
|
||||
dbwhlEraseFunc(tile, dinfo, window)
|
||||
Tile *tile; /* Tile describing area to be erased. */
|
||||
TileType dinfo; /* Split tile information (unused) */
|
||||
MagWindow *window; /* Window that is being altered. */
|
||||
{
|
||||
Rect area;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "tcltk/tclmagic.h"
|
||||
#include "utils/main.h"
|
||||
#include "utils/magic.h"
|
||||
#include "utils/geometry.h"
|
||||
|
|
@ -33,6 +34,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#include "utils/hash.h"
|
||||
#include "database/database.h"
|
||||
#include "utils/main.h"
|
||||
#include "cif/cif.h"
|
||||
#include "commands/commands.h"
|
||||
#include "dbwind/dbwind.h"
|
||||
#include "graphics/graphics.h"
|
||||
|
|
@ -653,6 +655,311 @@ DBWexit()
|
|||
return (CmdWarnWrite() == 1);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbwValueFormat ---
|
||||
*
|
||||
* Remove unnecessary trailing zeros and decimal from a floating-point
|
||||
* value formatted with "%.Nf" where N is the expected maximum number
|
||||
* of places after the decimal, matching the argument "places".
|
||||
* This makes the "%f" formatting work like "%g" formatting, but
|
||||
* works around the limitation of "%.Ng" that it operates on the number
|
||||
* of significant digits, not the number of decimal places.
|
||||
*
|
||||
* Results:
|
||||
* None.
|
||||
*
|
||||
* Side effects:
|
||||
* The string "buf" may be altered with a new terminating null character.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
void
|
||||
dbwValueFormat(char *buf,
|
||||
int places)
|
||||
{
|
||||
char *p = buf + strlen(buf) - 1;
|
||||
while (p > buf && *p == '0') *p-- = '\0';
|
||||
if (p > buf && *p == '.') *p = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* dbwPrintValue0 --
|
||||
*
|
||||
* Convert a value in internal database units to a string based on
|
||||
* the chosen display units as defined by DBWUnits (which is set
|
||||
* with the "units" command). If DBWUnits has not been changed
|
||||
* since startup, then the behavior is to print the internal units
|
||||
* in string form. If DBWUnits has been set, then the units type
|
||||
* determines how the output is displayed.
|
||||
*
|
||||
* If "is_square" is TRUE, then the value is in units squared, and
|
||||
* scaling is done accordingly. In the case of DBW_UNITS_USER,
|
||||
* where values are in grid multiples, the units for X and Y may
|
||||
* differ, and "is_x" = TRUE indicates a measurement in the X direction,
|
||||
* while false indicase a measurements in the Y direction. Naturally,
|
||||
* if "is_square" is TRUE then "is_x" is ignored. "is_x" is also ignored
|
||||
* for any output units other than user/grid units.
|
||||
*
|
||||
* If "is_cif" is true, then "value" is in CIF database units
|
||||
* (centimicrons, nanometers, or angstroms, according to the
|
||||
* scalefactor line in the tech file), rather than internal units.
|
||||
*
|
||||
* This routine is generally meant to be called as one of the three
|
||||
* variants defined below it: DBWPrintValue(), DBWPrintSqValue(),
|
||||
* or DBWPrintCIFValue().
|
||||
*
|
||||
* Results:
|
||||
* A pointer to a string. To facilitate printing up to four values
|
||||
* (e.g., rectangle coordinates, such as from "box values"), a static
|
||||
* string partitioned into four parts is created in this subroutine,
|
||||
* and the result points to one position in the string, which is cycled
|
||||
* through every four calls to the subroutine. The caller does not
|
||||
* free the returned string.
|
||||
*
|
||||
* Side effects:
|
||||
* None.
|
||||
*
|
||||
* NOTE: Prior to the introduction of the "units" command, magic had the
|
||||
* inconsistent behavior that parsed input values on the command line
|
||||
* would be interpreted per the "snap" setting, but output values were
|
||||
* (almost) always given in internal units. This routine keeps the
|
||||
* original behavior backwards-compatible, as inconsistent as it is.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
dbwPrintValue0(int value, /* value to print, in internal units */
|
||||
MagWindow *w, /* current window, for use with grid */
|
||||
bool is_x, /* TRUE if value is an X dimension */
|
||||
bool is_square, /* TRUE if value is a dimension squared */
|
||||
bool is_cif) /* TRUE if value is in centimicrons */
|
||||
{
|
||||
char *result;
|
||||
float oscale, dscale, fvalue;
|
||||
DBWclientRec *crec;
|
||||
int locunits;
|
||||
|
||||
/* This routine is called often, so avoid constant use of malloc and
|
||||
* free by keeping up to four printed results in static memory.
|
||||
*/
|
||||
static char resultstr[128];
|
||||
static unsigned char resultpos = 0;
|
||||
|
||||
result = &resultstr[resultpos];
|
||||
resultpos += 32;
|
||||
resultpos &= 127; /* At 128, cycle back to zero */
|
||||
|
||||
/* CIF database units are centimicrons/nanometers/angstroms as
|
||||
* set by the "scalefactor" line in the tech file. When "is_cif"
|
||||
* is TRUE, then "value" is in these units. Find the conversion
|
||||
* factor to convert "value" to internal units, and then it can
|
||||
* be subsequently converted to lambda, microns, etc.
|
||||
*/
|
||||
if (is_cif == TRUE)
|
||||
dscale = CIFGetScale(100) / CIFGetOutputScale(1000);
|
||||
else
|
||||
dscale = 1.0;
|
||||
|
||||
/* When printing user/grid units, check for a valid window */
|
||||
|
||||
locunits = DBWUnits;
|
||||
if (locunits != DBW_UNITS_DEFAULT) locunits &= DBW_UNITS_TYPE_MASK;
|
||||
|
||||
/* The MagWindow argument is only needed for user units, since the
|
||||
* user grid values are found there. Setting MagWindow to NULL
|
||||
* effectively disables printing values in user grid units, which
|
||||
* then default to internal units.
|
||||
*/
|
||||
if (locunits == DBW_UNITS_USER)
|
||||
{
|
||||
if (w == (MagWindow *)NULL)
|
||||
{
|
||||
windCheckOnlyWindow(&w, DBWclientID);
|
||||
if (w == (MagWindow *)NULL)
|
||||
locunits = DBW_UNITS_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
switch (locunits)
|
||||
{
|
||||
case DBW_UNITS_DEFAULT:
|
||||
snprintf(result, 32, "%d", value);
|
||||
break;
|
||||
|
||||
case DBW_UNITS_INTERNAL:
|
||||
if (is_cif)
|
||||
{
|
||||
if (is_square)
|
||||
{
|
||||
snprintf(result, 32, "%.6f", value * dscale * dscale);
|
||||
dbwValueFormat(result, 6);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(result, 32, "%.3f", value * dscale);
|
||||
dbwValueFormat(result, 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
snprintf(result, 32, "%d", value);
|
||||
if (is_square)
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 29))
|
||||
strcat(result, "i^2");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 31))
|
||||
strcat(result, "i");
|
||||
}
|
||||
break;
|
||||
|
||||
case DBW_UNITS_LAMBDA:
|
||||
|
||||
oscale = (float)DBLambda[0];
|
||||
oscale /= (float)DBLambda[1];
|
||||
if (is_square)
|
||||
{
|
||||
fvalue = (float)value * oscale * oscale * dscale * dscale;
|
||||
snprintf(result, 32, "%0.6f", (double)fvalue);
|
||||
dbwValueFormat(result, 6);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 29))
|
||||
strcat(result, "l^2");
|
||||
}
|
||||
else
|
||||
{
|
||||
fvalue = (float)value * oscale * dscale;
|
||||
snprintf(result, 32, "%0.3f", (double)fvalue);
|
||||
dbwValueFormat(result, 3);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 31))
|
||||
strcat(result, "l");
|
||||
}
|
||||
break;
|
||||
|
||||
case DBW_UNITS_MICRONS:
|
||||
oscale = CIFGetOutputScale(1000);
|
||||
if (is_square)
|
||||
{
|
||||
fvalue = (float)value * oscale * oscale * dscale * dscale;
|
||||
snprintf(result, 32, "%0.6f", (double)fvalue);
|
||||
dbwValueFormat(result, 6);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 28))
|
||||
strcat(result, "um^2");
|
||||
}
|
||||
else
|
||||
{
|
||||
fvalue = (float)value * oscale * dscale;
|
||||
snprintf(result, 32, "%0.3f", (double)fvalue);
|
||||
dbwValueFormat(result, 3);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 30))
|
||||
strcat(result, "um");
|
||||
}
|
||||
break;
|
||||
|
||||
case DBW_UNITS_USER:
|
||||
if (is_square)
|
||||
{
|
||||
oscale = (float)((crec->dbw_gridRect.r_xtop -
|
||||
crec->dbw_gridRect.r_xbot) *
|
||||
(crec->dbw_gridRect.r_ytop -
|
||||
crec->dbw_gridRect.r_ybot));
|
||||
}
|
||||
else if (is_x)
|
||||
{
|
||||
oscale = (float)(crec->dbw_gridRect.r_xtop -
|
||||
crec->dbw_gridRect.r_xbot);
|
||||
}
|
||||
else
|
||||
{
|
||||
oscale = (float)(crec->dbw_gridRect.r_ytop -
|
||||
crec->dbw_gridRect.r_ybot);
|
||||
}
|
||||
fvalue = (float)value * oscale * dscale;
|
||||
if (is_square)
|
||||
{
|
||||
fvalue *= dscale;
|
||||
snprintf(result, 32, "%0.6f", (double)fvalue);
|
||||
dbwValueFormat(result, 6);
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 27))
|
||||
strcat(result, "gx*gy");
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(result, 32, "%0.3f", (double)fvalue);
|
||||
dbwValueFormat(result, 3);
|
||||
if (is_x)
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 30))
|
||||
strcat(result, "gx");
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((DBWUnits & DBW_UNITS_PRINT_FLAG) && (strlen(result) < 30))
|
||||
strcat(result, "gy");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* DBWPrintValue --
|
||||
* DBWPrintSqValue --
|
||||
* DBWPrintCIFValue --
|
||||
* DBWPrintCIFSqValue --
|
||||
*
|
||||
* Convenience functions which call dbwPrintValue0() with specific
|
||||
* fixed arguments, so that the calls are not full of boolean values.
|
||||
* The "is_x" boolean is retained because it is used often.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
char *
|
||||
DBWPrintValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w, /* current window, for use with grid */
|
||||
bool is_x) /* TRUE if value is an X dimension */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = FALSE and is_cif = FALSE */
|
||||
return dbwPrintValue0(value, w, is_x, FALSE, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
DBWPrintSqValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w) /* current window, for use with grid */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = TRUE and is_cif = FALSE */
|
||||
/* is_x is set to TRUE although it is unused. */
|
||||
return dbwPrintValue0(value, w, TRUE, TRUE, FALSE);
|
||||
}
|
||||
|
||||
char *
|
||||
DBWPrintCIFValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w, /* current window, for use with grid */
|
||||
bool is_x) /* TRUE if value is an X dimension */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = FALSE and is_cif = TRUE */
|
||||
return dbwPrintValue0(value, w, is_x, FALSE, TRUE);
|
||||
}
|
||||
|
||||
char *
|
||||
DBWPrintCIFSqValue(int value, /* value to print, in internal units */
|
||||
MagWindow *w) /* current window, for use with grid */
|
||||
{
|
||||
/* Call dbwPrintValue0() with is_square = TRUE and is_cif = TRUE */
|
||||
/* is_x is set to TRUE although it is unused. */
|
||||
return dbwPrintValue0(value, w, TRUE, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
|
|
|
|||
|
|
@ -65,11 +65,21 @@ typedef struct _crosshairRec {
|
|||
static CrosshairRec curCrosshair; /* Crosshair position */
|
||||
|
||||
/*
|
||||
* If the following is DBW_SNAP_USER, the box gets snapped to the user's
|
||||
* If the following is DBW_UNITS_USER, the box gets snapped to the user's
|
||||
* grid always, instead of snapping to the usual 1x1 grid. If the value
|
||||
* is DBW_SNAP_INTERNAL, the box gets snapped to the internal grid.
|
||||
* is DBW_UNITS_INTERNAL, the box gets snapped to the internal grid.
|
||||
*/
|
||||
int DBWSnapToGrid = DBW_SNAP_LAMBDA;
|
||||
int DBWSnapToGrid = DBW_UNITS_LAMBDA;
|
||||
|
||||
/*
|
||||
* The original behavior with respect to units was that un-suffixed
|
||||
* values follow whatever the snap setting is (DBWSnapToGrid, above).
|
||||
* Current behavior is that the original behavior is followed while
|
||||
* DBWUnits is set to DBW_UNITS_DEFAULT. However, if the "units"
|
||||
* command is given, then displayed and entered units follow that
|
||||
* value independently of the snap setting.
|
||||
*/
|
||||
int DBWUnits = DBW_UNITS_DEFAULT;
|
||||
|
||||
/* Forward reference: */
|
||||
|
||||
|
|
@ -82,8 +92,8 @@ extern int DBWToolDraw();
|
|||
* toolFindPoint --
|
||||
*
|
||||
* Returns the point in root coordinates.
|
||||
* If DBWSnapToGrid is DBW_SNAP_USER, pick the nearest point that is
|
||||
* aligned with the window's grid. If DBWSnapToGrid is DBW_SNAP_LAMBDA,
|
||||
* If DBWSnapToGrid is DBW_UNITS_USER, pick the nearest point that is
|
||||
* aligned with the window's grid. If DBWSnapToGrid is DBW_UNITS_LAMBDA,
|
||||
* pick the nearest point that is an integer lambda value.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -120,7 +130,7 @@ toolFindPoint(p, rootPoint, rootArea)
|
|||
if (!GEO_ENCLOSE(p, &WindCurrentWindow->w_screenArea)) return NULL;
|
||||
|
||||
WindPointToSurface(WindCurrentWindow, p, rootPoint, rootArea);
|
||||
if (DBWSnapToGrid != DBW_SNAP_INTERNAL)
|
||||
if (DBWSnapToGrid != DBW_UNITS_INTERNAL)
|
||||
ToolSnapToGrid(WindCurrentWindow, rootPoint, rootArea);
|
||||
return WindCurrentWindow;
|
||||
|
||||
|
|
@ -764,7 +774,10 @@ DBWDrawBox(window, plane)
|
|||
}
|
||||
|
||||
int
|
||||
dbwBoxAlways1()
|
||||
dbwBoxAlways1(
|
||||
Tile *tile, /* (unused) */
|
||||
TileType dinfo, /* (unused) */
|
||||
ClientData clientdata) /* (unused) */
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -841,8 +854,8 @@ DBWResetBox(CellDef *def)
|
|||
* Repositions the box by one of its corners.
|
||||
* If the point given to reposition the box is in screen coordinates,
|
||||
* the box corner is snapped to the user's grid (set with the :grid
|
||||
* command) if DBWSnapToGrid is DBW_SNAP_USER. If DBWSnapToGrid is
|
||||
* DBW_SNAP_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* command) if DBWSnapToGrid is DBW_UNITS_USER. If DBWSnapToGrid is
|
||||
* DBW_UNITS_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* lambda value.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -945,8 +958,8 @@ ToolMoveBox(corner, point, screenCoords, rootDef)
|
|||
*
|
||||
* If the point given to reposition the box is in screen coordinates,
|
||||
* the box corner is snapped to the user's grid (set with the :grid
|
||||
* command) if DBWSnapToGrid is DBW_SNAP_USER. If DBWSnapToGrid is
|
||||
* DBW_SNAP_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* command) if DBWSnapToGrid is DBW_UNITS_USER. If DBWSnapToGrid is
|
||||
* DBW_UNITS_LAMBDA, the box corner is snapped to the nearest integer
|
||||
* lambda value.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -1089,7 +1102,7 @@ ToolSnapToGrid(w, p, rEnclose)
|
|||
if (crec == NULL || p == NULL)
|
||||
return;
|
||||
|
||||
if (DBWSnapToGrid == DBW_SNAP_LAMBDA)
|
||||
if (DBWSnapToGrid == DBW_UNITS_LAMBDA)
|
||||
{
|
||||
lr.r_xbot = lr.r_ybot = 0;
|
||||
lr.r_xtop = DBLambda[1] / DBLambda[0];
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/dbwind/dbwind.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DBWIND_H
|
||||
#define _DBWIND_H
|
||||
#ifndef _MAGIC__DBWIND__DBWIND_H
|
||||
#define _MAGIC__DBWIND__DBWIND_H
|
||||
|
||||
#include "database/database.h"
|
||||
#include "windows/windows.h"
|
||||
|
|
@ -113,6 +113,7 @@ typedef struct DBW1 {
|
|||
|
||||
extern WindClient DBWclientID;
|
||||
extern int DBWSnapToGrid;
|
||||
extern int DBWUnits;
|
||||
|
||||
extern int DBWMaxTechStyles;
|
||||
extern int DBWMaxTileStyles;
|
||||
|
|
@ -121,13 +122,17 @@ extern int DBWNumStyles;
|
|||
extern int RtrPolyWidth, RtrMetalWidth, RtrContactWidth;
|
||||
|
||||
/*
|
||||
* Exported procedure headers for redisplay
|
||||
* Exported procedure headers for redisplay and output
|
||||
*/
|
||||
|
||||
extern int DBWWatchTiles();
|
||||
extern void DBWAreaChanged();
|
||||
extern void DBWLabelChanged();
|
||||
extern void DBWDrawLabel();
|
||||
extern char *DBWPrintValue(int value, MagWindow *w, bool is_x);
|
||||
extern char *DBWPrintSqValue(int value, MagWindow *w);
|
||||
extern char *DBWPrintCIFValue(int value, MagWindow *w, bool is_x);
|
||||
extern char *DBWPrintCIFSqValue(int value, MagWindow *w);
|
||||
|
||||
/*
|
||||
* Exported procedures and variables related to the technology file
|
||||
|
|
@ -145,6 +150,7 @@ extern void (*DBWButtonCurrentProc)();
|
|||
typedef void (*cb_database_buttonhandler_t)(MagWindow *w, TxCommand *cmd);
|
||||
extern void DBWAddButtonHandler(const char *name, const cb_database_buttonhandler_t proc,
|
||||
int cursor, const char *doc);
|
||||
extern char *DBWGetButtonHandler();
|
||||
extern char *DBWChangeButtonHandler();
|
||||
extern void DBWPrintButtonDoc();
|
||||
extern void DBWBoxHandler();
|
||||
|
|
@ -168,14 +174,36 @@ extern void DBWBoxHandler();
|
|||
#define TOOL_ILG -1
|
||||
|
||||
/* The following defines are used to indicate which coordinate system
|
||||
* the cursor box snaps to when moved with mouse clicks (values for
|
||||
* DBWSnapToGrid).
|
||||
* is used when displaying or returning values. By default this is
|
||||
* set to DBW_UNITS_INTERNAL. From magic version 8.3.595, this is
|
||||
* independently set from "snap". For backwards compatibility,
|
||||
* the value starts as DBW_UNITS_DEFAULT which implements the original
|
||||
* behavior in which the "snap" setting dictates the dispaly units.
|
||||
* Only if set to a non-negative value do the display units operate
|
||||
* independently of the snap setting.
|
||||
*
|
||||
* NOTES:
|
||||
* Lambda units are fixed by the tech file.
|
||||
* Internal units are scalable.
|
||||
* User units are scalable; this can be used, for example, to
|
||||
* set a box position according to multiples of a track
|
||||
* pitch, but is most often used manually with the "g"
|
||||
* (for "grid") suffix; e.g., "move box e 1g"
|
||||
* Micron units are dependent on the specified cifoutput style
|
||||
* and how the tech file defines the scalefactor for it.
|
||||
*/
|
||||
|
||||
#define DBW_SNAP_INTERNAL 0 /* internal units (fine grid) */
|
||||
#define DBW_SNAP_LAMBDA 1 /* lambda units (coarse grid) */
|
||||
#define DBW_SNAP_USER 2 /* user grid units (user grid) */
|
||||
#define DBW_SNAP_MICRONS 3 /* micron units */
|
||||
#define DBW_UNITS_DEFAULT -1 /* backwards-compatible behavior */
|
||||
#define DBW_UNITS_INTERNAL 0 /* internal units */
|
||||
#define DBW_UNITS_LAMBDA 1 /* lambda units */
|
||||
#define DBW_UNITS_USER 2 /* user grid units */
|
||||
#define DBW_UNITS_MICRONS 3 /* micron units */
|
||||
#define DBW_UNITS_TYPE_MASK 3 /* everything but the flag field(s) */
|
||||
#define DBW_UNITS_PRINT_FLAG 4 /* flag used to indicate that
|
||||
* the units should be printed
|
||||
* with the value; e.g.,
|
||||
* "10um" instead of "10".
|
||||
*/
|
||||
|
||||
/* The following window mask can be used to select all database windows
|
||||
* for things like the mask parameter to DBWAreaChanged.
|
||||
|
|
@ -261,4 +289,4 @@ extern void dbwElementInit();
|
|||
extern void dbwCrosshairInit();
|
||||
|
||||
|
||||
#endif /* _DBWIND_H */
|
||||
#endif /* _MAGIC__DBWIND__DBWIND_H */
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/dbwind/dbwtech.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DBWTECH_H
|
||||
#define _DBWTECH_H
|
||||
#ifndef _MAGIC__DBWIND__DBWTECH_H
|
||||
#define _MAGIC__DBWIND__DBWTECH_H
|
||||
|
||||
extern TileTypeBitMask *DBWStyleToTypesTbl;
|
||||
|
||||
|
|
@ -23,4 +23,4 @@ extern void DBWElementStyle();
|
|||
extern void DBWElementText();
|
||||
extern void DBWSetCrosshair();
|
||||
|
||||
#endif /* _DBWTECH_H */
|
||||
#endif /* _MAGIC__DBWIND__DBWTECH_H */
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@
|
|||
* rcsid $Header: /usr/cvsroot/magic-8.0/debug/debug.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $
|
||||
*/
|
||||
|
||||
#ifndef _DEBUG_H
|
||||
#define _DEBUG_H
|
||||
#ifndef _MAGIC__DEBUG__DEBUG_H
|
||||
#define _MAGIC__DEBUG__DEBUG_H
|
||||
|
||||
#include "utils/magic.h"
|
||||
|
||||
|
|
@ -76,4 +76,4 @@ extern int DebugAddFlag(ClientData clientID, const char *name);
|
|||
extern void DebugShow(ClientData clientID);
|
||||
extern void DebugSet(ClientData clientID, int argc, char *argv[], int value);
|
||||
|
||||
#endif /* _DEBUG_H */
|
||||
#endif /* _MAGIC__DEBUG__DEBUG_H */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<STYLE type="text/css">
|
||||
H1 {color: black }
|
||||
H2 {color: maroon }
|
||||
H3 {color: #007090 }
|
||||
A.head:link {color: #0060a0 }
|
||||
A.head:visited {color: #3040c0 }
|
||||
A.head:active {color: white }
|
||||
A.head:hover {color: yellow }
|
||||
A.red:link {color: red }
|
||||
A.red:visited {color: maroon }
|
||||
A.red:active {color: yellow }
|
||||
</STYLE>
|
||||
</HEAD>
|
||||
<TITLE>Magic-8.3 Command Reference</TITLE>
|
||||
<BODY BACKGROUND=graphics/blpaper.gif>
|
||||
<H1> <IMG SRC=graphics/magic_title8_3.png ALT="Magic VLSI Layout Tool Version 8.3">
|
||||
<IMG SRC=graphics/magic_OGL_sm.gif ALIGN="top" ALT="*"> </H1>
|
||||
|
||||
<H2>archive</H2>
|
||||
<HR>
|
||||
Handle archive files
|
||||
<HR>
|
||||
|
||||
<H3>Usage:</H3>
|
||||
<BLOCKQUOTE>
|
||||
<B>archive write</B> | <B>read</B> <I>filename</I> <BR><BR>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>Summary:</H3>
|
||||
<BLOCKQUOTE>
|
||||
The <B>archive</B> command handles archive files. The exact
|
||||
operation depends on the option, and are outlined below:
|
||||
<DL>
|
||||
<DT> <B>archive write</B> <I>filename</I>
|
||||
<DD> creates and writes to the file <I>filename</I> a copy of
|
||||
the contents of all database cells. <P>
|
||||
<DT> <B>archive read</B> <I>filename</I>
|
||||
<DD> recovers the database from the contents of the saved archive
|
||||
file <I>filename</I>. <P>
|
||||
</DL>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
Archive files use the same format as crash recovery files, which is a
|
||||
single file containing all database files with additional metadata
|
||||
about the original location of each file.
|
||||
|
||||
<H3>Implementation Notes:</H3>
|
||||
<BLOCKQUOTE>
|
||||
<B>archive</B> is implemented as a built-in command in <B>magic</B>.
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<H3>See Also:</H3>
|
||||
<BLOCKQUOTE>
|
||||
<A HREF=crash.html><B>crash</B></A> <BR>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P><IMG SRC=graphics/line1.gif><P>
|
||||
<TABLE BORDER=0>
|
||||
<TR>
|
||||
<TD> <A HREF=commands.html>Return to command index</A>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P><I>Last updated:</I> January 12, 2021 at 10:10am <P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
|
@ -334,23 +334,23 @@
|
|||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=undo.html> <B>undo</B></A> </TD>
|
||||
<TD> <A HREF=units.html> <B>units</B></A> </TD>
|
||||
<TD> <A HREF=updatedisplay.html> <B>updatedisplay</B></A> </TD>
|
||||
<TD> <A HREF=version.html> <B>version</B></A> </TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=version.html> <B>version</B></A> </TD>
|
||||
<TD> <A HREF=view.html> <B>view</B></A> </TD>
|
||||
<TD> <A HREF=windowborder.html> <B>windowborder</B></A> </TD>
|
||||
<TD> <A HREF=windowcaption.html> <B>windowcaption</B></A> </TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=windowcaption.html> <B>windowcaption</B></A> </TD>
|
||||
<TD> <A HREF=windownames.html> <B>windownames</B></A> </TD>
|
||||
<TD> <A HREF=windowscrollbars.html> <B>windowscrollbars</B></A> </TD>
|
||||
<TD> <A HREF=xview.html> <B>xview</B></A> </TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=xview.html> <B>xview</B></A> </TD>
|
||||
<TD> <A HREF=zoom.html> <B>zoom</B></A> </TD>
|
||||
<TD> <A HREF=tk_path_name.html> <I>tk_path_name</I></A> </TD>
|
||||
<TD> </TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
|
|
@ -362,184 +362,189 @@
|
|||
cellpadding="5" bgcolor="#ccccff">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD> <A HREF=addcommandentry.html><B>addcommandentry</B></A><TD>
|
||||
<TD> <A HREF=addpath.html> <B>addpath</B></A><TD>
|
||||
<TD> <A HREF=antennacheck.html> <B>antennacheck</B></A><TD>
|
||||
<TD> <A HREF=addcommandentry.html><B>addcommandentry</B></A></TD>
|
||||
<TD> <A HREF=addpath.html> <B>addpath</B></A></TD>
|
||||
<TD> <A HREF=antennacheck.html> <B>antennacheck</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=array.html> <B>array</B></A><TD>
|
||||
<TD> <A HREF=box.html> <B>box</B></A><TD>
|
||||
<TD> <A HREF=calma.html> <B>calma</B></A><TD>
|
||||
<TD> <A HREF=archive.html> <B>array</B></A></TD>
|
||||
<TD> <A HREF=array.html> <B>array</B></A></TD>
|
||||
<TD> <A HREF=box.html> <B>box</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=caption.html> <B>caption</B></A><TD>
|
||||
<TD> <A HREF=cellmanager.html> <B>cellmanager</B></A><TD>
|
||||
<TD> <A HREF=cellname.html> <B>cellname</B></A><TD>
|
||||
<TD> <A HREF=calma.html> <B>calma</B></A></TD>
|
||||
<TD> <A HREF=caption.html> <B>caption</B></A></TD>
|
||||
<TD> <A HREF=cellmanager.html> <B>cellmanager</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=cellsearch.html> <B>cellsearch</B></A><TD>
|
||||
<TD> <A HREF=channels.html> <B>channels</B></A><TD>
|
||||
<TD> <A HREF=cif.html> <B>cif</B></A><TD>
|
||||
<TD> <A HREF=cellname.html> <B>cellname</B></A></TD>
|
||||
<TD> <A HREF=cellsearch.html> <B>cellsearch</B></A></TD>
|
||||
<TD> <A HREF=channels.html> <B>channels</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=clockwise.html> <B>clockwise</B></A><TD>
|
||||
<TD> <A HREF=closewrapper.html> <B>closewrapper</B></A><TD>
|
||||
<TD> <A HREF=contact.html> <B>contact</B></A><TD>
|
||||
<TD> <A HREF=cif.html> <B>cif</B></A></TD>
|
||||
<TD> <A HREF=clockwise.html> <B>clockwise</B></A></TD>
|
||||
<TD> <A HREF=closewrapper.html> <B>closewrapper</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=copy.html> <B>copy</B></A><TD>
|
||||
<TD> <A HREF=corner.html> <B>corner</B></A><TD>
|
||||
<TD> <A HREF=crash.html> <B>crash</B></A><TD>
|
||||
<TD> <A HREF=contact.html> <B>contact</B></A></TD>
|
||||
<TD> <A HREF=copy.html> <B>copy</B></A></TD>
|
||||
<TD> <A HREF=corner.html> <B>corner</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=crashbackups.html> <B>crashbackups</B></A><TD>
|
||||
<TD> <A HREF=crosshair.html> <B>crosshair</B></A><TD>
|
||||
<TD> <A HREF=def.html> <B>def</B></A><TD>
|
||||
<TD> <A HREF=crash.html> <B>crash</B></A></TD>
|
||||
<TD> <A HREF=crashbackups.html> <B>crashbackups</B></A></TD>
|
||||
<TD> <A HREF=crosshair.html> <B>crosshair</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=delete.html> <B>delete</B></A><TD>
|
||||
<TD> <A HREF=deletecommandentry.html> <B>deletecommandentry</B></A><TD>
|
||||
<TD> <A HREF=down.html> <B>down</B></A><TD>
|
||||
<TD> <A HREF=def.html> <B>def</B></A></TD>
|
||||
<TD> <A HREF=delete.html> <B>delete</B></A></TD>
|
||||
<TD> <A HREF=deletecommandentry.html> <B>deletecommandentry</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=drc.html> <B>drc</B></A><TD>
|
||||
<TD> <A HREF=dump.html> <B>dump</B></A><TD>
|
||||
<TD> <A HREF=edit.html> <B>edit</B></A><TD>
|
||||
<TD> <A HREF=down.html> <B>down</B></A></TD>
|
||||
<TD> <A HREF=drc.html> <B>drc</B></A></TD>
|
||||
<TD> <A HREF=dump.html> <B>dump</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=element.html> <B>element</B></A><TD>
|
||||
<TD> <A HREF=erase.html> <B>erase</B></A><TD>
|
||||
<TD> <A HREF=expand.html> <B>expand</B></A><TD>
|
||||
<TD> <A HREF=edit.html> <B>edit</B></A></TD>
|
||||
<TD> <A HREF=element.html> <B>element</B></A></TD>
|
||||
<TD> <A HREF=erase.html> <B>erase</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=ext.html> <B>ext</B></A><TD>
|
||||
<TD> <A HREF=ext2sim.html> <B>ext2sim</B></A><TD>
|
||||
<TD> <A HREF=ext2spice.html> <B>ext2spice</B></A><TD>
|
||||
<TD> <A HREF=expand.html> <B>expand</B></A></TD>
|
||||
<TD> <A HREF=ext.html> <B>ext</B></A></TD>
|
||||
<TD> <A HREF=ext2sim.html> <B>ext2sim</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=extract.html> <B>extract</B></A><TD>
|
||||
<TD> <A HREF=extresist.html> <B>extresist</B></A><TD>
|
||||
<TD> <A HREF=ext2sim.html> <B>exttosim</B></A><TD>
|
||||
<TD> <A HREF=ext2spice.html> <B>ext2spice</B></A></TD>
|
||||
<TD> <A HREF=extract.html> <B>extract</B></A></TD>
|
||||
<TD> <A HREF=extresist.html> <B>extresist</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=ext2spice.html> <B>exttospice</B></A><TD>
|
||||
<TD> <A HREF=feedback.html> <B>feedback</B></A><TD>
|
||||
<TD> <A HREF=fill.html> <B>fill</B></A><TD>
|
||||
<TD> <A HREF=ext2sim.html> <B>exttosim</B></A></TD>
|
||||
<TD> <A HREF=ext2spice.html> <B>exttospice</B></A></TD>
|
||||
<TD> <A HREF=feedback.html> <B>feedback</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=findbox.html> <B>findbox</B></A><TD>
|
||||
<TD> <A HREF=findlabel.html> <B>findlabel</B></A><TD>
|
||||
<TD> <A HREF=flatten.html> <B>flatten</B></A><TD>
|
||||
<TD> <A HREF=fill.html> <B>fill</B></A></TD>
|
||||
<TD> <A HREF=findbox.html> <B>findbox</B></A></TD>
|
||||
<TD> <A HREF=findlabel.html> <B>findlabel</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=flush.html> <B>flush</B></A><TD>
|
||||
<TD> <A HREF=garoute.html> <B>garoute</B></A><TD>
|
||||
<TD> <A HREF=gds.html> <B>gds</B></A><TD>
|
||||
<TD> <A HREF=flatten.html> <B>flatten</B></A></TD>
|
||||
<TD> <A HREF=flush.html> <B>flush</B></A></TD>
|
||||
<TD> <A HREF=garoute.html> <B>garoute</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=get.html> <B>get</B></A><TD>
|
||||
<TD> <A HREF=getcell.html> <B>getcell</B></A><TD>
|
||||
<TD> <A HREF=getnode.html> <B>getnode</B></A><TD>
|
||||
<TD> <A HREF=gds.html> <B>gds</B></A></TD>
|
||||
<TD> <A HREF=get.html> <B>get</B></A></TD>
|
||||
<TD> <A HREF=getcell.html> <B>getcell</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=goto.html> <B>goto</B></A><TD>
|
||||
<TD> <A HREF=grid.html> <B>grid</B></A><TD>
|
||||
<TD> <A HREF=help.html> <B>help</B></A><TD>
|
||||
<TD> <A HREF=getnode.html> <B>getnode</B></A></TD>
|
||||
<TD> <A HREF=goto.html> <B>goto</B></A></TD>
|
||||
<TD> <A HREF=grid.html> <B>grid</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=identify.html> <B>identify</B></A><TD>
|
||||
<TD> <A HREF=initialize.html> <B>initialize</B></A><TD>
|
||||
<TD> <A HREF=instance.html> <B>instance</B></A><TD>
|
||||
<TD> <A HREF=help.html> <B>help</B></A></TD>
|
||||
<TD> <A HREF=identify.html> <B>identify</B></A></TD>
|
||||
<TD> <A HREF=initialize.html> <B>initialize</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=iroute.html> <B>iroute</B></A><TD>
|
||||
<TD> <A HREF=irsim.html> <B>irsim</B></A><TD>
|
||||
<TD> <A HREF=label.html> <B>label</B></A><TD>
|
||||
<TD> <A HREF=instance.html> <B>instance</B></A></TD>
|
||||
<TD> <A HREF=iroute.html> <B>iroute</B></A></TD>
|
||||
<TD> <A HREF=irsim.html> <B>irsim</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=lef.html> <B>lef</B></A><TD>
|
||||
<TD> <A HREF=load.html> <B>load</B></A><TD>
|
||||
<TD> <A HREF=maketoolbar.html> <B>maketoolbar</B></A><TD>
|
||||
<TD> <A HREF=label.html> <B>label</B></A></TD>
|
||||
<TD> <A HREF=lef.html> <B>lef</B></A></TD>
|
||||
<TD> <A HREF=load.html> <B>load</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=move.html> <B>move</B></A><TD>
|
||||
<TD> <A HREF=measure.html> <B>measure</B></A><TD>
|
||||
<TD> <A HREF=openwrapper.html> <B>openwrapper</B></A><TD>
|
||||
<TD> <A HREF=maketoolbar.html> <B>maketoolbar</B></A></TD>
|
||||
<TD> <A HREF=move.html> <B>move</B></A></TD>
|
||||
<TD> <A HREF=measure.html> <B>measure</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=paint.html> <B>paint</B></A><TD>
|
||||
<TD> <A HREF=path.html> <B>path</B></A><TD>
|
||||
<TD> <A HREF=peekbox.html> <B>peekbox</B></A><TD>
|
||||
<TD> <A HREF=openwrapper.html> <B>openwrapper</B></A></TD>
|
||||
<TD> <A HREF=paint.html> <B>paint</B></A></TD>
|
||||
<TD> <A HREF=path.html> <B>path</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=plot.html> <B>plot</B></A><TD>
|
||||
<TD> <A HREF=plow.html> <B>plow</B></A><TD>
|
||||
<TD> <A HREF=polygon.html> <B>polygon</B></A><TD>
|
||||
<TD> <A HREF=peekbox.html> <B>peekbox</B></A></TD>
|
||||
<TD> <A HREF=plot.html> <B>plot</B></A></TD>
|
||||
<TD> <A HREF=plow.html> <B>plow</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=popbox.html> <B>popbox</B></A><TD>
|
||||
<TD> <A HREF=popstack.html> <B>popstack</B></A><TD>
|
||||
<TD> <A HREF=port.html> <B>port</B></A><TD>
|
||||
<TD> <A HREF=polygon.html> <B>polygon</B></A></TD>
|
||||
<TD> <A HREF=popbox.html> <B>popbox</B></A></TD>
|
||||
<TD> <A HREF=popstack.html> <B>popstack</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=promptload.html> <B>promptload</B></A><TD>
|
||||
<TD> <A HREF=promptsave.html> <B>promptsave</B></A><TD>
|
||||
<TD> <A HREF=property.html> <B>property</B></A><TD>
|
||||
<TD> <A HREF=port.html> <B>port</B></A></TD>
|
||||
<TD> <A HREF=promptload.html> <B>promptload</B></A></TD>
|
||||
<TD> <A HREF=promptsave.html> <B>promptsave</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=pushbox.html> <B>pushbox</B></A><TD>
|
||||
<TD> <A HREF=pushstack.html> <B>pushstack</B></A><TD>
|
||||
<TD> <A HREF=render3d.html> <B>render3d</B></A><TD>
|
||||
<TD> <A HREF=property.html> <B>property</B></A></TD>
|
||||
<TD> <A HREF=pushbox.html> <B>pushbox</B></A></TD>
|
||||
<TD> <A HREF=pushstack.html> <B>pushstack</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=resumeall.html> <B>resumeall</B></A><TD>
|
||||
<TD> <A HREF=rotate.html> <B>rotate</B></A><TD>
|
||||
<TD> <A HREF=route.html> <B>route</B></A><TD>
|
||||
<TD> <A HREF=render3d.html> <B>render3d</B></A></TD>
|
||||
<TD> <A HREF=resumeall.html> <B>resumeall</B></A></TD>
|
||||
<TD> <A HREF=rotate.html> <B>rotate</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=save.html> <B>save</B></A><TD>
|
||||
<TD> <A HREF=scalegrid.html> <B>scalegrid</B></A><TD>
|
||||
<TD> <A HREF=search.html> <B>search</B></A><TD>
|
||||
<TD> <A HREF=route.html> <B>route</B></A></TD>
|
||||
<TD> <A HREF=save.html> <B>save</B></A></TD>
|
||||
<TD> <A HREF=scalegrid.html> <B>scalegrid</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=see.html> <B>see</B></A><TD>
|
||||
<TD> <A HREF=select.html> <B>select</B></A><TD>
|
||||
<TD> <A HREF=setlabel.html> <B>setlabel</B> <I>(version 8.0)</I></A><TD>
|
||||
<TD> <A HREF=search.html> <B>search</B></A></TD>
|
||||
<TD> <A HREF=see.html> <B>see</B></A></TD>
|
||||
<TD> <A HREF=select.html> <B>select</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=shell.html> <B>shell</B></A><TD>
|
||||
<TD> <A HREF=sideways.html> <B>sideways</B></A><TD>
|
||||
<TD> <A HREF=snap.html> <B>snap</B></A><TD>
|
||||
<TD> <A HREF=setlabel.html> <B>setlabel</B> <I>(version 8.0)</I></A></TD>
|
||||
<TD> <A HREF=shell.html> <B>shell</B></A></TD>
|
||||
<TD> <A HREF=sideways.html> <B>sideways</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=spliterase.html> <B>spliterase</B></A><TD>
|
||||
<TD> <A HREF=splitpaint.html> <B>splitpaint</B></A><TD>
|
||||
<TD> <A HREF=startup.html> <B>startup</B></A><TD>
|
||||
<TD> <A HREF=snap.html> <B>snap</B></A></TD>
|
||||
<TD> <A HREF=spliterase.html> <B>spliterase</B></A></TD>
|
||||
<TD> <A HREF=splitpaint.html> <B>splitpaint</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=straighten.html> <B>straighten</B></A><TD>
|
||||
<TD> <A HREF=stretch.html> <B>stretch</B></A><TD>
|
||||
<TD> <A HREF=suspendall.html> <B>suspendall</B></A><TD>
|
||||
<TD> <A HREF=startup.html> <B>startup</B></A></TD>
|
||||
<TD> <A HREF=straighten.html> <B>straighten</B></A></TD>
|
||||
<TD> <A HREF=stretch.html> <B>stretch</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=tag.html> <B>tag</B></A><TD>
|
||||
<TD> <A HREF=tech.html> <B>tech</B></A><TD>
|
||||
<TD> <A HREF=techmanager.html> <B>techmanager</B></A><TD>
|
||||
<TD> <A HREF=suspendall.html> <B>suspendall</B></A></TD>
|
||||
<TD> <A HREF=tag.html> <B>tag</B></A></TD>
|
||||
<TD> <A HREF=tech.html> <B>tech</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=tool.html> <B>tool</B> <I>(non-Tcl version)</I></A><TD>
|
||||
<TD> <A HREF=changetool.html> <B>tool</B> <I>(Tcl version)</I></A><TD>
|
||||
<TD> <A HREF=unexpand.html> <B>unexpand</B></A><TD>
|
||||
<TD> <A HREF=techmanager.html> <B>techmanager</B></A></TD>
|
||||
<TD> <A HREF=tool.html> <B>tool</B> <I>(non-Tcl version)</I></A></TD>
|
||||
<TD> <A HREF=changetool.html> <B>tool</B> <I>(Tcl version)</I></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=unmeasure.html> <B>unmeasure</B></A><TD>
|
||||
<TD> <A HREF=upsidedown.html> <B>upsidedown</B></A><TD>
|
||||
<TD> <A HREF=what.html> <B>what</B></A><TD>
|
||||
<TD> <A HREF=unexpand.html> <B>unexpand</B></A></TD>
|
||||
<TD> <A HREF=unmeasure.html> <B>unmeasure</B></A></TD>
|
||||
<TD> <A HREF=upsidedown.html> <B>upsidedown</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=wire.html> <B>wire</B></A><TD>
|
||||
<TD> <A HREF=writeall.html> <B>writeall</B></A><TD>
|
||||
<TD> <A HREF=xload.html> <B>xload</B></A><TD>
|
||||
<TD> <A HREF=what.html> <B>what</B></A></TD>
|
||||
<TD> <A HREF=wire.html> <B>wire</B></A></TD>
|
||||
<TD> <A HREF=writeall.html> <B>writeall</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=xload.html> <B>xload</B></A></TD>
|
||||
<TD> </TD>
|
||||
<TD> </TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
|
|
@ -551,38 +556,38 @@
|
|||
cellpadding="5" bgcolor="#ffcccc">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD> <A HREF=netlist/add.html><B>add</B></A><TD>
|
||||
<TD> <A HREF=netlist/cleanup.html><B>cleanup</B></A><TD>
|
||||
<TD> <A HREF=netlist/cull.html><B>cull</B></A><TD>
|
||||
<TD> <A HREF=netlist/add.html><B>add</B></A></TD>
|
||||
<TD> <A HREF=netlist/cleanup.html><B>cleanup</B></A></TD>
|
||||
<TD> <A HREF=netlist/cull.html><B>cull</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=netlist/dnet.html><B>dnet</B></A><TD>
|
||||
<TD> <A HREF=netlist/dterm.html><B>dterm</B></A><TD>
|
||||
<TD> <A HREF=netlist/extract.html><B>extract</B></A><TD>
|
||||
<TD> <A HREF=netlist/dnet.html><B>dnet</B></A></TD>
|
||||
<TD> <A HREF=netlist/dterm.html><B>dterm</B></A></TD>
|
||||
<TD> <A HREF=netlist/extract.html><B>extract</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=netlist/find.html><B>find</B></A><TD>
|
||||
<TD> <A HREF=netlist/flush.html><B>flush</B></A><TD>
|
||||
<TD> <A HREF=netlist/join.html><B>join</B></A><TD>
|
||||
<TD> <A HREF=netlist/find.html><B>find</B></A></TD>
|
||||
<TD> <A HREF=netlist/flush.html><B>flush</B></A></TD>
|
||||
<TD> <A HREF=netlist/join.html><B>join</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=netlist/netlist.html><B>netlist</B></A><TD>
|
||||
<TD> <A HREF=netlist/orient.html><B>orient</B></A><TD>
|
||||
<TD> <A HREF=netlist/pushbutton.html><B>pushbutton</B></A><TD>
|
||||
<TD> <A HREF=netlist/netlist.html><B>netlist</B></A></TD>
|
||||
<TD> <A HREF=netlist/orient.html><B>orient</B></A></TD>
|
||||
<TD> <A HREF=netlist/pushbutton.html><B>pushbutton</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=netlist/print.html><B>print</B></A><TD>
|
||||
<TD> <A HREF=netlist/ripup.html><B>ripup</B></A><TD>
|
||||
<TD> <A HREF=netlist/savenetlist.html><B>savenetlist</B></A><TD>
|
||||
<TD> <A HREF=netlist/print.html><B>print</B></A></TD>
|
||||
<TD> <A HREF=netlist/ripup.html><B>ripup</B></A></TD>
|
||||
<TD> <A HREF=netlist/savenetlist.html><B>savenetlist</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=netlist/shownet.html><B>shownet</B></A><TD>
|
||||
<TD> <A HREF=netlist/showterms.html><B>showterms</B></A><TD>
|
||||
<TD> <A HREF=netlist/trace.html><B>trace</B></A><TD>
|
||||
<TD> <A HREF=netlist/shownet.html><B>shownet</B></A></TD>
|
||||
<TD> <A HREF=netlist/showterms.html><B>showterms</B></A></TD>
|
||||
<TD> <A HREF=netlist/trace.html><B>trace</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=netlist/verify.html><B>verify</B></A><TD>
|
||||
<TD> <A HREF=netlist/writeall.html><B>writeall</B></A><TD>
|
||||
<TD> <A HREF=netlist/verify.html><B>verify</B></A></TD>
|
||||
<TD> <A HREF=netlist/writeall.html><B>writeall</B></A></TD>
|
||||
<TD></TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
|
|
@ -595,24 +600,24 @@
|
|||
cellpadding="5" bgcolor="#ccffcc">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD> <A HREF=wind3d/cif.html><B>cif</B></A><TD>
|
||||
<TD> <A HREF=wind3d/closewindow.html><B>closewindow</B></A><TD>
|
||||
<TD> <A HREF=wind3d/cutbox.html><B>cutbox</B></A><TD>
|
||||
<TD> <A HREF=wind3d/cif.html><B>cif</B></A></TD>
|
||||
<TD> <A HREF=wind3d/closewindow.html><B>closewindow</B></A></TD>
|
||||
<TD> <A HREF=wind3d/cutbox.html><B>cutbox</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=wind3d/defaults.html><B>defaults</B></A><TD>
|
||||
<TD> <A HREF=wind3d/help.html><B>help</B></A><TD>
|
||||
<TD> <A HREF=wind3d/level.html><B>level</B></A><TD>
|
||||
<TD> <A HREF=wind3d/defaults.html><B>defaults</B></A></TD>
|
||||
<TD> <A HREF=wind3d/help.html><B>help</B></A></TD>
|
||||
<TD> <A HREF=wind3d/level.html><B>level</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=wind3d/refresh.html><B>refresh</B></A><TD>
|
||||
<TD> <A HREF=wind3d/render.html><B>render</B></A><TD>
|
||||
<TD> <A HREF=wind3d/scroll.html><B>scroll</B></A><TD>
|
||||
<TD> <A HREF=wind3d/refresh.html><B>refresh</B></A></TD>
|
||||
<TD> <A HREF=wind3d/render.html><B>render</B></A></TD>
|
||||
<TD> <A HREF=wind3d/scroll.html><B>scroll</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=wind3d/see.html><B>see</B></A><TD>
|
||||
<TD> <A HREF=wind3d/view.html><B>view</B></A><TD>
|
||||
<TD> <A HREF=wind3d/zoom.html><B>zoom</B></A><TD>
|
||||
<TD> <A HREF=wind3d/see.html><B>see</B></A></TD>
|
||||
<TD> <A HREF=wind3d/view.html><B>view</B></A></TD>
|
||||
<TD> <A HREF=wind3d/zoom.html><B>zoom</B></A></TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
|
|
@ -624,12 +629,12 @@
|
|||
cellpadding="5" bgcolor="#ffccff">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD> <A HREF=color/pushbutton.html><B>pushbutton</B></A><TD>
|
||||
<TD> <A HREF=color/color.html><B>color</B></A><TD>
|
||||
<TD> <A HREF=color/load.html><B>load</B></A><TD>
|
||||
<TD> <A HREF=color/pushbutton.html><B>pushbutton</B></A></TD>
|
||||
<TD> <A HREF=color/color.html><B>color</B></A></TD>
|
||||
<TD> <A HREF=color/load.html><B>load</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=color/save.html><B>save</B></A><TD>
|
||||
<TD> <A HREF=color/save.html><B>save</B></A></TD>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
</TR>
|
||||
|
|
@ -643,19 +648,19 @@
|
|||
cellpadding="5" bgcolor="#ffffcc">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD> <A HREF=wizard/bypass.html><B>*bypass</B></A><TD>
|
||||
<TD> <A HREF=wizard/coord.html><B>*coord</B></A><TD>
|
||||
<TD> <A HREF=wizard/extract.html><B>*extract</B></A><TD>
|
||||
<TD> <A HREF=wizard/bypass.html><B>*bypass</B></A></TD>
|
||||
<TD> <A HREF=wizard/coord.html><B>*coord</B></A></TD>
|
||||
<TD> <A HREF=wizard/extract.html><B>*extract</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=wizard/plow.html><B>*plow</B></A><TD>
|
||||
<TD> <A HREF=wizard/psearch.html><B>*psearch</B></A><TD>
|
||||
<TD> <A HREF=wizard/showtech.html><B>*showtech</B></A><TD>
|
||||
<TD> <A HREF=wizard/plow.html><B>*plow</B></A></TD>
|
||||
<TD> <A HREF=wizard/psearch.html><B>*psearch</B></A></TD>
|
||||
<TD> <A HREF=wizard/showtech.html><B>*showtech</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=wizard/tilestats.html><B>*tilestats</B></A><TD>
|
||||
<TD> <A HREF=wizard/tsearch.html><B>*tsearch</B></A><TD>
|
||||
<TD> <A HREF=wizard/watch.html><B>*watch</B></A><TD>
|
||||
<TD> <A HREF=wizard/tilestats.html><B>*tilestats</B></A></TD>
|
||||
<TD> <A HREF=wizard/tsearch.html><B>*tsearch</B></A></TD>
|
||||
<TD> <A HREF=wizard/watch.html><B>*watch</B></A></TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
|
|
@ -667,14 +672,14 @@
|
|||
cellpadding="5" bgcolor="#cccccc">
|
||||
<TBODY>
|
||||
<TR>
|
||||
<TD> <A HREF=wizard/crash.html><B>*crash</B></A><TD>
|
||||
<TD> <A HREF=wizard/files.html><B>*files</B></A><TD>
|
||||
<TD> <A HREF=wizard/grstats.html><B>*grstats</B></A><TD>
|
||||
<TD> <A HREF=wizard/crash.html><B>*crash</B></A></TD>
|
||||
<TD> <A HREF=wizard/files.html><B>*files</B></A></TD>
|
||||
<TD> <A HREF=wizard/grstats.html><B>*grstats</B></A></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD> <A HREF=wizard/pause.html><B>*pause</B></A><TD>
|
||||
<TD> <A HREF=wizard/winddebug.html><B>*winddebug</B></A><TD>
|
||||
<TD> <A HREF=wizard/winddump.html><B>*winddump</B></A><TD>
|
||||
<TD> <A HREF=wizard/pause.html><B>*pause</B></A></TD>
|
||||
<TD> <A HREF=wizard/winddebug.html><B>*winddebug</B></A></TD>
|
||||
<TD> <A HREF=wizard/winddump.html><B>*winddump</B></A></TD>
|
||||
</TR>
|
||||
</TBODY>
|
||||
</TABLE>
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue