Compare commits

..

No commits in common. "master" and "8.3.521" have entirely different histories.

467 changed files with 14187 additions and 29121 deletions

28
.github/workflows/appimage.yml vendored Normal file
View File

@ -0,0 +1,28 @@
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

View File

@ -1,170 +0,0 @@
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}}

View File

@ -1,170 +0,0 @@
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}}

View File

@ -1,170 +0,0 @@
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}}

View File

@ -1,170 +0,0 @@
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}}

View File

@ -12,35 +12,37 @@ jobs:
strategy: strategy:
max-parallel: 3 max-parallel: 3
matrix: matrix:
os: [ubuntu-24.04, ubuntu-22.04] os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
# Configure Options # Configure Options
# X11 OGL CAIRO pkgs: [all, none, no_tk_tcl_rl, no_rl, no_zlib, no_gc_gl_gu, no_gc_gu]
pkgs: [all, none, no_tk_tcl_rl, no_tk_tcl_brl, no_zlib, no_gc_gl_gu, no_gc, no_gl_gu]
# Toolchain # Toolchain
# ubuntu-20.04 [gcc-9, clang-10] # ubuntu-20.04 [gcc-9] gcc-10
# ubuntu-22.04 [gcc-11, clang-14] # ubuntu-22.04 [gcc-11] gcc-12
# ubuntu-24.04 [gcc-13, clang-18] # ubuntu-24.04 [gcc-13] gcc-14
tc: [default, gcc-10, gcc-11, gcc-12, gcc-13, gcc-14, clang-14, clang-15, clang-17, clang-18, clang-19] tc: [default, gcc-10, gcc-12, gcc-14, clang-17, clang-18]
exclude: 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 - os: ubuntu-22.04
tc: gcc-13 tc: gcc-10
- os: ubuntu-22.04 - os: ubuntu-22.04
tc: gcc-14 tc: gcc-14
- os: ubuntu-22.04 - os: ubuntu-22.04
tc: clang-17 tc: clang-17
- os: ubuntu-22.04 # some sources show this as present but not found
tc: clang-18
- os: ubuntu-22.04 - os: ubuntu-22.04
tc: clang-19 tc: clang-18
- os: ubuntu-24.04 - os: ubuntu-24.04
tc: gcc-10 tc: gcc-10
- os: ubuntu-24.04 - os: ubuntu-24.04
tc: gcc-11 tc: gcc-12
- os: ubuntu-24.04
tc: clang-14
- os: ubuntu-24.04
tc: clang-15
fail-fast: false fail-fast: false
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:
@ -67,19 +69,16 @@ jobs:
# z no.*_zl zlib1g-dev # z no.*_zl zlib1g-dev
# n no.*_nc libncurses-dev # n no.*_nc libncurses-dev
# r no.*_rl libreadline-dev # r no.*_rl libreadline-dev
# R no.*_brl --enable-readline-bundled
# c no.*_tcl tcl-dev # c no.*_tcl tcl-dev
# k no.*_tk tk-dev # k no.*_tk tk-dev
# C no.*_gc libcairo-dev # C no.*_gc libcairo-dev
# L no.*_gl libgl-dev # L no.*_gl libgl-dev
# U no.*_gu libglu1-mesa-dev # GLU requires GL # U no.*_gu libglu1-mesa-dev
# X no.*_gx libx11-dev # X no.*_gx libx11-dev
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#z##'); fi pkgs=$(echo -n "$pkgs" | sed -e 's#z##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_nc"; then if echo -n "$MATRIX_PKGS" | grep -q "^no.*_nc"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#n##'); fi 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 if echo -n "$MATRIX_PKGS" | grep -q "^no.*_rl"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#r##'); fi pkgs=$(echo -n "$pkgs" | sed -e 's#r##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then
@ -112,8 +111,6 @@ jobs:
_configure_args=() _configure_args=()
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then
_configure_args+=(--disable-compression); fi _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 if echo -n "$MATRIX_PKGS" | grep -q "^no.*_rl"; then
_configure_args+=(--disable-readline); fi _configure_args+=(--disable-readline); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then
@ -138,8 +135,6 @@ jobs:
echo "BUILD_GCC_VERSION=$BUILD_GCC_VERSION" >> $GITHUB_ENV echo "BUILD_GCC_VERSION=$BUILD_GCC_VERSION" >> $GITHUB_ENV
echo "BUILD_CLANG_VERSION=$BUILD_CLANG_VERSION" >> $GITHUB_ENV echo "BUILD_CLANG_VERSION=$BUILD_CLANG_VERSION" >> $GITHUB_ENV
sudo apt-get update
if [ -n "$BUILD_GCC_VERSION" ] if [ -n "$BUILD_GCC_VERSION" ]
then then
GCCV=$BUILD_GCC_VERSION GCCV=$BUILD_GCC_VERSION
@ -208,7 +203,6 @@ jobs:
export CPP="clang-cpp-${BUILD_CLANG_VERSION}" export CPP="clang-cpp-${BUILD_CLANG_VERSION}"
fi fi
set -o pipefail # due to pipe inside CI
./configure $CONFIGURE_ARGS 2>&1 | tee CONFIGURE.LOG ./configure $CONFIGURE_ARGS 2>&1 | tee CONFIGURE.LOG
egrep "^(CPP|CXX|CC)\s" defs.mak egrep "^(CPP|CXX|CC)\s" defs.mak

View File

@ -1,23 +0,0 @@
# CI for native ARM64 Linux build.
name: CI-aarch64
on:
push:
pull_request:
workflow_dispatch:
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)

View File

@ -10,8 +10,8 @@ on:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel # A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs: jobs:
simple_build_macos15: simple_build_macos13:
runs-on: macos-15-intel # only and last supported intel MacOS runs-on: macos-13
timeout-minutes: 45 # x86_64 seems non-SSD based (slower) timeout-minutes: 45 # x86_64 seems non-SSD based (slower)
steps: steps:
- name: Checkout - name: Checkout
@ -22,8 +22,8 @@ jobs:
run: | run: |
brew install --cask xquartz brew install --cask xquartz
PACKAGE_LIST="xquartz" PACKAGE_LIST="xquartz"
brew install cairo tcl-tk@8 tcsh gnu-sed brew install cairo tcl-tk@8 tcsh
_package_list="cairo tcl-tk@8 tcsh gnu-sed" _package_list="cairo tcl-tk@8 tcsh"
# These seem needed maybe they are being provided from somewhere else GHA runner # 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. # or brew transitive depend either way doesn't hurt to confirm they are installed.
_package_list="$_package_list libglu freeglut" _package_list="$_package_list libglu freeglut"
@ -54,7 +54,6 @@ jobs:
brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE
brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE
brew info tcsh > $TMPFILE && head -n1 $TMPFILE brew info tcsh > $TMPFILE && head -n1 $TMPFILE
brew info gnu-sed > $TMPFILE && head -n1 $TMPFILE
echo "" echo ""
cc -v 2>&1 cc -v 2>&1
echo "" echo ""
@ -235,10 +234,10 @@ jobs:
cp *.mak dist/BUILD-INFO/ cp *.mak dist/BUILD-INFO/
cp *.LOG dist/BUILD-INFO/ cp *.LOG dist/BUILD-INFO/
- name: Upload archive magic-macos15 - name: Upload archive magic-macos13
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: magic-macos15 name: magic-macos13
path: | path: |
${{ github.workspace }}/dist ${{ github.workspace }}/dist
@ -254,8 +253,8 @@ jobs:
run: | run: |
brew install --cask xquartz brew install --cask xquartz
PACKAGE_LIST="xquartz" PACKAGE_LIST="xquartz"
brew install cairo tcl-tk@8 tcsh gnu-sed brew install cairo tcl-tk@8 tcsh
_package_list="cairo tcl-tk@8 tcsh gnu-sed" _package_list="cairo tcl-tk@8 tcsh"
# These seem needed maybe they are being provided from somewhere else GHA runner # 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. # or brew transitive depend either way doesn't hurt to confirm they are installed.
_package_list="$_package_list libglu freeglut" _package_list="$_package_list libglu freeglut"
@ -286,7 +285,6 @@ jobs:
brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE
brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE
brew info tcsh > $TMPFILE && head -n1 $TMPFILE brew info tcsh > $TMPFILE && head -n1 $TMPFILE
brew info gnu-sed > $TMPFILE && head -n1 $TMPFILE
echo "" echo ""
cc -v 2>&1 cc -v 2>&1
echo "" echo ""

View File

@ -1,160 +0,0 @@
name: CI-wasm
# Builds the Magic WebAssembly target on every push and pull request.
# When the VERSION file changes on the default branch, the package is
# additionally published to GitHub Packages (npm.pkg.github.com) as
# @<owner>/magic-vlsi-wasm — no manual tag or token required.
# Tim Edwards updates VERSION to trigger a new release; the scope resolves
# automatically to the repo owner, so forks publish under their own namespace.
#
# WASM is architecture-independent — built once on x86-64, usable everywhere.
on:
push:
pull_request:
workflow_dispatch:
inputs:
emsdk_version:
description: 'emsdk version to build with (default: latest; pin a version number to bisect)'
type: string
default: 'latest'
dry_run:
description: 'Dry run: pack only, do not publish even on tag pushes'
type: boolean
default: true
# actions/upload-artifact@v5 still runs on Node.js 20. Force Node 24 to
# silence the deprecation warning until upload-artifact ships a Node-24
# release. Drop this once upgraded.
env:
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
permissions:
contents: read
packages: write
jobs:
build-wasm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
with:
fetch-depth: 2
- name: Set up Node.js
uses: actions/setup-node@v5
with:
node-version: '22'
registry-url: 'https://npm.pkg.github.com'
- name: Install emsdk
env:
# Defaults to latest so CI tracks emsdk HEAD and catches breakage early.
# Override via workflow_dispatch to pin a specific version when needed
# (e.g. to bisect a regression or verify a post-build.sh patch still applies).
EMSDK_VERSION: ${{ github.event.inputs.emsdk_version || 'latest' }}
run: |
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install "$EMSDK_VERSION"
./emsdk activate "$EMSDK_VERSION"
# Dump native + emscripten preprocessor defines. Useful for diagnosing
# WASM-build differences after an emsdk bump.
- name: Emscripten Diagnostic
run: |
source ./emsdk/emsdk_env.sh
echo "===== gcc -dM -E - ====="; echo | gcc -dM -E - | sort
echo "===== g++ -dM -E - ====="; echo | g++ -dM -E - | sort
echo "===== emcc -dM -E - ====="; echo | emcc -dM -E - | sort
echo "===== em++ -dM -E - ====="; echo | em++ -dM -E - | sort
- name: Build WASM
run: |
source ./emsdk/emsdk_env.sh
# --without/--disable flags: no WASM library available for these features
CFLAGS="--std=c17 -D_DEFAULT_SOURCE=1 -DEMSCRIPTEN=1" emconfigure ./configure \
--without-cairo --without-opengl --without-x --without-tk --without-tcl \
--disable-readline --disable-compression \
--host=asmjs-unknown-emscripten \
--target=asmjs-unknown-emscripten
# Append WASM linker flags and activate the WASM link target
cat toolchains/emscripten/defs.mak >> defs.mak
# Echo the merged defs.mak so CI logs show the exact build config
echo "===== defs.mak ====="; cat defs.mak; echo "===== defs.mak ====="
# Build in order: techs must exist before mains (--embed-file embeds them)
emmake make depend
emmake make -j$(nproc) modules libs
emmake make techs
emmake make mains
- name: Copy WASM artifacts into npm/
run: |
cp magic/magic.js npm/
cp magic/magic.wasm npm/
- name: Run example tests
run: cd npm && npm run test
# Dump generated text outputs (.ext, .spice, .cif, …) into the CI log
# so a regression in extraction / netlisting / cifoutput is visible
# without having to download artifacts. The .gds output is binary —
# skip it and just record its size.
- name: Display example outputs
run: |
shopt -s nullglob
for f in npm/examples/output/*; do
name=$(basename "$f")
case "$f" in
*.gds) echo "===== $name (binary, $(wc -c < "$f") bytes — skipped) =====" ;;
*) echo "===== $name ====="; cat "$f" ;;
esac
done
- name: Set package version and scope
run: |
base=$(cat VERSION) # e.g. 8.3.637
date=$(git show -s --format=%cs | tr -d '-') # e.g. 20260414
hash=$(git show -s --format=%h) # e.g. d157eea
VERSION="${base}-${date}.${hash}"
# Scope the package to the repo owner so it lands in the right
# GitHub Packages namespace regardless of who hosts the repo.
# e.g. @rtimothyedwards/magic-vlsi-wasm on Tim's repo,
# @intubun/magic-vlsi-wasm on a fork.
SCOPED_NAME="@${{ github.repository_owner }}/magic-vlsi-wasm"
cd npm
npm pkg set name="$SCOPED_NAME"
npm pkg set publishConfig.registry="https://npm.pkg.github.com"
npm version "$VERSION" --no-git-tag-version
- name: Pack
run: ./npm/pack.sh
- name: Upload tarball as artifact
uses: actions/upload-artifact@v5
with:
name: magic-vlsi-wasm-npm
path: npm/*.tgz
- name: Check if VERSION changed
id: version_changed
if: github.event_name == 'push'
run: |
if echo "${{ github.ref }}" | grep -q '^refs/tags/'; then
echo "changed=true" >> $GITHUB_OUTPUT
elif [ "${{ github.ref }}" = "refs/heads/${{ github.event.repository.default_branch }}" ]; then
if git diff --name-only HEAD~1 HEAD 2>/dev/null | grep -q '^VERSION$'; then
echo "changed=true" >> $GITHUB_OUTPUT
else
echo "changed=false" >> $GITHUB_OUTPUT
fi
else
echo "changed=false" >> $GITHUB_OUTPUT
fi
- name: Publish to GitHub Packages
if: steps.version_changed.outputs.changed == 'true' && github.event.inputs.dry_run != 'true'
run: cd npm && npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -1,21 +1,58 @@
# This is a basic workflow to help you get started with Actions
name: CI name: CI
# Controls when the workflow will run
on: on:
push: push:
pull_request: pull_request:
workflow_dispatch: workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs: jobs:
simple_build_linux: vezzal:
# The type of runner that the job will run on
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps: steps:
- uses: actions/checkout@v5 - name: Pulling the docker image
run: docker pull vezzal/vezzal:v1
- name: Start the container with the docker image
run: docker run -id --name test_magic vezzal/vezzal:v1 bash | exit
- name: Run the testing on the container and send the mail
run: docker exec test_magic /vezzal/test_magic.sh "lankasaicharan123@gmail.com,tim@opencircuitdesign.com" ${{secrets.MAILING_KEY}}
simple_build_linux:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Get Dependencies - name: Get Dependencies
run: | run: |
sudo apt-get update
sudo apt-get install -y tcl-dev tk-dev libcairo-dev sudo apt-get install -y tcl-dev tk-dev libcairo-dev
- name: Build - name: Build
run: | run: |
./configure ./configure
make database/database.h make database/database.h
make -j$(nproc) make -j$(nproc)
simple_build_wasm:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: Get Dependencies
run: |
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
- name: Build
run: |
source ./emsdk/emsdk_env.sh
emconfigure ./configure --without-cairo --without-opengl --without-x --disable-readline --disable-compression --target=asmjs-unknown-emscripten
emmake make
- name: archive wasm bundle
uses: actions/upload-artifact@v4
with:
name: magic-wasm-bundle
path: |
${{ github.workspace }}/magic/magic.wasm

46
.gitignore vendored
View File

@ -1,33 +1,19 @@
# Autoconf / configure outputs
defs.mak defs.mak
!toolchains/emscripten/defs.mak */Depend
config.cache config.cache
config.log config.log
scripts/config.log scripts/config.log
scripts/config.status scripts/config.status
scripts/defs.mak scripts/defs.mak
install.log
make.log
reconfigure.sh
# Compiled objects / libraries
*.o
*.a
*.so
*/Depend
database/database.h
# Editor / OS cruft
.*.swp .*.swp
.*.swo *.o
*.so
*~ *~
.DS_Store
.vscode/
.idea/
# Magic runtime-generated files
magic/proto.magicrc
scmos/cif_template/objs/* scmos/cif_template/objs/*
database/database.h
install.log
magic/proto.magicrc
make.log
scmos/gdsquery.tech scmos/gdsquery.tech
scmos/minimum.tech scmos/minimum.tech
scmos/scmos-sub.tech scmos/scmos-sub.tech
@ -35,28 +21,14 @@ scmos/scmos-tm.tech
scmos/scmos.tech scmos/scmos.tech
scmos/scmosWR.tech scmos/scmosWR.tech
scmos/nmos.tech scmos/nmos.tech
# Native build artifacts
magic/magic
magic/tclmagic.dylib
tcltk/magic.sh tcltk/magic.sh
tcltk/magic.tcl tcltk/magic.tcl
tcltk/magicdnull tcltk/magicdnull
tcltk/magicexec tcltk/magicexec
tcltk/ext2spice.sh tcltk/ext2spice.sh
tcltk/ext2sim.sh tcltk/ext2sim.sh
magic/tclmagic.dylib
tcltk/magicdnull.dSYM/ tcltk/magicdnull.dSYM/
tcltk/magicexec.dSYM/ tcltk/magicexec.dSYM/
reconfigure.sh
pfx/ pfx/
# WASM build artifacts
magic/magic.js
magic/magic.js.symbols
magic/magic.symbols
magic/magic.wasm
net2ir/net2ir
net2ir/net2ir.js
net2ir/net2ir.wasm
# Generated test output
npm/examples/output/

View File

@ -3,10 +3,11 @@
Get [Homebrew](https://brew.sh). Get [Homebrew](https://brew.sh).
```sh ```sh
brew install cairo tcl-tk@8 python3 gnu-sed # TCL9 should be supported soon (Q2 2025)
brew install cairo tcl-tk@8 python3
brew install --cask xquartz brew install --cask xquartz
./scripts/configure_mac ./scripts/configure_mac
# If you have both TCL8 and TCL9 installed you may need to verify which was selected. # If you have both TCL8 and TCL9 installed you may need to verify TCL8 was selected.
make database/database.h make database/database.h
make -j$(sysctl -n hw.ncpu) make -j$(sysctl -n hw.ncpu)
make install # may need sudo depending on your setup make install # may need sudo depending on your setup

103
Makefile
View File

@ -4,33 +4,31 @@
MAGICDIR = . MAGICDIR = .
PROGRAMS = magic PROGRAMS = magic
TECHS = scmos TECH = scmos
LIBRARIES = database utils extflat LIBRARIES = database utils extflat
MODULES = bplane cmwind commands database dbwind debug drc extflat \ MODULES = bplane cmwind commands database dbwind debug drc extflat \
extract graphics netmenu plow resis select sim textio tiles \ extract graphics netmenu plow resis select sim textio tiles \
utils windows wiring utils windows wiring
# This was `cat VERSION`
VERSION := $(shell cat ${MAGICDIR}/VERSION)
MAKEFLAGS = MAKEFLAGS =
INSTALL_CAD_DIRS = windows doc ${TECHS} INSTALL_CAD_DIRS = windows doc ${TECH}
-include defs.mak -include defs.mak
all: $(ALL_TARGET) techs all: $(ALL_TARGET)
standard: mains standard:
@echo --- errors and warnings logged in file make.log
@${MAKE} mains
tcl: tcllibrary tcl:
@echo --- errors and warnings logged in file make.log
@${MAKE} tcllibrary
force: force: clean all
@${MAKE} clean
@${MAKE} all
defs.mak: defs.mak:
@echo No \"defs.mak\" file found. Run "configure" to make one. @echo No \"defs.mak\" file found. Run "configure" to make one.
@exit 1
config: config:
${MAGICDIR}/configure ${MAGICDIR}/configure
@ -45,56 +43,24 @@ mains: database/database.h modules libs
for dir in ${PROGRAMS}; do \ for dir in ${PROGRAMS}; do \
(cd $$dir && ${MAKE} main) || exit 1; done (cd $$dir && ${MAKE} main) || exit 1; done
database/database.h: ${MAGICDIR}/database/database.h.in database/database.h: database/database.h.in
@echo --- making header file database/database.h @echo --- making header file database/database.h
${SCRIPTS}/makedbh ${MAGICDIR}/database/database.h.in database/database.h ${SCRIPTS}/makedbh database/database.h.in database/database.h
# tiles xyz => tiles/libtiles.o xyz/libxyz.o modules: database/database.h depend
MODULES_SUBDIR := $(shell for i in ${MODULES}; do echo "$${i}/lib$${i}.o"; done) @echo --- making modules
# tiles xyz => tiles/libtiles.a xyz/libxyz.a for dir in ${MODULES} ${PROGRAMS}; do \
LIBS_SUBDIR := $(shell for i in ${MODULES}; do echo "$${i}/lib$${i}.a"; done) (cd $$dir && ${MAKE} module) || exit 1; done
.PHONY: FORCE libs:
${MODULES_SUBDIR}: FORCE @echo --- making libraries
@${MAKE} -C $(dir $@) module for dir in ${LIBRARIES}; do \
(cd $$dir && ${MAKE} lib) || exit 1; done
.PHONY: modules depend: database/database.h
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 @echo --- making dependencies
${MAKE} -C $(dir $@) depend for dir in ${MODULES} ${UNUSED_MODULES} ${PROGRAMS}; do \
(cd $$dir && ${MAKE} depend) || exit 1; done
.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) install: $(INSTALL_TARGET)
@ -129,7 +95,7 @@ install-tcl-real: install-tcl-dirs
(cd $$dir && ${MAKE} install-tcl); done (cd $$dir && ${MAKE} install-tcl); done
clean: clean:
for dir in ${SUBDIRS_FILTERED} ${TECHS} ${BUNDLED_MODULES}; do \ for dir in ${MODULES} ${PROGRAMS} ${TECH} ${UNUSED_MODULES}; do \
(cd $$dir && ${MAKE} clean); done (cd $$dir && ${MAKE} clean); done
${RM} *.tmp */*.tmp *.sav */*.sav *.log TAGS tags ${RM} *.tmp */*.tmp *.sav */*.sav *.log TAGS tags
@ -139,19 +105,18 @@ distclean:
${RM} defs.mak old.defs.mak ${MAGICDIR}/scripts/defs.mak ${RM} defs.mak old.defs.mak ${MAGICDIR}/scripts/defs.mak
${RM} ${MAGICDIR}/scripts/default.conf ${RM} ${MAGICDIR}/scripts/default.conf
${RM} ${MAGICDIR}/scripts/config.log ${MAGICDIR}/scripts/config.status ${RM} ${MAGICDIR}/scripts/config.log ${MAGICDIR}/scripts/config.status
${RM} database/database.h ${RM} scripts/magic.spec magic-`cat VERSION` magic-`cat VERSION`.tgz
${RM} scripts/magic.spec magic-${VERSION} magic-${VERSION}.tgz ${RM} *.log */Depend
${RM} *.log
dist: dist:
${RM} scripts/magic.spec magic-${VERSION} magic-${VERSION}.tgz ${RM} scripts/magic.spec magic-`cat VERSION` magic-`cat VERSION`.tgz
${SED} -e /@VERSION@/s%@VERSION@%${VERSION}% \ sed -e /@VERSION@/s%@VERSION@%`cat VERSION`% \
scripts/magic.spec.in > scripts/magic.spec scripts/magic.spec.in > scripts/magic.spec
${LN} -nsf . magic-${VERSION} ln -nsf . magic-`cat VERSION`
tar zchvf magic-${VERSION}.tgz --exclude CVS \ tar zchvf magic-`cat VERSION`.tgz --exclude CVS \
--exclude magic-${VERSION}/magic-${VERSION} \ --exclude magic-`cat VERSION`/magic-`cat VERSION` \
--exclude magic-${VERSION}/magic-${VERSION}.tgz \ --exclude magic-`cat VERSION`/magic-`cat VERSION`.tgz \
magic-${VERSION} magic-`cat VERSION`
clean-mains: clean-mains:
for dir in ${PROGRAMS}; do \ for dir in ${PROGRAMS}; do \
@ -168,6 +133,6 @@ TAGS:
setup-git: setup-git:
git config --local include.path ../.gitconfig git config --local include.path ../.gitconfig
git stash save git stash save
${RM} .git/index rm .git/index
git checkout HEAD -- "$$(git rev-parse --show-toplevel)" git checkout HEAD -- "$$(git rev-parse --show-toplevel)"
git stash pop git stash pop

View File

@ -1 +1 @@
8.3.661 8.3.521

View File

@ -1,59 +0,0 @@
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"]

View File

@ -1,46 +0,0 @@
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

View File

@ -1,127 +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.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 |

View File

@ -1,46 +0,0 @@
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

View File

@ -1,137 +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.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 |

View File

@ -1,58 +0,0 @@
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"]

View File

@ -1,46 +0,0 @@
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

View File

@ -1,126 +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.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 |

View File

@ -1,59 +0,0 @@
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"]

View File

@ -1,46 +0,0 @@
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

View File

@ -1,128 +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.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 |

View File

@ -13,22 +13,19 @@ RUN ls -l /etc/yum.repos.d/ \
&& yum -y update \ && yum -y update \
&& rm -f /tmp/CentOS-Base.repo.old && rm -f /tmp/CentOS-Base.repo.old
# Build Dependencies (and dump version to logging) # Build Dependencies
RUN yum install -y cairo-devel freeglut-devel gcc make tcsh \ RUN yum install -y cairo-devel freeglut-devel gcc make tcsh
&& echo "### rpm -qa:" \
&& rpm -qa | sort \
&& echo ""
# Tcl/Tk # Tcl/Tk
WORKDIR /tcl WORKDIR /tcl
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \ RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl8.6.12-src.tar.gz | tar --strip-components=1 -xzC . \
&& cd unix \ && cd unix \
&& ./configure --prefix=/prefix \ && ./configure --prefix=/prefix \
&& make \ && make \
&& make install && make install
WORKDIR /tk WORKDIR /tk
RUN curl -L https://prdownloads.sourceforge.net/tcl/tk8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \ RUN curl -L https://prdownloads.sourceforge.net/tcl/tk8.6.12-src.tar.gz | tar --strip-components=1 -xzC . \
&& cd unix \ && cd unix \
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib\ && ./configure --prefix=/prefix --with-tcl=/prefix/lib\
&& make \ && make \
@ -52,16 +49,6 @@ RUN ./configure \
&& make -j$(nproc) \ && make -j$(nproc) \
&& make install && 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 / WORKDIR /
RUN tar -czf /prefix.tar.gz -C ./prefix . RUN tar -czf /prefix.tar.gz -C ./prefix .

33
appimage/Makefile Normal file
View File

@ -0,0 +1,33 @@
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

24
appimage/README.md Normal file
View File

@ -0,0 +1,24 @@
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`

View File

@ -1,39 +1,7 @@
#!/usr/bin/env bash #!/bin/sh
export CURDIR=$(dirname $(readlink -f "${0}")) export CURDIR=$(dirname $(readlink -f "${0}"))
export PATH="${CURDIR}/bin":$PATH export PATH="${CURDIR}/bin":$PATH
export LD_LIBRARY_PATH=${CURDIR}/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=${CURDIR}/lib:$LD_LIBRARY_PATH
export CAD_ROOT="${CURDIR}/lib" export CAD_ROOT="${CURDIR}/lib"
export MAGIC_WISH="${CURDIR}/bin/wish" 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" "$@"

View File

@ -1,4 +0,0 @@
# Usage: wish version_check.tcl
puts "tcl_version=$tcl_version"
puts "tk_version=$tk_version"
exit 0

View File

@ -93,7 +93,7 @@ static BinArray *bpBinArrayNew(int dx, /* x diameter of bins */
/* allocate array */ /* allocate array */
size = sizeof(BinArray) + numBins*(sizeof(void *)); size = sizeof(BinArray) + numBins*(sizeof(void *));
new = (BinArray *)callocMagic(1, size); new = (BinArray *)callocMagic(size);
/* initial */ /* initial */
new->ba_bbox = *bbox; new->ba_bbox = *bbox;

View File

@ -78,7 +78,6 @@ void bpDumpRect(Rect *r)
fprintf(stderr,"%d", fprintf(stderr,"%d",
r->r_ytop); r->r_ytop);
} }
#ifdef CIF_MODULE
else else
{ {
float oscale; float oscale;
@ -94,7 +93,6 @@ void bpDumpRect(Rect *r)
fprintf(stderr,"%f", fprintf(stderr,"%f",
oscale * (float)r->r_ytop); oscale * (float)r->r_ytop);
} }
#endif
} }
/* /*
@ -172,7 +170,6 @@ static void bpBinArrayDump(BinArray *ba, int indent)
fprintf(stderr,"{dx %d} {dy %d} ", fprintf(stderr,"{dx %d} {dy %d} ",
dx,dy); dx,dy);
} }
#ifdef CIF_MODULE
else else
{ {
float oscale; float oscale;
@ -185,7 +182,6 @@ static void bpBinArrayDump(BinArray *ba, int indent)
fprintf(stderr,"{dy %f} ", fprintf(stderr,"{dy %f} ",
(float)dy * oscale); (float)dy * oscale);
} }
#endif
fprintf(stderr,"{dimX %d} {dimY %d} { bbox ", fprintf(stderr,"{dimX %d} {dimY %d} { bbox ",
dimX, dimX,
dimY); dimY);

View File

@ -50,9 +50,9 @@
*/ */
void BPEnumInit(BPEnum *bpe, /* enum to initialize */ void BPEnumInit(BPEnum *bpe, /* enum to initialize */
BPlane *bp, BPlane *bp,
const Rect *area, /* search area */ Rect *area, /* search area */
int match, int match,
const char *id) /* for debugging */ char *id) /* for debugging */
{ {
bool inside = FALSE; bool inside = FALSE;
bpe->bpe_plane = bp; bpe->bpe_plane = bp;

View File

@ -25,8 +25,8 @@
// //
// ************************************************************************ // ************************************************************************
#ifndef _MAGIC__BPLANE__BPENUM_H #ifndef _BPENUM_H
#define _MAGIC__BPLANE__BPENUM_H #define _BPENUM_H
/* bpEnum.h -- /* bpEnum.h --
* *
@ -534,4 +534,4 @@ static __inline__ void *BPEnumNext(BPEnum *bpe)
} }
} }
#endif /* _MAGIC__BPLANE__BPENUM_H */ #endif /* _BPENUM_H */

View File

@ -27,12 +27,12 @@
#ifndef _MAGIC__BPLANE__BPOPAQUE_H #ifndef _BPOPAQUE_H
#define _MAGIC__BPLANE__BPOPAQUE_H #define _BPOPAQUE_H
#ifndef _MAGIC__UTILS__IHASH_H #ifndef _IHASH_H
#include "utils/ihash.h" #include "utils/ihash.h"
#endif #endif /* _IHASH_H */
/* /*
* bpOpaque.h -- * bpOpaque.h --
@ -182,7 +182,7 @@ typedef struct bpenum
BPlane *bpe_plane; /* plane being searched */ BPlane *bpe_plane; /* plane being searched */
Rect bpe_srchArea; /* area being searched */ Rect bpe_srchArea; /* area being searched */
int bpe_match; /* match criteria */ int bpe_match; /* match criteria */
const char *bpe_id; /* for debug */ char *bpe_id; /* for debug */
int bpe_subBinMinX; int bpe_subBinMinX;
int bpe_subBinMinY; /* consider subbinning int bpe_subBinMinY; /* consider subbinning
* for bins bigger than this. * for bins bigger than this.
@ -192,4 +192,4 @@ typedef struct bpenum
BPStack bpe_stack[10000]; /* stack for tree traversal during enum */ BPStack bpe_stack[10000]; /* stack for tree traversal during enum */
} BPEnum; } BPEnum;
#endif /* _MAGIC__BPLANE__BPOPAQUE_H */ #endif /* _BPOPAQUE_H */

View File

@ -27,8 +27,8 @@
#ifndef _MAGIC__BPLANE__BPLANE_H #ifndef _BPLANE_H
#define _MAGIC__BPLANE__BPLANE_H #define _BPLANE_H
/* /*
* bplane.h -- * bplane.h --
@ -185,9 +185,9 @@ extern void BPEnumInit(BPEnum *bpe, /* this procedure initializes this
* enumeration. * enumeration.
*/ */
BPlane *bp, /* bplane to search */ BPlane *bp, /* bplane to search */
const Rect *area, /* area to search */ Rect *area, /* area to search */
int match, /* see below */ int match, /* see below */
const char *id); /* for debugging */ char *id); /* for debugging */
/* match values */ /* match values */
/* enum all elements in the bplane (area arg must be null) */ /* enum all elements in the bplane (area arg must be null) */
@ -232,4 +232,4 @@ BPStat(BPlane *bp,
int *totUnbinned, /* ret tot num of e's not binned */ int *totUnbinned, /* ret tot num of e's not binned */
int *maxDepth); /* ret max bin array depth */ int *maxDepth); /* ret max bin array depth */
#endif /* _MAGIC__BPLANE__BPLANE_H */ #endif /* _BPLANE_H */

View File

@ -33,8 +33,8 @@
* This file defines constants and datastructures used internally by the * This file defines constants and datastructures used internally by the
* bplane module, but not exported to the rest of the world. * bplane module, but not exported to the rest of the world.
*/ */
#ifndef _MAGIC__BPLANE__BPLANEINT_H #ifndef _BPLANEINT_H
#define _MAGIC__BPLANE__BPLANEINT_H #define _BPLANEINT_H
/* Tcl linked Parameters */ /* Tcl linked Parameters */
extern int bpMinBAPop; /* don't sub(bin) when count less than this 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); extern int bpRand(int min, int max);
#endif /* _MAGIC__BPLANE__BPLANEINT_H */ #endif /* _BPLANEINT_H */

View File

@ -53,7 +53,6 @@ int calmaNonManhattan;
int CalmaFlattenLimit = 10; int CalmaFlattenLimit = 10;
int NameConvertErrors = 0; int NameConvertErrors = 0;
bool CalmaRewound = FALSE; bool CalmaRewound = FALSE;
bool CalmaRecordPaths = FALSE;
TileTypeBitMask *CalmaMaskHints = NULL; TileTypeBitMask *CalmaMaskHints = NULL;
extern HashTable calmaDefInitHash; extern HashTable calmaDefInitHash;
@ -246,9 +245,7 @@ calmaExact(void)
int pNum; int pNum;
Plane *newplane; Plane *newplane;
Plane **parray; 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 *)); parray = (Plane **)mallocMagic(MAXCIFRLAYERS * sizeof(Plane *));
@ -390,15 +387,6 @@ calmaParseStructure(
he = HashFind(&calmaDefInitHash, strname); he = HashFind(&calmaDefInitHash, strname);
if ((def = (CellDef *)HashGetValue(he)) != NULL) 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 (def->cd_flags & CDPROCESSEDGDS)
{ {
/* If cell definition was marked as processed, then skip */ /* If cell definition was marked as processed, then skip */
@ -408,7 +396,6 @@ calmaParseStructure(
if (!CalmaPostOrder && !CalmaRewound) if (!CalmaPostOrder && !CalmaRewound)
{ {
cifReadCellDef = def;
CalmaReadError("Cell \"%s\" was already defined in this file.\n", CalmaReadError("Cell \"%s\" was already defined in this file.\n",
strname); strname);
CalmaReadError("Ignoring duplicate definition\n"); CalmaReadError("Ignoring duplicate definition\n");
@ -420,7 +407,6 @@ calmaParseStructure(
{ {
char *newname; char *newname;
cifReadCellDef = def;
CalmaReadError("Cell \"%s\" was already defined in this file.\n", CalmaReadError("Cell \"%s\" was already defined in this file.\n",
strname); strname);
newname = (char *)mallocMagic(strlen(strname) + 20); newname = (char *)mallocMagic(strlen(strname) + 20);
@ -506,33 +492,28 @@ calmaParseStructure(
if (CalmaReadOnly || predefined) if (CalmaReadOnly || predefined)
{ {
PropertyRecord *proprec;
char cstring[1024]; char cstring[1024];
/* Writing the file position into a string is slow, but */
/* it prevents requiring special handling when printing */
/* out the properties. */
char *fpcopy = (char *)mallocMagic(20);
char *fncopy;
/* Substitute variable for PDK path or ~ for home directory */ /* Substitute variable for PDK path or ~ for home directory */
/* the same way that cell references are handled in .mag files. */ /* the same way that cell references are handled in .mag files. */
DBPathSubstitute(filename, cstring, cifReadCellDef); DBPathSubstitute(filename, cstring, cifReadCellDef);
fncopy = StrDup(NULL, cstring);
sprintf(fpcopy, "%"DLONG_PREFIX"d", (dlong) filepos);
DBPropPut(cifReadCellDef, "GDS_START", (ClientData)fpcopy);
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); fpcopy = (char *)mallocMagic(20);
proprec->prop_type = PROPERTY_TYPE_DOUBLE;
proprec->prop_len = 1;
proprec->prop_value.prop_double[0] = filepos;
DBPropPut(cifReadCellDef, "GDS_START", (ClientData)proprec);
filepos = FTELL(calmaInputFile); filepos = FTELL(calmaInputFile);
sprintf(fpcopy, "%"DLONG_PREFIX"d", (dlong) filepos);
DBPropPut(cifReadCellDef, "GDS_END", (ClientData)fpcopy);
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); DBPropPut(cifReadCellDef, "GDS_FILE", (ClientData)fncopy);
proprec->prop_type = PROPERTY_TYPE_DOUBLE;
proprec->prop_len = 1;
proprec->prop_value.prop_double[0] = filepos;
DBPropPut(cifReadCellDef, "GDS_END", (ClientData)proprec);
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) - 7 +
strlen(cstring));
proprec->prop_type = PROPERTY_TYPE_STRING;
proprec->prop_len = 1;
strcpy(proprec->prop_value.prop_string, cstring);
DBPropPut(cifReadCellDef, "GDS_FILE", (ClientData)proprec);
if (predefined) if (predefined)
{ {
@ -759,7 +740,6 @@ calmaParseElement(
int int
calmaEnumFunc( calmaEnumFunc(
Tile *tile, Tile *tile,
TileType dinfo,
int *plane) int *plane)
{ {
return 1; return 1;
@ -789,22 +769,20 @@ calmaElementSref(
char *filename) char *filename)
{ {
int nbytes, rtype, cols, rows, nref, n, i, savescale; int nbytes, rtype, cols, rows, nref, n, i, savescale;
int xlo, ylo, xhi, yhi, xsep, ysep, angle; int xlo, ylo, xhi, yhi, xsep, ysep;
bool madeinst = FALSE, rotated = FALSE; bool madeinst = FALSE;
char *sname = NULL; char *sname = NULL;
bool isArray = FALSE; bool isArray = FALSE;
bool dolookahead = FALSE;
Transform trans, tinv; Transform trans, tinv;
Point refarray[3], refunscaled[3], p; Point refarray[3], refunscaled[3], p;
CellUse *use; CellUse *use;
CellDef *def; 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; char *useid = NULL, *arraystr = NULL;
int propAttrType; int propAttrType;
/* Forward reference */
int gdsCopyPaintFunc(Tile *tile, TileType dinfo, GDSCopyRec *gdsCopyRec);
int gdsHasUses(CellUse *use, ClientData clientdata);
/* Skip CALMA_ELFLAGS, CALMA_PLEX */ /* Skip CALMA_ELFLAGS, CALMA_PLEX */
calmaSkipSet(calmaElementIgnore); calmaSkipSet(calmaElementIgnore);
@ -820,38 +798,7 @@ calmaElementSref(
*/ */
def = calmaLookCell(sname); 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 /* Force the GDS parser to read the cell definition in
* post-order. If cellname "sname" is not defined before * post-order. If cellname "sname" is not defined before
@ -885,7 +832,6 @@ calmaElementSref(
FSEEK(calmaInputFile, originalFilePos, SEEK_SET); FSEEK(calmaInputFile, originalFilePos, SEEK_SET);
cifReadCellDef = calmaLookCell(currentSname); cifReadCellDef = calmaLookCell(currentSname);
def = calmaLookCell(sname); def = calmaLookCell(sname);
def->cd_flags |= CDPRELOADED;
cifCurReadPlanes = savePlanes; cifCurReadPlanes = savePlanes;
calmaLayerHash = OrigCalmaLayerHash; calmaLayerHash = OrigCalmaLayerHash;
if (crsMultiplier != cifCurReadStyle->crs_multiplier) if (crsMultiplier != cifCurReadStyle->crs_multiplier)
@ -990,73 +936,17 @@ calmaElementSref(
refarray[2].p_x = refarray[2].p_y = 0; refarray[2].p_x = refarray[2].p_y = 0;
} }
/* If the array is given an angle, then the meaning of rows and
* columns needs to be swapped for the purpose of ignoring
* X or Y values in the case of a 1-row or 1-column entry.
*/
angle = GeoTransAngle(&trans, 0);
if ((angle == 90) || (angle == 270) || (angle == -90) || (angle == -270))
rotated = TRUE;
/* If this is a cell reference, then we scale to magic coordinates /* If this is a cell reference, then we scale to magic coordinates
* and place the cell in the magic database. However, if this is * and place the cell in the magic database. However, if this is
* a cell to be flattened a la "gds flatten", then we keep the GDS * a cell to be flattened a la "gds flatten", then we keep the GDS
* coordinates, and don't scale to the magic database. * coordinates, and don't scale to the magic database.
*
* NOTE: Scaling everything in the middle or reading array data
* and then retroactively adjusting the array data read earlier
* is problematic, and probably incorrect.
*/ */
for (n = 0; n < nref; n++)
{
savescale = calmaReadScale1;
/* If there is only one column, then X data in the 2nd or 3rd
* entry is irrelevant. If there is only one row, then Y data
* in the 2nd or 3rd entry is irrelevant. Prevent issues caused
* by incorrect/uninitialized data in these positions by ignoring
* them as needed.
*/
if ((n > 0) && ((!rotated && (rows == 1)) || (rotated && (cols == 1))))
{
calmaReadX(&refarray[n], 1);
calmaSkipBytes(4);
refarray[n].p_y = refarray[0].p_y;
}
else if ((n > 0) && ((!rotated && (cols == 1)) || (rotated && (rows == 1))))
{
calmaSkipBytes(4);
calmaReadY(&refarray[n], 1);
refarray[n].p_x = refarray[0].p_x;
}
else
calmaReadPoint(&refarray[n], 1);
if (savescale != calmaReadScale1)
{
/* Scale changed, so update previous points read */
int newscale = calmaReadScale1 / savescale;
for (i = 0; i < n; i++)
{
refarray[i].p_x *= newscale;
refarray[i].p_y *= newscale;
}
}
if (FEOF(calmaInputFile))
return -1;
}
for (n = 0; n < nref; n++)
refunscaled[n] = refarray[n]; // Save for CDFLATGDS cells
for (n = 0; n < nref; n++) for (n = 0; n < nref; n++)
{ {
savescale = cifCurReadStyle->crs_scaleFactor; savescale = cifCurReadStyle->crs_scaleFactor;
calmaReadPoint(&refarray[n], 1);
refunscaled[n] = refarray[n]; // Save for CDFLATGDS cells
refarray[n].p_x = CIFScaleCoord(refarray[n].p_x, COORD_EXACT); refarray[n].p_x = CIFScaleCoord(refarray[n].p_x, COORD_EXACT);
if (savescale != cifCurReadStyle->crs_scaleFactor) if (savescale != cifCurReadStyle->crs_scaleFactor)
{ {
@ -1077,6 +967,9 @@ calmaElementSref(
} }
refarray[n].p_x *= (savescale / cifCurReadStyle->crs_scaleFactor); refarray[n].p_x *= (savescale / cifCurReadStyle->crs_scaleFactor);
} }
if (FEOF(calmaInputFile))
return -1;
} }
/* Skip remainder */ /* Skip remainder */
@ -1352,28 +1245,27 @@ gdsHasUses(
int int
gdsCopyPaintFunc( gdsCopyPaintFunc(
Tile *tile, Tile *tile,
TileType dinfo,
GDSCopyRec *gdsCopyRec) GDSCopyRec *gdsCopyRec)
{ {
int pNum; int pNum;
TileType newdinfo; TileType dinfo;
Rect sourceRect, targetRect; Rect sourceRect, targetRect;
Transform *trans = gdsCopyRec->trans; Transform *trans = gdsCopyRec->trans;
Plane *plane = gdsCopyRec->plane; Plane *plane = gdsCopyRec->plane;
newdinfo = TiGetTypeExact(tile) | dinfo; dinfo = TiGetTypeExact(tile);
if (trans) if (trans)
{ {
TiToRect(tile, &sourceRect); TiToRect(tile, &sourceRect);
GeoTransRect(trans, &sourceRect, &targetRect); GeoTransRect(trans, &sourceRect, &targetRect);
if (IsSplit(tile)) if (IsSplit(tile))
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, trans); dinfo = DBTransformDiagonal(TiGetTypeExact(tile), trans);
} }
else else
TiToRect(tile, &targetRect); TiToRect(tile, &targetRect);
DBNMPaintPlane(plane, newdinfo, &targetRect, CIFPaintTable, DBNMPaintPlane(plane, dinfo, &targetRect, CIFPaintTable,
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
return 0; return 0;
@ -1491,18 +1383,13 @@ calmaFindCell(
if (was_called) *was_called = FALSE; if (was_called) *was_called = FALSE;
} }
else else
{
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", TxPrintf("Warning: cell %s already existed before reading GDS!\n",
name); name);
if (CalmaNoDuplicates)
{
if (predefined) *predefined = TRUE;
TxPrintf("Using pre-existing cell definition\n");
} }
if (was_called) *was_called = TRUE; if (was_called) *was_called = TRUE;
} }

View File

@ -58,7 +58,7 @@ extern int CalmaPathCount;
extern HashTable calmaDefInitHash; extern HashTable calmaDefInitHash;
extern void calmaLayerError(char *mesg, int layer, int dt); extern void calmaLayerError(char *mesg, int layer, int dt);
CIFPath *calmaReadPath(int iscale); bool calmaReadPath(CIFPath **pathheadpp, int iscale);
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -114,8 +114,6 @@ calmaInputRescale(
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* calmaReadX ---
* calmaReadY ---
* calmaReadPoint --- * calmaReadPoint ---
* *
* Read a point from the input. * Read a point from the input.
@ -134,17 +132,11 @@ calmaInputRescale(
* encountered, then everything in the GDS planes is rescaled * encountered, then everything in the GDS planes is rescaled
* to match. * to match.
* *
* Notes:
* This routine has been split into individual X and Y reads so that
* array data can be read while ignoring offset information when there
* is only one row or column; otherwise, bad or uninitialized data
* in the record can cause unnecessary and incorrect scaling.
*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
void void
calmaReadX( calmaReadPoint(
Point *p, Point *p,
int iscale) int iscale)
{ {
@ -171,15 +163,6 @@ calmaReadX(
} }
} }
p->p_x /= calmaReadScale2; p->p_x /= calmaReadScale2;
}
void
calmaReadY(
Point *p,
int iscale)
{
int rescale;
READI4((p)->p_y); READI4((p)->p_y);
p->p_y *= (calmaReadScale1 * iscale); p->p_y *= (calmaReadScale1 * iscale);
@ -205,15 +188,6 @@ calmaReadY(
p->p_y /= calmaReadScale2; p->p_y /= calmaReadScale2;
} }
void
calmaReadPoint(
Point *p,
int iscale)
{
calmaReadX(p, iscale);
calmaReadY(p, iscale);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -239,7 +213,7 @@ calmaElementBoundary(void)
LinkedRect *rp; LinkedRect *rp;
Plane *plane; Plane *plane;
CellUse *use; CellUse *use;
CellDef *savedef = NULL, *newdef = NULL; CellDef *savedef, *newdef = NULL;
/* Skip CALMA_ELFLAGS, CALMA_PLEX */ /* Skip CALMA_ELFLAGS, CALMA_PLEX */
calmaSkipSet(calmaElementIgnore); calmaSkipSet(calmaElementIgnore);
@ -263,8 +237,7 @@ calmaElementBoundary(void)
plane = cifCurReadPlanes[ciftype]; plane = cifCurReadPlanes[ciftype];
/* Read the path itself, building up a path structure */ /* Read the path itself, building up a path structure */
pathheadp = calmaReadPath((plane == NULL) ? 0 : 1); if (!calmaReadPath(&pathheadp, (plane == NULL) ? 0 : 1))
if (pathheadp == NULL)
{ {
if (plane != NULL) if (plane != NULL)
CalmaReadError("Error while reading path for boundary/box; ignored.\n"); CalmaReadError("Error while reading path for boundary/box; ignored.\n");
@ -284,7 +257,7 @@ calmaElementBoundary(void)
if ((CalmaSubcellPolygons != CALMA_POLYGON_NONE) && (calmaNonManhattan > 0)) if ((CalmaSubcellPolygons != CALMA_POLYGON_NONE) && (calmaNonManhattan > 0))
{ {
/* Place the polygon in its own subcell */ /* Place the polygon in its own subcell */
char newname[20]; char newname[16];
HashEntry *he; HashEntry *he;
savedef = cifReadCellDef; savedef = cifReadCellDef;
@ -386,14 +359,12 @@ calmaElementBoundary(void)
} }
/* Paint the rectangles (if any) */ /* Paint the rectangles (if any) */
free_magic1_t mm1 = freeMagic1_init();
for (; rp != NULL ; rp = rp->r_next) for (; rp != NULL ; rp = rp->r_next)
{ {
if (plane) if (plane)
DBPaintPlane(plane, &rp->r_r, CIFPaintTable, (PaintUndoInfo *)NULL); DBPaintPlane(plane, &rp->r_r, CIFPaintTable, (PaintUndoInfo *)NULL);
freeMagic1(&mm1, (char *) rp); freeMagic((char *) rp);
} }
freeMagic1_end(&mm1);
if (cifCurReadPlanes == cifEditCellPlanes) if (cifCurReadPlanes == cifEditCellPlanes)
{ {
@ -537,10 +508,11 @@ calmaElementPath(void)
int layer, dt, width, pathtype, ciftype, savescale; int layer, dt, width, pathtype, ciftype, savescale;
int xmin, ymin, xmax, ymax, temp; int xmin, ymin, xmax, ymax, temp;
CIFPath *pathheadp, *pathp, *previousp; CIFPath *pathheadp, *pathp, *previousp;
Rect segment;
Plane *plane; Plane *plane;
int first,last; int first,last;
CellUse *use; CellUse *use;
CellDef *savedef = NULL, *newdef = NULL; CellDef *savedef, *newdef = NULL;
/* Skip CALMA_ELFLAGS, CALMA_PLEX */ /* Skip CALMA_ELFLAGS, CALMA_PLEX */
calmaSkipSet(calmaElementIgnore); calmaSkipSet(calmaElementIgnore);
@ -623,8 +595,7 @@ calmaElementPath(void)
/* Read the points in the path */ /* Read the points in the path */
savescale = calmaReadScale1; savescale = calmaReadScale1;
pathheadp = calmaReadPath(2); if (!calmaReadPath(&pathheadp, 2))
if (pathheadp == NULL)
{ {
CalmaReadError("Improper path; ignored.\n"); CalmaReadError("Improper path; ignored.\n");
return; return;
@ -717,12 +688,7 @@ calmaElementPath(void)
} }
} }
/* If requested by command option, record the path centerline as a
* property of the cell def.
*/
if (CalmaRecordPaths)
CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE, "path"); CIFPropRecordPath(cifReadCellDef, pathheadp, TRUE, "path");
CIFPaintWirePath(pathheadp, width, CIFPaintWirePath(pathheadp, width,
(pathtype == CALMAPATH_SQUAREFLUSH || pathtype == CALMAPATH_CUSTOM) ? (pathtype == CALMAPATH_SQUAREFLUSH || pathtype == CALMAPATH_CUSTOM) ?
FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL); FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL);
@ -1132,24 +1098,26 @@ calmaElementText(void)
* centerline, to avoid roundoff errors. * centerline, to avoid roundoff errors.
* *
* Results: * Results:
* non-NULL CIFPath* the caller takes ownership of * TRUE is returned if the path was parsed successfully,
* if the path was parsed successfully, otherwise NULL. * FALSE otherwise.
* *
* Side effects: * Side effects:
* None * Modifies the parameter pathheadpp to point to the path
* that is constructed.
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
CIFPath * bool
calmaReadPath( calmaReadPath(
CIFPath **pathheadpp,
int iscale) int iscale)
{ {
CIFPath path, *pathheadp, *pathtailp, *newpathp; CIFPath path, *pathtailp, *newpathp;
int nbytes, rtype, npoints, savescale; int nbytes, rtype, npoints, savescale;
bool nonManhattan = FALSE; bool nonManhattan = FALSE;
pathheadp = (CIFPath *) NULL; *pathheadpp = (CIFPath *) NULL;
pathtailp = (CIFPath *) NULL; pathtailp = (CIFPath *) NULL;
path.cifp_next = (CIFPath *) NULL; path.cifp_next = (CIFPath *) NULL;
@ -1158,12 +1126,12 @@ calmaReadPath(
if (nbytes < 0) if (nbytes < 0)
{ {
CalmaReadError("EOF when reading path.\n"); CalmaReadError("EOF when reading path.\n");
return (NULL); return (FALSE);
} }
if (rtype != CALMA_XY) if (rtype != CALMA_XY)
{ {
calmaUnexpected(CALMA_XY, rtype); calmaUnexpected(CALMA_XY, rtype);
return (NULL); return (FALSE);
} }
/* Read this many points (pairs of four-byte integers) */ /* Read this many points (pairs of four-byte integers) */
@ -1174,7 +1142,7 @@ calmaReadPath(
calmaReadPoint(&path.cifp_point, iscale); calmaReadPoint(&path.cifp_point, iscale);
if (savescale != calmaReadScale1) if (savescale != calmaReadScale1)
{ {
CIFPath *phead = pathheadp; CIFPath *phead = *pathheadpp;
int newscale = calmaReadScale1 / savescale; int newscale = calmaReadScale1 / savescale;
while (phead != NULL) while (phead != NULL)
{ {
@ -1189,8 +1157,8 @@ calmaReadPath(
} }
if (FEOF(calmaInputFile)) if (FEOF(calmaInputFile))
{ {
CIFFreePath(pathheadp); CIFFreePath(*pathheadpp);
return (NULL); return (FALSE);
} }
if (iscale != 0) if (iscale != 0)
@ -1198,7 +1166,7 @@ calmaReadPath(
newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath)));
*newpathp = path; *newpathp = path;
if (pathheadp) if (*pathheadpp)
{ {
/* /*
* Check that this segment is Manhattan. If not, remember the * Check that this segment is Manhattan. If not, remember the
@ -1219,11 +1187,11 @@ calmaReadPath(
} }
pathtailp->cifp_next = newpathp; pathtailp->cifp_next = newpathp;
} }
else pathheadp = newpathp; else *pathheadpp = newpathp;
pathtailp = newpathp; pathtailp = newpathp;
} }
} }
return (pathheadp); return (*pathheadpp != NULL);
} }
/* /*

View File

@ -112,7 +112,7 @@ bool CalmaUnique = FALSE; /* If TRUE, then if a cell exists in
extern bool CalmaDoLibrary; /* Also used by GDS write */ extern bool CalmaDoLibrary; /* Also used by GDS write */
extern void calmaUnexpected(int wanted, int got); extern void calmaUnexpected(int wanted, int got);
extern int calmaWriteInitFunc(CellDef *def, ClientData cdata); /* UNUSED */ extern int calmaWriteInitFunc(CellDef *def);
/* /*
* Scaling. * Scaling.
@ -613,23 +613,20 @@ CalmaTechInit(void)
ASSERT(sizeof(FourByteInt)==4, "definition in calmaInt.h"); ASSERT(sizeof(FourByteInt)==4, "definition in calmaInt.h");
ASSERT(sizeof(TwoByteInt)==2, "definition in calmaInt.h"); ASSERT(sizeof(TwoByteInt)==2, "definition in calmaInt.h");
/* NOTE: Add "$$*$$" to the default "flatglob" value */ /* NOTE: Enable the code below when CalmaContactArrays */
/* when CalmaContactArrays behaves like the non-arrayed */ /* behaves like the non-arrayed function and can be enabled */
/* function and can be enabled by default. */ /* by default. */
#if 0
/* Initialize CalmaFlattenByName to have one entry for */ /* Initialize CalmaFlattenByName to have one entry for */
/* "*_CDNS_*" to match the name style used by many foundry */ /* "$$*$$" to match the name style used by the contact */
/* cells and which corresponds to pcells that often split */ /* array cell generation. This can be overridden by the */
/* layers between cells in ways that magic can't cope with; */ /* "gds flatglob none" command option. */
/* 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) if (CalmaFlattenUsesByName == (char **)NULL)
{ {
CalmaFlattenUsesByName = (char **)mallocMagic(2 * sizeof(char *)); CalmaFlattenUsesByName = (char **)mallocMagic(2 * sizeof(char *));
*CalmaFlattenUsesByName = StrDup((char **)NULL, "*_CDNS_*"); *CalmaFlattenUsesByName = StrDup((char **)NULL, "$$*$$");
*(CalmaFlattenUsesByName + 1) = NULL; *(CalmaFlattenUsesByName + 1) = NULL;
} }
#endif
} }

View File

@ -28,15 +28,9 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>
#include <arpa/inet.h> /* for htons() */ #include <arpa/inet.h> /* for htons() */
#ifdef TIME_WITH_SYS_TIME #include <time.h> /* since C89 */
# include <sys/time.h>
# include <time.h>
#else
#ifdef HAVE_SYS_TIME_H #ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
# else
# include <time.h>
# endif
#endif #endif
#include "utils/magic.h" #include "utils/magic.h"
@ -44,7 +38,6 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
#include "utils/geometry.h" #include "utils/geometry.h"
#include "tiles/tile.h" #include "tiles/tile.h"
#include "utils/utils.h" #include "utils/utils.h"
#include "utils/magic_zlib.h"
#include "utils/hash.h" #include "utils/hash.h"
#include "database/database.h" #include "database/database.h"
#include "database/databaseInt.h" #include "database/databaseInt.h"
@ -91,19 +84,19 @@ int CalmaCompression = 0; /* Output file compression level (0 = uncompressed) *
typedef struct { typedef struct {
FILE *f; /* File stream for output */ FILE *f; /* File stream for output */
const Rect *area; /* Clipping area, in GDS coordinates */ Rect *area; /* Clipping area, in GDS coordinates */
int type; /* Layer index */ int type; /* Layer index */
} calmaOutputStruct; } calmaOutputStruct;
/* Forward declarations */ /* Forward declarations */
extern int calmaWriteInitFunc(CellDef *def, ClientData cdata); /* UNUSED */ extern int calmaWriteInitFunc(CellDef *def);
extern int calmaWritePaintFunc(Tile *tile, TileType dinfo, calmaOutputStruct *cos); extern int calmaWritePaintFunc(Tile *tile, calmaOutputStruct *cos);
extern int calmaMergePaintFunc(Tile *tile, TileType dinfo, calmaOutputStruct *cos); extern int calmaMergePaintFunc(Tile *tile, calmaOutputStruct *cos);
extern int calmaWriteUseFunc(CellUse *use, FILE *f); extern int calmaWriteUseFunc(CellUse *use, FILE *f);
extern int calmaPaintLabelFunc(Tile *tile, TileType dinfo, calmaOutputStruct *cos); extern int calmaPaintLabelFunc(Tile *tile, calmaOutputStruct *cos);
extern void calmaWriteContacts(FILE *f); extern void calmaWriteContacts(FILE *f);
extern void calmaDelContacts(void); extern void calmaDelContacts(void);
extern void calmaOutFunc(CellDef *def, FILE *f, const Rect *cliprect); extern void calmaOutFunc(CellDef *def, FILE *f, Rect *cliprect);
extern void calmaOutStructName(int type, CellDef *def, FILE *f); extern void calmaOutStructName(int type, CellDef *def, FILE *f);
extern void calmaWriteLabelFunc(Label *lab, int ltype, int type, FILE *f); extern void calmaWriteLabelFunc(Label *lab, int ltype, int type, FILE *f);
extern void calmaOutHeader(CellDef *rootDef, FILE *f); extern void calmaOutHeader(CellDef *rootDef, FILE *f);
@ -124,8 +117,8 @@ extern void calmaRemoveDegenerate(BoundaryTop *blist);
#define GDS_PROCESSED 1 #define GDS_PROCESSED 1
#define PUSHTILEC(tp) \ #define PUSHTILEC(tp) \
if (TiGetClient(tp) == GDS_UNPROCESSED) { \ if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \
TiSetClientINT(tp, GDS_PENDING); \ (tp)->ti_client = (ClientData) GDS_PENDING; \
STACKPUSH((ClientData) (tp), SegStack); \ STACKPUSH((ClientData) (tp), SegStack); \
} }
@ -528,7 +521,7 @@ calmaDumpStructure(
/* Is view abstract? */ /* Is view abstract? */
DBPropGet(edef, "LEFview", &isAbstract); DBPropGet(edef, "LEFview", &isAbstract);
chklibname = DBPropGetString(edef, "GDS_FILE", &isReadOnly); chklibname = (char *)DBPropGet(edef, "GDS_FILE", &isReadOnly);
if (isAbstract && isReadOnly) if (isAbstract && isReadOnly)
{ {
@ -738,7 +731,7 @@ calmaFullDump(
* names in the GDS file do not shadow any names in the database. * names in the GDS file do not shadow any names in the database.
*/ */
viewopts = DBPropGetString(def, "LEFview", &isAbstract); viewopts = (char *)DBPropGet(def, "LEFview", &isAbstract);
if ((!isAbstract) || (strcasecmp(viewopts, "no_prefix"))) if ((!isAbstract) || (strcasecmp(viewopts, "no_prefix")))
{ {
/* Generate a SHORT name for this cell (else it is easy to run into the /* Generate a SHORT name for this cell (else it is easy to run into the
@ -822,11 +815,9 @@ done:
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
/*ARGSUSED*/
int int
calmaWriteInitFunc( calmaWriteInitFunc(
CellDef *def, CellDef *def)
ClientData cdata) /* UNUSED */
{ {
def->cd_client = (ClientData) 0; def->cd_client = (ClientData) 0;
return (0); return (0);
@ -920,7 +911,7 @@ calmaProcessDef(
DBPropGet(def, "GDS_END", &hasGDSEnd); DBPropGet(def, "GDS_END", &hasGDSEnd);
DBPropGet(def, "CIFhier", &needHier); DBPropGet(def, "CIFhier", &needHier);
filename = DBPropGetString(def, "GDS_FILE", &isReadOnly); filename = (char *)DBPropGet(def, "GDS_FILE", &isReadOnly);
/* When used with "calma addendum true", don't output the read-only */ /* When used with "calma addendum true", don't output the read-only */
/* cells. This makes the library incomplete and dependent on the */ /* cells. This makes the library incomplete and dependent on the */
@ -1035,12 +1026,13 @@ calmaProcessDef(
} }
else else
{ {
cval = DBPropGetDouble(def, "GDS_END", NULL); offptr = (char *)DBPropGet(def, "GDS_END", NULL);
sscanf(offptr, "%"DLONG_PREFIX"d", &cval);
cellend = (off_t)cval; cellend = (off_t)cval;
cval = DBPropGetDouble(def, "GDS_BEGIN", &oldStyle); offptr = (char *)DBPropGet(def, "GDS_BEGIN", &oldStyle);
if (!oldStyle) if (!oldStyle)
{ {
cval = DBPropGetDouble(def, "GDS_START", NULL); offptr = (char *)DBPropGet(def, "GDS_START", NULL);
/* Write our own header and string name, to ensure */ /* Write our own header and string name, to ensure */
/* that the magic cell name and GDS name match. */ /* that the magic cell name and GDS name match. */
@ -1057,6 +1049,7 @@ calmaProcessDef(
calmaOutStructName(CALMA_STRNAME, def, outf); calmaOutStructName(CALMA_STRNAME, def, outf);
} }
sscanf(offptr, "%"DLONG_PREFIX"d", &cval);
cellstart = (off_t)cval; cellstart = (off_t)cval;
/* GDS_START has been defined as the start of data after the cell */ /* GDS_START has been defined as the start of data after the cell */
@ -1252,7 +1245,7 @@ void
calmaOutFunc( calmaOutFunc(
CellDef *def, /* Pointer to cell def to be written */ CellDef *def, /* Pointer to cell def to be written */
FILE *f, /* Open output file */ FILE *f, /* Open output file */
const Rect *cliprect)/* Area to clip to (used for contact cells), Rect *cliprect) /* Area to clip to (used for contact cells),
* in CIF/GDS coordinates. * in CIF/GDS coordinates.
*/ */
{ {
@ -1263,7 +1256,7 @@ calmaOutFunc(
int dbunits; int dbunits;
calmaOutputStruct cos; calmaOutputStruct cos;
bool propfound; bool propfound;
PropertyRecord *proprec; char *propvalue;
cos.f = f; cos.f = f;
cos.area = (cliprect == &TiPlaneRect) ? NULL : cliprect; cos.area = (cliprect == &TiPlaneRect) ? NULL : cliprect;
@ -1323,21 +1316,15 @@ calmaOutFunc(
/* Include any fixed bounding box as part of the area to process, */ /* Include any fixed bounding box as part of the area to process, */
/* in case the fixed bounding box is larger than the geometry. */ /* in case the fixed bounding box is larger than the geometry. */
proprec = DBPropGet(def, "FIXED_BBOX", &propfound); propvalue = (char *)DBPropGet(def, "FIXED_BBOX", &propfound);
if (propfound) if (propfound)
{ {
Rect bbox; Rect bbox;
if ((proprec->prop_type == PROPERTY_TYPE_DIMENSION) && if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
(proprec->prop_len == 4)) &bbox.r_xtop, &bbox.r_ytop) == 4)
{
bbox.r_xbot = proprec->prop_value.prop_integer[0];
bbox.r_ybot = proprec->prop_value.prop_integer[1];
bbox.r_xtop = proprec->prop_value.prop_integer[2];
bbox.r_ytop = proprec->prop_value.prop_integer[3];
GeoInclude(&bbox, &bigArea); GeoInclude(&bbox, &bigArea);
} }
}
CIFErrorDef = def; CIFErrorDef = def;
CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE,
@ -1406,10 +1393,8 @@ calmaOutFunc(
{ {
pllist[i].pl_label = ll->ll_label; pllist[i].pl_label = ll->ll_label;
pllist[i].pl_port = (unsigned int)ll->ll_attr; pllist[i].pl_port = (unsigned int)ll->ll_attr;
free_magic1_t mm1 = freeMagic1_init(); freeMagic(ll);
freeMagic1(&mm1, ll);
ll = ll->ll_next; ll = ll->ll_next;
freeMagic1_end(&mm1);
i++; i++;
} }
@ -2430,27 +2415,19 @@ calmaProcessBoundary(
/* Free the LinkedBoundary list */ /* Free the LinkedBoundary list */
{
free_magic1_t mm1 = freeMagic1_init();
lbref = listtop; lbref = listtop;
while (lbref->lb_next != listtop) while (lbref->lb_next != listtop)
{ {
freeMagic1(&mm1, lbref); freeMagic(lbref);
lbref = lbref->lb_next; lbref = lbref->lb_next;
} }
freeMagic1(&mm1, lbref); freeMagic(lbref);
freeMagic1_end(&mm1);
}
} }
/* Free the BoundaryTop list */ /* Free the BoundaryTop list */
{
free_magic1_t mm1 = freeMagic1_init();
for (bounds = blist; bounds != NULL; bounds = bounds->bt_next) for (bounds = blist; bounds != NULL; bounds = bounds->bt_next)
freeMagic1(&mm1, bounds); freeMagic(bounds);
freeMagic1_end(&mm1);
}
} }
/* /*
@ -2470,11 +2447,10 @@ calmaProcessBoundary(
int int
calmaMergePaintFunc( calmaMergePaintFunc(
Tile *tile, /* Tile to be written out. */ Tile *tile, /* Tile to be written out. */
TileType dinfo, /* Split tile information (unused) */
calmaOutputStruct *cos) /* Information needed by algorithm */ calmaOutputStruct *cos) /* Information needed by algorithm */
{ {
FILE *f = cos->f; FILE *f = cos->f;
const Rect *clipArea = cos->area; Rect *clipArea = cos->area;
Tile *t, *tp; Tile *t, *tp;
TileType ttype; TileType ttype;
int i, llx, lly, urx, ury, intedges, num_points, split_type; int i, llx, lly, urx, ury, intedges, num_points, split_type;
@ -2486,7 +2462,7 @@ calmaMergePaintFunc(
BoundaryTop *bounds = NULL; BoundaryTop *bounds = NULL;
/* Quick check for tiles that have already been processed */ /* Quick check for tiles that have already been processed */
if (TiGetClientINT(tile) == GDS_PROCESSED) return 0; if (tile->ti_client == (ClientData)GDS_PROCESSED) return 0;
if (SegStack == (Stack *)NULL) if (SegStack == (Stack *)NULL)
SegStack = StackNew(64); SegStack = StackNew(64);
@ -2495,16 +2471,17 @@ calmaMergePaintFunc(
while (!StackEmpty(SegStack)) while (!StackEmpty(SegStack))
{ {
t = (Tile *) STACKPOP(SegStack); t = (Tile *) STACKPOP(SegStack);
if (TiGetClientINT(t) != GDS_PENDING) continue; if (t->ti_client != (ClientData)GDS_PENDING) continue;
TiSetClientINT(t, GDS_PROCESSED); t->ti_client = (ClientData)GDS_PROCESSED;
split_type = -1; split_type = -1;
if (IsSplit(t)) if (IsSplit(t))
{ {
/* If we use TT_SIDE, then we need to set it when the */ /* If we use SplitSide, then we need to set it when the */
/* tile is pushed. Since these are one-or-zero mask layers */ /* tile is pushed. Since these are one-or-zero mask layers */
/* I assume it is okay to just check which side is TT_SPACE */ /* I assume it is okay to just check which side is TT_SPACE */
/* split_type = (SplitSide(t) << 1) | SplitDirection(t); */
split_type = SplitDirection(t); split_type = SplitDirection(t);
if (TiGetLeftType(t) == TT_SPACE) split_type |= 2; if (TiGetLeftType(t) == TT_SPACE) split_type |= 2;
num_points = 2; num_points = 2;
@ -2516,10 +2493,8 @@ calmaMergePaintFunc(
lb = edge; lb = edge;
while (lb->lb_next != edge) lb = lb->lb_next; while (lb->lb_next != edge) lb = lb->lb_next;
lb->lb_next = edge->lb_next; lb->lb_next = edge->lb_next;
free_magic1_t mm1 = freeMagic1_init(); freeMagic(edge);
freeMagic1(&mm1, edge);
edge = edge->lb_next; edge = edge->lb_next;
freeMagic1_end(&mm1);
} }
} }
else else
@ -2727,9 +2702,7 @@ right_search:
done_searches: done_searches:
if (intedges == 0) if (intedges == 0)
{ {
calmaWritePaintFunc(t, calmaWritePaintFunc(t, cos);
(split_type & 2) ? (TileType)TT_SIDE : (TileType)0,
cos);
/* Although calmaWritePaintFunc is called only on isolated */ /* Although calmaWritePaintFunc is called only on isolated */
/* tiles, we may have expanded it. This could use a LOT of */ /* tiles, we may have expanded it. This could use a LOT of */
@ -2740,13 +2713,11 @@ done_searches:
if (num_points != 4) if (num_points != 4)
{ {
free_magic1_t mm1 = freeMagic1_init();
for (i = 0; i < num_points; i++) for (i = 0; i < num_points; i++)
{ {
freeMagic1(&mm1, edge); freeMagic(edge);
edge = edge->lb_next; edge = edge->lb_next;
} }
freeMagic1_end(&mm1);
edge = NULL; edge = NULL;
} }
if (!StackEmpty(SegStack)) if (!StackEmpty(SegStack))
@ -2799,11 +2770,10 @@ done_searches:
int int
calmaWritePaintFunc( calmaWritePaintFunc(
Tile *tile, /* Tile to be written out. */ Tile *tile, /* Tile to be written out. */
TileType dinfo, /* Split tile information */
calmaOutputStruct *cos) /* File for output and clipping area */ calmaOutputStruct *cos) /* File for output and clipping area */
{ {
FILE *f = cos->f; FILE *f = cos->f;
const Rect *clipArea = cos->area; Rect *clipArea = cos->area;
Rect r, r2; Rect r, r2;
TiToRect(tile, &r); TiToRect(tile, &r);
@ -2835,7 +2805,7 @@ calmaWritePaintFunc(
/* Coordinates */ /* Coordinates */
calmaOutRH(36, CALMA_XY, CALMA_I4, f); calmaOutRH(36, CALMA_XY, CALMA_I4, f);
switch (((dinfo & TT_SIDE) ? 2 : 0) | SplitDirection(tile)) switch ((SplitSide(tile) << 1) | SplitDirection(tile))
{ {
case 0x0: case 0x0:
calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f); calmaOutI4(r.r_xbot, f); calmaOutI4(r.r_ybot, f);
@ -3076,11 +3046,10 @@ calmaWriteLabelFunc(
int int
calmaPaintLabelFunc( calmaPaintLabelFunc(
Tile *tile, /* Tile contains area for label. */ Tile *tile, /* Tile contains area for label. */
TileType dinfo, /* Split tile information (unused) */
calmaOutputStruct *cos) /* File for output and clipping area */ calmaOutputStruct *cos) /* File for output and clipping area */
{ {
FILE *f = cos->f; FILE *f = cos->f;
const Rect *clipArea = cos->area; Rect *clipArea = cos->area;
Rect r, r2; Rect r, r2;
Point p; Point p;
int len; int len;

View File

@ -38,15 +38,10 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
#include <ctype.h> #include <ctype.h>
#include <sys/types.h> #include <sys/types.h>
#include <arpa/inet.h> /* for htons() */ #include <arpa/inet.h> /* for htons() */
#ifdef TIME_WITH_SYS_TIME #if defined(SYSV) || defined(EMSCRIPTEN)
# include <sys/time.h>
#include <time.h> #include <time.h>
#else #else
# ifdef HAVE_SYS_TIME_H
#include <sys/time.h> #include <sys/time.h>
# else
# include <time.h>
# endif
#endif #endif
#include "utils/magic.h" #include "utils/magic.h"
@ -54,7 +49,6 @@ static const char rcsid[] __attribute__ ((unused)) ="$Header: /usr/cvsroot/magic
#include "utils/geometry.h" #include "utils/geometry.h"
#include "tiles/tile.h" #include "tiles/tile.h"
#include "utils/utils.h" #include "utils/utils.h"
#include "utils/magic_zlib.h"
#include "utils/hash.h" #include "utils/hash.h"
#include "database/database.h" #include "database/database.h"
#include "database/databaseInt.h" #include "database/databaseInt.h"
@ -96,23 +90,23 @@ extern int calmaPaintLayerNumber;
extern int calmaPaintLayerType; extern int calmaPaintLayerType;
/* External functions from CalmaWrite.c */ /* External functions from CalmaWrite.c */
extern int calmaWriteInitFunc(CellDef *def, ClientData cdata); /* UNUSED */ extern int calmaWriteInitFunc(CellDef *def);
/* Structure used by calmaWritePaintFuncZ() and others */ /* Structure used by calmaWritePaintFuncZ() and others */
typedef struct { typedef struct {
gzFile f; /* Compressed file stream for output */ gzFile f; /* Compressed file stream for output */
const Rect *area; /* Clipping area, in GDS coordinates */ Rect *area; /* Clipping area, in GDS coordinates */
int type; /* Layer index */ int type; /* Layer index */
} calmaOutputStructZ; } calmaOutputStructZ;
/* Forward declarations */ /* Forward declarations */
extern int calmaWritePaintFuncZ(Tile *tile, TileType dinfo, calmaOutputStructZ *cos); extern int calmaWritePaintFuncZ(Tile *tile, calmaOutputStructZ *cos);
extern int calmaMergePaintFuncZ(Tile *tile, TileType dinfo, calmaOutputStructZ *cos); extern int calmaMergePaintFuncZ(Tile *tile, calmaOutputStructZ *cos);
extern int calmaWriteUseFuncZ(CellUse *use, gzFile f); extern int calmaWriteUseFuncZ(CellUse *use, gzFile f);
extern int calmaPaintLabelFuncZ(Tile *tile, TileType dinfo, calmaOutputStructZ *cos); extern int calmaPaintLabelFuncZ(Tile *tile, calmaOutputStructZ *cos);
extern void calmaWriteContactsZ(gzFile f); extern void calmaWriteContactsZ(gzFile f);
extern void calmaOutFuncZ(CellDef *def, gzFile f, const Rect *cliprect); extern void calmaOutFuncZ(CellDef *def, gzFile f, Rect *cliprect);
extern void calmaOutStructNameZ(int type, CellDef *def, gzFile f); extern void calmaOutStructNameZ(int type, CellDef *def, gzFile f);
extern void calmaWriteLabelFuncZ(Label *lab, int ltype, int type, gzFile f); extern void calmaWriteLabelFuncZ(Label *lab, int ltype, int type, gzFile f);
extern void calmaOutHeaderZ(CellDef *rootDef, gzFile f); extern void calmaOutHeaderZ(CellDef *rootDef, gzFile f);
@ -130,8 +124,8 @@ extern void calmaOutR8Z(double d, gzFile f);
#define GDS_PROCESSED 1 #define GDS_PROCESSED 1
#define PUSHTILEZ(tp) \ #define PUSHTILEZ(tp) \
if (TiGetClient(tp) == GDS_UNPROCESSED) { \ if ((tp)->ti_client == (ClientData) GDS_UNPROCESSED) { \
TiSetClientINT(tp, GDS_PENDING); \ (tp)->ti_client = (ClientData) GDS_PENDING; \
STACKPUSH((ClientData) (tp), SegStack); \ STACKPUSH((ClientData) (tp), SegStack); \
} }
@ -508,7 +502,7 @@ calmaDumpStructureZ(
/* Is view abstract? */ /* Is view abstract? */
DBPropGet(edef, "LEFview", &isAbstract); DBPropGet(edef, "LEFview", &isAbstract);
chklibname = DBPropGetString(edef, "GDS_FILE", &isReadOnly); chklibname = (char *)DBPropGet(edef, "GDS_FILE", &isReadOnly);
if (isAbstract && isReadOnly) if (isAbstract && isReadOnly)
{ {
@ -716,7 +710,7 @@ calmaFullDumpZ(
* names in the GDS file do not shadow any names in the database. * names in the GDS file do not shadow any names in the database.
*/ */
viewopts = DBPropGetString(def, "LEFview", &isAbstract); viewopts = (char *)DBPropGet(def, "LEFview", &isAbstract);
if ((!isAbstract) || (strcasecmp(viewopts, "no_prefix"))) if ((!isAbstract) || (strcasecmp(viewopts, "no_prefix")))
{ {
/* Generate a SHORT name for this cell (else it is easy to run into the /* Generate a SHORT name for this cell (else it is easy to run into the
@ -870,7 +864,7 @@ calmaProcessDefZ(
DBPropGet(def, "GDS_START", &hasContent); DBPropGet(def, "GDS_START", &hasContent);
DBPropGet(def, "GDS_END", &hasGDSEnd); DBPropGet(def, "GDS_END", &hasGDSEnd);
DBPropGet(def, "CIFhier", &needHier); DBPropGet(def, "CIFhier", &needHier);
filename = DBPropGetString(def, "GDS_FILE", &isReadOnly); filename = (char *)DBPropGet(def, "GDS_FILE", &isReadOnly);
/* When used with "calma addendum true", don't output the read-only */ /* When used with "calma addendum true", don't output the read-only */
/* cells. This makes the library incomplete and dependent on the */ /* cells. This makes the library incomplete and dependent on the */
@ -985,12 +979,13 @@ calmaProcessDefZ(
} }
else else
{ {
cval = DBPropGetDouble(def, "GDS_END", NULL); offptr = (char *)DBPropGet(def, "GDS_END", NULL);
sscanf(offptr, "%"DLONG_PREFIX"d", &cval);
cellend = (z_off_t)cval; cellend = (z_off_t)cval;
cval = DBPropGetDouble(def, "GDS_BEGIN", &oldStyle); offptr = (char *)DBPropGet(def, "GDS_BEGIN", &oldStyle);
if (!oldStyle) if (!oldStyle)
{ {
cval = DBPropGetDouble(def, "GDS_START", NULL); offptr = (char *)DBPropGet(def, "GDS_START", NULL);
/* Write our own header and string name, to ensure */ /* Write our own header and string name, to ensure */
/* that the magic cell name and GDS name match. */ /* that the magic cell name and GDS name match. */
@ -1007,6 +1002,7 @@ calmaProcessDefZ(
calmaOutStructNameZ(CALMA_STRNAME, def, outf); calmaOutStructNameZ(CALMA_STRNAME, def, outf);
} }
sscanf(offptr, "%"DLONG_PREFIX"d", &cval);
cellstart = (z_off_t)cval; cellstart = (z_off_t)cval;
/* GDS_START has been defined as the start of data after the cell */ /* GDS_START has been defined as the start of data after the cell */
@ -1173,7 +1169,7 @@ void
calmaOutFuncZ( calmaOutFuncZ(
CellDef *def, /* Pointer to cell def to be written */ CellDef *def, /* Pointer to cell def to be written */
gzFile f, /* Open output file */ gzFile f, /* Open output file */
const Rect *cliprect)/* Area to clip to (used for contact cells), Rect *cliprect) /* Area to clip to (used for contact cells),
* in CIF/GDS coordinates. * in CIF/GDS coordinates.
*/ */
{ {
@ -1184,7 +1180,6 @@ calmaOutFuncZ(
int dbunits; int dbunits;
calmaOutputStructZ cos; calmaOutputStructZ cos;
bool propfound; bool propfound;
PropertyRecord *proprec;
char *propvalue; char *propvalue;
extern int compport(const void *one, const void *two); /* Forward declaration */ extern int compport(const void *one, const void *two); /* Forward declaration */
@ -1246,21 +1241,15 @@ calmaOutFuncZ(
/* Include any fixed bounding box as part of the area to process, */ /* Include any fixed bounding box as part of the area to process, */
/* in case the fixed bounding box is larger than the geometry. */ /* in case the fixed bounding box is larger than the geometry. */
proprec = DBPropGet(def, "FIXED_BBOX", &propfound); propvalue = (char *)DBPropGet(def, "FIXED_BBOX", &propfound);
if (propfound) if (propfound)
{ {
Rect bbox; Rect bbox;
if ((proprec->prop_type == PROPERTY_TYPE_DIMENSION) && if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
(proprec->prop_len == 4)) &bbox.r_xtop, &bbox.r_ytop) == 4)
{
bbox.r_xbot = proprec->prop_value.prop_integer[0];
bbox.r_ybot = proprec->prop_value.prop_integer[1];
bbox.r_xtop = proprec->prop_value.prop_integer[2];
bbox.r_ytop = proprec->prop_value.prop_integer[3];
GeoInclude(&bbox, &bigArea); GeoInclude(&bbox, &bigArea);
} }
}
CIFErrorDef = def; CIFErrorDef = def;
CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE,
@ -1329,10 +1318,8 @@ calmaOutFuncZ(
{ {
pllist[i].pl_label = ll->ll_label; pllist[i].pl_label = ll->ll_label;
pllist[i].pl_port = (unsigned int)ll->ll_attr; pllist[i].pl_port = (unsigned int)ll->ll_attr;
free_magic1_t mm1 = freeMagic1_init(); freeMagic(ll);
freeMagic1(&mm1, ll);
ll = ll->ll_next; ll = ll->ll_next;
freeMagic1_end(&mm1);
i++; i++;
} }
@ -1864,27 +1851,19 @@ calmaProcessBoundaryZ(
/* Free the LinkedBoundary list */ /* Free the LinkedBoundary list */
{
free_magic1_t mm1 = freeMagic1_init();
lbref = listtop; lbref = listtop;
while (lbref->lb_next != listtop) while (lbref->lb_next != listtop)
{ {
freeMagic1(&mm1, lbref); freeMagic(lbref);
lbref = lbref->lb_next; lbref = lbref->lb_next;
} }
freeMagic1(&mm1, lbref); freeMagic(lbref);
freeMagic1_end(&mm1);
}
} }
/* Free the BoundaryTop list */ /* Free the BoundaryTop list */
{
free_magic1_t mm1 = freeMagic1_init();
for (bounds = blist; bounds != NULL; bounds = bounds->bt_next) for (bounds = blist; bounds != NULL; bounds = bounds->bt_next)
freeMagic1(&mm1, bounds); freeMagic(bounds);
freeMagic1_end(&mm1);
}
} }
/* /*
@ -1904,11 +1883,10 @@ calmaProcessBoundaryZ(
int int
calmaMergePaintFuncZ( calmaMergePaintFuncZ(
Tile *tile, /* Tile to be written out. */ Tile *tile, /* Tile to be written out. */
TileType dinfo, /* Split tile information (unused) */
calmaOutputStructZ *cos) /* Information needed by algorithm */ calmaOutputStructZ *cos) /* Information needed by algorithm */
{ {
gzFile f = cos->f; gzFile f = cos->f;
const Rect *clipArea = cos->area; Rect *clipArea = cos->area;
Tile *t, *tp; Tile *t, *tp;
TileType ttype; TileType ttype;
int i, llx, lly, urx, ury, intedges, num_points, split_type; int i, llx, lly, urx, ury, intedges, num_points, split_type;
@ -1920,7 +1898,7 @@ calmaMergePaintFuncZ(
BoundaryTop *bounds = NULL; BoundaryTop *bounds = NULL;
/* Quick check for tiles that have already been processed */ /* Quick check for tiles that have already been processed */
if (TiGetClientINT(tile) == GDS_PROCESSED) return 0; if (tile->ti_client == (ClientData)GDS_PROCESSED) return 0;
if (SegStack == (Stack *)NULL) if (SegStack == (Stack *)NULL)
SegStack = StackNew(64); SegStack = StackNew(64);
@ -1929,16 +1907,17 @@ calmaMergePaintFuncZ(
while (!StackEmpty(SegStack)) while (!StackEmpty(SegStack))
{ {
t = (Tile *) STACKPOP(SegStack); t = (Tile *) STACKPOP(SegStack);
if (TiGetClientINT(t) != GDS_PENDING) continue; if (t->ti_client != (ClientData)GDS_PENDING) continue;
TiSetClientINT(t, GDS_PROCESSED); t->ti_client = (ClientData)GDS_PROCESSED;
split_type = -1; split_type = -1;
if (IsSplit(t)) if (IsSplit(t))
{ {
/* If we use TT_SIDE, then we need to set it when the */ /* If we use SplitSide, then we need to set it when the */
/* tile is pushed. Since these are one-or-zero mask layers */ /* tile is pushed. Since these are one-or-zero mask layers */
/* I assume it is okay to just check which side is TT_SPACE */ /* I assume it is okay to just check which side is TT_SPACE */
/* split_type = (SplitSide(t) << 1) | SplitDirection(t); */
split_type = SplitDirection(t); split_type = SplitDirection(t);
if (TiGetLeftType(t) == TT_SPACE) split_type |= 2; if (TiGetLeftType(t) == TT_SPACE) split_type |= 2;
num_points = 2; num_points = 2;
@ -1950,10 +1929,8 @@ calmaMergePaintFuncZ(
lb = edge; lb = edge;
while (lb->lb_next != edge) lb = lb->lb_next; while (lb->lb_next != edge) lb = lb->lb_next;
lb->lb_next = edge->lb_next; lb->lb_next = edge->lb_next;
free_magic1_t mm1 = freeMagic1_init(); freeMagic(edge);
freeMagic1(&mm1, edge);
edge = edge->lb_next; edge = edge->lb_next;
freeMagic1_end(&mm1);
} }
} }
else else
@ -2161,9 +2138,7 @@ right_search:
done_searches: done_searches:
if (intedges == 0) if (intedges == 0)
{ {
calmaWritePaintFuncZ(t, calmaWritePaintFuncZ(t, cos);
(split_type & 2) ? (TileType)TT_SIDE : (TileType)0,
cos);
/* Although calmaWritePaintFunc is called only on isolated */ /* Although calmaWritePaintFunc is called only on isolated */
/* tiles, we may have expanded it. This could use a LOT of */ /* tiles, we may have expanded it. This could use a LOT of */
@ -2174,13 +2149,11 @@ done_searches:
if (num_points != 4) if (num_points != 4)
{ {
free_magic1_t mm1 = freeMagic1_init();
for (i = 0; i < num_points; i++) for (i = 0; i < num_points; i++)
{ {
freeMagic1(&mm1, edge); freeMagic(edge);
edge = edge->lb_next; edge = edge->lb_next;
} }
freeMagic1_end(&mm1);
edge = NULL; edge = NULL;
} }
if (!StackEmpty(SegStack)) if (!StackEmpty(SegStack))
@ -2233,11 +2206,10 @@ done_searches:
int int
calmaWritePaintFuncZ( calmaWritePaintFuncZ(
Tile *tile, /* Tile to be written out. */ Tile *tile, /* Tile to be written out. */
TileType dinfo, /* Split tile information */
calmaOutputStructZ *cos) /* File for output and clipping area */ calmaOutputStructZ *cos) /* File for output and clipping area */
{ {
gzFile f = cos->f; gzFile f = cos->f;
const Rect *clipArea = cos->area; Rect *clipArea = cos->area;
Rect r, r2; Rect r, r2;
TiToRect(tile, &r); TiToRect(tile, &r);
@ -2269,7 +2241,7 @@ calmaWritePaintFuncZ(
/* Coordinates */ /* Coordinates */
calmaOutRHZ(36, CALMA_XY, CALMA_I4, f); calmaOutRHZ(36, CALMA_XY, CALMA_I4, f);
switch (((dinfo & TT_SIDE) ? 2 : 0) | SplitDirection(tile)) switch ((SplitSide(tile) << 1) | SplitDirection(tile))
{ {
case 0x0: case 0x0:
calmaOutI4Z(r.r_xbot, f); calmaOutI4Z(r.r_ybot, f); calmaOutI4Z(r.r_xbot, f); calmaOutI4Z(r.r_ybot, f);
@ -2510,11 +2482,10 @@ calmaWriteLabelFuncZ(
int int
calmaPaintLabelFuncZ( calmaPaintLabelFuncZ(
Tile *tile, /* Tile contains area for label. */ Tile *tile, /* Tile contains area for label. */
TileType dinfo, /* Split tile information (unused) */
calmaOutputStructZ *cos) /* File for output and clipping area */ calmaOutputStructZ *cos) /* File for output and clipping area */
{ {
gzFile f = cos->f; gzFile f = cos->f;
const Rect *clipArea = cos->area; Rect *clipArea = cos->area;
Rect r, r2; Rect r, r2;
Point p; Point p;
int len; int len;

View File

@ -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 $ * rcsid $Header: /usr/cvsroot/magic-8.0/calma/calma.h,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $
*/ */
#ifndef _MAGIC__CALMA__CALMA_H #ifndef _CALMA_H
#define _MAGIC__CALMA__CALMA_H #define _CALMA_H
#include "utils/magic.h" #include "utils/magic.h"
@ -38,7 +38,6 @@ extern TileTypeBitMask *CalmaMaskHints;
extern bool CalmaMergeTiles; extern bool CalmaMergeTiles;
extern bool CalmaFlattenArrays; extern bool CalmaFlattenArrays;
extern bool CalmaNoDRCCheck; extern bool CalmaNoDRCCheck;
extern bool CalmaRecordPaths;
extern bool CalmaFlattenUses; extern bool CalmaFlattenUses;
extern int CalmaFlattenLimit; extern int CalmaFlattenLimit;
extern float CalmaMagScale; extern float CalmaMagScale;
@ -82,8 +81,6 @@ extern int calmaProcessDefZ(CellDef *def, gzFile outf, bool do_library);
#endif #endif
extern bool calmaReadI2Record(int type, int *pvalue); extern bool calmaReadI2Record(int type, int *pvalue);
extern bool calmaReadI4Record(int type, int *pvalue); extern bool calmaReadI4Record(int type, int *pvalue);
extern void calmaReadX(Point *p, int iscale);
extern void calmaReadY(Point *p, int iscale);
extern void calmaReadPoint(Point *p, int iscale); extern void calmaReadPoint(Point *p, int iscale);
extern bool calmaReadR8(double *pd); extern bool calmaReadR8(double *pd);
extern bool calmaReadStampRecord(int type, int *stampptr); extern bool calmaReadStampRecord(int type, int *stampptr);
@ -100,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); extern bool CalmaGenerateArrayZ(gzFile f, TileType type, int llx, int lly, int pitch, int cols, int rows);
#endif #endif
#endif /* _MAGIC__CALMA__CALMA_H */ #endif /* _CALMA_H */

View File

@ -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 $ * rcsid $Header: /usr/cvsroot/magic-8.0/calma/calmaInt.h,v 1.2 2010/06/24 12:37:15 tim Exp $
*/ */
#ifndef _MAGIC__CALMA__CALMAINT_H #ifndef _CALMAINT_H
#define _MAGIC__CALMA__CALMAINT_H #define _CALMAINT_H
#include "utils/magic.h" #include "utils/magic.h"
#include "database/database.h" #include "database/database.h"
@ -274,4 +274,4 @@ extern Plane **cifCurReadPlanes;
extern HashTable CifCellTable; extern HashTable CifCellTable;
extern Plane *cifEditCellPlanes[]; extern Plane *cifEditCellPlanes[];
#endif /* _MAGIC__CALMA__CALMAINT_H */ #endif /* _CALMAINT_H */

File diff suppressed because it is too large Load Diff

View File

@ -209,41 +209,52 @@ typedef struct _maskHintsData
{ {
Transform *mh_trans; Transform *mh_trans;
CellDef *mh_def; CellDef *mh_def;
Plane *mh_plane;
} MaskHintsData; } MaskHintsData;
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* cifCopyMaskHintFunc -- * cifMaskHints --
* *
* Callback function used by cifFlatMaskHints. Transforms a tile * Copy a mask hint into a target cell by adding it to the
* from the original plane and paints it into the target plane, * property list of the target cell. If the target cell already
* both of which are properties. * has the same mask hint key, then the mask hint value is
* appended to the property in the target cell def.
* *
* Results: * Returns:
* Zero to keep the search going. * 0 to keep the search going.
* *
* Side effects: * Side effects:
* Paints geometry into the target plane. * Modifies properties of the target cell def.
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
/* DEPRECATED */
int int
cifCopyMaskHintFunc(Tile *tile, cifMaskHints(
TileType dinfo, char *name,
ClientData cdata) char *value,
CellDef *targetDef)
{ {
MaskHintsData *mhd = (MaskHintsData *)cdata; char *propvalue, *newval;
Rect r, newr; bool propfound;
TiToRect(tile, &r); if (!strncmp(name, "MASKHINTS_", 10))
{
/* Transform tile area to coordinates of mhd->mh_plane and paint */ /* Check if name exists already in the flattened cell */
GeoTransRect(mhd->mh_trans, &r, &newr); propvalue = (char *)DBPropGet(targetDef, name, &propfound);
DBPaintPlane(mhd->mh_plane, &newr, CIFPaintTable, (PaintUndoInfo *)NULL); if (propfound)
{
/* Append value to the property */
newval = mallocMagic(strlen(value) + strlen(propvalue) + 2);
sprintf(newval, "%s %s", propvalue, value);
}
else
newval = StrDup((char **)NULL, value);
DBPropPut(targetDef, name, newval);
}
return 0; return 0;
} }
@ -253,8 +264,8 @@ cifCopyMaskHintFunc(Tile *tile,
* cifFlatMaskHints -- * cifFlatMaskHints --
* *
* Copy a mask hint into a flattened cell by transforming it into the * Copy a mask hint into a flattened cell by transforming it into the
* coordinate system of the flattened cell, and painting it into the * coordinate system of the flattened cell, and adding it to the
* property plane of the flattened cell. * property list of the flattened cell.
* *
* Returns: * Returns:
* 0 to keep the search going. * 0 to keep the search going.
@ -268,40 +279,67 @@ cifCopyMaskHintFunc(Tile *tile,
int int
cifFlatMaskHints( cifFlatMaskHints(
char *name, char *name,
PropertyRecord *proprec, char *value,
MaskHintsData *mhd) MaskHintsData *mhd)
{ {
Rect r, newr; Rect r, newr;
char *vptr, *newval, *lastval, *propvalue; char *vptr, *newval, *lastval, *propvalue;
bool propfound; bool propfound;
int i, lastlen, numvals; int lastlen, numvals;
PropertyRecord *newproprec, *oldproprec;
Plane *plane;
if (!strncmp(name, "MASKHINTS_", 10)) if (!strncmp(name, "MASKHINTS_", 10))
{ {
/* Check if name exists already in the flattened cell */ newval = (char *)NULL;
oldproprec = (PropertyRecord *)DBPropGet(mhd->mh_def, name, &propfound); vptr = value;
if (propfound) while (*vptr != '\0')
{ {
ASSERT(oldproprec->prop_type == PROPERTY_TYPE_PLANE, numvals = sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
"cifFlatMaskHints"); &r.r_xtop, &r.r_ytop);
plane = oldproprec->prop_value.prop_plane; if (numvals == 4)
{
/* Transform rectangle to top level coordinates */
GeoTransRect(mhd->mh_trans, &r, &newr);
lastval = newval;
lastlen = (lastval) ? strlen(lastval) : 0;
newval = mallocMagic(40 + lastlen);
if (lastval)
strcpy(newval, lastval);
else
*newval = '\0';
sprintf(newval + lastlen, "%s%d %d %d %d", (lastval) ? " " : "",
newr.r_xbot, newr.r_ybot, newr.r_xtop, newr.r_ytop);
if (lastval) freeMagic(lastval);
/* Parse through the four values and check if there's more */
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
} }
else else
{ {
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); TxError("MASKHINTS_%s: Expected 4 values, found only %d\n",
newproprec->prop_len = 0; /* (unused) */ name + 10, numvals);
newproprec->prop_type = PROPERTY_TYPE_PLANE; break;
plane = DBNewPlane((ClientData)TT_SPACE); }
newproprec->prop_value.prop_plane = plane;
DBPropPut(mhd->mh_def, name, newproprec);
} }
mhd->mh_plane = plane; /* Check if name exists already in the flattened cell */
DBSrPaintArea((Tile *)NULL, proprec->prop_value.prop_plane, propvalue = (char *)DBPropGet(mhd->mh_def, name, &propfound);
&TiPlaneRect, &CIFSolidBits, if (propfound)
cifCopyMaskHintFunc, (ClientData)mhd); {
/* Append newval to the property */
lastval = newval;
newval = mallocMagic(strlen(lastval) + strlen(propvalue) + 2);
sprintf(newval, "%s %s", propvalue, lastval);
freeMagic(lastval);
}
DBPropPut(mhd->mh_def, name, newval);
} }
return 0; return 0;
} }
@ -312,10 +350,9 @@ cifFlatMaskHints(
* CIFCopyMaskHints -- * CIFCopyMaskHints --
* *
* Callback function to copy mask hints from one cell into another. * Callback function to copy mask hints from one cell into another.
* (Occasionally called as a standalone function, not as a callback.)
* *
* Results: * Results:
* Return 0 to keep the search going. * None.
* *
* Side effects: * Side effects:
* May modify properties in the target cell. * May modify properties in the target cell.
@ -323,7 +360,7 @@ cifFlatMaskHints(
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
int void
CIFCopyMaskHints( CIFCopyMaskHints(
SearchContext *scx, SearchContext *scx,
CellDef *targetDef) CellDef *targetDef)
@ -333,9 +370,38 @@ CIFCopyMaskHints(
CellDef *sourceDef = scx->scx_use->cu_def; CellDef *sourceDef = scx->scx_use->cu_def;
mhd.mh_trans = &scx->scx_trans; mhd.mh_trans = &scx->scx_trans;
mhd.mh_def = targetDef; mhd.mh_def = targetDef;
mhd.mh_plane = (Plane *)NULL;
DBPropEnum(sourceDef, cifFlatMaskHints, &mhd); DBPropEnum(sourceDef, cifFlatMaskHints, &mhd);
}
/*
* ----------------------------------------------------------------------------
*
* cifHierCopyMaskHints --
*
* Callback function to copy mask hints from a subcell into a flattened
* cell, which is passed in the clientData record.
*
* Results:
* Always returns 0 to keep the search alive.
*
* Side effects:
* May modify properties in the flattened cell.
*
* ----------------------------------------------------------------------------
*/
int
cifHierCopyMaskHints(
SearchContext *scx,
ClientData clientData)
{
MaskHintsData mhd;
mhd.mh_trans = &scx->scx_trans;
mhd.mh_def = (CellDef *)clientData;
DBPropEnum(scx->scx_use->cu_def, cifFlatMaskHints, &mhd);
return 0; return 0;
} }
@ -367,16 +433,15 @@ CIFCopyMaskHints(
int int
cifHierCopyFunc( cifHierCopyFunc(
Tile *tile, /* Pointer to tile to copy. */ Tile *tile, /* Pointer to tile to copy. */
TileType dinfo, /* Split tile information */
TreeContext *cxp) /* Describes context of search, including TreeContext *cxp) /* Describes context of search, including
* transform and client data. * transform and client data.
*/ */
{ {
TileType type = TiGetTypeExact(tile) | dinfo; TileType type = TiGetTypeExact(tile);
Rect sourceRect, targetRect; Rect sourceRect, targetRect;
int pNum; int pNum;
CellDef *def = (CellDef *) cxp->tc_filter->tf_arg; CellDef *def = (CellDef *) cxp->tc_filter->tf_arg;
TileType newdinfo = 0; int dinfo = 0;
/* Ignore tiles in vendor GDS, unless this is specifically */ /* Ignore tiles in vendor GDS, unless this is specifically */
/* overridden by the "see-vendor" option. */ /* overridden by the "see-vendor" option. */
@ -392,8 +457,8 @@ cifHierCopyFunc(
if (IsSplit(tile)) if (IsSplit(tile))
{ {
newdinfo = DBTransformDiagonal(type, &cxp->tc_scx->scx_trans); dinfo = DBTransformDiagonal(type, &cxp->tc_scx->scx_trans);
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : type = (SplitSide(tile)) ? SplitRightType(tile) :
SplitLeftType(tile); SplitLeftType(tile);
} }
@ -408,7 +473,7 @@ cifHierCopyFunc(
{ {
if (DBPaintOnPlane(type, pNum)) if (DBPaintOnPlane(type, pNum))
{ {
DBNMPaintPlane(def->cd_planes[pNum], newdinfo, &targetRect, DBNMPaintPlane(def->cd_planes[pNum], dinfo, &targetRect,
DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL); DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL);
} }
} }
@ -460,7 +525,7 @@ cifHierCellFunc(
/* Flatten mask hints in the area of interest */ /* Flatten mask hints in the area of interest */
CIFCopyMaskHints(scx, CIFComponentDef); CIFCopyMaskHints(scx, CIFComponentDef);
DBTreeSrCells(&newscx, 0, CIFCopyMaskHints, DBTreeSrCells(&newscx, 0, cifHierCopyMaskHints,
(ClientData)CIFComponentDef); (ClientData)CIFComponentDef);
/* Set CIFErrorDef to NULL to ignore errors here... these will /* Set CIFErrorDef to NULL to ignore errors here... these will
@ -497,11 +562,9 @@ cifHierCellFunc(
int int
cifHierErrorFunc( cifHierErrorFunc(
Tile *tile, /* Tile that covers area it shouldn't. */ Tile *tile, /* Tile that covers area it shouldn't. */
TileType dinfo, /* Split tile information */
Rect *checkArea) /* Intersection of this and tile is error. */ Rect *checkArea) /* Intersection of this and tile is error. */
{ {
Rect area; Rect area;
bool side = (dinfo & TT_SIDE) ? TRUE : FALSE;
TiToRect(tile, &area); TiToRect(tile, &area);
@ -509,8 +572,8 @@ cifHierErrorFunc(
* space bounds the checkArea. * space bounds the checkArea.
*/ */
if (IsSplit(tile)) if (IsSplit(tile))
if (((area.r_xbot == checkArea->r_xbot) && !side) || if (((area.r_xbot == checkArea->r_xbot) && !SplitSide(tile)) ||
((area.r_xtop == checkArea->r_xtop) && side)) ((area.r_xtop == checkArea->r_xtop) && SplitSide(tile)))
return 0; return 0;
GeoClip(&area, checkArea); GeoClip(&area, checkArea);
@ -541,7 +604,6 @@ cifHierErrorFunc(
int int
cifHierCheckFunc( cifHierCheckFunc(
Tile *tile, /* Tile containing CIF. */ Tile *tile, /* Tile containing CIF. */
TileType dinfo, /* Split tile information */
Plane *plane) /* Plane to check against and modify. */ Plane *plane) /* Plane to check against and modify. */
{ {
Rect area; Rect area;
@ -550,10 +612,10 @@ cifHierCheckFunc(
if (IsSplit(tile)) if (IsSplit(tile))
{ {
DBSrPaintNMArea((Tile *)NULL, plane, TiGetTypeExact(tile) | dinfo, DBSrPaintNMArea((Tile *)NULL, plane, TiGetTypeExact(tile),
&area, &DBSpaceBits, cifHierErrorFunc, (ClientData) &area); &area, &DBSpaceBits, cifHierErrorFunc, (ClientData) &area);
DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFEraseTable, DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable,
(PaintUndoInfo *) NULL); (PaintUndoInfo *) NULL);
} }
else else
@ -589,7 +651,6 @@ cifHierCheckFunc(
int int
cifHierTempCheckFunc( cifHierTempCheckFunc(
Tile *tile, /* Tile containing CIF. */ Tile *tile, /* Tile containing CIF. */
TileType dinfo, /* Information about split tiles */
Plane *plane) /* Plane to check against and modify. */ Plane *plane) /* Plane to check against and modify. */
{ {
Rect area; Rect area;
@ -597,7 +658,7 @@ cifHierTempCheckFunc(
TiToRect(tile, &area); TiToRect(tile, &area);
if (IsSplit(tile)) if (IsSplit(tile))
DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFEraseTable, DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFEraseTable,
(PaintUndoInfo *) NULL); (PaintUndoInfo *) NULL);
else else
DBPaintPlane(plane, &area, CIFEraseTable, (PaintUndoInfo *) NULL); DBPaintPlane(plane, &area, CIFEraseTable, (PaintUndoInfo *) NULL);
@ -625,7 +686,6 @@ cifHierTempCheckFunc(
int int
cifHierPaintFunc( cifHierPaintFunc(
Tile *tile, Tile *tile,
TileType dinfo, /* Information about split tiles */
Plane *plane) /* Plane in which to paint CIF over tile's Plane *plane) /* Plane in which to paint CIF over tile's
* area. * area.
*/ */
@ -633,9 +693,9 @@ cifHierPaintFunc(
Rect area; Rect area;
TiToRect(tile, &area); TiToRect(tile, &area);
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, dinfo, &area); if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area);
if (IsSplit(tile)) if (IsSplit(tile))
DBNMPaintPlane(plane, TiGetTypeExact(tile) | dinfo, &area, CIFPaintTable, DBNMPaintPlane(plane, TiGetTypeExact(tile), &area, CIFPaintTable,
(PaintUndoInfo *) NULL); (PaintUndoInfo *) NULL);
else else
DBPaintPlane(plane, &area, CIFPaintTable, (PaintUndoInfo *) NULL); DBPaintPlane(plane, &area, CIFPaintTable, (PaintUndoInfo *) NULL);
@ -735,10 +795,8 @@ CIFGenSubcells(
/* This routine can take a long time, so use the display /* This routine can take a long time, so use the display
* timer to force a 5-second progress check (like is done * timer to force a 5-second progress check (like is done
* with extract). Save and restore GrDisplayStatus so that * with extract)
* a headless (DISPLAY_SUSPEND) build isn't left in DISPLAY_IDLE.
*/ */
unsigned char savedDisplayStatus = GrDisplayStatus;
GrDisplayStatus = DISPLAY_IN_PROGRESS; GrDisplayStatus = DISPLAY_IN_PROGRESS;
SigSetTimer(5); /* Print at 5-second intervals */ SigSetTimer(5); /* Print at 5-second intervals */
cuts = 0; cuts = 0;
@ -790,7 +848,7 @@ CIFGenSubcells(
cifHierCopyFunc, (ClientData) CIFTotalDef); cifHierCopyFunc, (ClientData) CIFTotalDef);
/* Flatten mask hints in the area of interest */ /* Flatten mask hints in the area of interest */
CIFCopyMaskHints(&scx, CIFTotalDef); CIFCopyMaskHints(&scx, CIFTotalDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints, DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
(ClientData)CIFTotalDef); (ClientData)CIFTotalDef);
CIFErrorDef = def; CIFErrorDef = def;
@ -863,7 +921,7 @@ CIFGenSubcells(
CIFHierTileOps += CIFTileOps - oldTileOps; CIFHierTileOps += CIFTileOps - oldTileOps;
GrDisplayStatus = savedDisplayStatus; GrDisplayStatus = DISPLAY_IDLE;
SigRemoveTimer(); SigRemoveTimer();
UndoEnable(); UndoEnable();
@ -968,14 +1026,14 @@ cifHierElementFunc(
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
cifHierCopyFunc, (ClientData) CIFTotalDef); cifHierCopyFunc, (ClientData) CIFTotalDef);
CIFCopyMaskHints(&scx, CIFTotalDef); CIFCopyMaskHints(&scx, CIFTotalDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints, DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
(ClientData)CIFTotalDef); (ClientData)CIFTotalDef);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
(void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0, (void) DBTreeSrTiles(&scx, &CIFCurStyle->cs_yankLayers, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFCopyMaskHints(&scx, CIFComponentDef); CIFCopyMaskHints(&scx, CIFComponentDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints, DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
(ClientData)CIFComponentDef); (ClientData)CIFComponentDef);
CIFErrorDef = (CellDef *) NULL; CIFErrorDef = (CellDef *) NULL;
@ -1009,7 +1067,6 @@ cifHierElementFunc(
int int
cifGrowSliver( cifGrowSliver(
Tile *tile, Tile *tile,
TileType dinfo, /* Split tile information, needs to be handled */
Rect *area) Rect *area)
{ {
int height, width, expand_up, expand_side; int height, width, expand_up, expand_side;
@ -1070,24 +1127,22 @@ cifGrowSliver(
int int
cifHierPaintArrayFunc( cifHierPaintArrayFunc(
Tile *tile, Tile *tile)
TileType dinfo,
ClientData clientdata) /* (unused) */
{ {
Rect area; Rect area;
int i, j, xbot, xtop; int i, j, xbot, xtop;
TiToRect(tile, &area); TiToRect(tile, &area);
if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, dinfo, &area); if (CIFCurStyle->cs_flags & CWF_GROW_SLIVERS) cifGrowSliver(tile, &area);
xbot = area.r_xbot; xbot = area.r_xbot;
xtop = area.r_xtop; xtop = area.r_xtop;
for (i=0; i<cifHierYCount; i++) for (i=0; i<cifHierYCount; i++)
{ {
for (j=0; j<cifHierXCount; j++) for (j=0; j<cifHierXCount; j++)
{ {
DBNMPaintPlane(cifHierCurPlane, TiGetTypeExact(tile) | dinfo, DBPaintPlane(cifHierCurPlane, &area, CIFPaintTable,
&area, CIFPaintTable, (PaintUndoInfo *) NULL); (PaintUndoInfo *) NULL);
CIFTileOps++; CIFTileOps += 1;
area.r_xbot += cifHierXSpacing; area.r_xbot += cifHierXSpacing;
area.r_xtop += cifHierXSpacing; area.r_xtop += cifHierXSpacing;
} }

View File

@ -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 $" * rcsid "$Header: /usr/cvsroot/magic-8.0/cif/CIFint.h,v 1.3 2008/12/04 17:10:29 tim Exp $"
*/ */
#ifndef _MAGIC__CIF__CIFINT_H #ifndef _CIFINT_H
#define _MAGIC__CIF__CIFINT_H #define _CIFINT_H
#include "database/database.h" #include "database/database.h"
@ -141,12 +141,9 @@ typedef struct cifop
* which will be painted into parent cells instead of the * which will be painted into parent cells instead of the
* current cell. This replaces the "fault" method. * current cell. This replaces the "fault" method.
* CIFOP_CLOSE - Added 11/25/19---close up areas smaller than indicated * CIFOP_CLOSE - Added 11/25/19---close up areas smaller than indicated
* CIFOP_MANHATTAN - Added 3/27/25---remove or fill nonmanhattan areas
* CIFOP_BRIDGE - Added 6/11/20---Bridge across catecorner gaps * CIFOP_BRIDGE - Added 6/11/20---Bridge across catecorner gaps
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers * CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
* CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any. * CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any.
* CIFOP_NOTSQUARE - Added 2/26/26---Keep only geometry which is not square.
* CIFOP_TAGGED - Added 3/11/26---Find geometry attached to the given text label
*/ */
#define CIFOP_AND 1 #define CIFOP_AND 1
@ -170,12 +167,9 @@ typedef struct cifop
#define CIFOP_INTERACT 19 #define CIFOP_INTERACT 19
#define CIFOP_COPYUP 20 #define CIFOP_COPYUP 20
#define CIFOP_CLOSE 21 #define CIFOP_CLOSE 21
#define CIFOP_MANHATTAN 22 #define CIFOP_BRIDGE 22
#define CIFOP_BRIDGE 23 #define CIFOP_BRIDGELIM 23
#define CIFOP_BRIDGELIM 24 #define CIFOP_MASKHINTS 24
#define CIFOP_MASKHINTS 25
#define CIFOP_NOTSQUARE 26
#define CIFOP_TAGGED 27
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */ /* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */ #define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
@ -333,15 +327,16 @@ typedef struct cifstyle
extern bool CIFNameToMask(char *name, TileTypeBitMask *result, TileTypeBitMask *depend); extern bool CIFNameToMask(char *name, TileTypeBitMask *result, TileTypeBitMask *depend);
extern void CIFGenSubcells(CellDef *def, Rect *area, Plane **output); extern void CIFGenSubcells(CellDef *def, Rect *area, Plane **output);
extern void CIFGenArrays(CellDef *def, Rect *area, Plane **output); extern void CIFGenArrays(CellDef *def, Rect *area, Plane **output);
extern void CIFGen(CellDef *cellDef, CellDef *origDef, const Rect *area, Plane **planes, TileTypeBitMask *layers, extern void CIFGen(CellDef *cellDef, CellDef *origDef, Rect *area, Plane **planes, TileTypeBitMask *layers,
bool replace, bool genAllPlanes, bool hier, ClientData clientdata); bool replace, bool genAllPlanes, bool hier, ClientData clientdata);
extern void CIFClearPlanes(Plane **planes); extern void CIFClearPlanes(Plane **planes);
extern Plane *CIFGenLayer(CIFOp *op, const Rect *area, CellDef *cellDef, CellDef *origDef, Plane *temps[], extern Plane *CIFGenLayer(CIFOp *op, Rect *area, CellDef *cellDef, CellDef *origDef, Plane *temps[],
bool hier, ClientData clientdata); bool hier, ClientData clientdata);
extern void CIFInitCells(void); extern void CIFInitCells(void);
extern int cifHierCopyFunc(Tile *tile, TileType dinfo, TreeContext *cxp); extern int cifHierCopyFunc(Tile *tile, TreeContext *cxp);
extern int cifHierCopyMaskHints(SearchContext *scx, ClientData clientData);
extern void CIFLoadStyle(char *stylename); extern void CIFLoadStyle(char *stylename);
extern int CIFCopyMaskHints(SearchContext *scx, CellDef *targetDef); extern void CIFCopyMaskHints(SearchContext *scx, CellDef *targetDef);
/* C99 compat */ /* C99 compat */
extern void CIFCoverageLayer(CellDef *rootDef, Rect *area, char *layer, bool dolist); extern void CIFCoverageLayer(CellDef *rootDef, Rect *area, char *layer, bool dolist);
@ -349,7 +344,7 @@ extern bool CIFWriteFlat(CellDef *rootDef, FILE *f);
extern void CIFScalePlanes(int scalen, int scaled, Plane **planearray); extern void CIFScalePlanes(int scalen, int scaled, Plane **planearray);
extern void CIFInputRescale(int n, int d); extern void CIFInputRescale(int n, int d);
extern int CIFScaleCoord(int cifCoord, int snap_type); extern int CIFScaleCoord(int cifCoord, int snap_type);
extern int cifGrowSliver(Tile *tile, TileType dinfo, Rect *area); extern int cifGrowSliver(Tile *tile, Rect *area);
extern int cifHierElementFunc(CellUse *use, Transform *transform, int x, int y, Rect *checkArea); 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 cifSquareFunc(Rect *area, CIFOp *op, int *rows, int *columns, Rect *cut);
extern int cifSquareGridFunc(Rect *area, CIFOp *op, int *rows, int *columns, Rect *cut); extern int cifSquareGridFunc(Rect *area, CIFOp *op, int *rows, int *columns, Rect *cut);
@ -370,9 +365,6 @@ extern CellUse *CIFDummyUse; /* Used to dummy up a CellUse for a
* def. * def.
*/ */
extern Plane *CIFTotalPlanes[]; /* Exported for diagnostics */
extern Plane *CIFComponentPlanes[]; /* Exported for diagnostics */
/* Valid values of CIFWarningLevel (see cif.h) */ /* Valid values of CIFWarningLevel (see cif.h) */
typedef enum {CIF_WARN_DEFAULT, CIF_WARN_NONE, CIF_WARN_ALIGN, typedef enum {CIF_WARN_DEFAULT, CIF_WARN_NONE, CIF_WARN_ALIGN,
@ -402,4 +394,4 @@ extern void CIFError(Rect *area, char *message);
#define CIF_SOLIDTYPE 1 #define CIF_SOLIDTYPE 1
extern TileTypeBitMask CIFSolidBits; extern TileTypeBitMask CIFSolidBits;
#endif /* _MAGIC__CIF__CIFINT_H */ #endif /* _CIFINT_H */

View File

@ -505,7 +505,6 @@ CIFParseStart(void)
int cifCheckPaintFunc( int cifCheckPaintFunc(
Tile *tile, Tile *tile,
TileType dinfo,
ClientData clientData) ClientData clientData)
{ {
return 1; return 1;
@ -516,28 +515,27 @@ int cifCheckPaintFunc(
int int
cifCopyPaintFunc( cifCopyPaintFunc(
Tile *tile, Tile *tile,
TileType dinfo,
CIFCopyRec *cifCopyRec) CIFCopyRec *cifCopyRec)
{ {
int pNum; int pNum;
TileType newdinfo; TileType dinfo;
Rect sourceRect, targetRect; Rect sourceRect, targetRect;
Transform *trans = cifCopyRec->trans; Transform *trans = cifCopyRec->trans;
Plane *plane = cifCopyRec->plane; Plane *plane = cifCopyRec->plane;
newdinfo = TiGetTypeExact(tile) | dinfo; dinfo = TiGetTypeExact(tile);
if (trans) if (trans)
{ {
TiToRect(tile, &sourceRect); TiToRect(tile, &sourceRect);
GeoTransRect(trans, &sourceRect, &targetRect); GeoTransRect(trans, &sourceRect, &targetRect);
if (IsSplit(tile)) if (IsSplit(tile))
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, trans); dinfo = DBTransformDiagonal(TiGetTypeExact(tile), trans);
} }
else else
TiToRect(tile, &targetRect); TiToRect(tile, &targetRect);
DBNMPaintPlane(plane, newdinfo, &targetRect, CIFPaintTable, DBNMPaintPlane(plane, dinfo, &targetRect, CIFPaintTable,
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
return 0; return 0;
@ -563,7 +561,6 @@ cifCopyPaintFunc(
int int
cifMaskHintFunc( cifMaskHintFunc(
Tile *tile, Tile *tile,
TileType dinfo, /* Unused, do not support non-manhattan hints */
LinkedRect **lrecp) LinkedRect **lrecp)
{ {
Rect r; Rect r;
@ -600,9 +597,8 @@ int
CIFPaintCurrent( CIFPaintCurrent(
int filetype) int filetype)
{ {
/* Forward declarations. */ extern int cifMakeBoundaryFunc(Tile *tile, ClientData clientdata); /* Forward declaration. */
extern int cifMakeBoundaryFunc(Tile *tile, TileType dinfo, ClientData clientdata); extern int cifPaintCurrentFunc(Tile *tile, TileType type); /* Forward declaration. */
extern int cifPaintCurrentFunc(Tile *tile, TileType dinfo, TileType type);
Plane *plane, *swapplane; Plane *plane, *swapplane;
int i; int i;
@ -613,7 +609,7 @@ CIFPaintCurrent(
CIFOp *op; CIFOp *op;
plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops, plane = CIFGenLayer(cifCurReadStyle->crs_layers[i]->crl_ops,
&TiPlaneRect, cifReadCellDef, cifReadCellDef, &TiPlaneRect, (CellDef *)NULL, (CellDef *)NULL,
cifCurReadPlanes, FALSE, (ClientData)NULL); cifCurReadPlanes, FALSE, (ClientData)NULL);
/* Generate a paint/erase table, then paint from the CIF /* Generate a paint/erase table, then paint from the CIF
@ -688,8 +684,6 @@ CIFPaintCurrent(
} }
else if (op == NULL) else if (op == NULL)
{ {
LinkedRect *lrec = NULL, *lsrch;
/* Handle boundary layer */ /* Handle boundary layer */
op = cifCurReadStyle->crs_layers[i]->crl_ops; op = cifCurReadStyle->crs_layers[i]->crl_ops;
@ -704,102 +698,6 @@ CIFPaintCurrent(
(ClientData)NULL) == 1)) (ClientData)NULL) == 1))
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect, DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
&CIFSolidBits, cifMakeBoundaryFunc, INT2CD(filetype)); &CIFSolidBits, cifMakeBoundaryFunc, INT2CD(filetype));
/* Handle mask-hints input operator */
op = cifCurReadStyle->crs_layers[i]->crl_ops;
while (op)
{
if (op->co_opcode == CIFOP_MASKHINTS) break;
op = op->co_next;
}
if (op && (DBSrPaintArea((Tile *)NULL, plane, &TiPlaneRect,
&DBAllButSpaceBits, cifCheckPaintFunc,
(ClientData)NULL) == 1))
{
/* (To do: remove the linked Rects and paint directly
* into the plane in cifMaskHintFunc())
*/
DBSrPaintArea((Tile *) NULL, plane, &TiPlaneRect,
&CIFSolidBits, cifMaskHintFunc,
(ClientData)&lrec);
if (lrec != NULL)
{
PropertyRecord *proprec, *proporig;
char *propname, *layername;
int proplen, i, savescale;
bool origfound = FALSE;
Plane *plane;
layername = (char *)op->co_client;
propname = (char *)mallocMagic(11 + strlen(layername));
sprintf(propname, "MASKHINTS_%s", layername);
/* If there is already a mask hint plane for this layer,
* then add to it; otherwise, create a new plane.
*/
proprec = DBPropGet(cifReadCellDef, layername, &origfound);
if (origfound)
plane = proprec->prop_value.prop_plane;
else
{
proprec = (PropertyRecord *)mallocMagic(
sizeof(PropertyRecord));
proprec->prop_type = PROPERTY_TYPE_PLANE;
proprec->prop_len = 0; /* (unused) */
plane = DBNewPlane((ClientData)TT_SPACE);
proprec->prop_value.prop_plane = plane;
DBPropPut(cifReadCellDef, propname, proprec);
}
while (lrec != NULL)
{
lrec->r_r.r_xtop =
CIFScaleCoord(lrec->r_r.r_xtop, COORD_EXACT);
savescale = cifCurReadStyle->crs_scaleFactor;
lrec->r_r.r_ytop =
CIFScaleCoord(lrec->r_r.r_ytop, COORD_EXACT);
if (savescale != cifCurReadStyle->crs_scaleFactor)
{
lrec->r_r.r_xtop *=
(savescale / cifCurReadStyle->crs_scaleFactor);
savescale = cifCurReadStyle->crs_scaleFactor;
}
lrec->r_r.r_xbot =
CIFScaleCoord(lrec->r_r.r_xbot, COORD_EXACT);
if (savescale != cifCurReadStyle->crs_scaleFactor)
{
lrec->r_r.r_xtop *=
(savescale / cifCurReadStyle->crs_scaleFactor);
lrec->r_r.r_ytop *=
(savescale / cifCurReadStyle->crs_scaleFactor);
savescale = cifCurReadStyle->crs_scaleFactor;
}
lrec->r_r.r_ybot =
CIFScaleCoord(lrec->r_r.r_ybot, COORD_EXACT);
if (savescale != cifCurReadStyle->crs_scaleFactor)
{
lrec->r_r.r_xtop *=
(savescale / cifCurReadStyle->crs_scaleFactor);
lrec->r_r.r_ytop *=
(savescale / cifCurReadStyle->crs_scaleFactor);
lrec->r_r.r_xbot *=
(savescale / cifCurReadStyle->crs_scaleFactor);
}
DBPaintPlane(plane, &lrec->r_r, CIFPaintTable,
(PaintUndoInfo *)NULL);
free_magic1_t mm1 = freeMagic1_init();
freeMagic1(&mm1, lrec);
lrec = lrec->r_next;
freeMagic1_end(&mm1);
}
freeMagic(propname);
}
}
} }
/* Swap planes */ /* Swap planes */
@ -888,7 +786,9 @@ CIFPaintCurrent(
for (i = 0; i < cifNReadLayers; i++) for (i = 0; i < cifNReadLayers; i++)
{ {
LinkedRect *lrec = NULL, *lsrch; LinkedRect *lrec = NULL;
char *propstr = NULL;
char locstr[512];
Plane *tempp; Plane *tempp;
if (!TTMaskHasType(CalmaMaskHints, i)) continue; if (!TTMaskHasType(CalmaMaskHints, i)) continue;
@ -913,55 +813,51 @@ CIFPaintCurrent(
(CellDef *)NULL, CIFPlanes, FALSE, (ClientData)NULL); (CellDef *)NULL, CIFPlanes, FALSE, (ClientData)NULL);
/* Scan the resulting plane and generate linked Rect structures for /* Scan the resulting plane and generate linked Rect structures for
* each shape found. (To do: Remove the linked Rects and paint * each shape found.
* directly into the plane in cifMaskHintFunc(), which is more
* efficient but not hugely so.)
*/ */
DBSrPaintArea((Tile *)NULL, presult, &TiPlaneRect, &CIFSolidBits, DBSrPaintArea((Tile *)NULL, presult, &TiPlaneRect, &CIFSolidBits,
cifMaskHintFunc, (ClientData)&lrec); cifMaskHintFunc, (ClientData)&lrec);
if (lrec != NULL) if (lrec != NULL)
{ {
PropertyRecord *proprec;
bool propfound;
char *propname; char *propname;
Plane *plane;
propname = (char *)mallocMagic(11 + strlen(cifReadLayers[i])); propname = (char *)mallocMagic(11 + strlen(cifReadLayers[i]));
sprintf(propname, "MASKHINTS_%s", cifReadLayers[i]); sprintf(propname, "MASKHINTS_%s", cifReadLayers[i]);
/* Paint all linked Rects into a mask-hints property plane propstr = (char *)NULL;
* in the target cell.
/* Turn all linked Rects into a mask-hints property in the
* target cell.
*/ */
proprec = DBPropGet(cifReadCellDef, propname, &propfound);
if (!propfound)
{
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
proprec->prop_type = PROPERTY_TYPE_PLANE;
proprec->prop_len = 0; /* (unused) */
plane = DBNewPlane((ClientData)TT_SPACE);
proprec->prop_value.prop_plane = plane;
DBPropPut(cifReadCellDef, propname, proprec);
}
else
plane = proprec->prop_value.prop_plane;
while (lrec != NULL) while (lrec != NULL)
{ {
lrec->r_r.r_xbot /= CIFCurStyle->cs_scaleFactor; char *newstr;
lrec->r_r.r_ybot /= CIFCurStyle->cs_scaleFactor; sprintf(locstr, "%d %d %d %d",
lrec->r_r.r_xtop /= CIFCurStyle->cs_scaleFactor; lrec->r_r.r_xbot / CIFCurStyle->cs_scaleFactor,
lrec->r_r.r_ytop /= CIFCurStyle->cs_scaleFactor; lrec->r_r.r_ybot / CIFCurStyle->cs_scaleFactor,
lrec->r_r.r_xtop / CIFCurStyle->cs_scaleFactor,
DBPaintPlane(plane, &lrec->r_r, CIFPaintTable, lrec->r_r.r_ytop / CIFCurStyle->cs_scaleFactor);
(PaintUndoInfo *)NULL); if (propstr == NULL)
{
free_magic1_t mm1 = freeMagic1_init(); newstr = (char *)mallocMagic(strlen(locstr) + 1);
freeMagic1(&mm1, lrec); sprintf(newstr, "%s", locstr);
lrec = lrec->r_next;
freeMagic1_end(&mm1);
} }
else
{
newstr = (char *)mallocMagic(strlen(locstr)
+ strlen(propstr) + 2);
sprintf(newstr, "%s %s", propstr, locstr);
freeMagic(propstr);
}
propstr = newstr;
freeMagic(lrec);
lrec = lrec->r_next;
}
/* NOTE: propstr is transferred to the CellDef and should
* not be free'd here.
*/
DBPropPut(cifReadCellDef, propname, propstr);
freeMagic(propname); freeMagic(propname);
} }
@ -993,14 +889,12 @@ CIFPaintCurrent(
int int
cifMakeBoundaryFunc( cifMakeBoundaryFunc(
Tile *tile, /* Tile of CIF information. */ Tile *tile, /* Tile of CIF information. */
TileType dinfo, /* Split tile information (unused) */
ClientData clientdata) /* Pass the file type (CIF or CALMA) */ ClientData clientdata) /* Pass the file type (CIF or CALMA) */
{ {
/* It is assumed that there is one rectangle for the boundary. */ /* It is assumed that there is one rectangle for the boundary. */
/* If there are multiple rectangles defined with the boundary */ /* If there are multiple rectangles defined with the boundary */
/* layer, then the last one defines the FIXED_BBOX property. */ /* layer, then the last one defines the FIXED_BBOX property. */
PropertyRecord *proprec;
Rect area; Rect area;
char propertyvalue[128], *storedvalue; char propertyvalue[128], *storedvalue;
int savescale; int savescale;
@ -1032,24 +926,19 @@ cifMakeBoundaryFunc(
if (cifReadCellDef->cd_flags & CDFIXEDBBOX) if (cifReadCellDef->cd_flags & CDFIXEDBBOX)
{ {
PropertyRecord *proprec; char *propvalue;
bool found; bool found;
/* Only flag a warning if the redefined boundary was */ /* Only flag a warning if the redefined boundary was */
/* different from the original. */ /* different from the original. */
proprec = DBPropGet(cifReadCellDef, "FIXED_BBOX", &found); propvalue = (char *)DBPropGet(cifReadCellDef, "FIXED_BBOX", &found);
if (found) if (found)
{ {
Rect bbox; Rect bbox;
if ((proprec->prop_type == PROPERTY_TYPE_DIMENSION) && if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
(proprec->prop_len == 4)) &bbox.r_xtop, &bbox.r_ytop) == 4)
{ {
bbox.r_xbot = proprec->prop_value.prop_integer[0];
bbox.r_ybot = proprec->prop_value.prop_integer[1];
bbox.r_xtop = proprec->prop_value.prop_integer[2];
bbox.r_ytop = proprec->prop_value.prop_integer[3];
if ((bbox.r_xbot != area.r_xbot) || if ((bbox.r_xbot != area.r_xbot) ||
(bbox.r_ybot != area.r_ybot) || (bbox.r_ybot != area.r_ybot) ||
(bbox.r_xtop != area.r_xtop) || (bbox.r_xtop != area.r_xtop) ||
@ -1066,15 +955,10 @@ cifMakeBoundaryFunc(
} }
} }
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + 2 * sizeof(int)); sprintf(propertyvalue, "%d %d %d %d",
proprec->prop_type = PROPERTY_TYPE_DIMENSION; area.r_xbot, area.r_ybot, area.r_xtop, area.r_ytop);
proprec->prop_len = 4; storedvalue = StrDup((char **)NULL, propertyvalue);
proprec->prop_value.prop_integer[0] = area.r_xbot; DBPropPut(cifReadCellDef, "FIXED_BBOX", storedvalue);
proprec->prop_value.prop_integer[1] = area.r_ybot;
proprec->prop_value.prop_integer[2] = area.r_xtop;
proprec->prop_value.prop_integer[3] = area.r_ytop;
DBPropPut(cifReadCellDef, "FIXED_BBOX", proprec);
cifReadCellDef->cd_flags |= CDFIXEDBBOX; cifReadCellDef->cd_flags |= CDFIXEDBBOX;
return 0; return 0;
} }
@ -1084,7 +968,6 @@ cifMakeBoundaryFunc(
int int
cifPaintCurrentFunc( cifPaintCurrentFunc(
Tile *tile, /* Tile of CIF information. */ Tile *tile, /* Tile of CIF information. */
TileType dinfo, /* Split tile information */
TileType type) /* Magic type to be painted. */ TileType type) /* Magic type to be painted. */
{ {
Rect area; Rect area;
@ -1134,7 +1017,7 @@ cifPaintCurrentFunc(
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++) for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
if (DBPaintOnPlane(type, pNum)) if (DBPaintOnPlane(type, pNum))
{ {
DBNMPaintPlane(cifReadCellDef->cd_planes[pNum], TiGetTypeExact(tile) | dinfo, DBNMPaintPlane(cifReadCellDef->cd_planes[pNum], TiGetTypeExact(tile),
&area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL); &area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) NULL);
} }
@ -1786,8 +1669,8 @@ CIFReadCellCleanup(
} }
/* Do geometrical processing on the top-level cell. */ /* Do geometrical processing on the top-level cell. */
if (filetype == FILE_CIF) CIFPaintCurrent(filetype);
CIFPaintCurrent(FILE_CIF);
DBAdjustLabels(EditCellUse->cu_def, &TiPlaneRect); DBAdjustLabels(EditCellUse->cu_def, &TiPlaneRect);
DBReComputeBbox(EditCellUse->cu_def); DBReComputeBbox(EditCellUse->cu_def);
DBWAreaChanged(EditCellUse->cu_def, &EditCellUse->cu_def->cd_bbox, DBWAreaChanged(EditCellUse->cu_def, &EditCellUse->cu_def->cd_bbox,

View File

@ -244,61 +244,40 @@ CIFPropRecordPath(
{ {
extern float CIFGetOutputScale(int convert); extern float CIFGetOutputScale(int convert);
CIFPath *pathp; CIFPath *pathp;
char *namestr = NULL; char *pathstr, *sptr;
int components, i, x, y, mult, pathnum; int components;
PropertyRecord *proprec; float x, y, oscale, mult;
bool propfound;
/* If "name" is a property, then append a suffix to it to ensure uniqueness */ oscale = CIFGetOutputScale(1000); /* 1000 for conversion to um */
DBPropGet(def, propname, &propfound); if (oscale == 0.0) oscale = 1.0;
if (propfound) mult = (iswire == TRUE) ? 0.5 : 1.0;
{
pathnum = 0;
namestr = mallocMagic(strlen(propname) + 10);
while (propfound)
{
sprintf(namestr, "%s_%d", propname, pathnum);
DBPropGet(def, namestr, &propfound);
pathnum++;
}
}
mult = (iswire == TRUE) ? 1 : 0;
/* Count the number of components in the path */
pathp = pathheadp; pathp = pathheadp;
components = 0; components = 0;
/* Count the number of components in the path */
while (pathp != NULL) while (pathp != NULL)
{ {
components++;
pathp = pathp->cifp_next; pathp = pathp->cifp_next;
components++;
} }
/* Allocate enough space to hold 2 * N points. */ /* Allocate enough space to hold 2 * N points at "infinity" */
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) + pathstr = (char *)mallocMagic(components * 40);
((components - 1) * 2) * sizeof(int));
proprec->prop_type = PROPERTY_TYPE_DIMENSION;
proprec->prop_len = components * 2;
pathp = pathheadp; pathp = pathheadp;
i = 0; sptr = pathstr;
while (pathp != NULL) while (pathp != NULL)
{ {
x = pathp->cifp_x >> mult; x = (float)pathp->cifp_x * oscale * mult;
y = pathp->cifp_y >> mult; y = (float)pathp->cifp_y * oscale * mult;
sprintf(sptr, "%.3f %.3f ", x, y);
proprec->prop_value.prop_integer[i] = x; sptr = sptr + strlen(sptr);
proprec->prop_value.prop_integer[i + 1] = y;
i += 2;
pathp = pathp->cifp_next; pathp = pathp->cifp_next;
} }
if (namestr)
{ /* Reallocate pathstr to be no larger than needed to hold the path contents */
DBPropPut(def, namestr, proprec); StrDup(&pathstr, pathstr);
freeMagic(namestr); DBPropPut(def, propname, (ClientData)pathstr);
}
else
DBPropPut(def, propname, proprec);
} }
/* /*
@ -359,20 +338,18 @@ CIFPaintWirePath(
pathp = pathheadp->cifp_next; pathp = pathheadp->cifp_next;
if (pathp != NULL) if (pathp != NULL)
{ {
free_magic1_t mm1 = freeMagic1_init();
while (pathp->cifp_next != NULL) while (pathp->cifp_next != NULL)
{ {
if (pathp->cifp_next->cifp_x == pathp->cifp_x && if (pathp->cifp_next->cifp_x == pathp->cifp_x &&
pathp->cifp_next->cifp_y == pathp->cifp_y) pathp->cifp_next->cifp_y == pathp->cifp_y)
{ {
previousp->cifp_next = pathp->cifp_next; previousp->cifp_next = pathp->cifp_next;
freeMagic1(&mm1, pathp); freeMagic(pathp);
} }
else else
previousp = pathp; previousp = pathp;
pathp = pathp->cifp_next; pathp = pathp->cifp_next;
} }
freeMagic1_end(&mm1);
} }
previousp = pathheadp; previousp = pathheadp;
@ -462,22 +439,8 @@ CIFPaintWirePath(
/* Wire reverses direction. Break wire here, */ /* Wire reverses direction. Break wire here, */
/* draw, and start new polygon. */ /* draw, and start new polygon. */
/* Check first if last point and current point */ TxError("Warning: direction reversal in path.\n");
/* are the same, in which case a different */
/* message should be issued (and possibly */
/* should be handled differently?) */
if (previousp && previousp->cifp_x == pathp->cifp_x
&& previousp->cifp_y == pathp->cifp_y)
{
TxError("Warning: duplicate point in path at (%d, %d).\n",
pathp->cifp_x / 2, pathp->cifp_y / 2);
}
else
{
TxError("Warning: direction reversal in path at (%d, %d).\n",
pathp->cifp_x / 2, pathp->cifp_y / 2);
}
phi = theta; phi = theta;
if (endcap) if (endcap)
{ {
@ -488,8 +451,7 @@ CIFPaintWirePath(
firstpoint = TRUE; firstpoint = TRUE;
} }
else { else {
TxError("Error: mitre limit exceeded at wire junction at (%d, %d).\n", TxError("Error: mitre limit exceeded at wire junction.\n");
pathp->cifp_x, pathp->cifp_y);
TxError("Route has been truncated.\n"); TxError("Route has been truncated.\n");
break; break;
} }
@ -522,13 +484,11 @@ CIFPaintWirePath(
rectp = CIFPolyToRects(polypath, plane, ptable, ui, FALSE); rectp = CIFPolyToRects(polypath, plane, ptable, ui, FALSE);
CIFFreePath(polypath); CIFFreePath(polypath);
free_magic1_t mm1 = freeMagic1_init();
for (; rectp != NULL ; rectp = rectp->r_next) for (; rectp != NULL ; rectp = rectp->r_next)
{ {
DBPaintPlane(plane, &rectp->r_r, ptable, ui); DBPaintPlane(plane, &rectp->r_r, ptable, ui);
freeMagic1(&mm1, (char *) rectp); freeMagic((char *) rectp);
} }
freeMagic1_end(&mm1);
polypath = NULL; polypath = NULL;
} }
else else
@ -626,13 +586,11 @@ PaintPolygon(
rectlist = CIFPolyToRects(cifpath, plane, ptable, ui, FALSE); rectlist = CIFPolyToRects(cifpath, plane, ptable, ui, FALSE);
CIFFreePath(cifpath); CIFFreePath(cifpath);
free_magic1_t mm1 = freeMagic1_init();
for (rectp = rectlist; rectp != NULL ; rectp = rectp->r_next) for (rectp = rectlist; rectp != NULL ; rectp = rectp->r_next)
{ {
DBPaintPlane(plane, &rectp->r_r, ptable, ui); DBPaintPlane(plane, &rectp->r_r, ptable, ui);
if (!keep) freeMagic1(&mm1, (char *) rectp); if (!keep) freeMagic((char *) rectp);
} }
freeMagic1_end(&mm1);
return (keep) ? rectlist : (LinkedRect *)NULL; return (keep) ? rectlist : (LinkedRect *)NULL;
} }
@ -729,8 +687,7 @@ CIFParseWire(void)
width /= cifReadScale2; width /= cifReadScale2;
savescale = cifReadScale1; savescale = cifReadScale1;
pathheadp = CIFParsePath(2); if (!CIFParsePath(&pathheadp, 2))
if (pathheadp == NULL)
{ {
CIFReadError("wire, but improper path; ignored.\n"); CIFReadError("wire, but improper path; ignored.\n");
CIFSkipToSemi(); CIFSkipToSemi();
@ -840,8 +797,7 @@ CIFParsePoly(void)
CIFSkipToSemi(); CIFSkipToSemi();
return FALSE; return FALSE;
} }
pathheadp = CIFParsePath(1); if (!CIFParsePath(&pathheadp, 1))
if (pathheadp == NULL)
{ {
CIFReadError("polygon, but improper path; ignored.\n"); CIFReadError("polygon, but improper path; ignored.\n");
CIFSkipToSemi(); CIFSkipToSemi();
@ -861,13 +817,11 @@ CIFParsePoly(void)
CIFSkipToSemi(); CIFSkipToSemi();
return FALSE; return FALSE;
} }
free_magic1_t mm1 = freeMagic1_init();
for (; rectp != NULL ; rectp = rectp->r_next) for (; rectp != NULL ; rectp = rectp->r_next)
{ {
DBPaintPlane(cifReadPlane, &rectp->r_r, CIFPaintTable, DBPaintPlane(cifReadPlane, &rectp->r_r, CIFPaintTable,
(PaintUndoInfo *) NULL); (PaintUndoInfo *) NULL);
freeMagic1(&mm1, (char *) rectp); freeMagic((char *) rectp);
} }
freeMagic1_end(&mm1);
return TRUE; return TRUE;
} }

View File

@ -324,20 +324,13 @@ cifNewReadStyle(void)
{ {
/* Destroy old style and free all memory allocated to it */ /* Destroy old style and free all memory allocated to it */
for (i = 0; i < MAXCIFRLAYERS; i++) for (i=0; i<MAXCIFRLAYERS; i+=1)
{ {
layer = cifCurReadStyle->crs_layers[i]; layer = cifCurReadStyle->crs_layers[i];
if (layer != NULL) if (layer != NULL)
{ {
free_magic1_t mm1 = freeMagic1_init();
for (op = layer->crl_ops; op != NULL; op = op->co_next) for (op = layer->crl_ops; op != NULL; op = op->co_next)
{ freeMagic((char *)op);
if (op->co_opcode == CIFOP_MASKHINTS ||
op->co_opcode == CIFOP_TAGGED)
freeMagic((char *)op->co_client);
freeMagic1(&mm1, (char *)op);
}
freeMagic1_end(&mm1);
freeMagic((char *)layer); freeMagic((char *)layer);
} }
} }
@ -415,13 +408,11 @@ CIFReadTechInit(void)
/* forget the list of styles */ /* forget the list of styles */
free_magic1_t mm1 = freeMagic1_init();
for (style = cifReadStyleList; style != NULL; style = style->crs_next) for (style = cifReadStyleList; style != NULL; style = style->crs_next)
{ {
freeMagic(style->crs_name); freeMagic(style->crs_name);
freeMagic1(&mm1, style); freeMagic(style);
} }
freeMagic1_end(&mm1);
cifReadStyleList = NULL; cifReadStyleList = NULL;
} }
@ -995,12 +986,6 @@ CIFReadTechLine(
newOp->co_opcode = CIFOP_COPYUP; newOp->co_opcode = CIFOP_COPYUP;
else if (strcmp(argv[0], "boundary") == 0) else if (strcmp(argv[0], "boundary") == 0)
newOp->co_opcode = CIFOP_BOUNDARY; newOp->co_opcode = CIFOP_BOUNDARY;
else if (strcmp(argv[0], "not-square") == 0)
newOp->co_opcode = CIFOP_NOTSQUARE;
else if (strcmp(argv[0], "mask-hints") == 0)
newOp->co_opcode = CIFOP_MASKHINTS;
else if (strcmp(argv[0], "tagged") == 0)
newOp->co_opcode = CIFOP_TAGGED;
else else
{ {
TechError("Unknown statement \"%s\".\n", argv[0]); TechError("Unknown statement \"%s\".\n", argv[0]);
@ -1027,16 +1012,6 @@ CIFReadTechLine(
goto errorReturn; goto errorReturn;
} }
break; break;
case CIFOP_MASKHINTS:
if (argc != 2) goto wrongNumArgs;
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
break;
case CIFOP_TAGGED:
if ((argc != 2) && (argc != 3)) goto wrongNumArgs;
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
if (argc == 3)
CIFParseReadLayers(argv[2], &newOp->co_cifMask, TRUE);
break;
} }
/* Link the new CIFOp onto the list. */ /* Link the new CIFOp onto the list. */
@ -1120,7 +1095,6 @@ CIFReadTechFinal(void)
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
void void
CIFReadLoadStyle( CIFReadLoadStyle(
char *stylename) char *stylename)

View File

@ -276,10 +276,8 @@ CIFScaleCoord(
PlowAfterTech(); PlowAfterTech();
ExtTechScale(1, denom); ExtTechScale(1, denom);
WireTechScale(1, denom); WireTechScale(1, denom);
#ifdef ROUTE_MODULE
MZAfterTech(); MZAfterTech();
IRAfterTech(); IRAfterTech();
#endif
#ifdef LEF_MODULE #ifdef LEF_MODULE
LefTechScale(1, denom); LefTechScale(1, denom);
#endif #endif
@ -651,11 +649,12 @@ CIFParsePoint(
* one or more points. * one or more points.
* *
* Results: * Results:
* non-NULL CIFPath* the caller takes ownership of * TRUE is returned if the path was parsed successfully,
* if the path was parsed successfully, otherwise NULL. * FALSE otherwise.
* *
* Side effects: * Side effects:
* None * Modifies the parameter pathheadpp to point to the path
* that is constructed.
* *
* Corrections: * Corrections:
* CIF coordinates are multiplied by 2 to cover the case where * CIF coordinates are multiplied by 2 to cover the case where
@ -667,16 +666,17 @@ CIFParsePoint(
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
CIFPath * bool
CIFParsePath( CIFParsePath(
CIFPath **pathheadpp,
int iscale) int iscale)
{ {
CIFPath *pathheadp, *pathtailp, *newpathp; CIFPath *pathtailp, *newpathp;
bool nonManhattan = FALSE; /* diagnostic only */ bool nonManhattan = FALSE; /* diagnostic only */
CIFPath path; CIFPath path;
int savescale; int savescale;
pathheadp = NULL; *pathheadpp = NULL;
pathtailp = NULL; pathtailp = NULL;
path.cifp_next = NULL; path.cifp_next = NULL;
while (TRUE) while (TRUE)
@ -688,12 +688,12 @@ CIFParsePath(
savescale = cifReadScale1; savescale = cifReadScale1;
if (!CIFParsePoint(&path.cifp_point, iscale)) if (!CIFParsePoint(&path.cifp_point, iscale))
{ {
CIFFreePath(pathheadp); CIFFreePath(*pathheadpp);
return NULL; return FALSE;
} }
if (savescale != cifReadScale1) if (savescale != cifReadScale1)
{ {
CIFPath *phead = pathheadp; CIFPath *phead = *pathheadpp;
int newscale = cifReadScale1 / savescale; int newscale = cifReadScale1 / savescale;
while (phead != NULL) while (phead != NULL)
{ {
@ -704,7 +704,7 @@ CIFParsePath(
} }
newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath))); newpathp = (CIFPath *) mallocMagic((unsigned) (sizeof (CIFPath)));
*newpathp = path; *newpathp = path;
if (pathheadp) if (*pathheadpp)
{ {
/* /*
* Check that this segment is Manhattan. If not, remember the * Check that this segment is Manhattan. If not, remember the
@ -721,10 +721,10 @@ CIFParsePath(
} }
pathtailp->cifp_next = newpathp; pathtailp->cifp_next = newpathp;
} }
else pathheadp = newpathp; else *pathheadpp = newpathp;
pathtailp = newpathp; pathtailp = newpathp;
} }
return pathheadp; return (*pathheadpp != NULL);
} }
/* /*
@ -1338,13 +1338,11 @@ void
CIFFreePath( CIFFreePath(
CIFPath *path) /* Path to be freed. */ CIFPath *path) /* Path to be freed. */
{ {
free_magic1_t mm1 = freeMagic1_init();
while (path != NULL) while (path != NULL)
{ {
freeMagic1(&mm1, (char *) path); freeMagic((char *) path);
path = path->cifp_next; path = path->cifp_next;
} }
freeMagic1_end(&mm1);
} }
/* /*

View File

@ -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 $ * rcsid "$Header: /usr/cvsroot/magic-8.0/cif/CIFread.h,v 1.3 2010/08/25 17:33:55 tim Exp $
*/ */
#ifndef _MAGIC__CIF__CIFREAD_H #ifndef _CIFREAD_H
#define _MAGIC__CIF__CIFREAD_H #define _CIFREAD_H
#include "cif/CIFint.h" #include "cif/CIFint.h"
@ -166,7 +166,7 @@ extern bool CIFParseUser(void);
extern bool CIFParseCall(void); extern bool CIFParseCall(void);
extern bool CIFParseTransform(Transform *transformp); extern bool CIFParseTransform(Transform *transformp);
extern bool CIFParseInteger(int *valuep); extern bool CIFParseInteger(int *valuep);
extern CIFPath *CIFParsePath(int iscale); extern bool CIFParsePath(CIFPath **pathheadpp, int iscale);
extern bool CIFParsePoint(Point *pointp, int iscale); extern bool CIFParsePoint(Point *pointp, int iscale);
extern bool CIFParseSInteger(int *valuep); extern bool CIFParseSInteger(int *valuep);
extern void CIFSkipToSemi(void); extern void CIFSkipToSemi(void);
@ -221,4 +221,4 @@ extern int cifParseLaChar;
? (cifParseLaAvail = FALSE, cifParseLaChar) \ ? (cifParseLaAvail = FALSE, cifParseLaChar) \
: (cifParseLaChar = getc(cifInputFile))) : (cifParseLaChar = getc(cifInputFile)))
#endif /* _MAGIC__CIF__CIFREAD_H */ #endif /* _CIFREAD_H */

View File

@ -78,7 +78,6 @@ typedef struct {
int int
cifPaintDBFunc( cifPaintDBFunc(
Tile *tile, /* Tile of CIF information. */ Tile *tile, /* Tile of CIF information. */
TileType dinfo,
PaintLayerData *pld) PaintLayerData *pld)
{ {
Rect area; Rect area;
@ -107,7 +106,7 @@ cifPaintDBFunc(
if (DBPaintOnPlane(type, pNum)) if (DBPaintOnPlane(type, pNum))
{ {
ui.pu_pNum = pNum; ui.pu_pNum = pNum;
DBNMPaintPlane(paintDef->cd_planes[pNum], TiGetTypeExact(tile) | dinfo, DBNMPaintPlane(paintDef->cd_planes[pNum], TiGetTypeExact(tile),
&area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) &ui); &area, DBStdPaintTbl(type, pNum), (PaintUndoInfo *) &ui);
} }
@ -168,7 +167,7 @@ CIFPaintLayer(
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFCopyMaskHints(&scx, CIFComponentDef); CIFCopyMaskHints(&scx, CIFComponentDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints, DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
(ClientData)CIFComponentDef); (ClientData)CIFComponentDef);
oldCount = DBWFeedbackCount; oldCount = DBWFeedbackCount;
@ -220,7 +219,6 @@ CIFPaintLayer(
int int
cifSeeFunc( cifSeeFunc(
Tile *tile, /* Tile to be entered as feedback. */ Tile *tile, /* Tile to be entered as feedback. */
TileType dinfo, /* Split tile information */
SeeLayerData *sld) /* Layer and explanation for the feedback. */ SeeLayerData *sld) /* Layer and explanation for the feedback. */
{ {
Rect area; Rect area;
@ -235,10 +233,10 @@ cifSeeFunc(
(float)area.r_ybot / (float)CIFCurStyle->cs_scaleFactor); (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, DBWFeedbackAdd(&area, sld->text, cifSeeDef, CIFCurStyle->cs_scaleFactor,
sld->style | ((TiGetTypeExact(tile) | dinfo) & sld->style |
(TT_DIAGONAL | TT_DIRECTION | TT_SIDE))); (TiGetTypeExact(tile) & (TT_DIAGONAL | TT_DIRECTION | TT_SIDE)));
/* (preserve information about the geometry of a diagonal tile) */
return 0; return 0;
} }
@ -289,7 +287,7 @@ CIFSeeLayer(
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFCopyMaskHints(&scx, CIFComponentDef); CIFCopyMaskHints(&scx, CIFComponentDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints, DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
(ClientData)CIFComponentDef); (ClientData)CIFComponentDef);
oldCount = DBWFeedbackCount; oldCount = DBWFeedbackCount;
@ -440,11 +438,9 @@ CIFCoverageLayer(
SearchContext scx; SearchContext scx;
TileTypeBitMask mask, depend; TileTypeBitMask mask, depend;
float fcover; float fcover;
int cifCoverageFunc(Tile *tile, ClientData *arg);
bool doBox = (area != &rootDef->cd_bbox) ? TRUE : FALSE; bool doBox = (area != &rootDef->cd_bbox) ? TRUE : FALSE;
/* Forward declaration */
int cifCoverageFunc(Tile *tile, TileType dinfo, ClientData *arg);
/* Check out the CIF layer name. */ /* Check out the CIF layer name. */
if (!CIFNameToMask(layer, &mask, &depend)) return; if (!CIFNameToMask(layer, &mask, &depend)) return;
@ -461,7 +457,7 @@ CIFCoverageLayer(
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFCopyMaskHints(&scx, CIFComponentDef); CIFCopyMaskHints(&scx, CIFComponentDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints, DBTreeSrCells(&scx, 0, cifHierCopyMaskHints,
(ClientData)CIFComponentDef); (ClientData)CIFComponentDef);
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
@ -504,10 +500,10 @@ CIFCoverageLayer(
} }
else else
{ {
TxPrintf("%s Area = %"DLONG_PREFIX"d CIF units^2\n", doBox ? "Cursor Box" : TxPrintf("%s Area = %lld CIF units^2\n", doBox ? "Cursor Box" :
"Cell", btotal); "Cell", btotal);
TxPrintf("Layer Bounding Area = %"DLONG_PREFIX"d CIF units^2\n", atotal); TxPrintf("Layer Bounding Area = %lld CIF units^2\n", atotal);
TxPrintf("Layer Total Area = %"DLONG_PREFIX"d CIF units^2\n", cstats.coverage); TxPrintf("Layer Total Area = %lld CIF units^2\n", cstats.coverage);
TxPrintf("Coverage in %s = %1.1f%%\n", doBox ? "box" : TxPrintf("Coverage in %s = %1.1f%%\n", doBox ? "box" :
"cell", 100.0 * fcover); "cell", 100.0 * fcover);
} }
@ -516,7 +512,6 @@ CIFCoverageLayer(
int int
cifCoverageFunc( cifCoverageFunc(
Tile *tile, Tile *tile,
TileType dinfo, /* (unused) */
ClientData *arg) ClientData *arg)
{ {
coverstats *cstats = (coverstats *)arg; coverstats *cstats = (coverstats *)arg;

View File

@ -100,7 +100,6 @@ cifTechFreeStyle(void)
layer = CIFCurStyle->cs_layers[i]; layer = CIFCurStyle->cs_layers[i];
if (layer != NULL) if (layer != NULL)
{ {
free_magic1_t mm1 = freeMagic1_init();
for (op = layer->cl_ops; op != NULL; op = op->co_next) for (op = layer->cl_ops; op != NULL; op = op->co_next)
{ {
if (op->co_client != (ClientData)NULL) if (op->co_client != (ClientData)NULL)
@ -112,7 +111,6 @@ cifTechFreeStyle(void)
case CIFOP_MAXRECT: case CIFOP_MAXRECT:
case CIFOP_BOUNDARY: case CIFOP_BOUNDARY:
case CIFOP_INTERACT: case CIFOP_INTERACT:
case CIFOP_MANHATTAN:
/* These options use co_client to hold a single */ /* These options use co_client to hold a single */
/* integer value, so it is not allocated. */ /* integer value, so it is not allocated. */
break; break;
@ -121,9 +119,8 @@ cifTechFreeStyle(void)
break; break;
} }
} }
freeMagic1(&mm1, (char *)op); freeMagic((char *)op);
} }
freeMagic1_end(&mm1);
freeMagic((char *)layer); freeMagic((char *)layer);
} }
} }
@ -236,7 +233,7 @@ cifParseLayers(
*/ */
{ {
TileTypeBitMask curCifMask, curPaintMask; TileTypeBitMask curCifMask, curPaintMask;
char curLayer[512], *p, *cp; char curLayer[40], *p, *cp;
TileType paintType; TileType paintType;
int i; int i;
bool allResidues; bool allResidues;
@ -248,10 +245,6 @@ cifParseLayers(
{ {
p = curLayer; p = curLayer;
if (*string == '(')
while ((*string != ')') && (*string != 0))
*p++ = *string++;
if (*string == '*') if (*string == '*')
{ {
allResidues = TRUE; allResidues = TRUE;
@ -269,22 +262,7 @@ cifParseLayers(
if (paintMask != NULL) if (paintMask != NULL)
{ {
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); paintType = DBTechNameTypes(curLayer, &curPaintMask);
if (paintType >= 0) goto okpaint; if (paintType >= 0) goto okpaint;
} }
else paintType = -2; else paintType = -2;
@ -320,7 +298,7 @@ okpaint:
TechError("Ambiguous layer (type) \"%s\".\n", curLayer); TechError("Ambiguous layer (type) \"%s\".\n", curLayer);
continue; continue;
} }
if ((paintType >= 0) || (paintType == -3)) if (paintType >= 0)
{ {
if (paintType == TT_SPACE && spaceOK ==0) if (paintType == TT_SPACE && spaceOK ==0)
TechError("\"Space\" layer not permitted in CIF rules.\n"); TechError("\"Space\" layer not permitted in CIF rules.\n");
@ -390,13 +368,11 @@ CIFTechInit(void)
/* forget the list of styles */ /* forget the list of styles */
free_magic1_t mm1 = freeMagic1_init();
for (style = CIFStyleList; style != NULL; style = style->cs_next) for (style = CIFStyleList; style != NULL; style = style->cs_next)
{ {
freeMagic(style->cs_name); freeMagic(style->cs_name);
freeMagic1(&mm1, style); freeMagic(style);
} }
freeMagic1_end(&mm1);
CIFStyleList = NULL; CIFStyleList = NULL;
} }
@ -817,7 +793,7 @@ CIFTechLine(
else else
{ {
l = strlen(CIFCurStyle->cs_name) - strlen(tptr); l = strlen(CIFCurStyle->cs_name) - strlen(tptr);
if ((l > 0) && !strcmp(tptr, CIFCurStyle->cs_name + l)) if (!strcmp(tptr, CIFCurStyle->cs_name + l))
{ {
CIFCurStyle->cs_status = TECH_PENDING; CIFCurStyle->cs_status = TECH_PENDING;
return TRUE; return TRUE;
@ -1107,8 +1083,6 @@ CIFTechLine(
newOp->co_opcode = CIFOP_BBOX; newOp->co_opcode = CIFOP_BBOX;
else if (strcmp(argv[0], "net") == 0) else if (strcmp(argv[0], "net") == 0)
newOp->co_opcode = CIFOP_NET; newOp->co_opcode = CIFOP_NET;
else if (strcmp(argv[0], "tagged") == 0)
newOp->co_opcode = CIFOP_TAGGED;
else if (strcmp(argv[0], "maxrect") == 0) else if (strcmp(argv[0], "maxrect") == 0)
newOp->co_opcode = CIFOP_MAXRECT; newOp->co_opcode = CIFOP_MAXRECT;
else if (strcmp(argv[0], "boundary") == 0) else if (strcmp(argv[0], "boundary") == 0)
@ -1117,10 +1091,6 @@ CIFTechLine(
newOp->co_opcode = CIFOP_MASKHINTS; newOp->co_opcode = CIFOP_MASKHINTS;
else if (strcmp(argv[0], "close") == 0) else if (strcmp(argv[0], "close") == 0)
newOp->co_opcode = CIFOP_CLOSE; newOp->co_opcode = CIFOP_CLOSE;
else if (strcmp(argv[0], "orthogonal") == 0)
newOp->co_opcode = CIFOP_MANHATTAN;
else if (strcmp(argv[0], "not-square") == 0)
newOp->co_opcode = CIFOP_NOTSQUARE;
else if (strcmp(argv[0], "bridge") == 0) else if (strcmp(argv[0], "bridge") == 0)
newOp->co_opcode = CIFOP_BRIDGE; newOp->co_opcode = CIFOP_BRIDGE;
else if (strcmp(argv[0], "bridge-lim") == 0) else if (strcmp(argv[0], "bridge-lim") == 0)
@ -1163,6 +1133,7 @@ CIFTechLine(
case CIFOP_GROWMIN: case CIFOP_GROWMIN:
case CIFOP_GROW_G: case CIFOP_GROW_G:
case CIFOP_SHRINK: case CIFOP_SHRINK:
case CIFOP_CLOSE:
if (argc != 2) goto wrongNumArgs; if (argc != 2) goto wrongNumArgs;
newOp->co_distance = atoi(argv[1]); newOp->co_distance = atoi(argv[1]);
if (newOp->co_distance <= 0) if (newOp->co_distance <= 0)
@ -1172,26 +1143,6 @@ CIFTechLine(
} }
break; break;
case CIFOP_CLOSE:
/* "close" is like "grow" and "shrink" except that it can have
* no argument, in which case any closed shape of any size
* will be closed (useful for finding enclosed areas).
*/
if (argc == 1)
newOp->co_distance = 0;
else if (argc != 2)
goto wrongNumArgs;
else
{
newOp->co_distance = atoi(argv[1]);
if (newOp->co_distance <= 0)
{
TechError("Grow/shrink distance must be greater than zero.\n");
goto errorReturn;
}
}
break;
case CIFOP_BRIDGE: case CIFOP_BRIDGE:
if (argc != 3) goto wrongNumArgs; if (argc != 3) goto wrongNumArgs;
newOp->co_distance = atoi(argv[1]); newOp->co_distance = atoi(argv[1]);
@ -1359,10 +1310,8 @@ bloatCheck:
bloatDone: break; bloatDone: break;
case CIFOP_NET: case CIFOP_NET:
case CIFOP_TAGGED: if (argc != 3) goto wrongNumArgs;
if ((argc != 2) && (argc != 3)) goto wrongNumArgs;
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]); newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
if (argc == 3)
cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask, cifParseLayers(argv[2], CIFCurStyle, &newOp->co_paintMask,
&newOp->co_cifMask, FALSE); &newOp->co_cifMask, FALSE);
break; break;
@ -1385,19 +1334,6 @@ bloatCheck:
goto wrongNumArgs; goto wrongNumArgs;
break; break;
case CIFOP_MANHATTAN:
if (argc == 2)
{
if (!strcmp(argv[1], "fill"))
newOp->co_client = (ClientData)1;
else if (strcmp(argv[1], "remove"))
TechError("Orthogonal takes only one optional argument "
"\"fill\" or \"remove\" (default).\n");
}
else if (argc != 1)
goto wrongNumArgs;
break;
case CIFOP_BBOX: case CIFOP_BBOX:
if (argc == 2) if (argc == 2)
{ {
@ -1675,12 +1611,12 @@ cifComputeRadii(
for (op = layer->cl_ops; op != NULL; op = op->co_next) for (op = layer->cl_ops; op != NULL; op = op->co_next)
{ {
/* BBOX, NET, TAGGED, and MASKHINTS operators should never be */ /* BBOX, NET, and MASKHINTS operators should never be used */
/* used hierarchically so ignore any grow/shrink operators that */ /* hierarchically so ignore any grow/shrink operators that */
/* come after them. */ /* come after them. */
if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET || if (op->co_opcode == CIFOP_BBOX || op->co_opcode == CIFOP_NET ||
op->co_opcode == CIFOP_TAGGED || op->co_opcode == CIFOP_MASKHINTS) op->co_opcode == CIFOP_MASKHINTS)
break; break;
/* If CIF layers are used, switch to the max of current /* If CIF layers are used, switch to the max of current
@ -1787,7 +1723,6 @@ cifComputeHalo(
if (maxGrow > maxShrink) if (maxGrow > maxShrink)
style->cs_radius = 2*maxGrow; style->cs_radius = 2*maxGrow;
else style->cs_radius = 2*maxShrink; else style->cs_radius = 2*maxShrink;
if (style->cs_scaleFactor > 0)
style->cs_radius /= style->cs_scaleFactor; style->cs_radius /= style->cs_scaleFactor;
style->cs_radius++; style->cs_radius++;
@ -1990,10 +1925,10 @@ CIFTechFinal(void)
} }
} }
/* Presence of op->co_opcode in CIFOP_OR indicates a copy */ /* Presence of op->co_opcode in CIFOP_OR indicates a copy */
/* of the SquaresData pointer from a following operator. */ /* of the SquaresData pointer from a following operator */
/* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */ /* CIFOP_BBOX and CIFOP_MAXRECT uses the co_client field */
/* as a flag field, while CIFOP_NET, CIFOP_MASKHINTS, and */ /* as a flag field, while CIFOP_NET and CIFOP_MASKHINTS */
/* CIFOP_TAGGED use it for a string. */ /* uses it for a string. */
else else
{ {
switch (op->co_opcode) switch (op->co_opcode)
@ -2003,9 +1938,7 @@ CIFTechFinal(void)
case CIFOP_MASKHINTS: case CIFOP_MASKHINTS:
case CIFOP_BOUNDARY: case CIFOP_BOUNDARY:
case CIFOP_MAXRECT: case CIFOP_MAXRECT:
case CIFOP_MANHATTAN:
case CIFOP_NET: case CIFOP_NET:
case CIFOP_TAGGED:
break; break;
case CIFOP_BRIDGELIM: case CIFOP_BRIDGELIM:
case CIFOP_BRIDGE: case CIFOP_BRIDGE:
@ -2539,9 +2472,7 @@ CIFTechOutputScale(
case CIFOP_BOUNDARY: case CIFOP_BOUNDARY:
case CIFOP_MASKHINTS: case CIFOP_MASKHINTS:
case CIFOP_MAXRECT: case CIFOP_MAXRECT:
case CIFOP_MANHATTAN:
case CIFOP_NET: case CIFOP_NET:
case CIFOP_TAGGED:
case CIFOP_INTERACT: case CIFOP_INTERACT:
break; break;
case CIFOP_BRIDGELIM: case CIFOP_BRIDGELIM:
@ -2657,8 +2588,8 @@ CIFTechOutputScale(
default: default:
/* op->co_opcode in CIFOP_OR is a pointer copy, */ /* op->co_opcode in CIFOP_OR is a pointer copy, */
/* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */ /* in CIFOP_BBOX and CIFOP_MAXRECT is a flag, */
/* and in CIFOP_NET, CIFOP_MASKHINTS, and */ /* and in CIFOP_NET and CIFOP_MASKHINTS is a */
/* CIFOP_TAGGED is a string. */ /* string. */
break; break;
} }
} }

View File

@ -44,10 +44,10 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "textio/textio.h" #include "textio/textio.h"
/* Forward declarations */ /* Forward declarations */
extern int cifWriteInitFunc(CellDef *def, ClientData cdata); /* UNUSED */ extern int cifWriteInitFunc(CellDef *def);
extern int cifWriteMarkFunc(CellUse *use); extern int cifWriteMarkFunc(CellUse *use);
extern int cifWritePaintFunc(Tile *tile, TileType dinfo, FILE *f); extern int cifWritePaintFunc(Tile *tile, FILE *f);
extern int cifWriteLabelFunc(Tile *tile, TileType dinfo, FILE *f); extern int cifWriteLabelFunc(Tile *tile, FILE *f);
extern int cifWriteUseFunc(CellUse *use, FILE *f); extern int cifWriteUseFunc(CellUse *use, FILE *f);
extern void cifOutPreamble(FILE *outf, CellDef *cell); extern void cifOutPreamble(FILE *outf, CellDef *cell);
extern void cifOut(FILE *outf); extern void cifOut(FILE *outf);
@ -204,11 +204,9 @@ CIFWrite(
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
/*ARGSUSED*/
int int
cifWriteInitFunc( cifWriteInitFunc(
CellDef *def, CellDef *def)
ClientData cdata) /* UNUSED */
{ {
def->cd_client = (ClientData) 0; def->cd_client = (ClientData) 0;
return (0); return (0);
@ -586,7 +584,6 @@ cifWriteUseFunc(
int int
cifWriteLabelFunc( cifWriteLabelFunc(
Tile *tile, /* Tile to be written out. */ Tile *tile, /* Tile to be written out. */
TileType dinfo, /* Split tile information (unused) */
FILE *f) /* File in which to write. */ FILE *f) /* File in which to write. */
{ {
Rect r; Rect r;
@ -646,7 +643,6 @@ cifWriteLabelFunc(
int int
cifWritePaintFunc( cifWritePaintFunc(
Tile *tile, /* Tile to be written out. */ Tile *tile, /* Tile to be written out. */
TileType dinfo, /* Split tile information */
FILE *f) /* File in which to write. */ FILE *f) /* File in which to write. */
{ {
Rect r; Rect r;
@ -666,7 +662,7 @@ cifWritePaintFunc(
Point points[5]; Point points[5];
int i, np; int i, np;
GrClipTriangle(&r, NULL, FALSE, TiGetTypeExact(tile) | dinfo, points, &np); GrClipTriangle(&r, NULL, FALSE, TiGetTypeExact(tile), points, &np);
/* Write triangle as a CIF polygon */ /* Write triangle as a CIF polygon */

View File

@ -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 $ * rcsid "$Header: /usr/cvsroot/magic-8.0/cif/cif.h,v 1.4 2010/06/24 12:37:15 tim Exp $
*/ */
#ifndef _MAGIC__CIF__CIF_H #ifndef _CIF_H
#define _MAGIC__CIF__CIF_H #define _CIF_H
#include "database/database.h" #include "database/database.h"
@ -95,4 +95,4 @@ extern LinkedRect *PaintPolygon(Point *pointlist, int number, Plane *plane, Pain
/* C99 compat */ /* C99 compat */
extern int CIFGetContactSize(TileType type, int *edge, int *spacing, int *border); extern int CIFGetContactSize(TileType type, int *edge, int *spacing, int *border);
#endif /* _MAGIC__CIF__CIF_H */ #endif /* _CIF_H */

View File

@ -217,11 +217,10 @@ CMWdelete(
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
/*ARGSUSED*/
void void
CMWreposition( CMWreposition(
MagWindow *window, MagWindow *window,
Rect *newScreenArea, /* UNUSED */ Rect *newScreenArea,
bool final) bool final)
{ {
if (final) if (final)

View File

@ -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 $ * rcsid $Header: /usr/cvsroot/magic-8.0/cmwind/cmwind.h,v 1.2 2009/09/10 20:32:51 tim Exp $
*/ */
#ifndef _MAGIC__CMWIND__CMWIND_H #ifndef _CMWIND_H
#define _MAGIC__CMWIND__CMWIND_H #define _CMWIND_H
#include "windows/windows.h" #include "windows/windows.h"
#include "textio/txcommands.h" #include "textio/txcommands.h"
@ -81,4 +81,4 @@ extern bool CMWCheckWritten(void);
extern void CMWinit(void); extern void CMWinit(void);
#endif /* _MAGIC__CMWIND__CMWIND_H */ #endif /* _CMWIND_H */

View File

@ -81,70 +81,6 @@ CmdAddPath(
PaAppend(&Path, cmd->tx_argv[1]); 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 */ /* Linked-list structure for returning information about arrayed cells */
@ -338,17 +274,14 @@ CmdArray(
case ARRAY_WIDTH: case ARRAY_WIDTH:
if (locargc == 2) if (locargc == 2)
{ {
char *xsepvalue;
for (la = lahead; la != NULL; la = la->ar_next) for (la = lahead; la != NULL; la = la->ar_next)
{ {
xsepvalue = DBWPrintValue(la->arrayInfo.ar_xsep,
w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
if (doList) if (doList)
{ {
tobj = Tcl_NewListObj(0, NULL); tobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, tobj, Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewStringObj(xsepvalue, -1)); Tcl_NewIntObj(la->arrayInfo.ar_xsep));
Tcl_SetObjResult(magicinterp, tobj); Tcl_SetObjResult(magicinterp, tobj);
} }
else else
@ -358,7 +291,7 @@ CmdArray(
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id); TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
else else
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name); TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
TxPrintf("x separation %s\n", xsepvalue); TxPrintf("x separation %d\n", la->arrayInfo.ar_xsep);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
} }
#endif #endif
@ -377,17 +310,14 @@ CmdArray(
case ARRAY_HEIGHT: case ARRAY_HEIGHT:
if (locargc == 2) if (locargc == 2)
{ {
char *ysepvalue;
for (la = lahead; la != NULL; la = la->ar_next) for (la = lahead; la != NULL; la = la->ar_next)
{ {
ysepvalue = DBWPrintValue(la->arrayInfo.ar_ysep,
w, FALSE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
if (doList) if (doList)
{ {
tobj = Tcl_NewListObj(0, NULL); tobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, tobj, Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewStringObj(ysepvalue, -1)); Tcl_NewIntObj(la->arrayInfo.ar_ysep));
Tcl_SetObjResult(magicinterp, tobj); Tcl_SetObjResult(magicinterp, tobj);
} }
else else
@ -397,7 +327,7 @@ CmdArray(
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id); TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
else else
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name); TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
TxPrintf("y separation %s\n", ysepvalue); TxPrintf("y separation %d\n", la->arrayInfo.ar_ysep);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
} }
#endif #endif
@ -416,21 +346,16 @@ CmdArray(
case ARRAY_PITCH: case ARRAY_PITCH:
if (locargc == 2) if (locargc == 2)
{ {
char *xpitch, *ypitch;
for (la = lahead; la != NULL; la = la->ar_next) 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 #ifdef MAGIC_WRAPPER
if (doList) if (doList)
{ {
tobj = Tcl_NewListObj(0, NULL); tobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, tobj, Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewStringObj(xpitch, -1)); Tcl_NewIntObj(la->arrayInfo.ar_xsep));
Tcl_ListObjAppendElement(magicinterp, tobj, Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewStringObj(ypitch, -1)); Tcl_NewIntObj(la->arrayInfo.ar_ysep));
Tcl_SetObjResult(magicinterp, tobj); Tcl_SetObjResult(magicinterp, tobj);
} }
else else
@ -440,8 +365,8 @@ CmdArray(
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id); TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
else else
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name); TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
TxPrintf("x separation %s ", xpitch); TxPrintf("x separation %d ", la->arrayInfo.ar_xsep);
TxPrintf("y separation %s\n", ypitch); TxPrintf("y separation %d\n", la->arrayInfo.ar_ysep);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
} }
#endif #endif
@ -461,21 +386,16 @@ CmdArray(
case ARRAY_POSITION: case ARRAY_POSITION:
if (locargc == 2) if (locargc == 2)
{ {
char *xpos, *ypos;
for (la = lahead; la != NULL; la = la->ar_next) 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 #ifdef MAGIC_WRAPPER
if (doList) if (doList)
{ {
tobj = Tcl_NewListObj(0, NULL); tobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, tobj, Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewStringObj(xpos, -1)); Tcl_NewIntObj(la->cellUse->cu_bbox.r_xbot));
Tcl_ListObjAppendElement(magicinterp, tobj, Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewStringObj(ypos, -1)); Tcl_NewIntObj(la->cellUse->cu_bbox.r_ybot));
Tcl_SetObjResult(magicinterp, tobj); Tcl_SetObjResult(magicinterp, tobj);
} }
else else
@ -485,8 +405,8 @@ CmdArray(
TxPrintf("Cell use \"%s\":", la->cellUse->cu_id); TxPrintf("Cell use \"%s\":", la->cellUse->cu_id);
else else
TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name); TxPrintf("Cell \"%s\":", la->cellUse->cu_def->cd_name);
TxPrintf("x=%s ", xpos); TxPrintf("x=%d ", la->cellUse->cu_bbox.r_xbot);
TxPrintf("y=%s\n", ypos); TxPrintf("y=%d\n", la->cellUse->cu_bbox.r_ybot);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
} }
#endif #endif
@ -546,15 +466,11 @@ badusage:
} }
freelist: freelist:
{
la = lahead; la = lahead;
while (la != NULL) while (la != NULL)
{ {
free_magic1_t mm1 = freeMagic1_init(); freeMagic((char *)la);
freeMagic1(&mm1, (char *)la);
la = la->ar_next; la = la->ar_next;
freeMagic1_end(&mm1);
}
} }
return; return;
} }
@ -779,8 +695,8 @@ CmdBox(
break; break;
case BOX_EXISTS: case BOX_EXISTS:
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_SetResult(magicinterp, ToolGetBox(NULL, NULL) ? "1" : "0",
Tcl_NewBooleanObj(ToolGetBox(NULL, NULL) ? TRUE : FALSE)); NULL);
#else #else
TxPrintf("%s\n", ToolGetBox(NULL, NULL) ? "True" : "False"); TxPrintf("%s\n", ToolGetBox(NULL, NULL) ? "True" : "False");
#endif #endif
@ -890,16 +806,13 @@ CmdBox(
TxRebuildCommand(cmd); TxRebuildCommand(cmd);
return; return;
} }
else if (DBWUnits != DBW_UNITS_USER) else if (DBWSnapToGrid != DBW_SNAP_USER)
{ {
distancex = cmdParseCoord(w, cmd->tx_argv[3], TRUE, FALSE); distancex = cmdParseCoord(w, cmd->tx_argv[3], TRUE, FALSE);
distancey = distancex; distancey = distancex;
} }
else else
{ {
/* For user units, the distance may be different in the X and Y
* directions for a given value.
*/
switch (direction) switch (direction)
{ {
case GEO_EAST: case GEO_WEST: case GEO_EAST: case GEO_WEST:
@ -927,14 +840,15 @@ CmdBox(
case BOX_WIDTH: case BOX_WIDTH:
if (argc == 2) if (argc == 2)
{ {
char *boxvalues;
boxvalues = DBWPrintValue(boxptr->r_xtop - boxptr->r_xbot,
w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(boxvalues, -1)); char *boxvalues = (char *)Tcl_Alloc(50);
sprintf(boxvalues, "%d",
boxptr->r_xtop - boxptr->r_xbot);
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
#else #else
TxPrintf("%s box width is %s\n", (refEdit) ? "Edit" : "Root", TxPrintf("%s box width is %d\n",
boxvalues); (refEdit) ? "Edit" : "Root",
boxptr->r_xtop - boxptr->r_xbot);
#endif #endif
return; return;
} }
@ -946,14 +860,15 @@ CmdBox(
case BOX_HEIGHT: case BOX_HEIGHT:
if (argc == 2) if (argc == 2)
{ {
char *boxvalues;
boxvalues = DBWPrintValue(boxptr->r_ytop - boxptr->r_ybot,
w, FALSE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(boxvalues, -1)); char *boxvalues = (char *)Tcl_Alloc(50);
sprintf(boxvalues, "%d",
boxptr->r_ytop - boxptr->r_ybot);
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
#else #else
TxPrintf("%s box height is %s\n", (refEdit) ? "Edit" : "Root", TxPrintf("%s box height is %d\n",
boxvalues); (refEdit) ? "Edit" : "Root",
boxptr->r_ytop - boxptr->r_ybot);
#endif #endif
return; return;
} }
@ -966,24 +881,16 @@ CmdBox(
if (argc == 2) if (argc == 2)
{ {
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_Obj *tobj; char *boxvalues = (char *)Tcl_Alloc(50);
#endif sprintf(boxvalues, "%d %d",
char *boxvaluex, *boxvaluey; boxptr->r_xtop - boxptr->r_xbot,
boxvaluex = DBWPrintValue(boxptr->r_xtop - boxptr->r_xbot, boxptr->r_ytop - boxptr->r_ybot);
w, TRUE); Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
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 #else
TxPrintf("%s box size is %s x %s\n", TxPrintf("%s box size is %d x %d\n",
(refEdit) ? "Edit" : "Root", (refEdit) ? "Edit" : "Root",
boxvaluex, boxvaluey); boxptr->r_xtop - boxptr->r_xbot,
boxptr->r_ytop - boxptr->r_ybot);
#endif #endif
return; return;
} }
@ -998,22 +905,14 @@ CmdBox(
if (argc == 2) if (argc == 2)
{ {
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_Obj *tobj; char *boxvalues = (char *)Tcl_Alloc(50);
#endif sprintf(boxvalues, "%d %d",
char *boxvaluex, *boxvaluey; boxptr->r_xbot, boxptr->r_ybot);
boxvaluex = DBWPrintValue(boxptr->r_xbot, w, TRUE); Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
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 #else
TxPrintf("%s box lower-left corner at (%s, %s)\n", TxPrintf("%s box lower-left corner at (%d, %d)\n",
(refEdit) ? "Edit" : "Root", (refEdit) ? "Edit" : "Root",
boxvaluex, boxvaluey); boxptr->r_xbot, boxptr->r_ybot);
#endif #endif
return; return;
} }
@ -1045,31 +944,16 @@ CmdBox(
if (argc == 2) if (argc == 2)
{ {
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_Obj *tobj; char *boxvalues = (char *)Tcl_Alloc(50);
#endif sprintf(boxvalues, "%d %d %d %d",
char *boxvaluellx, *boxvaluelly; boxptr->r_xbot, boxptr->r_ybot,
char *boxvalueurx, *boxvalueury; boxptr->r_xtop, boxptr->r_ytop);
Tcl_SetResult(magicinterp, boxvalues, TCL_DYNAMIC);
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 #else
TxPrintf("%s box coordinates (%s, %s) to (%s, %s)\n", TxPrintf("%s box coordinates (%d, %d) to (%d, %d)\n",
(refEdit) ? "Edit" : "Root", (refEdit) ? "Edit" : "Root",
boxvaluellx, boxvaluelly, boxvalueurx, boxvalueury); boxptr->r_xbot, boxptr->r_ybot,
boxptr->r_xtop, boxptr->r_ytop);
#endif #endif
return; return;
} }

View File

@ -24,7 +24,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <unistd.h>
#include "tcltk/tclmagic.h" #include "tcltk/tclmagic.h"
#include "utils/magic.h" #include "utils/magic.h"
@ -37,7 +36,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "utils/main.h" #include "utils/main.h"
#include "commands/commands.h" #include "commands/commands.h"
#include "utils/utils.h" #include "utils/utils.h"
#include "utils/magic_zlib.h"
#include "textio/textio.h" #include "textio/textio.h"
#include "drc/drc.h" #include "drc/drc.h"
#include "graphics/graphics.h" #include "graphics/graphics.h"
@ -117,13 +115,12 @@ bool cmdDumpParseArgs(char *cmdName, MagWindow *w, TxCommand *cmd, CellUse *dumm
#define CALMA_READ 19 #define CALMA_READ 19
#define CALMA_READONLY 20 #define CALMA_READONLY 20
#define CALMA_RESCALE 21 #define CALMA_RESCALE 21
#define CALMA_SAVEPATHS 22 #define CALMA_WARNING 22
#define CALMA_WARNING 23 #define CALMA_WRITE 23
#define CALMA_WRITE 24 #define CALMA_POLYS 24
#define CALMA_POLYS 25 #define CALMA_PATHS 25
#define CALMA_PATHS 26 #define CALMA_UNDEFINED 26
#define CALMA_UNDEFINED 27 #define CALMA_UNIQUE 27
#define CALMA_UNIQUE 28
#define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */ #define CALMA_WARN_HELP CIF_WARN_END /* undefined by CIF module */
@ -176,7 +173,6 @@ CmdCalma(
" into edit cell", " into edit cell",
"readonly [yes|no] set cell as read-only and generate output from GDS file", "readonly [yes|no] set cell as read-only and generate output from GDS file",
"rescale [yes|no] allow or disallow internal grid subdivision", "rescale [yes|no] allow or disallow internal grid subdivision",
"savepaths [yes|no] save path centerlines as cell properties",
"warning [option] set warning information level", "warning [option] set warning information level",
"write file output Calma GDS-II format to \"file\"\n" "write file output Calma GDS-II format to \"file\"\n"
" for the window's root cell", " for the window's root cell",
@ -433,7 +429,7 @@ CmdCalma(
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewDoubleObj((double)CalmaMagScale)); Tcl_SetObjResult(magicinterp, Tcl_NewDoubleObj((double)CalmaMagScale));
#else #else
TxPrintf("Text magnification 1.0 = %g microns.\n", (double)CalmaMagScale); TxPrintf("Text magnification 1.0 = %g microns.\n");
#endif #endif
return; return;
} }
@ -740,34 +736,13 @@ CmdCalma(
CalmaSubcellPolygons = (unsigned char)option; CalmaSubcellPolygons = (unsigned char)option;
return; return;
case CALMA_SAVEPATHS:
if (cmd->tx_argc == 2)
{
#ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaRecordPaths));
#else
TxPrintf("Paths in GDS cells read from input file are%s recorded"
" as cell properties.\n",
(CalmaRecordPaths) ? " " : " not");
#endif
return;
}
else if (cmd->tx_argc != 3)
goto wrongNumArgs;
option = Lookup(cmd->tx_argv[2], cmdCalmaYesNo);
if (option < 0)
goto wrongNumArgs;
CalmaRecordPaths = (option < 4) ? FALSE : TRUE;
return;
case CALMA_NO_DUP: case CALMA_NO_DUP:
if (cmd->tx_argc == 2) if (cmd->tx_argc == 2)
{ {
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaNoDuplicates)); Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaNoDuplicates));
#else #else
TxPrintf("Cell defs that exist before reading GDS will %sbe parsed.\n", TxPrintf("Cell defs that exist before reading GDS will not be paresd.\n",
(CalmaNoDuplicates) ? "not " : ""); (CalmaNoDuplicates) ? "not " : "");
#endif #endif
return; return;
@ -787,7 +762,7 @@ CmdCalma(
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaUnique)); Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(CalmaUnique));
#else #else
TxPrintf("Cell defs that exist before reading GDS will %sbe renamed.\n", TxPrintf("Cell defs that exist before reading GDS will be renamed.\n",
(CalmaUnique) ? "not " : ""); (CalmaUnique) ? "not " : "");
#endif #endif
return; return;
@ -1323,7 +1298,7 @@ CmdCellname(
if (cellDef == (CellDef *) NULL) if (cellDef == (CellDef *) NULL)
TxError("Unknown cell %s\n", cellname); TxError("Unknown cell %s\n", cellname);
else else
CmdDoProperty(cellDef, w, cmd, 3 + ((dolist) ? 1 : 0)); CmdDoProperty(cellDef, cmd, 3 + ((dolist) ? 1 : 0));
break; break;
case IDX_DELETE: case IDX_DELETE:
@ -2419,10 +2394,8 @@ CmdContact(
CCStruct ccs; CCStruct ccs;
Rect area; Rect area;
LinkedRect *lr = NULL; LinkedRect *lr = NULL;
int cmdContactFunc(Tile *tile, CCStruct *ccs); /* Forward declaration */
/* Forward declarations */ int cmdContactEraseFunc(Tile *tile, LinkedRect **lr); /* Forward declaration */
int cmdContactFunc(Tile *tile, TileType dinfo, CCStruct *ccs);
int cmdContactEraseFunc(Tile *tile, TileType dinfo, LinkedRect **lr);
windCheckOnlyWindow(&w, DBWclientID); windCheckOnlyWindow(&w, DBWclientID);
if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID)) if ((w == (MagWindow *) NULL) || (w->w_client != DBWclientID))
@ -2480,7 +2453,6 @@ CmdContact(
rmask = DBResidueMask(type); rmask = DBResidueMask(type);
free_magic1_t mm1 = freeMagic1_init();
while (lr != NULL) while (lr != NULL)
{ {
GeoClip(&lr->r_r, &area); GeoClip(&lr->r_r, &area);
@ -2491,10 +2463,9 @@ CmdContact(
if (TTMaskHasType(rmask, rtype)) if (TTMaskHasType(rmask, rtype))
DBPaint(EditCellUse->cu_def, &lr->r_r, rtype); DBPaint(EditCellUse->cu_def, &lr->r_r, rtype);
freeMagic1(&mm1, lr); freeMagic(lr);
lr = lr->r_next; lr = lr->r_next;
} }
freeMagic1_end(&mm1);
/* Refresh the layout drawing */ /* Refresh the layout drawing */
DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask); DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask);
@ -2531,16 +2502,14 @@ CmdContact(
DBSrPaintArea((Tile *) NULL, EditCellUse->cu_def->cd_planes[DBPlane(rtype)], DBSrPaintArea((Tile *) NULL, EditCellUse->cu_def->cd_planes[DBPlane(rtype)],
&area, &smask, cmdContactFunc, (ClientData) &ccs); &area, &smask, cmdContactFunc, (ClientData) &ccs);
free_magic1_t mm1 = freeMagic1_init();
while (ccs.lhead != NULL) while (ccs.lhead != NULL)
{ {
TTMaskSetOnlyType(&smask, type); TTMaskSetOnlyType(&smask, type);
TTMaskAndMask(&smask, &DBActiveLayerBits); TTMaskAndMask(&smask, &DBActiveLayerBits);
DBPaintMask(EditCellUse->cu_def, &ccs.lhead->r_r, &smask); DBPaintMask(EditCellUse->cu_def, &ccs.lhead->r_r, &smask);
freeMagic1(&mm1, ccs.lhead); freeMagic(ccs.lhead);
ccs.lhead = ccs.lhead->r_next; ccs.lhead = ccs.lhead->r_next;
} }
freeMagic1_end(&mm1);
/* Refresh the layout drawing */ /* Refresh the layout drawing */
DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask); DBWAreaChanged(EditCellUse->cu_def, &area, DBW_ALLWINDOWS, &smask);
@ -2556,14 +2525,11 @@ CmdContact(
int int
cmdContactFunc( cmdContactFunc(
Tile *tile, Tile *tile,
TileType dinfo,
CCStruct *ccs) CCStruct *ccs)
{ {
TileType stype; TileType stype;
TileTypeBitMask smask; TileTypeBitMask smask;
int cmdContactFunc2(Tile *tile, CCStruct *ccs); /* Forward declaration */
/* Forward declaration */
int cmdContactFunc2(Tile *tile, TileType dinfo, CCStruct *ccs);
TiToRect(tile, &ccs->area); TiToRect(tile, &ccs->area);
GeoClip(&ccs->area, &ccs->clip); GeoClip(&ccs->area, &ccs->clip);
@ -2573,16 +2539,14 @@ cmdContactFunc(
break; break;
TTMaskSetOnlyType(&smask, stype); TTMaskSetOnlyType(&smask, stype);
DBSrPaintNMArea((Tile *)NULL, ccs->rootDef->cd_planes[DBPlane(stype)], DBSrPaintArea((Tile *) NULL, ccs->rootDef->cd_planes[DBPlane(stype)],
TiGetTypeExact(tile) | dinfo, &ccs->area, &smask, &ccs->area, &smask, cmdContactFunc2, (ClientData)ccs);
cmdContactFunc2, (ClientData)ccs);
return 0; return 0;
} }
int int
cmdContactFunc2( cmdContactFunc2(
Tile *tile, Tile *tile,
TileType dinfo, /* (unused) */
CCStruct *ccs) CCStruct *ccs)
{ {
LinkedRect *newlr; LinkedRect *newlr;
@ -2605,7 +2569,6 @@ cmdContactFunc2(
int int
cmdContactEraseFunc( cmdContactEraseFunc(
Tile *tile, Tile *tile,
TileType dinfo, /* (unused) */
LinkedRect **lr) LinkedRect **lr)
{ {
LinkedRect *newlr; LinkedRect *newlr;
@ -2859,15 +2822,14 @@ CmdCorner(
TileTypeBitMask maskBits; TileTypeBitMask maskBits;
Rect editBox; Rect editBox;
SearchContext scx; SearchContext scx;
extern int cmdCornerFunc(Tile *tile, TreeContext *cxp);
bool hasErr = FALSE; bool hasErr = FALSE;
int locargc = cmd->tx_argc; int locargc = cmd->tx_argc;
extern int cmdBevelFunc(Tile *tile, TreeContext *cxp);
bool dobevel = FALSE; bool dobevel = FALSE;
NMCornerPath cmdPathList; 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) if (cmd->tx_argc < 3 || cmd->tx_argc > 5)
{ {
TxError("Usage: %s direction1 direction2 [layers]\n", TxError("Usage: %s direction1 direction2 [layers]\n",
@ -2988,22 +2950,14 @@ CmdCorner(
rectp = CIFPolyToRects(cmdPathList.pathlist->pathhead, plane, rectp = CIFPolyToRects(cmdPathList.pathlist->pathhead, plane,
resultTbl, &ui, FALSE); resultTbl, &ui, FALSE);
{
free_magic1_t mm1 = freeMagic1_init();
for (; rectp != NULL; rectp = rectp->r_next) for (; rectp != NULL; rectp = rectp->r_next)
{ {
DBPaintPlane(plane, &rectp->r_r, resultTbl, &ui); DBPaintPlane(plane, &rectp->r_r, resultTbl, &ui);
freeMagic1(&mm1, (char *)rectp); freeMagic((char *)rectp);
}
freeMagic1_end(&mm1);
} }
CIFFreePath(cmdPathList.pathlist->pathhead); CIFFreePath(cmdPathList.pathlist->pathhead);
{ freeMagic((char *)cmdPathList.pathlist);
free_magic1_t mm1 = freeMagic1_init();
freeMagic1(&mm1, (char *)cmdPathList.pathlist);
cmdPathList.pathlist = cmdPathList.pathlist->cpl_next; cmdPathList.pathlist = cmdPathList.pathlist->cpl_next;
freeMagic1_end(&mm1);
}
} }
} }
else else
@ -3021,15 +2975,13 @@ CmdCorner(
/* Now that we've got all the material, scan over the list /* Now that we've got all the material, scan over the list
* painting the material and freeing up the entries on the list. * painting the material and freeing up the entries on the list.
*/ */
free_magic1_t mm1 = freeMagic1_init();
while (cmdCornerList != NULL) while (cmdCornerList != NULL)
{ {
DBPaint(EditCellUse->cu_def, &cmdCornerList->cca_area, DBPaint(EditCellUse->cu_def, &cmdCornerList->cca_area,
cmdCornerList->cca_type); cmdCornerList->cca_type);
freeMagic1(&mm1, (char *) cmdCornerList); freeMagic((char *) cmdCornerList);
cmdCornerList = cmdCornerList->cca_next; cmdCornerList = cmdCornerList->cca_next;
} }
freeMagic1_end(&mm1);
} }
SelectClear(); SelectClear();
@ -3062,7 +3014,6 @@ CmdCorner(
int int
cmdCornerFunc( cmdCornerFunc(
Tile *tile, /* Tile to fill with. */ Tile *tile, /* Tile to fill with. */
TileType dinfo, /* Split tile information (unused) */
TreeContext *cxp) /* Describes state of search. */ TreeContext *cxp) /* Describes state of search. */
{ {
Rect r1, r2, r3; Rect r1, r2, r3;
@ -3229,7 +3180,6 @@ AddNewPoint(
int int
cmdBevelFunc( cmdBevelFunc(
Tile *tile, /* Tile to fill with. */ Tile *tile, /* Tile to fill with. */
TileType dinfo, /* Split tile information (unused) */
TreeContext *cxp) /* Describes state of search. */ TreeContext *cxp) /* Describes state of search. */
{ {
Rect r1, r2, r3; Rect r1, r2, r3;
@ -3691,10 +3641,8 @@ cmdBevelFunc(
GeoClip(&r3, &cmdCornerRootBox); GeoClip(&r3, &cmdCornerRootBox);
if (GEO_RECTNULL(&r2) || GEO_RECTNULL(&r3)) if (GEO_RECTNULL(&r2) || GEO_RECTNULL(&r3))
{ {
free_magic1_t mm1 = freeMagic1_init();
for (pptr = pathhead; pptr != NULL; pptr = pptr->cifp_next) for (pptr = pathhead; pptr != NULL; pptr = pptr->cifp_next)
freeMagic1(&mm1, (char *)pptr); freeMagic((char *)pptr);
freeMagic1_end(&mm1);
return 0; return 0;
} }
@ -3728,7 +3676,7 @@ cmdBevelFunc(
* Save cells to or recover cells from a crash backup file * Save cells to or recover cells from a crash backup file
* *
* Usage: * Usage:
* crash save|recover|archive|read [file] * crash save|recover [file]
* *
* Results: * Results:
* None. * None.
@ -3763,7 +3711,7 @@ CmdCrash(
switch(option) { switch(option) {
case 0: /* save */ case 0: /* save */
DBWriteBackup(filename, FALSE, FALSE); DBWriteBackup(filename);
break; break;
case 1: /* recover */ case 1: /* recover */
DBFileRecovery(filename); DBFileRecovery(filename);
@ -4204,7 +4152,6 @@ CmdDrc(
rootUse = (CellUse *) window->w_surfaceID; rootUse = (CellUse *) window->w_surfaceID;
dcl = DRCCount(rootUse, &rootArea, doforall); dcl = DRCCount(rootUse, &rootArea, doforall);
free_magic1_t mm1 = freeMagic1_init();
while (dcl != NULL) while (dcl != NULL)
{ {
if (count_total >= 0) if (count_total >= 0)
@ -4234,10 +4181,9 @@ CmdDrc(
} }
#endif #endif
} }
freeMagic1(&mm1, (char *)dcl); freeMagic((char *)dcl);
dcl = dcl->dcl_next; dcl = dcl->dcl_next;
} }
freeMagic1_end(&mm1);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
if ((count_total >= 0) || (!dolist)) if ((count_total >= 0) || (!dolist))
@ -4360,8 +4306,6 @@ CmdDrc(
#endif #endif
TxPrintf("Error area #%d:\n", result); TxPrintf("Error area #%d:\n", result);
if (DRCWhy(dolist, rootUse, &area, findonly)) break; if (DRCWhy(dolist, rootUse, &area, findonly)) break;
/* Check for interrupt or this will go into an infinite loop */
else if (SigInterruptPending) break;
drc_nth++; drc_nth++;
} }
else if (result < 0) else if (result < 0)
@ -4388,14 +4332,12 @@ CmdDrc(
} }
if (findonly) if (findonly)
{ {
free_magic1_t mm1 = freeMagic1_init();
/* Delete temporary rules */ /* Delete temporary rules */
while (DRCIgnoreRules != NULL) while (DRCIgnoreRules != NULL)
{ {
freeMagic1(&mm1, DRCIgnoreRules); freeMagic(DRCIgnoreRules);
DRCIgnoreRules = DRCIgnoreRules->li_next; DRCIgnoreRules = DRCIgnoreRules->li_next;
} }
freeMagic1_end(&mm1);
/* Replace temporary set of rules */ /* Replace temporary set of rules */
DRCIgnoreRules = DRCSaveRules; DRCIgnoreRules = DRCSaveRules;
} }
@ -4478,10 +4420,8 @@ CmdDrc(
{ {
while (DRCIgnoreRules != NULL) while (DRCIgnoreRules != NULL)
{ {
free_magic1_t mm1 = freeMagic1_init(); freeMagic(DRCIgnoreRules);
freeMagic1(&mm1, DRCIgnoreRules);
DRCIgnoreRules = DRCIgnoreRules->li_next; DRCIgnoreRules = DRCIgnoreRules->li_next;
freeMagic1_end(&mm1);
} }
} }
else else
@ -4537,7 +4477,6 @@ CmdDrc(
{ {
DRCPrintRulesTable (stdout); DRCPrintRulesTable (stdout);
} }
else
{ {
FILE *fp = fopen (argv[2], "w"); FILE *fp = fopen (argv[2], "w");
if (fp == NULL) if (fp == NULL)
@ -4619,7 +4558,6 @@ CmdDrc(
int int
cmdDropPaintCell( cmdDropPaintCell(
Tile *tile, Tile *tile,
TileType dinfo,
TreeContext *cxp) TreeContext *cxp)
{ {
CellDef *cellDef = cxp->tc_scx->scx_use->cu_def; CellDef *cellDef = cxp->tc_scx->scx_use->cu_def;
@ -4628,7 +4566,7 @@ cmdDropPaintCell(
TileType type; TileType type;
Rect area; Rect area;
if (dinfo & TT_SIDE) if (SplitSide(tile))
type = SplitRightType(tile); type = SplitRightType(tile);
else else
type = SplitLeftType(tile); type = SplitLeftType(tile);
@ -4661,7 +4599,6 @@ cmdDropPaintCell(
int int
cmdDropFunc( cmdDropFunc(
Tile *tile, Tile *tile,
TileType dinfo,
ClientData clientData) ClientData clientData)
{ {
TileTypeBitMask tMask, *lMask = (TileTypeBitMask *)clientData; TileTypeBitMask tMask, *lMask = (TileTypeBitMask *)clientData;
@ -4672,7 +4609,7 @@ cmdDropFunc(
scx.scx_use = EditCellUse; scx.scx_use = EditCellUse;
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
if (dinfo & TT_SIDE) if (SplitSide(tile))
type = SplitRightType(tile); type = SplitRightType(tile);
else else
type = SplitLeftType(tile); type = SplitLeftType(tile);
@ -4825,10 +4762,9 @@ CmdDrop(
* Usage: * Usage:
* dump cellName [child refPointChild] [parent refPointParent] * dump cellName [child refPointChild] [parent refPointParent]
* *
* where the refPoints are either "label" and a label name, e.g., * where the refPoints are either a label name, e.g., SOCKET_A, or an x-y
* "label SOCKET_A", a corner position, e.g., "ur", or an x-y pair of * pair of integers, e.g., 100 200. The words "child" and "parent" are
* coordinates, e.g., "100 200", or "1um 5um". The words "child", * keywords, and may be abbreviated.
* "parent", and "label" are keywords, and may be abbreviated.
* *
* Results: * Results:
* None. * None.
@ -5014,20 +4950,15 @@ cmdDumpParseArgs(
bbox = def->cd_bbox; bbox = def->cd_bbox;
if (def->cd_flags & CDFIXEDBBOX) if (def->cd_flags & CDFIXEDBBOX)
{ {
PropertyRecord *proprec; char *propvalue;
bool found; bool found;
proprec = DBPropGet(def, "FIXED_BBOX", &found); propvalue = (char *)DBPropGet(def, "FIXED_BBOX", &found);
if (found) if (found)
{ {
if ((proprec->prop_type == PROPERTY_TYPE_DIMENSION) && if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
(proprec->prop_len == 4)) &bbox.r_xtop, &bbox.r_ytop) != 4)
{ bbox = def->cd_bbox;
bbox.r_xbot = proprec->prop_value.prop_integer[0];
bbox.r_ybot = proprec->prop_value.prop_integer[1];
bbox.r_xtop = proprec->prop_value.prop_integer[2];
bbox.r_ytop = proprec->prop_value.prop_integer[3];
}
} }
} }
@ -5039,40 +4970,18 @@ cmdDumpParseArgs(
* points weren't provided. (Lower-left of the box tool is interpreted * points weren't provided. (Lower-left of the box tool is interpreted
* in root coordinates). * 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]; av = &cmd->tx_argv[2];
ac = cmd->tx_argc - 2; ac = cmd->tx_argc - 2;
hasChild = hasRoot = hasTrans = FALSE; hasChild = hasRoot = hasTrans = FALSE;
while (ac > 0) while (ac > 0)
{ {
static const char * const kwdNames[] = { "child", "parent", static const char * const kwdNames[] = { "child", "parent", "0", "90", "180", "270",
"0", "90", "180", "270",
"v", "0v", "90v", "180v", "270v", "v", "0v", "90v", "180v", "270v",
"h", "0h", "90h", "180h", "270h", 0 }; "h", "0h", "90h", "180h", "270h", 0 };
typedef enum { static const char * const refPointNames[] = { "ll", "lr", "ul", "ur", 0 };
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; Label *lab;
int n,p; int n,p;
Point locp;
n = Lookup(av[0], kwdNames); n = Lookup(av[0], kwdNames);
if (n < 0) if (n < 0)
@ -5082,143 +4991,130 @@ cmdDumpParseArgs(
} }
switch (n) switch (n)
{ {
case IDX_CHILD: /* "child" */ case 0: /* Child */
if (ac < 2) if (ac < 2)
{ {
TxError("Keyword must be followed by a reference point\n"); TxError("Keyword must be followed by a reference point\n");
goto usage; 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 else
{ {
p = Lookup(av[1], refPointNames); p = Lookup(av[1], refPointNames);
if (p == IDX_LL) /* lower left */ if (p == 0) /* lower left */
{ {
childPoint.p_x = bbox.r_ll.p_x; childPoint.p_x = bbox.r_ll.p_x;
childPoint.p_y = bbox.r_ll.p_y; childPoint.p_y = bbox.r_ll.p_y;
} }
else if (p == IDX_LR) /* lower right */ else if (p == 1) /* lower right */
{ {
childPoint.p_x = bbox.r_ur.p_x; childPoint.p_x = bbox.r_ur.p_x;
childPoint.p_y = bbox.r_ll.p_y; childPoint.p_y = bbox.r_ll.p_y;
} }
else if (p == IDX_UL) /* upper left */ else if (p == 2) /* upper left */
{ {
childPoint.p_x = bbox.r_ll.p_x; childPoint.p_x = bbox.r_ll.p_x;
childPoint.p_y = bbox.r_ur.p_y; childPoint.p_y = bbox.r_ur.p_y;
} }
else if (p == IDX_UR) /* upper right */ else if (p == 3) /* upper right */
{ {
childPoint.p_x = bbox.r_ur.p_x; childPoint.p_x = bbox.r_ur.p_x;
childPoint.p_y = bbox.r_ur.p_y; childPoint.p_y = bbox.r_ur.p_y;
} }
else if ((p == IDX_LABEL) && (ac >= 3)) /* label */ else
{ {
childPoint = TiPlaneRect.r_ur; childPoint = TiPlaneRect.r_ur;
(void) DBSrLabelLoc(dummy, av[2], cmdDumpFunc, (void) DBSrLabelLoc(dummy, av[1], cmdDumpFunc,
&childPoint); &childPoint);
if (childPoint.p_x == TiPlaneRect.r_xtop && if (childPoint.p_x == TiPlaneRect.r_xtop &&
childPoint.p_y == TiPlaneRect.r_ytop) childPoint.p_y == TiPlaneRect.r_ytop)
{ {
TxError("Couldn't find label \"%s\" in cell \"%s\".\n", TxError("Couldn't find label \"%s\" in cell \"%s\".\n",
av[2], cmd->tx_argv[1]); av[1], cmd->tx_argv[1]);
return FALSE; 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; av += 2;
ac -= 2; ac -= 2;
} }
hasChild = TRUE; hasChild = TRUE;
break; break;
case 1: /* Parent */
case IDX_PARENT: /* "parent" */
if (ac < 2) if (ac < 2)
{ {
TxError("Keyword must be followed by a reference point\n"); TxError("Keyword must be followed by a reference point\n");
goto usage; 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 else
{ {
p = Lookup(av[1], refPointNames); p = Lookup(av[1], refPointNames);
if (p == IDX_LL) /* lower left */ if (p == 0) /* lower left */
{ {
if (!ToolGetBox(&rootDef, &rootBox) || if (!ToolGetBox(&rootDef, &rootBox) ||
(rootDef != EditRootDef)) goto box_error; (rootDef != EditRootDef)) goto box_error;
rootPoint.p_x = rootBox.r_ll.p_x; rootPoint.p_x = rootBox.r_ll.p_x;
rootPoint.p_y = rootBox.r_ll.p_y; rootPoint.p_y = rootBox.r_ll.p_y;
} }
else if (p == IDX_LR) /* lower right */ else if (p == 1) /* lower right */
{ {
if (!ToolGetBox(&rootDef, &rootBox) || if (!ToolGetBox(&rootDef, &rootBox) ||
(rootDef != EditRootDef)) goto box_error; (rootDef != EditRootDef)) goto box_error;
rootPoint.p_x = rootBox.r_ur.p_x; rootPoint.p_x = rootBox.r_ur.p_x;
rootPoint.p_y = rootBox.r_ll.p_y; rootPoint.p_y = rootBox.r_ll.p_y;
} }
else if (p == IDX_UL) /* upper left */ else if (p == 2) /* upper left */
{ {
if (!ToolGetBox(&rootDef, &rootBox) || if (!ToolGetBox(&rootDef, &rootBox) ||
(rootDef != EditRootDef)) goto box_error; (rootDef != EditRootDef)) goto box_error;
rootPoint.p_x = rootBox.r_ll.p_x; rootPoint.p_x = rootBox.r_ll.p_x;
rootPoint.p_y = rootBox.r_ur.p_y; rootPoint.p_y = rootBox.r_ur.p_y;
} }
else if (p == IDX_UR) /* upper right */ else if (p == 3) /* upper right */
{ {
if (!ToolGetBox(&rootDef, &rootBox) || if (!ToolGetBox(&rootDef, &rootBox) ||
(rootDef != EditRootDef)) goto box_error; (rootDef != EditRootDef)) goto box_error;
rootPoint.p_x = rootBox.r_ur.p_x; rootPoint.p_x = rootBox.r_ur.p_x;
rootPoint.p_y = rootBox.r_ur.p_y; rootPoint.p_y = rootBox.r_ur.p_y;
} }
else if ((p == IDX_LABEL) && (ac >= 3)) /* label */ else
{ {
for (lab = editDef->cd_labels; lab; lab = lab->lab_next) for (lab = editDef->cd_labels; lab; lab = lab->lab_next)
if (strcmp(lab->lab_text, av[2]) == 0) if (strcmp(lab->lab_text, av[1]) == 0)
break; break;
if (lab == NULL) if (lab == NULL)
{ {
TxError("Couldn't find label \"%s\" in edit cell.\n", TxError("Couldn't find label \"%s\" in edit cell.\n",
av[2]); av[1]);
return FALSE; return FALSE;
} }
editPoint = lab->lab_rect.r_ll; editPoint = lab->lab_rect.r_ll;
GeoTransPoint(&EditToRootTransform, &editPoint, GeoTransPoint(&EditToRootTransform, &editPoint,
&rootPoint); &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; av += 2;
ac -= 2; ac -= 2;
} }
hasRoot = TRUE; hasRoot = TRUE;
break; break;
case IDX_ZERO: /* "0" */ case 2: /* 0 */
tx_cell = &GeoIdentityTransform; tx_cell = &GeoIdentityTransform;
transform_cell: transform_cell:
if (ac < 2 ) if (ac < 2 )
@ -5235,51 +5131,54 @@ default_action:
av += 1; av += 1;
ac -= 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
* Error case: else if (Lookup(av[1], kwdNames)>=0 && Lookup(av[1], kwdNames)!= 2 && strcmp(av[1],"90") && strcmp(av[1],"180") && strcmp(av[1],"270"))
* 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; goto default_action;
} }
else else
{
if (StrIsInt(av[1]))
{
editPoint.p_x = atoi(av[1]);
if (ac < 3 || !StrIsInt(av[2]))
{
TxError("Must provide two coordinates\n");
goto usage;
}
editPoint.p_y = atoi(av[2]);
av += 3;
ac -= 3;
}
else
{ {
p = Lookup(av[1], refPointNames); p = Lookup(av[1], refPointNames);
if (p == IDX_LL) /* lower left */ if (p == 0) /* lower left */
{ {
editPoint.p_x = bbox.r_ll.p_x; editPoint.p_x = bbox.r_ll.p_x;
editPoint.p_y = bbox.r_ll.p_y; editPoint.p_y = bbox.r_ll.p_y;
} }
else if (p == IDX_LR) /* lower right */ else if (p == 1) /* lower right */
{ {
editPoint.p_x = bbox.r_ur.p_x; editPoint.p_x = bbox.r_ur.p_x;
editPoint.p_y = bbox.r_ll.p_y; editPoint.p_y = bbox.r_ll.p_y;
} }
else if (p == IDX_UL) /* upper left */ else if (p == 2) /* upper left */
{ {
editPoint.p_x = bbox.r_ll.p_x; editPoint.p_x = bbox.r_ll.p_x;
editPoint.p_y = bbox.r_ur.p_y; editPoint.p_y = bbox.r_ur.p_y;
} }
else if (p == IDX_UR) /* upper right */ else if (p == 3) /* upper right */
{ {
editPoint.p_x = bbox.r_ur.p_x; editPoint.p_x = bbox.r_ur.p_x;
editPoint.p_y = bbox.r_ur.p_y; editPoint.p_y = bbox.r_ur.p_y;
} }
else if ((p == IDX_LABEL) && (ac >= 3)) /* label */ else
{ {
editPoint = TiPlaneRect.r_ur; editPoint = TiPlaneRect.r_ur;
(void) DBSrLabelLoc(dummy, av[1], cmdDumpFunc, &editPoint); (void) DBSrLabelLoc(dummy, av[1], cmdDumpFunc,
&editPoint);
if (editPoint.p_x == TiPlaneRect.r_xtop && if (editPoint.p_x == TiPlaneRect.r_xtop &&
editPoint.p_y == TiPlaneRect.r_ytop) editPoint.p_y == TiPlaneRect.r_ytop)
{ {
@ -5287,64 +5186,53 @@ default_action:
av[1], cmd->tx_argv[1]); av[1], cmd->tx_argv[1]);
return FALSE; return FALSE;
} }
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
{
TxError("Must provide two valid coordinates\n");
goto usage;
} }
av += 2; av += 2;
ac -= 2; ac -= 2;
}
{
Point p;
GeoTransPoint(tx_cell, &editPoint, &locp); GeoTransPoint(tx_cell, &editPoint, &p);
GeoTranslateTrans(tx_cell, editPoint.p_x - locp.p_x, GeoTranslateTrans(tx_cell, editPoint.p_x - p.p_x,
editPoint.p_y - locp.p_y, editPoint.p_y - p.p_y, &trans_cell);
&trans_cell); }
} }
hasTrans = TRUE; hasTrans = TRUE;
break; break;
case IDX_90: /* "90" */ case 3: /* 90 */
tx_cell = &Geo90Transform; tx_cell = &Geo90Transform;
goto transform_cell; goto transform_cell;
case IDX_180: /* "180" */ case 4: /* 180 */
tx_cell = &Geo180Transform; tx_cell = &Geo180Transform;
goto transform_cell; goto transform_cell;
case IDX_270: /* "270" */ case 5: /* 270 */
tx_cell = &Geo270Transform; tx_cell = &Geo270Transform;
goto transform_cell; goto transform_cell;
case IDX_VERT: /* "v" */ case 6: /* v */
case IDX_ZERO_VERT: /* "0v" */ case 7: /* 0v */
tx_cell = &GeoUpsideDownTransform; tx_cell = &GeoUpsideDownTransform;
goto transform_cell; goto transform_cell;
case IDX_90_VERT: /* "90v" */ case 8: /* 90v */
tx_cell = &GeoRef45Transform; tx_cell = &GeoRef45Transform;
goto transform_cell; goto transform_cell;
case IDX_180_VERT: /* "180v" */ case 9: /* 180v */
tx_cell = &GeoSidewaysTransform; tx_cell = &GeoSidewaysTransform;
goto transform_cell; goto transform_cell;
case IDX_270_VERT: /* "270v" */ case 10: /* 270v */
tx_cell = &GeoRef135Transform; tx_cell = &GeoRef135Transform;
goto transform_cell; goto transform_cell;
case IDX_HORZ: /* "h" */ case 11: /* h */
case IDX_ZERO_HORZ: /* "0h" */ case 12: /* 0h */
tx_cell = &GeoSidewaysTransform; tx_cell = &GeoSidewaysTransform;
goto transform_cell; goto transform_cell;
case IDX_90_HORZ: /* "90h" */ case 13: /* 90h */
tx_cell = &GeoRef135Transform; tx_cell = &GeoRef135Transform;
goto transform_cell; goto transform_cell;
case IDX_180_HORZ: /* "180h" */ case 14: /* 180h */
tx_cell = &GeoUpsideDownTransform; tx_cell = &GeoUpsideDownTransform;
goto transform_cell; goto transform_cell;
case IDX_270_HORZ: /* "270h" */ case 15: /* 270h */
tx_cell = &GeoRef45Transform; tx_cell = &GeoRef45Transform;
goto transform_cell; goto transform_cell;
} }
@ -5404,17 +5292,15 @@ usage:
"Usage: %s cellName [child refPointChild] [parent refPointParent]\n", "Usage: %s cellName [child refPointChild] [parent refPointParent]\n",
cmdName); cmdName);
TxError(" [transform [refPointTrans]],\n"); TxError(" [transform [refPointTrans]],\n");
TxError(" where the refPoints are one of:\n"); TxError(" where the refPoints are either a single label name,\n");
TxError( TxError(
" 'label' followed by a single label name,\n"); " or ll for lower left corner, or lr for lower right corner\n");
TxError( TxError(
" or 'll' for lower left corner, 'lr' for lower right corner,\n"); " or ul for upper left corner, or ur for upper right corner\n");
TxError( TxError(
" 'ul' for upper left corner, 'ur' for upper right corner,\n"); " or a pair of integer coordinates, and the transform is one of\n");
TxError( TxError(
" or a pair of coordinates. The transform is one of:\n"); " 90, 180, 270, v, 90v, 180v, 270v, h, 90h, 180h, 270h.\n");
TxError(
" 90, 180, 270, v, 90v, 180v, 270v, h, 90h, 180h, or 270h.\n");
return FALSE; return FALSE;
} }

View File

@ -781,81 +781,38 @@ cmdEraseCellsFunc(
* Implement the "expand" command. * Implement the "expand" command.
* *
* Usage: * Usage:
* expand [selection|surround|overlap|all] [toggle] * expand
* * expand toggle
* "selection" expands cells in the selection. All other options
* expand cells in the layout. "all" expands all cells in the
* layout. "surround" expands cells which the cursor box
* surrounds completely, and "overlap" expands cells which the
* cursor box overlaps.
*
* If "toggle" is specified, flips the expanded/unexpanded status.
* Cells which were expanded are unexpanded, and cells which were
* unexpanded are expanded.
*
* For backwards compatibility:
* "expand" alone implements "expand overlap".
* "expand toggle" implements "expand selection toggle".
*
* Also see: CmdUnexpand
* *
* Results: * Results:
* None. * None.
* *
* Side effects: * Side effects:
* Expansion state of cells is changed. May read cells in from * If "toggle" is specified, flips the expanded/unexpanded status
* disk, and update bounding boxes that have changed. * of all selected cells. Otherwise, aren't any unexpanded cells
* left under the box. May read cells in from disk, and updates
* bounding boxes that have changed.
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
#define EXPAND_SELECTION 0
#define EXPAND_SURROUND 1
#define EXPAND_OVERLAP 2
#define EXPAND_ALL 3
#define EXPAND_HELP 4
void void
CmdExpand( CmdExpand(
MagWindow *w, MagWindow *w,
TxCommand *cmd) TxCommand *cmd)
{ {
int windowMask, boxMask, d, option; int windowMask, boxMask, d;
bool doToggle = FALSE;
const char * const *msg;
Rect rootRect; Rect rootRect;
CellUse *rootBoxUse; CellUse *rootBoxUse;
CellDef *rootBoxDef; CellDef *rootBoxDef;
int cmdExpandFunc(CellUse *use, int windowMask); /* Forward reference. */ int cmdExpandFunc(CellUse *use, int windowMask); /* Forward reference. */
static const char * const cmdExpandOption[] = { if (cmd->tx_argc > 2 || (cmd->tx_argc == 2
"selection expand cell instances in the selection", && (strncmp(cmd->tx_argv[1], "toggle", strlen(cmd->tx_argv[1])) != 0)))
"surround expand cell instances which the cursor box surrounds",
"overlap expand cell instances which the cursor box overlaps",
"all expand all cell instances",
NULL
};
if (cmd->tx_argc > 1)
{ {
if (!strncmp(cmd->tx_argv[cmd->tx_argc - 1], "toggle", TxError("Usage: %s or %s toggle\n", cmd->tx_argv[0], cmd->tx_argv[0]);
strlen(cmd->tx_argv[cmd->tx_argc - 1]))) return;
{
doToggle = TRUE;
cmd->tx_argc--;
} }
}
if (cmd->tx_argc > 1)
{
option = Lookup(cmd->tx_argv[1], cmdExpandOption);
if (option < 0) option = EXPAND_HELP;
}
else
option = EXPAND_OVERLAP;
if (option == EXPAND_HELP) goto badusage;
windCheckOnlyWindow(&w, DBWclientID); windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *) NULL) if (w == (MagWindow *) NULL)
@ -887,95 +844,23 @@ CmdExpand(
WindScale(d, 1); WindScale(d, 1);
TxPrintf("expand: rescaled by %d\n", d); TxPrintf("expand: rescaled by %d\n", d);
d = DBLambda[1]; d = DBLambda[1];
if (doToggle) break; /* Don't toggle twice */ if (cmd->tx_argc == 2) break; /* Don't toggle twice */
} }
(void) ToolGetBoxWindow(&rootRect, &boxMask); (void) ToolGetBoxWindow(&rootRect, &boxMask);
if (option != EXPAND_SELECTION) if (cmd->tx_argc == 2)
SelectExpand(windowMask);
else
{ {
if ((boxMask & windowMask) != windowMask) if ((boxMask & windowMask) != windowMask)
{ {
TxError("The box isn't in the same window as the cursor.\n"); TxError("The box isn't in the same window as the cursor.\n");
return; return;
} }
}
switch (option)
{
case EXPAND_SELECTION:
SelectExpand(windowMask,
(doToggle) ? DB_EXPAND_TOGGLE : DB_EXPAND,
(Rect *)NULL);
break;
case EXPAND_OVERLAP:
if (doToggle)
{
DBExpandAll(rootBoxUse, &rootRect, windowMask, DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_OVERLAP, TRUE, cmdExpandFunc, (ClientData)(pointertype) windowMask);
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_OVERLAP,
&rootRect);
}
else
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
&rootRect);
}
break;
case EXPAND_SURROUND:
if (doToggle)
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_SURROUND,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_SURROUND,
&rootRect);
}
else
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND | DB_EXPAND_SURROUND,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_SURROUND,
&rootRect);
}
break;
case EXPAND_ALL:
if (doToggle)
{
DBExpandAll(rootBoxUse, &TiPlaneRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
(Rect *)NULL);
}
else
{
DBExpandAll(rootBoxUse, &TiPlaneRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
(Rect *)NULL);
}
break;
} }
} while (d != DBLambda[1]); } while (d != DBLambda[1]);
return;
badusage:
for (msg = &(cmdExpandOption[0]); *msg != NULL; msg++)
TxPrintf(" %s\n", *msg);
TxPrintf(" toggle Toggle the visibility of cell instances.\n");
} }
/* This function is called for each cell whose expansion status changed. /* This function is called for each cell whose expansion status changed.
@ -1040,14 +925,11 @@ cmdExpandFunc(
#define DOALL 1 #define DOALL 1
#define DOCAPACITANCE 2 #define DOCAPACITANCE 2
#define DOCOUPLING 3 #define DOCOUPLING 3
#define DOEXTRESIST 4 #define DOLENGTH 4
#define DOLENGTH 5 #define DOLOCAL 5
#define DOLOCAL 6 #define DORESISTANCE 6
#define DORESISTANCE 7 #define DOLABELCHECK 7
#define DOLABELCHECK 8 #define DOALIASES 8
#define DOALIASES 9
#define DOUNIQUE 10
#define DOEXTRESIST2 11
#define LENCLEAR 0 #define LENCLEAR 0
#define LENDRIVER 1 #define LENDRIVER 1
@ -1090,14 +972,11 @@ CmdExtract(
"all all options", "all all options",
"capacitance extract substrate capacitance", "capacitance extract substrate capacitance",
"coupling extract coupling capacitance", "coupling extract coupling capacitance",
"extresist extract resistance",
"length compute driver-receiver pathlengths", "length compute driver-receiver pathlengths",
"local put all generated files in the current directory", "local put all generated files in the current directory",
"lumped estimate lumped resistance", "resistance estimate resistance",
"labelcheck check for connections through sticky labels", "labelcheck check for connections through sticky labels",
"aliases output all net name aliases", "aliases output all net name aliases",
"unique [notopports] ensure unique node names during extraction",
"resistance extract resistance (same as \"do extresist\")",
NULL NULL
}; };
static const char * const cmdExtLength[] = static const char * const cmdExtLength[] =
@ -1241,13 +1120,12 @@ CmdExtract(
} }
else if (argc == 2) else if (argc == 2)
{ {
char *halodisp;
halodisp = DBWPrintValue(ExtCurStyle->exts_sideCoupleHalo,
w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(halodisp, -1)); Tcl_Obj *tobj;
tobj = Tcl_NewIntObj(ExtCurStyle->exts_sideCoupleHalo);
Tcl_SetObjResult(magicinterp, tobj);
#else #else
TxPrintf("Side overlap halo is %s\n", halodisp); TxPrintf("Side overlap halo is %d\n", ExtCurStyle->exts_sideCoupleHalo);
#endif #endif
return; return;
} }
@ -1272,12 +1150,12 @@ CmdExtract(
} }
else if (argc == 2) else if (argc == 2)
{ {
char *stepdisp;
stepdisp = DBWPrintValue(ExtCurStyle->exts_stepSize, w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(stepdisp, -1)); Tcl_Obj *tobj;
tobj = Tcl_NewIntObj(ExtCurStyle->exts_stepSize);
Tcl_SetObjResult(magicinterp, tobj);
#else #else
TxPrintf("Extraction step size is %s\n", stepdisp); TxPrintf("Extraction step size is %d\n", ExtCurStyle->exts_stepSize);
#endif #endif
return; return;
} }
@ -1399,12 +1277,9 @@ CmdExtract(
TxPrintf("%s capacitance\n", OPTSET(EXT_DOCAPACITANCE)); TxPrintf("%s capacitance\n", OPTSET(EXT_DOCAPACITANCE));
TxPrintf("%s coupling\n", OPTSET(EXT_DOCOUPLING)); TxPrintf("%s coupling\n", OPTSET(EXT_DOCOUPLING));
TxPrintf("%s length\n", OPTSET(EXT_DOLENGTH)); TxPrintf("%s length\n", OPTSET(EXT_DOLENGTH));
TxPrintf("%s lumped R\n", OPTSET(EXT_DORESISTANCE)); TxPrintf("%s resistance\n", OPTSET(EXT_DORESISTANCE));
TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK)); TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK));
TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES)); TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES));
TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE));
TxPrintf("%s unique notopports\n", OPTSET(EXT_DOUNIQNOTOPPORTS));
TxPrintf("%s resistance (extresist)\n", OPTSET(EXT_DOEXTRESIST));
return; return;
#undef OPTSET #undef OPTSET
} }
@ -1434,19 +1309,6 @@ CmdExtract(
case DORESISTANCE: option = EXT_DORESISTANCE; break; case DORESISTANCE: option = EXT_DORESISTANCE; break;
case DOLABELCHECK: option = EXT_DOLABELCHECK; break; case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
case DOALIASES: option = EXT_DOALIASES; break; case DOALIASES: option = EXT_DOALIASES; break;
case DOEXTRESIST:
case DOEXTRESIST2: option = EXT_DOEXTRESIST; break;
case DOUNIQUE:
if (argc == 4)
{
if (!strncmp(argv[3], "notop", 5))
option = EXT_DOUNIQNOTOPPORTS | EXT_DOUNIQUE;
else
TxError("Usage: extract do unique [notopports]\n");
}
else
option = EXT_DOUNIQUE;
break;
case DOLOCAL: case DOLOCAL:
/* "extract do local" and "extract no local" are kept for /* "extract do local" and "extract no local" are kept for
* backwards compatibility, but now effectively implement * backwards compatibility, but now effectively implement

View File

@ -102,17 +102,15 @@ struct cmdFPArg
int int
feedPolyFunc( feedPolyFunc(
Tile *tile, Tile *tile,
TileType dinfo,
struct cmdFPArg *arg) struct cmdFPArg *arg)
{ {
Rect area; Rect area;
TiToRect(tile, &area); TiToRect(tile, &area);
/* (NOTE: Preserve information about the geometry of a diagonal tile) */
DBWFeedbackAdd(&area, arg->text, arg->def, FEEDMAGNIFY, DBWFeedbackAdd(&area, arg->text, arg->def, FEEDMAGNIFY,
arg->style | arg->style |
((TiGetTypeExact(tile) | dinfo) & (TiGetTypeExact(tile) & (TT_DIAGONAL | TT_DIRECTION | TT_SIDE)));
(TT_DIAGONAL | TT_DIRECTION | TT_SIDE))); /* (preserve information about the geometry of a diagonal tile) */
return 0; return 0;
} }
@ -515,9 +513,7 @@ CmdFill(
TileTypeBitMask maskBits; TileTypeBitMask maskBits;
Rect editBox; Rect editBox;
SearchContext scx; 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) if (cmd->tx_argc < 2 || cmd->tx_argc > 3)
{ {
@ -585,15 +581,13 @@ CmdFill(
/* Now that we've got all the material, scan over the list /* Now that we've got all the material, scan over the list
* painting the material and freeing up the entries on the list. * painting the material and freeing up the entries on the list.
*/ */
free_magic1_t mm1 = freeMagic1_init();
while (cmdFillList != NULL) while (cmdFillList != NULL)
{ {
DBPaint(EditCellUse->cu_def, &cmdFillList->cfa_area, DBPaint(EditCellUse->cu_def, &cmdFillList->cfa_area,
cmdFillList->cfa_type); cmdFillList->cfa_type);
freeMagic1(&mm1, (char *) cmdFillList); freeMagic((char *) cmdFillList);
cmdFillList = cmdFillList->cfa_next; cmdFillList = cmdFillList->cfa_next;
} }
freeMagic1_end(&mm1);
SelectClear(); SelectClear();
DBAdjustLabels(EditCellUse->cu_def, &editBox); DBAdjustLabels(EditCellUse->cu_def, &editBox);
@ -607,16 +601,11 @@ CmdFill(
* paint here it may mess up the search. Instead, the procedures * paint here it may mess up the search. Instead, the procedures
* save areas on a list. The list is post-processed to paint the * save areas on a list. The list is post-processed to paint the
* areas once the search is finished. * 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 int
cmdFillFunc( cmdFillFunc(
Tile *tile, /* Tile to fill with. */ Tile *tile, /* Tile to fill with. */
TileType dinfo, /* Split tile information (unused) */
TreeContext *cxp) /* Describes state of search. */ TreeContext *cxp) /* Describes state of search. */
{ {
Rect r1, r2; Rect r1, r2;
@ -852,7 +841,7 @@ CmdFindLabel(
return; return;
}; };
labname = cmd->tx_argv[1 + ((doglob) ? 1 : 0)]; labname = cmd->tx_argv[1 + (doglob) ? 1 : 0];
labUse = EditCellUse; labUse = EditCellUse;
if (labUse == NULL) labUse = (CellUse *)w->w_surfaceID; if (labUse == NULL) labUse = (CellUse *)w->w_surfaceID;
@ -1227,8 +1216,7 @@ CmdGetnode(
else else
SimGetnode(); SimGetnode();
if (SimGetnodeAlias) /* "erase" the hash table */ if (SimGetnodeAlias) { /* "erase" the hash table */
{
HashKill(&SimGNAliasTbl); HashKill(&SimGNAliasTbl);
HashInit(&SimGNAliasTbl, 120, STRINGS); HashInit(&SimGNAliasTbl, 120, STRINGS);
} }
@ -1614,7 +1602,7 @@ CmdFindNetProc(
int pnum, xpos, ypos; int pnum, xpos, ypos;
char *xstr, *ystr; char *xstr, *ystr;
bool locvalid = FALSE, usefound = TRUE; bool locvalid = FALSE, usefound = TRUE;
TileType ttype, dinfo = (TileType)0; TileType ttype;
scx.scx_use = use; scx.scx_use = use;
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
@ -1652,7 +1640,6 @@ CmdFindNetProc(
if ((xstr = strchr(s, '_')) != NULL) if ((xstr = strchr(s, '_')) != NULL)
{ {
char *hashpos;
bool isNeg = FALSE; bool isNeg = FALSE;
/* The characters up to the leading '_' should match one of the */ /* The characters up to the leading '_' should match one of the */
@ -1696,17 +1683,6 @@ 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;
} }
} }
@ -1729,23 +1705,17 @@ checklocal:
if (locvalid == TRUE) if (locvalid == TRUE)
{ {
int findTile(Tile *tile, TileType dinfo, TileAndDinfo *tad); int findTile(Tile *tile, TileType *rtype);
CellDef *targetdef = use->cu_def; CellDef *targetdef = use->cu_def;
Plane *plane = targetdef->cd_planes[pnum]; Plane *plane = targetdef->cd_planes[pnum];
TileAndDinfo tad;
ttype = TT_SPACE; /* revert to space in case of failure */
/* Find the tile type of the tile at the specified point which */ /* Find the tile type of the tile at the specified point which */
/* exists on the plane pnum. Note that in the case of a split */ /* exists on the plane pnum. */
/* 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, DBSrPaintArea(NULL, plane, &localrect, &DBAllTypeBits, findTile,
(ClientData) &tad); (ClientData) &ttype);
ttype = tad.tad_dinfo & TT_LEFTMASK;
} }
else else
{ {
@ -1813,7 +1783,7 @@ CmdGoto(
MagWindow *w, MagWindow *w,
TxCommand *cmd) TxCommand *cmd)
{ {
char *nodename = cmd->tx_argv[1]; char *s, *nodename = cmd->tx_argv[1];
Rect rect; Rect rect;
CellUse *use; CellUse *use;
int locargc; int locargc;
@ -1854,9 +1824,9 @@ CmdGoto(
/* are multiple layers drawn at the indicated point. */ /* are multiple layers drawn at the indicated point. */
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetResult(magicinterp, (char*)DBTypeLongName(ttype), NULL); /* Tcl treats as const */ Tcl_SetResult(magicinterp, DBTypeLongName(ttype), NULL);
#else #else
TxPrintf("node %s is type %s\n", nodename, DBTypeLongName(ttype)); TxPrintf("node %s is type %s\n", s, DBTypeLongName(ttype));
#endif #endif
} }
@ -1869,31 +1839,20 @@ CmdGoto(
int int
findTile( findTile(
Tile *tile, Tile *tile,
TileType dinfo, /* (unused) */ TileType *rtype)
TileAndDinfo *tad)
{ {
TileType ttype; 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 (IsSplit(tile))
{ {
if (tad->tad_dinfo & TT_SIDE) if (SplitSide(tile))
ttype = SplitRightType(tile); ttype = SplitRightType(tile);
else else
ttype = SplitLeftType(tile); ttype = SplitLeftType(tile);
} }
else else
ttype = TiGetTypeExact(tile); ttype = TiGetTypeExact(tile);
*rtype = ttype;
/* Leave the tile type in tad_dinfo before returning */
tad->tad_dinfo = ttype;
return 1; /* stop search */ return 1; /* stop search */
} }

View File

@ -45,8 +45,9 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "utils/undo.h" #include "utils/undo.h"
#include "select/select.h" #include "select/select.h"
#include "netmenu/netmenu.h" #include "netmenu/netmenu.h"
/* C99 compat */
#include "cif/cif.h" #include "cif/cif.h"
#include "cif/CIFint.h"
/* Forward declarations */ /* Forward declarations */
@ -517,14 +518,14 @@ CmdLoad(
DBExpandAll(topuse, &(topuse->cu_bbox), DBExpandAll(topuse, &(topuse->cu_bbox),
((DBWclientRec *)w->w_clientData)->dbw_bitmask, ((DBWclientRec *)w->w_clientData)->dbw_bitmask,
DB_EXPAND, keepGoing, NULL); TRUE, keepGoing, NULL);
DBExpandAll(topuse, &(topuse->cu_bbox), DBExpandAll(topuse, &(topuse->cu_bbox),
((DBWclientRec *)w->w_clientData)->dbw_bitmask, ((DBWclientRec *)w->w_clientData)->dbw_bitmask,
DB_UNEXPAND, keepGoing, NULL); FALSE, keepGoing, NULL);
DBExpand(topuse, DBExpand(topuse,
((DBWclientRec *)w->w_clientData)->dbw_bitmask, ((DBWclientRec *)w->w_clientData)->dbw_bitmask,
DB_EXPAND); TRUE);
/* We don't want to save and restore DBLambda, because */ /* We don't want to save and restore DBLambda, because */
/* loading the file may change their values. Instead, we */ /* loading the file may change their values. Instead, we */
@ -2174,9 +2175,6 @@ parseindex:
if (sl->lab_flags & PORT_DIR_MASK) if (sl->lab_flags & PORT_DIR_MASK)
{ {
if ((int)sl->lab_port == idx) if ((int)sl->lab_port == idx)
{
/* 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" TxError("Port index %d is already used by port %s.\n"
"Use command \"port index %d\" to force " "Use command \"port index %d\" to force "
@ -2186,7 +2184,6 @@ parseindex:
} }
} }
} }
}
argstart++; argstart++;
} }
else else
@ -2295,8 +2292,6 @@ parsepositions:
editDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP); editDef->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
} }
#define PROPERTY_TYPE_COMPAT 4 /* Last entry in cmdPropertyType */
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -2320,448 +2315,47 @@ parsepositions:
void void
CmdDoProperty( CmdDoProperty(
CellDef *def, CellDef *def,
MagWindow *w,
TxCommand *cmd, TxCommand *cmd,
int argstart) int argstart)
{ {
PropertyRecord *proprec = NULL;
char *value;
bool propfound, dolist;
int proptype, proplen, propvalue, i;
dlong dvalue;
int locargc = cmd->tx_argc - argstart + 1;
#ifdef MAGIC_WRAPPER
Tcl_Obj *tobj;
#endif
/* Forward declarations */
int printPropertiesFunc(); int printPropertiesFunc();
int printPlanePropFunc(); char *value;
bool propfound;
/* These should match the property codes in database.h.in, except int locargc = cmd->tx_argc - argstart + 1;
* for "compat" which must come at the end.
*/
static const char * const cmdPropertyType[] = {
"string", "integer", "dimension", "double", "plane", "compat", NULL
};
/* If the first keyword is "list", then set dolist and increment
* the starting argument position.
*/
dolist = FALSE;
if (locargc > 1)
{
if (!strcmp(cmd->tx_argv[argstart], "list"))
{
dolist = TRUE;
locargc--;
argstart++;
}
}
/* If a property type is given, parse it and then strip it from
* the arguments list.
*/
if (locargc > 1)
{
proptype = Lookup(cmd->tx_argv[argstart], cmdPropertyType);
if (proptype >= 0)
{
if (proptype != PROPERTY_TYPE_COMPAT)
{
locargc--;
argstart++;
}
}
else
proptype = PROPERTY_TYPE_STRING; /* default */
}
else
proptype = PROPERTY_TYPE_STRING; /* default */
if (locargc == 1) if (locargc == 1)
{ {
#ifdef MAGIC_WRAPPER
Tcl_Obj *tobj;
/* Create an empty list for the interpreter result; the
* printPropertiesFunc() function will append values to it.
*/
tobj = Tcl_NewListObj(0, NULL);
Tcl_SetObjResult(magicinterp, tobj);
#endif
/* print all properties and their values */ /* print all properties and their values */
DBPropEnum(def, printPropertiesFunc, (ClientData)w); DBPropEnum(def, printPropertiesFunc, NULL);
} }
else if (locargc == 2) else if (locargc == 2)
{ {
/* If the property type was "compat", then give the state of the /* print the value of the indicated property */
* compatibility flag and return. value = (char *)DBPropGet(def, cmd->tx_argv[argstart], &propfound);
*/
if (proptype == PROPERTY_TYPE_COMPAT)
{
#ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewBooleanObj(DBPropCompat));
#else
TxPrintf("%s\n", (DBPropCompat == TRUE) ? "True" : "False");
#endif
return;
}
/* Print the value of the indicated property */
proprec = (PropertyRecord *)DBPropGet(def, cmd->tx_argv[argstart], &propfound);
if (propfound) if (propfound)
{
proptype = proprec->prop_type;
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
switch (proptype) Tcl_SetResult(magicinterp, value, NULL);
{
case PROPERTY_TYPE_STRING:
Tcl_SetResult(magicinterp, proprec->prop_value.prop_string, NULL);
break;
case PROPERTY_TYPE_INTEGER:
if (proprec->prop_len == 1)
Tcl_SetObjResult(magicinterp,
Tcl_NewIntObj(proprec->prop_value.prop_integer[0]));
else
{
tobj = Tcl_NewListObj(0, NULL);
for (i = 0; i < proprec->prop_len; i++)
Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewIntObj(
proprec->prop_value.prop_integer[i]));
Tcl_SetObjResult(magicinterp, tobj);
}
break;
case PROPERTY_TYPE_DIMENSION:
if (proprec->prop_len == 1)
Tcl_SetResult(magicinterp,
DBWPrintValue(proprec->prop_value.prop_integer[0],
w, TRUE), NULL);
else
{
tobj = Tcl_NewListObj(0, NULL);
for (i = 0; i < proprec->prop_len; i++)
Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewStringObj(DBWPrintValue(
proprec->prop_value.prop_integer[i], w,
((i % 2) == 0) ? TRUE : FALSE), -1));
Tcl_SetObjResult(magicinterp, tobj);
}
break;
case PROPERTY_TYPE_PLANE:
tobj = Tcl_NewListObj(0, NULL);
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
proprec->prop_value.prop_plane,
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
(ClientData)tobj);
Tcl_SetObjResult(magicinterp, tobj);
break;
case PROPERTY_TYPE_DOUBLE:
if (proprec->prop_len == 1)
Tcl_SetObjResult(magicinterp,
Tcl_NewWideIntObj((Tcl_WideInt)
proprec->prop_value.prop_double[0]));
else
{
tobj = Tcl_NewListObj(0, NULL);
for (i = 0; i < proprec->prop_len; i++)
Tcl_ListObjAppendElement(magicinterp, tobj,
Tcl_NewWideIntObj((Tcl_WideInt)
proprec->prop_value.prop_double[i]));
Tcl_SetObjResult(magicinterp, tobj);
}
break;
}
#else #else
switch (proptype) TxPrintf("%s", value);
{
case PROPERTY_TYPE_STRING:
TxPrintf("%s\n", proprec->prop_value.prop_string);
break;
case PROPERTY_TYPE_INTEGER:
for (i = 0; i < proprec->prop_len; i++)
TxPrintf("%d ", proprec->prop_value.prop_integer[i]);
TxPrintf("\n");
break;
case PROPERTY_TYPE_DIMENSION:
for (i = 0; i < proprec->prop_len; i++)
TxPrintf("%s ", DBWPrintValue(
proprec->prop_value.prop_integer[i], w,
((i % 2) == 0) ? TRUE : FALSE));
TxPrintf("\n");
break;
case PROPERTY_TYPE_PLANE:
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
proprec->prop_value.prop_plane,
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
(ClientData)NULL);
TxPrintf("\n");
break;
case PROPERTY_TYPE_DOUBLE:
for (i = 0; i < proprec->prop_len; i++)
TxPrintf( "%"DLONG_PREFIX"d",
proprec->prop_value.prop_double[i]);
TxPrintf("\n");
break;
}
#endif #endif
}
else { else {
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
/* If the command was "cellname list property ...", then */ /* If the command was "cellname list property ...", then */
/* just return NULL if the property was not found. */ /* just return NULL if the property was not found. */
if (!dolist) if (strcmp(cmd->tx_argv[1], "list"))
#endif #endif
TxError("Property name \"%s\" is not defined\n", cmd->tx_argv[argstart]); TxError("Property name \"%s\" is not defined\n", cmd->tx_argv[1]);
} }
} }
else if (locargc >= 3) else if (locargc == 3)
{ {
/* If the property type was "compat", then set the state of the
* compatibility flag and return.
*/
if (proptype == PROPERTY_TYPE_COMPAT)
{
int idx;
static const char * const cmdPropYesNo[] = {
"disable", "no", "false", "off", "0",
"enable", "yes", "true", "on", "1", 0 };
idx = Lookup(cmd->tx_argv[2], cmdPropYesNo);
if (idx < 0)
{
TxError("Unknown property compat option \"%s\"\n", cmd->tx_argv[2]);
return;
}
DBPropCompat = (idx <= 4) ? FALSE : TRUE;
return;
}
/* Catch the following known reserved keywords and cast them to the
* expected property type. If any property type was already given
* to the command, it is overridden. This ensures that the reserved
* keyword functions work correctly.
*
* GDS_START, GDS_END: PROPERTY_TYPE_DOUBLE
* MASKHINTS_*: PROPERTY_TYPE_PLANE
* FIXED_BBOX: PROPERTY_TYPE_DIMENSION
*/
if (!strcmp(cmd->tx_argv[argstart], "GDS_START"))
proptype = PROPERTY_TYPE_DOUBLE;
else if (!strcmp(cmd->tx_argv[argstart], "GDS_END"))
proptype = PROPERTY_TYPE_DOUBLE;
else if (!strcmp(cmd->tx_argv[argstart], "GDS_FILE"))
proptype = PROPERTY_TYPE_STRING;
else if (!strcmp(cmd->tx_argv[argstart], "FIXED_BBOX"))
proptype = PROPERTY_TYPE_DIMENSION;
else if (!strcmp(cmd->tx_argv[argstart], "OBS_BBOX"))
proptype = PROPERTY_TYPE_DIMENSION;
else if (!strncmp(cmd->tx_argv[argstart], "MASKHINTS_", 10))
proptype = PROPERTY_TYPE_PLANE;
if (strlen(cmd->tx_argv[argstart + 1]) == 0) if (strlen(cmd->tx_argv[argstart + 1]) == 0)
DBPropPut(def, cmd->tx_argv[argstart], NULL); DBPropPut(def, cmd->tx_argv[argstart], NULL);
else else
{ {
if (proptype == PROPERTY_TYPE_STRING) value = StrDup((char **)NULL, cmd->tx_argv[argstart + 1]);
{ DBPropPut(def, cmd->tx_argv[argstart], value);
proplen = strlen(cmd->tx_argv[argstart + 1]);
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) -
7 + proplen);
proprec->prop_type = proptype;
proprec->prop_len = proplen;
strcpy(proprec->prop_value.prop_string, cmd->tx_argv[argstart + 1]);
}
else /* All non-string properties */
{
Plane *plane;
Rect r;
/* Two choices: If locargc == 3 then all values are in one
* argument. If locargc > 3, then parse each argument as a
* separate value.
*/
if (locargc > 3)
{
proplen = locargc - 2;
if (proptype == PROPERTY_TYPE_DOUBLE)
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
(proplen - 1)*sizeof(dlong));
else if (proptype == PROPERTY_TYPE_PLANE)
{
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
plane = DBNewPlane((ClientData)TT_SPACE);
proprec->prop_value.prop_plane = plane;
}
else
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
(proplen - 2)*sizeof(int));
proprec->prop_type = proptype;
proprec->prop_len = proplen;
for (i = 1; i < locargc - 1; i++)
{
if (proptype == PROPERTY_TYPE_INTEGER)
{
if (sscanf(cmd->tx_argv[argstart + i], "%d",
&propvalue) == 1)
proprec->prop_value.prop_integer[i - 1] = propvalue;
else
{
TxError("Unable to parse value \"%s\" as an integer\n",
cmd->tx_argv[argstart + i]);
proprec->prop_value.prop_integer[i - 1] = 0;
}
}
else if (proptype == PROPERTY_TYPE_DOUBLE)
{
if (sscanf(cmd->tx_argv[argstart + i], "%"DLONG_PREFIX"d",
&dvalue) == 1)
proprec->prop_value.prop_double[i - 1] = dvalue;
else
{
TxError("Unable to parse value \"%s\" as an integer\n",
cmd->tx_argv[argstart + i]);
proprec->prop_value.prop_double[i - 1] = 0;
}
}
else if (proptype == PROPERTY_TYPE_PLANE)
{
propvalue = cmdParseCoord(w, cmd->tx_argv[argstart + i],
FALSE, ((i % 2) == 0) ? FALSE : TRUE);
switch ((i - 1) % 4)
{
case 0:
r.r_xbot = propvalue;
break;
case 1:
r.r_ybot = propvalue;
break;
case 2:
r.r_xtop = propvalue;
break;
case 3:
r.r_ytop = propvalue;
DBPaintPlane(plane, &r, CIFPaintTable,
(PaintUndoInfo *)NULL);
break;
}
}
else /* PROPERTY_TYPE_DIMENSION */
{
propvalue = cmdParseCoord(w, cmd->tx_argv[argstart + i],
FALSE, ((i % 2) == 0) ? FALSE : TRUE);
proprec->prop_value.prop_integer[i - 1] = propvalue;
}
}
}
else
{
/* Make two passes through the argument string, once to get
* the valid number of arguments, then again to parse the
* values, once the property record has been allocated
*/
value = cmd->tx_argv[argstart + 1];
for (proplen = 0; *value != '\0'; )
{
if (isspace(*value) && (*value != '\0')) value++;
if (!isspace(*value))
{
proplen++;
while (!isspace(*value) && (*value != '\0')) value++;
}
}
if (proplen > 0)
{
if (proptype == PROPERTY_TYPE_PLANE)
{
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord));
plane = DBNewPlane((ClientData)TT_SPACE);
proprec->prop_value.prop_plane = plane;
} else {
proprec = (PropertyRecord *)mallocMagic(
sizeof(PropertyRecord) +
(proplen - 2) * sizeof(int));
}
proprec->prop_type = proptype;
proprec->prop_len = proplen;
}
/* Second pass */
value = cmd->tx_argv[argstart + 1];
for (proplen = 0; proplen < proprec->prop_len; proplen++)
{
if (isspace(*value) && (*value != '\0')) value++;
if (!isspace(*value))
{
char *spptr, spchar;
/* cmdParseCoord() can only handle one value at a
* time, so look ahead and null out the next space
* character if there is one.
*/
spptr = value + 1;
while (!isspace(*spptr) && (*spptr != '\0')) spptr++;
spchar = *spptr;
*spptr = '\0';
if (proptype == PROPERTY_TYPE_INTEGER)
{
if (sscanf(value, "%d", &propvalue) != 1)
{
TxError("Unable to parse integer "
"value from \"%s\"\n",
value);
propvalue = 0;
}
proprec->prop_value.prop_integer[proplen] = propvalue;
}
else if (proptype == PROPERTY_TYPE_DOUBLE)
{
if (sscanf(value, "%"DLONG_PREFIX"d", &dvalue) != 1)
{
TxError("Unable to parse integer "
"value from \"%s\"\n",
value);
propvalue = 0;
}
proprec->prop_value.prop_double[proplen] = dvalue;
}
else if (proptype == PROPERTY_TYPE_PLANE)
{
propvalue = cmdParseCoord(w, value, FALSE,
((proplen % 2) == 0) ? TRUE : FALSE);
switch (proplen % 4)
{
case 0:
r.r_xbot = propvalue;
break;
case 1:
r.r_ybot = propvalue;
break;
case 2:
r.r_xtop = propvalue;
break;
case 3:
r.r_ytop = propvalue;
DBPaintPlane(plane, &r, CIFPaintTable,
(PaintUndoInfo *)NULL);
break;
}
}
else /* PROPERTY_TYPE_DIMENSION */
{
propvalue = cmdParseCoord(w, value, FALSE,
((proplen % 2) == 0) ? TRUE : FALSE);
proprec->prop_value.prop_integer[proplen] = propvalue;
}
*spptr = spchar;
while (!isspace(*value) && (*value != '\0')) value++;
}
}
}
}
DBPropPut(def, cmd->tx_argv[argstart], proprec);
} }
def->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP); def->cd_flags |= (CDMODIFIED | CDGETNEWSTAMP);
} }
@ -2782,14 +2376,10 @@ CmdDoProperty(
* defined in database/DBprop.c. * defined in database/DBprop.c.
* *
* Usage: * Usage:
* property [string|integer|dimension] [name] [value] * property [name] [value]
* *
* If the first argument is present, it must be one of the known * "name" is a unique string tag for the property, and "value" is its
* keywords, and determines the form in which "value" is interpreted and * string value.
* stored. "name" is a unique string tag for the property. "value" is
* the value of the property, which is either a string, integer, or a
* list of integers. The difference between an "integer" and a "dimension"
* is that all values which are dimensions are scaled with internal units.
* *
* Results: * Results:
* None. * None.
@ -2816,62 +2406,9 @@ CmdProperty(
else else
def = ((CellUse *) w->w_surfaceID)->cu_def; def = ((CellUse *) w->w_surfaceID)->cu_def;
CmdDoProperty(def, w, cmd, 1); CmdDoProperty(def, cmd, 1);
} }
/*
* ----------------------------------------------------------------------------
* Callback function for printing values from a Plane property
* ----------------------------------------------------------------------------
*/
#ifdef MAGIC_WRAPPER
int
printPlanePropFunc(
Tile *tile,
TileType dinfo,
Tcl_Obj *lobj)
{
Rect r;
MagWindow *w;
TiToRect(tile, &r);
windCheckOnlyWindow(&w, DBWclientID);
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(DBWPrintValue(r.r_xbot, w, TRUE), -1));
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(DBWPrintValue(r.r_ybot, w, FALSE), -1));
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(DBWPrintValue(r.r_xtop, w, TRUE), -1));
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(DBWPrintValue(r.r_ytop, w, FALSE), -1));
return 0;
}
#else
int
printPlanePropFunc(
Tile *tile,
TileType dinfo,
ClientData cdata) /* (unused) */
{
Rect r;
MagWindow *w;
TiToRect(tile, &r);
windCheckOnlyWindow(&w, DBWclientID);
TxPrintf("%s ", DBWPrintValue(r.r_xbot, w, TRUE));
TxPrintf("%s ", DBWPrintValue(r.r_ybot, w, FALSE));
TxPrintf("%s ", DBWPrintValue(r.r_xtop, w, TRUE));
TxPrintf("%s ", DBWPrintValue(r.r_ytop, w, FALSE));
return 0;
}
#endif
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* Callback function for printing a single property key:value pair * Callback function for printing a single property key:value pair
@ -2881,84 +2418,27 @@ printPlanePropFunc(
int int
printPropertiesFunc( printPropertiesFunc(
const char *name, const char *name,
PropertyRecord *proprec, ClientData value,
MagWindow *w) ClientData cdata) /* not used */
{ {
int i;
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_Obj *tobj, *lobj; char *keyvalue;
tobj = Tcl_GetObjResult(magicinterp); if (value == NULL)
lobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewStringObj(name, -1));
switch (proprec->prop_type)
{ {
case PROPERTY_TYPE_STRING: keyvalue = (char *)mallocMagic(strlen(name) + 4);
Tcl_ListObjAppendElement(magicinterp, lobj, sprintf(keyvalue, "%s {}", name);
Tcl_NewStringObj(proprec->prop_value.prop_string, -1));
break;
case PROPERTY_TYPE_INTEGER:
for (i = 0; i < proprec->prop_len; i++)
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewIntObj(proprec->prop_value.prop_integer[i]));
break;
case PROPERTY_TYPE_DIMENSION:
for (i = 0; i < proprec->prop_len; i++)
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(
DBWPrintValue(proprec->prop_value.prop_integer[i],
w, ((i % 2) == 0) ? TRUE : FALSE), -1));
break;
case PROPERTY_TYPE_PLANE:
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane),
proprec->prop_value.prop_plane,
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
(ClientData)lobj);
break;
case PROPERTY_TYPE_DOUBLE:
for (i = 0; i < proprec->prop_len; i++)
Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewWideIntObj(proprec->prop_value.prop_double[i]));
break;
} }
Tcl_ListObjAppendElement(magicinterp, tobj, lobj); else
Tcl_SetObjResult(magicinterp, tobj); {
keyvalue = (char *)mallocMagic(strlen(name) + strlen((char *)value) + 2);
sprintf(keyvalue, "%s %s", name, (char *)value);
}
Tcl_AppendElement(magicinterp, keyvalue);
freeMagic(keyvalue);
#else #else
switch (proprec->prop_type) TxPrintf("%s = %s\n", name, value);
{
case PROPERTY_TYPE_STRING:
TxPrintf("%s = %s\n", name, (const char *)proprec->prop_value.prop_string);
break;
case PROPERTY_TYPE_INTEGER:
TxPrintf("%s = ", name);
for (i = 0; i < proprec->prop_len; i++)
TxPrintf("%d ", proprec->prop_value.prop_integer[i]);
TxPrintf("\n");
break;
case PROPERTY_TYPE_DIMENSION:
TxPrintf("%s = ", name);
for (i = 0; i < proprec->prop_len; i++)
TxPrintf("%s ", DBWPrintValue(proprec->prop_value.prop_integer[i],
w, ((i % 2) == 0) ? TRUE : FALSE));
TxPrintf("\n");
break;
case PROPERTY_TYPE_PLANE:
TxPrintf("%s = ", name);
DBSrPaintArea((Tile *)NULL, proprec->prop_value.prop_plane,
&TiPlaneRect, &CIFSolidBits, printPlanePropFunc,
(ClientData)NULL);
TxPrintf("\n");
break;
case PROPERTY_TYPE_DOUBLE:
TxPrintf("%s = ", name);
for (i = 0; i < proprec->prop_len; i++)
TxPrintf("%"DLONG_PREFIX"d ", proprec->prop_value.prop_double[i]);
TxPrintf("\n");
break;
}
#endif #endif
return 0; /* keep the search alive */ return 0; /* keep the search alive */

View File

@ -99,7 +99,7 @@ CmdRandom(
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(random())); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(random()));
#else #else
TxPrintf("%ld", random()); TxPrintf("%d", random());
#endif #endif
} }
else if ((cmd->tx_argc >= 2) && (!strcmp(cmd->tx_argv[1], "seed"))) else if ((cmd->tx_argc >= 2) && (!strcmp(cmd->tx_argv[1], "seed")))
@ -220,6 +220,8 @@ CmdSave(
DBUpdateStamps(locDef); DBUpdateStamps(locDef);
if (cmd->tx_argc == 2) if (cmd->tx_argc == 2)
{ {
char *fileName;
if (CmdIllegalChars(cmd->tx_argv[1], "[],", "Cell name")) if (CmdIllegalChars(cmd->tx_argv[1], "[],", "Cell name"))
return; return;
@ -635,21 +637,10 @@ cmdSelectArea(
int i; int i;
for (i = 0; i < DBNumUserLayers; i++) for (i = 0; i < DBNumUserLayers; i++)
{ {
if ((TTMaskHasType(&mask, i)) && if((TTMaskHasType(&mask, i)) && !(TTMaskHasType(&crec->dbw_visibleLayers, i)))
!(TTMaskHasType(&crec->dbw_visibleLayers, i)))
TTMaskClearType(&mask, i); TTMaskClearType(&mask, i);
} }
/* Remove L_CELL and L_LABEL if crec->dbw_flags indicates that
* they are not visible in the layout window.
*/
if (!(crec->dbw_flags & DBW_SEELABELS)) TTMaskClearType(&mask, L_LABEL);
if (!(crec->dbw_flags & DBW_SEECELLS)) TTMaskClearType(&mask, L_CELL);
} }
else if (option == SEL_AREA)
TTMaskSetType(&mask, L_LABEL);
SelectArea(&scx, &mask, crec->dbw_bitmask, globmatch); SelectArea(&scx, &mask, crec->dbw_bitmask, globmatch);
} }
@ -1038,7 +1029,7 @@ CmdSelect(
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Select everything under the box, perhaps looking only at * Select everything under the box, perhaps looking only at
* particular layers, but only if it's visible. * particular layers, but only if its visible.
*-------------------------------------------------------------------- *--------------------------------------------------------------------
*/ */
@ -1095,33 +1086,25 @@ CmdSelect(
*/ */
case SEL_BBOX: case SEL_BBOX:
{
char *selllx, *sellly, *selurx, *selury;
GeoTransRect(&SelectUse->cu_transform, &SelectDef->cd_bbox, &selarea); 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 #ifdef MAGIC_WRAPPER
lobj = Tcl_NewListObj(0, NULL); lobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(selllx, -1)); Tcl_NewIntObj(selarea.r_xbot));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(sellly, -1)); Tcl_NewIntObj(selarea.r_ybot));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(selurx, -1)); Tcl_NewIntObj(selarea.r_xtop));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(selury, -1)); Tcl_NewIntObj(selarea.r_ytop));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("Select bounding box: %s %s %s %s\n", TxPrintf("Select bounding box: %d %d %d %d\n",
selllx, sellly, selurx, selury); selarea.r_xbot, selarea.r_ybot,
selarea.r_xtop, selarea.r_ytop);
#endif #endif
return; return;
}
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Make a copy of the selection at its present loction but do not * Make a copy of the selection at its present loction but do not
@ -1138,36 +1121,14 @@ CmdSelect(
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Move the selection relative to the cell def * 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: case SEL_MOVE:
if ((more) || (less) || ((primargs != 4) && (primargs != 2))) if ((more) || (less) || (primargs != 4)) goto usageError;
goto usageError;
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_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
p.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE); p.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
}
/* Erase first, then recompute the transform */ /* Erase first, then recompute the transform */
GeoTransRect(&SelectUse->cu_transform, &SelectDef->cd_bbox, &selarea); GeoTransRect(&SelectUse->cu_transform, &SelectDef->cd_bbox, &selarea);
@ -1275,17 +1236,15 @@ CmdSelect(
/* of rlist) */ /* of rlist) */
SelectClear(); SelectClear();
free_magic1_t mm1 = freeMagic1_init();
while (rlist != NULL) while (rlist != NULL)
{ {
/* Paint rlist back into SelectDef */ /* Paint rlist back into SelectDef */
DBPaint(SelectDef, &rlist->r_r, rlist->r_type); DBPaint(SelectDef, &rlist->r_r, rlist->r_type);
/* cleanup as we go */ /* cleanup as we go */
freeMagic1(&mm1, rlist); freeMagic(rlist);
rlist = rlist->r_next; rlist = rlist->r_next;
} }
freeMagic1_end(&mm1);
/* Force erase and redraw of the selection */ /* Force erase and redraw of the selection */
DBReComputeBbox(SelectDef); DBReComputeBbox(SelectDef);
@ -1812,18 +1771,13 @@ cmdLabelSizeFunc(
if (value == NULL) if (value == NULL)
{ {
char *labsize;
MagWindow *w;
windCheckOnlyWindow(&w, DBWclientID);
labsize = DBWPrintValue(label->lab_size / 8, w, FALSE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
lobj = Tcl_GetObjResult(magicinterp); lobj = Tcl_GetObjResult(magicinterp);
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_NewStringObj(labsize, -1)); Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewDoubleObj((double)label->lab_size / 8.0));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("%s\n", labsize); TxPrintf("%g\n", (double)label->lab_size / 8.0);
#endif #endif
} }
else if (label->lab_size != *value) else if (label->lab_size != *value)
@ -1968,22 +1922,18 @@ cmdLabelOffsetFunc(
if (point == NULL) if (point == NULL)
{ {
char *laboffx, *laboffy;
MagWindow *w;
windCheckOnlyWindow(&w, DBWclientID);
laboffx = DBWPrintValue(label->lab_offset.p_x / 8, w, TRUE);
laboffy = DBWPrintValue(label->lab_offset.p_x / 8, w, FALSE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
lobj = Tcl_GetObjResult(magicinterp); lobj = Tcl_GetObjResult(magicinterp);
pobj = Tcl_NewListObj(0, NULL); pobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, pobj); Tcl_ListObjAppendElement(magicinterp, lobj, pobj);
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(laboffx, -1)); Tcl_ListObjAppendElement(magicinterp, pobj,
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(laboffy, -1)); Tcl_NewDoubleObj((double)label->lab_offset.p_x / 8.0));
Tcl_ListObjAppendElement(magicinterp, pobj,
Tcl_NewDoubleObj((double)label->lab_offset.p_y / 8.0));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("%s %s\n", laboffx, laboffy); TxPrintf("%g %g\n", (double)(label->lab_offset.p_x) / 8.0,
(double)(label->lab_offset.p_y) / 8.0);
#endif #endif
} }
else if (!GEO_SAMEPOINT(label->lab_offset, *point)) else if (!GEO_SAMEPOINT(label->lab_offset, *point))
@ -2013,25 +1963,23 @@ cmdLabelRectFunc(
if (rect == NULL) 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 #ifdef MAGIC_WRAPPER
lobj = Tcl_GetObjResult(magicinterp); lobj = Tcl_GetObjResult(magicinterp);
pobj = Tcl_NewListObj(0, NULL); pobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, pobj); Tcl_ListObjAppendElement(magicinterp, lobj, pobj);
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(labllx, -1)); Tcl_ListObjAppendElement(magicinterp, pobj,
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(lablly, -1)); Tcl_NewIntObj((double)label->lab_rect.r_xbot));
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(laburx, -1)); Tcl_ListObjAppendElement(magicinterp, pobj,
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(labury, -1)); 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_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("%s %s %s %s\n", labllx, lablly, laburx,labury); 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);
#endif #endif
} }
else if (!GEO_SAMERECT(label->lab_rect, *rect)) else if (!GEO_SAMERECT(label->lab_rect, *rect))
@ -2232,13 +2180,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelTextFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelTextFunc, cmdLabelTextFunc, (locargc == 3) ?
(ClientData)cmd->tx_argv[argstart + 1]); (ClientData)cmd->tx_argv[argstart + 1] : (ClientData)NULL);
} }
break; break;
@ -2304,12 +2248,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelFontFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelFontFunc, (ClientData)&font); cmdLabelFontFunc, (locargc == 3) ?
(ClientData)&font : (ClientData)NULL);
} }
} }
break; break;
@ -2337,12 +2278,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelJustFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelJustFunc, (ClientData)&pos); cmdLabelJustFunc, (locargc == 3) ?
(ClientData)&pos : (ClientData)NULL);
} }
break; break;
@ -2357,13 +2295,11 @@ CmdSetLabel(
{ {
if (locargc == 2) if (locargc == 2)
{ {
char *labsize;
labsize = DBWPrintValue(DefaultLabel->lab_size, w, FALSE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(labsize, -1)); Tcl_SetObjResult(magicinterp,
Tcl_NewIntObj(DefaultLabel->lab_size));
#else #else
TxPrintf("%s\n", labsize); TxPrintf("%d\n", DefaultLabel->lab_size);
#endif #endif
} }
else else
@ -2371,12 +2307,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelSizeFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelSizeFunc, (ClientData)&size); cmdLabelSizeFunc, (locargc == 3) ?
(ClientData)&size : (ClientData)NULL);
} }
break; break;
@ -2405,20 +2338,16 @@ CmdSetLabel(
{ {
if (locargc == 2) 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 #ifdef MAGIC_WRAPPER
lobj = Tcl_NewListObj(0, NULL); lobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(laboffx, -1)); Tcl_NewIntObj(DefaultLabel->lab_offset.p_x));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(laboffy, -1)); Tcl_NewIntObj(DefaultLabel->lab_offset.p_y));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("%s %s\n", laboffx, laboffy); TxPrintf("%d %d\n", DefaultLabel->lab_offset.p_x,
DefaultLabel->lab_offset.p_y);
#endif #endif
} }
else else
@ -2426,12 +2355,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelOffsetFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelOffsetFunc, (ClientData)&offset); cmdLabelOffsetFunc, (locargc != 2) ?
(ClientData)&offset : (ClientData)NULL);
} }
break; break;
@ -2495,12 +2421,10 @@ CmdSetLabel(
rect.r_ytop = cmdScaleCoord(w, cmd->tx_argv[argstart + 4], rect.r_ytop = cmdScaleCoord(w, cmd->tx_argv[argstart + 4],
TRUE, FALSE, 1); TRUE, FALSE, 1);
} }
if ((locargc == 3) || (locargc == 6))
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelRectFunc, (ClientData)&rect); cmdLabelRectFunc,
else ((locargc == 6) || (locargc == 3)) ?
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL, (ClientData)&rect : (ClientData)NULL);
cmdLabelRectFunc, (ClientData)NULL);
} }
break; break;
@ -2526,12 +2450,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelRotateFunc, (ClientData)NULL);
else
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelRotateFunc, (ClientData)&rotate); cmdLabelRotateFunc, (locargc == 3) ?
(ClientData)&rotate : (ClientData)NULL);
} }
break; break;
@ -2563,12 +2484,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelStickyFunc, (ClientData)NULL); cmdLabelStickyFunc, (locargc == 3) ?
else (ClientData)&flags : (ClientData)NULL);
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelStickyFunc, (ClientData)&flags);
} }
break; break;
@ -2596,7 +2514,7 @@ CmdSetLabel(
else else
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetResult(magicinterp, Tcl_SetResult(magicinterp,
(char*)DBTypeLongNameTbl[DefaultLabel->lab_type], /* Tcl treats as const */ DBTypeLongNameTbl[DefaultLabel->lab_type],
TCL_VOLATILE); TCL_VOLATILE);
#else #else
TxPrintf("%s\n", DBTypeLongNameTbl[DefaultLabel->lab_type]); TxPrintf("%s\n", DBTypeLongNameTbl[DefaultLabel->lab_type]);
@ -2607,12 +2525,9 @@ CmdSetLabel(
} }
else if (EditCellUse) else if (EditCellUse)
{ {
if (locargc == 2)
SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL, SelEnumLabels(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelLayerFunc, (ClientData)NULL); cmdLabelLayerFunc, (locargc == 3) ?
else (ClientData)&ttype : (ClientData)NULL);
SelEnumLabelsMirror(&DBAllTypeBits, TRUE, (bool *)NULL,
cmdLabelLayerFunc, (ClientData)&ttype);
} }
break; break;
@ -2849,7 +2764,7 @@ CmdSimCmd(
{ {
static char cmdbuf[200]; static char cmdbuf[200];
char *strptr; char *strptr;
const char *nodeCmd; char *nodeCmd;
int i; int i;
if (!SimRsimRunning) { if (!SimRsimRunning) {
@ -2947,39 +2862,16 @@ CmdSnap(
TxPrintf("Usage: snap [internal | lambda | user]\n"); TxPrintf("Usage: snap [internal | lambda | user]\n");
return; return;
} }
/* Backwards compatibility: Use of "snap" to set units display and
* parsing has been deprecated as of February 2026. However, as this
* is rather disruptive to existing scripts which use "snap" to change
* the parsing of units, then the following measure is being taken
* (for now, anyway): If DBWUnits is set to DBW_UNITS_DEFAULT, then
* "snap internal" will set DBWUnits as well as DBWSnapToGrid. If
* DBWUnits is changed first (e.g., "units internal"), then "snap" will
* affect only the snap grid. The older usage will be accompanied by a
* warning message. Note that backwards compatibility is being kept
* only in the case of "snap internal", which was commonly used in
* scripts to make sure that all units were interpreted as internal
* units.
*/
if ((DBWUnits == DBW_UNITS_DEFAULT) && (n == SNAP_INTERNAL))
{
DBWUnits = DBW_UNITS_INTERNAL;
TxError("Warning: snap setting is also changing units. This usage "
"is deprecated\nand may be removed in the future. Use "
"\"units\" to change units, and\nchange units before "
"setting snap to keep this message from appearing.\n");
}
switch (n) switch (n)
{ {
case SNAP_OFF: case SNAP_INTERNAL: case SNAP_OFF: case SNAP_INTERNAL:
DBWSnapToGrid = DBW_UNITS_INTERNAL; DBWSnapToGrid = DBW_SNAP_INTERNAL;
return; return;
case SNAP_LAMBDA: case SNAP_LAMBDA:
DBWSnapToGrid = DBW_UNITS_LAMBDA; DBWSnapToGrid = DBW_SNAP_LAMBDA;
return; return;
case SNAP_GRID: case SNAP_USER: case SNAP_ON: case SNAP_GRID: case SNAP_USER: case SNAP_ON:
DBWSnapToGrid = DBW_UNITS_USER; DBWSnapToGrid = DBW_SNAP_USER;
return; return;
} }
@ -2987,19 +2879,21 @@ printit:
if (n == SNAP_LIST) /* list */ if (n == SNAP_LIST) /* list */
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetResult(magicinterp, Tcl_SetResult(magicinterp,
(DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" : (DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user"), ((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"),
TCL_VOLATILE); TCL_VOLATILE);
#else #else
TxPrintf("%s\n", (DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" : TxPrintf("%s\n", (DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user")); ((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"));
#endif #endif
else else
TxPrintf("Box is aligned to %s grid\n", TxPrintf("Box is aligned to %s grid\n",
(DBWSnapToGrid == DBW_UNITS_INTERNAL) ? "internal" : (DBWSnapToGrid == DBW_SNAP_INTERNAL) ? "internal" :
((DBWSnapToGrid == DBW_UNITS_LAMBDA) ? "lambda" : "user")); ((DBWSnapToGrid == DBW_SNAP_LAMBDA) ? "lambda" : "user"));
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *

View File

@ -73,22 +73,9 @@ TileTypeBitMask CmdYMAllButSpace;
* lambda, a suffix of "g" indicates the user grid, and a suffix in metric * lambda, a suffix of "g" indicates the user grid, and a suffix in metric
* notation ("nm", "um", "mm", "cm") indicates natural units. Other valid * notation ("nm", "um", "mm", "cm") indicates natural units. Other valid
* units are "cu" or "centimicrons" for centimicrons, or "microns" for um. * units are "cu" or "centimicrons" for centimicrons, or "microns" for um.
* Traditional (backwards-compatible) behavior: Units without any suffix * Units without any suffix are assumed to be in lambda if "snap"
* are assumed to be in lambda if "snap" (DBWSnapToGrid) is set to lambda, * (DBWSnapToGrid) is set to lambda, grid units if "snap" is set to the
* grid units if "snap" is set to the user grid, and internal units otherwise. * 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 * 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 * the value of the grid for the given window. In this case, because the
@ -112,13 +99,6 @@ 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 int
cmdScaleCoord( cmdScaleCoord(
MagWindow *w, MagWindow *w,
@ -129,69 +109,45 @@ cmdScaleCoord(
{ {
char *endptr; char *endptr;
double dval = 0; double dval = 0;
int mscale = 1, curunits; int mscale = 1;
int retval, curval, parseop;
DBWclientRec *crec; DBWclientRec *crec;
if (*arg == '{' || *arg == '"') arg++; if (*arg == '{') arg++;
while (isspace(*arg) && (*arg != '\0')) arg++; while (isspace(*arg)) arg++;
parseop = PARSEOP_NONE;
retval = 0;
while (*arg != '\0')
{
dval = strtod(arg, &endptr); dval = strtod(arg, &endptr);
dval *= (double)scale; dval *= (double)scale;
mscale = -1;
if (endptr == arg) if (endptr == arg)
{ {
/* strtod() error condition */ /* strtod() error condition */
TxError("Coordinate value cannot be parsed: assuming 0\n"); TxError("Coordinate value cannot be parsed: assuming 0\n");
curval = 0; return 0;
break;
} }
/* Original behavior was to accept un-suffixed values according to the else if ((*endptr == 'l')
* "snap" setting. This behavior remains in effect until the "units" || ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_LAMBDA)))
* command is used, in which case units follow the selected units
* value indepedendently of the snap setting.
*
* Updated 12/24/2026 to handle space-separated values (in which
* *endptr may be a space as well as NULL).
*/
if (DBWUnits == DBW_UNITS_DEFAULT)
curunits = DBWSnapToGrid;
else
curunits = DBWUnits & DBW_UNITS_TYPE_MASK;
if ((*endptr == 'l')
|| (((*endptr == '\0') || isspace(*endptr))
&& (curunits == DBW_UNITS_LAMBDA)))
{ {
/* lambda or default units */ /* lambda or default units */
dval *= (double)DBLambda[1]; dval *= (double)DBLambda[1];
dval /= (double)DBLambda[0]; dval /= (double)DBLambda[0];
return round(dval);
} }
else if ((*endptr == 'i') else if ((*endptr == 'i')
|| (((*endptr == '\0') || isspace(*endptr)) || ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_INTERNAL)))
&& (curunits == DBW_UNITS_INTERNAL)))
{ {
/* internal units */ /* internal units */
return round(dval);
} }
else if ((*endptr == 'g') else if ((*endptr == 'g')
|| (((*endptr == '\0') || isspace(*endptr)) || ((*endptr == '\0') && (DBWSnapToGrid == DBW_SNAP_USER)))
&& (curunits == DBW_UNITS_USER)))
{ {
/* grid units */ /* grid units */
if (w == (MagWindow *)NULL) if (w == (MagWindow *)NULL)
{ {
windCheckOnlyWindow(&w, DBWclientID); windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *)NULL) if (w == (MagWindow *)NULL)
{ return round(dval); /* Default, if window is unknown */
curval = round(dval); /* Default, if window is unknown */
break;
}
} }
crec = (DBWclientRec *) w->w_clientData; crec = (DBWclientRec *) w->w_clientData;
if (is_x) if (is_x)
@ -208,13 +164,9 @@ cmdScaleCoord(
if (!is_relative) if (!is_relative)
dval += (double)crec->dbw_gridRect.r_ybot; dval += (double)crec->dbw_gridRect.r_ybot;
} }
return round(dval);
} }
else if (((*endptr == '\0') || isspace(*endptr)) else
&& (curunits == DBW_UNITS_MICRONS))
{
mscale = 1000;
}
else if (*endptr != '\0')
{ {
/* natural units referred to the current cifoutput style */ /* natural units referred to the current cifoutput style */
if (*(endptr + 1) == 'm') if (*(endptr + 1) == 'm')
@ -234,12 +186,12 @@ cmdScaleCoord(
mscale = 10000000; mscale = 10000000;
break; break;
default: default:
TxError("Unknown metric prefix \"%cm\"; assuming " TxError("Unknown metric prefix \"%cm\"; assuming internal units\n",
"internal units\n", *endptr); *endptr);
mscale = -1; return round(dval);
} }
} }
else if ((*endptr == 'u') && !isalnum(*(endptr + 1))) else if (!strcmp(endptr, "u"))
/* Maybe "u" is too ambiguous but it is very commonly used as /* Maybe "u" is too ambiguous but it is very commonly used as
* an abbreviation for "micron". * an abbreviation for "micron".
*/ */
@ -248,76 +200,16 @@ cmdScaleCoord(
mscale = 1000; mscale = 1000;
else if (!strncmp(endptr, "centimicron", 11) || !strcmp(endptr, "cu")) else if (!strncmp(endptr, "centimicron", 11) || !strcmp(endptr, "cu"))
mscale = 10; mscale = 10;
else if (!isspace(*endptr) && (*endptr != '+') && (*endptr != '-') && else if (!isspace(*endptr))
(*endptr != '*') && (*endptr != '/'))
{ {
TxError("Unknown coordinate type at \"%s\"; assuming internal units\n", TxError("Unknown coordinate type \"%s\"; assuming internal units\n",
endptr); endptr);
mscale = -1; return round(dval);
} }
} }
if (mscale != -1) if (!isspace(*endptr))
dval /= CIFGetOutputScale(mscale); dval /= CIFGetOutputScale(mscale);
curval = round(dval); return 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 '}':
case '"':
parseop = PARSEOP_END;
break;
case '+':
parseop = PARSEOP_ADD;
endptr++;
break;
case '-':
parseop = PARSEOP_SUB;
endptr++;
break;
case '*':
parseop = PARSEOP_MUL;
endptr++;
break;
case '/':
parseop = PARSEOP_DIV;
endptr++;
break;
case ' ':
case '\t':
endptr++;
break;
default:
/* Should this flag an error? */
return retval;
}
if (parseop != PARSEOP_NONE) break;
}
arg = endptr;
while (isspace(*arg) && (*arg != '\0')) arg++;
}
return retval;
} }
/* /*
@ -761,9 +653,7 @@ cmdSaveCell(
if (!tryRename || (fileName == NULL) || (strcmp(cellDef->cd_name, fileName) == 0)) if (!tryRename || (fileName == NULL) || (strcmp(cellDef->cd_name, fileName) == 0))
goto cleanup; goto cleanup;
/* Rename the cell, unless fileName is a .tcl file (scripted output) */ /* Rename the cell */
if ((strlen(fileName) <= 4) || strcmp(fileName + strlen(fileName) - 4, ".tcl"))
{
if (!DBCellRenameDef(cellDef, fileName)) if (!DBCellRenameDef(cellDef, fileName))
{ {
/* This should never happen */ /* This should never happen */
@ -771,7 +661,6 @@ cmdSaveCell(
fileName); fileName);
goto cleanup; goto cleanup;
} }
}
if (EditCellUse && (cellDef == EditCellUse->cu_def)) if (EditCellUse && (cellDef == EditCellUse->cu_def))
{ {
@ -1019,7 +908,7 @@ CmdSetWindCaption(
* edit cell was selected. * edit cell was selected.
*/ */
{ {
int cmdWindSet(MagWindow *window, ClientData clientData); /* UNUSED */ int cmdWindSet(MagWindow *window);
newEditDef = (newEditUse) ? newEditUse->cu_def : NULL; newEditDef = (newEditUse) ? newEditUse->cu_def : NULL;
newRootDef = rootDef; newRootDef = rootDef;
@ -1053,11 +942,9 @@ CmdSetWindCaption(
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
/*ARGSUSED*/
int int
cmdWindSet( cmdWindSet(
MagWindow *window, MagWindow *window)
ClientData clientData) /* UNUSED */
{ {
char caption[200]; char caption[200];
CellDef *wDef; CellDef *wDef;
@ -1241,7 +1128,7 @@ cmdExpandOneLevel(
extern int cmdExpand1func(CellUse *cu, ClientData bitmask); extern int cmdExpand1func(CellUse *cu, ClientData bitmask);
/* first, expand this cell use */ /* first, expand this cell use */
DBExpand(cu, bitmask, expand ? DB_EXPAND : DB_UNEXPAND); DBExpand(cu, bitmask, expand);
/* now, unexpand its direct children (ONE LEVEL ONLY) */ /* now, unexpand its direct children (ONE LEVEL ONLY) */
if (expand) if (expand)
@ -1253,7 +1140,7 @@ cmdExpand1func(
CellUse *cu, CellUse *cu,
ClientData bitmask) ClientData bitmask)
{ {
DBExpand(cu, (int)CD2INT(bitmask), DB_UNEXPAND); DBExpand(cu, (int)CD2INT(bitmask), FALSE);
return 0; return 0;
} }
@ -1309,17 +1196,6 @@ cmdGetSelFunc(
return 1; /* Skip any other selected cells. */ 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;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1352,7 +1228,7 @@ CmdIllegalChars(
for (p = string; *p != 0; p++) for (p = string; *p != 0; p++)
{ {
if (!magic_isascii(*p)) goto error; if (!isascii(*p)) goto error;
if (iscntrl(*p)) goto error; if (iscntrl(*p)) goto error;
for (bad = illegal; *bad != 0; bad++) for (bad = illegal; *bad != 0; bad++)
{ {
@ -1361,7 +1237,7 @@ CmdIllegalChars(
continue; continue;
error: error:
if (!magic_isascii(*p) || iscntrl(*p)) if (!isascii(*p) || iscntrl(*p))
{ {
TxError("%s contains illegal control character 0x%x\n", TxError("%s contains illegal control character 0x%x\n",
msg, *p); msg, *p);

View File

@ -61,9 +61,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
int int
existFunc( existFunc(
Tile *tile, /* (unused) */ Tile *tile)
TileType dinfo, /* (unused) */
ClientData clientdata) /* (unused) */
{ {
return 1; return 1;
} }
@ -455,18 +453,15 @@ CmdTech(
} }
if (!strncmp(cmd->tx_argv[2], "width", 5)) if (!strncmp(cmd->tx_argv[2], "width", 5))
{ {
char *techwidth;
tresult = DRCGetDefaultLayerWidth(t1); tresult = DRCGetDefaultLayerWidth(t1);
techwidth = DBWPrintValue(tresult, w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techwidth, -1)); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
#else #else
TxPrintf("Minimum width is %s\n", techwidth); TxPrintf("Minimum width is %d\n", tresult);
#endif #endif
} }
else if (!strncmp(cmd->tx_argv[2], "spac", 4)) else if (!strncmp(cmd->tx_argv[2], "spac", 4))
{ {
char *techspace;
if (cmd->tx_argc >= 5) if (cmd->tx_argc >= 5)
{ {
t2 = DBTechNoisyNameType(cmd->tx_argv[4]); t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
@ -478,16 +473,14 @@ CmdTech(
else else
t2 = t1; t2 = t1;
tresult = DRCGetDefaultLayerSpacing(t1, t2); tresult = DRCGetDefaultLayerSpacing(t1, t2);
techspace = DBWPrintValue(tresult, w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techspace, -1)); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
#else #else
TxPrintf("Minimum spacing is %s\n", techspace); TxPrintf("Minimum spacing is %d\n", tresult);
#endif #endif
} }
else if (!strncmp(cmd->tx_argv[2], "surr", 4)) else if (!strncmp(cmd->tx_argv[2], "surr", 4))
{ {
char *techsurround;
if (cmd->tx_argc >= 5) if (cmd->tx_argc >= 5)
{ {
t2 = DBTechNoisyNameType(cmd->tx_argv[4]); t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
@ -503,17 +496,14 @@ CmdTech(
} }
tresult = DRCGetDefaultLayerSurround(t1, t2); tresult = DRCGetDefaultLayerSurround(t1, t2);
techsurround = DBWPrintValue(tresult, w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techsurround, -1)); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
#else #else
TxPrintf("Minimum surround is %s\n", techsurround); TxPrintf("Minimum surround is %d\n", tresult);
#endif #endif
} }
else if (!strncmp(cmd->tx_argv[2], "direc", 5)) else if (!strncmp(cmd->tx_argv[2], "direc", 5))
{ {
char *techdirec;
if (cmd->tx_argc >= 5) if (cmd->tx_argc >= 5)
{ {
t2 = DBTechNoisyNameType(cmd->tx_argv[4]); t2 = DBTechNoisyNameType(cmd->tx_argv[4]);
@ -529,11 +519,10 @@ CmdTech(
} }
tresult = DRCGetDirectionalLayerSurround(t1, t2); tresult = DRCGetDirectionalLayerSurround(t1, t2);
techdirec = DBWPrintValue(tresult, w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(techdirec, -1)); Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult));
#else #else
TxPrintf("Minimum surround (in one orientation) is %s\n", techdirec); TxPrintf("Minimum surround (in one orientation) is %d\n", tresult);
#endif #endif
} }
} }
@ -682,15 +671,6 @@ CmdTool(
if (strcmp(cmd->tx_argv[1], "info") == 0) if (strcmp(cmd->tx_argv[1], "info") == 0)
DBWPrintButtonDoc(); 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]); else (void) DBWChangeButtonHandler(cmd->tx_argv[1]);
} }
@ -702,62 +682,32 @@ CmdTool(
* Implement the "unexpand" command. * Implement the "unexpand" command.
* *
* Usage: * Usage:
* unexpand [selection|surround|overlap|all] * unexpand
*
* "selection" unexpands (hides) cells in the selection. All
* other options unexpand cells in the layout. "all" unexpands
* all cells in the layout. "surround" unexpannds cells which
* the cursor box surrounds completely, and "overlap" unexpands
* cells which the cursor box overlaps.
*
* For backwards compatibility:
* "unexpand" alone implements "unexpand surround".
*
* Also see: CmdExpand
* *
* Results: * Results:
* None. * None.
* *
* Side effects: * Side effects:
* Changes the expansion state of cells. * Unexpands all cells under the box that don't completely
* contain the box.
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
#define UNEXPAND_SELECTION 0
#define UNEXPAND_SURROUND 1
#define UNEXPAND_OVERLAP 2
#define UNEXPAND_ALL 3
#define UNEXPAND_HELP 4
void void
CmdUnexpand( CmdUnexpand(
MagWindow *w, MagWindow *w,
TxCommand *cmd) TxCommand *cmd)
{ {
int windowMask, boxMask, option; int windowMask, boxMask;
const char * const *msg;
Rect rootRect; Rect rootRect;
int cmdUnexpandFunc(CellUse *use, int windowMask); /* Forward reference. */ int cmdUnexpandFunc(CellUse *use, int windowMask); /* Forward reference. */
static const char * const cmdUnexpandOption[] = { if (cmd->tx_argc != 1)
"selection expand cell instances in the selection",
"surround expand cell instances which the cursor box surrounds",
"overlap expand cell instances which the cursor box overlaps",
"all expand all cell instances",
NULL
};
if (cmd->tx_argc > 1)
{ {
option = Lookup(cmd->tx_argv[1], cmdUnexpandOption); TxError("Usage: %s\n", cmd->tx_argv[0]);
if (option < 0) option = UNEXPAND_HELP; return;
} }
else
option = UNEXPAND_SURROUND;
if (option == UNEXPAND_HELP) goto badusage;
windCheckOnlyWindow(&w, DBWclientID); windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *) NULL) if (w == (MagWindow *) NULL)
@ -773,42 +723,8 @@ CmdUnexpand(
TxError("The box isn't in the same window as the cursor.\n"); TxError("The box isn't in the same window as the cursor.\n");
return; return;
} }
switch (option)
{
case UNEXPAND_SELECTION:
SelectExpand(windowMask, DB_UNEXPAND, (Rect *)NULL);
break;
case UNEXPAND_OVERLAP:
DBExpandAll(((CellUse *) w->w_surfaceID), &rootRect, windowMask, DBExpandAll(((CellUse *) w->w_surfaceID), &rootRect, windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP, FALSE, cmdUnexpandFunc, (ClientData)(pointertype) windowMask);
cmdUnexpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP,
&rootRect);
break;
case UNEXPAND_SURROUND:
DBExpandAll(((CellUse *)w->w_surfaceID), &rootRect, windowMask,
DB_UNEXPAND | DB_EXPAND_SURROUND,
cmdUnexpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_UNEXPAND | DB_EXPAND_SURROUND,
&rootRect);
break;
case UNEXPAND_ALL:
DBExpandAll(((CellUse *)w->w_surfaceID), &TiPlaneRect, windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP,
cmdUnexpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_UNEXPAND | DB_EXPAND_OVERLAP,
(Rect *)NULL);
break;
}
return;
badusage:
for (msg = &(cmdUnexpandOption[0]); *msg != NULL; msg++)
TxPrintf(" %s\n", *msg);
} }
/* This function is called for each cell whose expansion status changed. /* This function is called for each cell whose expansion status changed.
@ -827,182 +743,6 @@ cmdUnexpandFunc(
return 0; 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]);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1090,8 +830,7 @@ struct linked_id {
int int
cmdWhatPrintCell( cmdWhatPrintCell(
Tile *tile, /* (unused) */ Tile *tile,
TileType dinfo, /* (unused) */
TreeContext *cxp) TreeContext *cxp)
{ {
struct linked_id **lid = (struct linked_id **)cxp->tc_filter->tf_arg; struct linked_id **lid = (struct linked_id **)cxp->tc_filter->tf_arg;
@ -1146,7 +885,6 @@ static LabelStore *labelBlockTop, *labelEntry;
int int
cmdFindWhatTileFunc( cmdFindWhatTileFunc(
Tile *tile, Tile *tile,
TileType dinfo,
ClientData clientData) ClientData clientData)
{ {
struct linked_id **lid = (struct linked_id **)clientData; struct linked_id **lid = (struct linked_id **)clientData;
@ -1158,7 +896,7 @@ cmdFindWhatTileFunc(
scx.scx_use = EditCellUse; scx.scx_use = EditCellUse;
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
if (dinfo & TT_SIDE) if (SplitSide(tile))
type = SplitRightType(tile); type = SplitRightType(tile);
else else
type = SplitLeftType(tile); type = SplitLeftType(tile);
@ -1356,13 +1094,11 @@ CmdWhat(
} }
#endif #endif
free_magic1_t mm1 = freeMagic1_init();
while (lid != NULL) while (lid != NULL)
{ {
freeMagic1(&mm1, lid); freeMagic(lid);
lid = lid->lid_next; lid = lid->lid_next;
} }
freeMagic1_end(&mm1);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
if (doListAll) if (doListAll)
Tcl_ListObjAppendElement(magicinterp, paintobj, Tcl_ListObjAppendElement(magicinterp, paintobj,
@ -1945,20 +1681,18 @@ CmdWire(
case VALUES: case VALUES:
if (locargc == 2) if (locargc == 2)
{ {
char *wdisp;
width = WireGetWidth(); width = WireGetWidth();
type = WireGetType(); type = WireGetType();
wdisp = DBWPrintValue(width, w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
lobj = Tcl_NewListObj(0, NULL); lobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(DBTypeLongNameTbl[type], -1)); Tcl_NewIntObj(width));
Tcl_ListObjAppendElement(magicinterp, lobj, Tcl_ListObjAppendElement(magicinterp, lobj,
Tcl_NewStringObj(wdisp, -1)); Tcl_NewStringObj(DBTypeLongNameTbl[type], -1));
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("Wire layer %s, width %s\n", TxPrintf("Wire layer %s, width %d\n",
DBTypeLongNameTbl[type], wdisp); DBTypeLongNameTbl[type], width);
#endif #endif
} }
break; break;
@ -1983,14 +1717,12 @@ CmdWire(
case WIDTH: case WIDTH:
if (locargc == 2) if (locargc == 2)
{ {
char *wdisp;
width = WireGetWidth(); width = WireGetWidth();
wdisp = DBWPrintValue(width, w, TRUE);
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
lobj = Tcl_NewStringObj(wdisp, -1); lobj = Tcl_NewIntObj(width);
Tcl_SetObjResult(magicinterp, lobj); Tcl_SetObjResult(magicinterp, lobj);
#else #else
TxPrintf("Wire width is %s\n", wdisp); TxPrintf("Wire width is %d\n", width);
#endif #endif
} }
else if (locargc != 3) else if (locargc != 3)
@ -2213,7 +1945,7 @@ CmdWriteall(
option = Lookup(cmd->tx_argv[1], writeallOpts); option = Lookup(cmd->tx_argv[1], writeallOpts);
if (option < 0) if (option < 0)
{ {
TxError("Usage: %s [force|modified [cellname ...]]\n", TxError("Usage: %s [force|modified|noupdate [cellname ...]]\n",
cmd->tx_argv[0]); cmd->tx_argv[0]);
return; return;
} }

View File

@ -47,10 +47,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "utils/utils.h" #include "utils/utils.h"
#include "textio/txcommands.h" #include "textio/txcommands.h"
/* For diagnostics */
#include "cif/CIFint.h"
#include "database/databaseInt.h"
/* C99 compat */ /* C99 compat */
#include "extract/extract.h" #include "extract/extract.h"
@ -193,234 +189,6 @@ CmdExtractTest(
} }
#endif #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);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -464,7 +232,7 @@ showTech(
fprintf(outf, "\n"); fprintf(outf, "\n");
fprintf(outf, "Types:\n"); fprintf(outf, "Types:\n");
for (i = 0; i < DBNumTypes; i++) { for (i = 0; i < DBNumTypes; i++) {
int pl ; const char *spl ; int pl ; char *spl ;
pl = DBPlane(i); pl = DBPlane(i);
spl = ( pl <= 0 || pl > DBNumPlanes ) ? "??" : DBPlaneLongName(pl); spl = ( pl <= 0 || pl > DBNumPlanes ) ? "??" : DBPlaneLongName(pl);
@ -801,13 +569,11 @@ cmdStatsCount(
CellDef *def, CellDef *def,
struct countClient *cc) struct countClient *cc)
{ {
int cmdStatsCountTile(Tile *tile, struct cellInfo *ci);
int pNum; int pNum;
struct cellInfo *ci; struct cellInfo *ci;
TileType t; TileType t;
/* Forward declaration */
int cmdStatsCountTile(Tile *tile, TileType dinfo, struct cellInfo *ci);
if (def->cd_client) if (def->cd_client)
return (1); return (1);
@ -832,7 +598,6 @@ cmdStatsCount(
int int
cmdStatsCountTile( cmdStatsCountTile(
Tile *tile, Tile *tile,
TileType dinfo, /* (unused) */
struct cellInfo *ci) struct cellInfo *ci)
{ {
TileType type = TiGetType(tile); TileType type = TiGetType(tile);
@ -1103,18 +868,17 @@ CmdTsearch(
MagWindow *w, MagWindow *w,
TxCommand *cmd) TxCommand *cmd)
{ {
int cmdTsrFunc(Tile *tp);
char *RunStats(int flags, struct tms *lastt, struct tms *deltat);
char *rstatp; char *rstatp;
static TileTypeBitMask mask; static TileTypeBitMask mask;
static struct tms tlast, tdelta; static struct tms tlast, tdelta;
Rect rtool, rsearch; Rect rtool, rsearch;
/**** Rect *ebox; ****/
Plane *plane; Plane *plane;
int i, pNum, count; int i, pNum, count;
int usPerSearch, usPerTile, usPerL2, us, boxarea; 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) if (cmd->tx_argc < 3 || cmd->tx_argc > 5)
{ {
TxError("Usage: tsearch plane count [mask [new|mayo]]\n"); TxError("Usage: tsearch plane count [mask [new|mayo]]\n");
@ -1214,12 +978,10 @@ CmdTsearch(
int int
cmdTsrFunc( cmdTsrFunc(
Tile *tp, Tile *tp)
TileType dinfo, /* (unused) */
ClientData clientdata) /* (unused) */
{ {
if (cmdTsearchDebug) if (cmdTsearchDebug)
TxPrintf("%lx\n", (intptr_t) tp); TxPrintf("%lx\n", (intmax_t) tp);
numTilesFound++; numTilesFound++;
return 0; return 0;
} }
@ -1285,7 +1047,7 @@ CmdWatch(
pNum = DBTechNamePlane(cmd->tx_argv[1]); pNum = DBTechNamePlane(cmd->tx_argv[1]);
if (pNum < 0) if (pNum < 0)
{ {
const char *cp; char *cp;
TxError("Unrecognized plane: %s. Legal names are:\n", TxError("Unrecognized plane: %s. Legal names are:\n",
cmd->tx_argv[1]); cmd->tx_argv[1]);
for(pNum=0; pNum < PL_MAXTYPES; pNum++) { for(pNum=0; pNum < PL_MAXTYPES; pNum++) {

View File

@ -12,9 +12,10 @@ SRCS = CmdSubrs.c CmdAB.c CmdCD.c CmdE.c CmdFI.c \
module: ${MAGICDIR}/readline/readline lib${MODULE}.o module: ${MAGICDIR}/readline/readline lib${MODULE}.o
# Delegate this task to the readline/Makefile
${MAGICDIR}/readline/readline: ${MAGICDIR}/readline/readline:
${MAKE} -C ${MAGICDIR}/readline readline-create-symlinks @if ( ! test -f ${MAGICDIR}/readline/readline ) ; then \
(cd ${MAGICDIR}/readline; ln -s `ls | grep readline` readline) ; \
fi
include ${MAGICDIR}/defs.mak include ${MAGICDIR}/defs.mak
include ${MAGICDIR}/rules.mak include ${MAGICDIR}/rules.mak

View File

@ -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 $ * rcsid $Header: /usr/cvsroot/magic-8.0/commands/commands.h,v 1.3 2009/01/19 15:43:03 tim Exp $
*/ */
#ifndef _MAGIC__COMMANDS__COMMANDS_H #ifndef _COMMANDS_H
#define _MAGIC__COMMANDS__COMMANDS_H #define _COMMANDS_H
#include "windows/windows.h" #include "windows/windows.h"
#include "database/database.h" #include "database/database.h"
@ -72,7 +72,7 @@ extern int cmdParseCoord(MagWindow *w, char *arg, bool is_relative, bool is_x);
extern void cmdSaveCell(CellDef *cellDef, char *newName, bool noninteractive, bool tryRename); extern void cmdSaveCell(CellDef *cellDef, char *newName, bool noninteractive, bool tryRename);
extern void CmdInit(void); extern void CmdInit(void);
extern void CmdDoProperty(CellDef *def, MagWindow *w, TxCommand *cmd, int argstart); extern void CmdDoProperty(CellDef *def, TxCommand *cmd, int argstart);
extern void CmdPaintEraseButton(MagWindow *w, Point *refPoint, bool isPaint, bool isScreen); extern void CmdPaintEraseButton(MagWindow *w, Point *refPoint, bool isPaint, bool isScreen);
#endif /* _MAGIC__COMMANDS__COMMANDS_H */ #endif /* _COMMANDS_H */

2
configure vendored
View File

@ -9,4 +9,4 @@
# script itself. It also sets up CFLAGS without the default optimizer # script itself. It also sets up CFLAGS without the default optimizer
# flag (-O2). # flag (-O2).
( CFLAGS=${CFLAGS:-"-g"}; export CFLAGS; cd scripts ; ./configure "$@" ) ( CFLAGS="-g"; export CFLAGS; cd scripts ; ./configure "$@" )

View File

@ -30,32 +30,19 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
typedef struct dbcellboundstruct typedef struct dbcellboundstruct
{ {
Rect *area; Rect *area;
Rect *extended; bool extended;
bool found; bool found;
} DBCellBoundStruct; } 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 int
DBBoundCellPlane(def, extended, rect) DBBoundCellPlane(def, extended, rect)
CellDef *def; CellDef *def;
Rect *extended; bool extended;
Rect *rect; Rect *rect;
{ {
TreeFilter filter; TreeFilter filter;
@ -83,18 +70,24 @@ dbCellBoundFunc(use, fp)
CellUse *use; CellUse *use;
TreeFilter *fp; TreeFilter *fp;
{ {
Rect *bbox;
DBCellBoundStruct *cbs; DBCellBoundStruct *cbs;
cbs = (DBCellBoundStruct *)fp->tf_arg; cbs = (DBCellBoundStruct *)fp->tf_arg;
bbox = &use->cu_bbox;
if (cbs->found) if (cbs->found)
{ {
GeoInclude(&use->cu_extended, cbs->extended); if (cbs->extended)
GeoInclude(&use->cu_extended, cbs->area);
else
GeoInclude(&use->cu_bbox, cbs->area); GeoInclude(&use->cu_bbox, cbs->area);
} }
else else
{ {
*cbs->extended = use->cu_extended; if (cbs->extended)
*cbs->area = use->cu_extended;
else
*cbs->area = use->cu_bbox; *cbs->area = use->cu_bbox;
cbs->found = TRUE; cbs->found = TRUE;
} }

View File

@ -108,55 +108,16 @@ DBCellFindDup(use, parent)
"DBCellFindDup"); "DBCellFindDup");
while ((dupUse = BPEnumNext(&bpe))) while ((dupUse = BPEnumNext(&bpe)))
if (dupUse->cu_def == use->cu_def) if (dupUse->cu_def == use->cu_def)
{
bool transMatch, arrayMatch, notXarray, notYarray;
/* Transforms must be equal---Aligned bounding boxes are /* Transforms must be equal---Aligned bounding boxes are
* an insufficient measure of exact overlap. Also, array * an insufficient measure of exact overlap.
* counts and separation must match for arrayed devices
*/ */
transMatch = ((dupUse->cu_transform.t_a == use->cu_transform.t_a) && if ((dupUse->cu_transform.t_a == use->cu_transform.t_a) &&
(dupUse->cu_transform.t_b == use->cu_transform.t_b) && (dupUse->cu_transform.t_b == use->cu_transform.t_b) &&
(dupUse->cu_transform.t_c == use->cu_transform.t_c) && (dupUse->cu_transform.t_c == use->cu_transform.t_c) &&
(dupUse->cu_transform.t_d == use->cu_transform.t_d) && (dupUse->cu_transform.t_d == use->cu_transform.t_d) &&
(dupUse->cu_transform.t_e == use->cu_transform.t_e) && (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; break;
}
BPEnumTerm(&bpe); BPEnumTerm(&bpe);
return dupUse; return dupUse;

View File

@ -59,15 +59,15 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
*/ */
char * char *
DBPrintUseId( DBPrintUseId(scx, name, size, display_only)
SearchContext *scx, /* Pointer to current search context, specifying a SearchContext *scx; /* Pointer to current search context, specifying a
* cell use and X,Y array indices. * cell use and X,Y array indices.
*/ */
char *name, /* Pointer to string into which we will copy the char *name; /* Pointer to string into which we will copy the
* print name of this instance. * print name of this instance.
*/ */
int size, /* Maximum number of characters to copy into string. */ int size; /* Maximum number of characters to copy into string. */
bool display_only) /* TRUE if called for displaying only */ bool display_only; /* TRUE if called for displaying only */
{ {
CellUse *use = scx->scx_use; CellUse *use = scx->scx_use;
char *sp, *id, *ep; char *sp, *id, *ep;
@ -619,8 +619,7 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
/* /*
* Include area of subcells separately * Include area of subcells separately
*/ */
if (!((foundAny = DBBoundCellPlane(cellDef, &extended, &rect)) > 0)) if ((foundAny = DBBoundCellPlane(cellDef, TRUE, &rect)) > 0)
extended = GeoNullRect;
area = rect; area = rect;
for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++) for (pNum = PL_PAINTBASE; pNum < DBNumPlanes; pNum++)
@ -635,7 +634,7 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
} }
/* /*
* Include the area of label anchors, too. * Include the area of labels, too.
*/ */
for (label = cellDef->cd_labels; label != NULL; label = label->lab_next) for (label = cellDef->cd_labels; label != NULL; label = label->lab_next)
{ {
@ -657,11 +656,7 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
} }
} }
/* Make sure the extended bounding box includes the area of all extended = area;
* paint material just found, then include the area of all text
* in the current cell.
*/
GeoInclude(&area, &extended);
if (foundAny) if (foundAny)
{ {
for (label = cellDef->cd_labels; label != NULL; label = label->lab_next) for (label = cellDef->cd_labels; label != NULL; label = label->lab_next)
@ -678,7 +673,6 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
degenerate = TRUE; degenerate = TRUE;
area.r_xbot = area.r_ybot = 0; area.r_xbot = area.r_ybot = 0;
area.r_xtop = area.r_ytop = 1; area.r_xtop = area.r_ytop = 1;
extended = area;
} }
else degenerate = FALSE; else degenerate = FALSE;
@ -693,11 +687,7 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
if (area.r_ybot == area.r_ytop) if (area.r_ybot == area.r_ytop)
area.r_ytop = area.r_ybot + 1; area.r_ytop = area.r_ybot + 1;
if (extended.r_xbot == extended.r_xtop) if (degenerate) extended = area;
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 /* Did the bounding box change? If not then there's no need to
* recompute the parents. If the cell has no material, then * recompute the parents. If the cell has no material, then

View File

@ -37,8 +37,9 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "windows/windows.h" #include "windows/windows.h"
#include "dbwind/dbwind.h" #include "dbwind/dbwind.h"
#include "commands/commands.h" #include "commands/commands.h"
/* C99 compat */
#include "graphics/graphics.h" #include "graphics/graphics.h"
#include "cif/CIFint.h"
/* /*
* The following variable points to the tables currently used for * The following variable points to the tables currently used for
@ -356,43 +357,9 @@ DBCellCheckCopyAllPaint(scx, mask, xMask, targetUse, func)
struct propUseDefStruct { struct propUseDefStruct {
CellDef *puds_source; CellDef *puds_source;
CellDef *puds_dest; CellDef *puds_dest;
Plane *puds_plane; /* Mask hint plane in dest */
Transform *puds_trans; /* Transform from source use to dest */ Transform *puds_trans; /* Transform from source use to dest */
Rect *puds_area; /* Clip area in source coordinates */
}; };
/*
*-----------------------------------------------------------------------------
*
* dbCopyMaskHintPlaneFunc --
*
* Translate tiles from a child mask-hint property plane into the
* coordinate system of the parent, and paint the mask-hint area
* into the mask-hint property plane of the parent.
*
*-----------------------------------------------------------------------------
*/
int
dbCopyMaskHintPlaneFunc(Tile *tile,
TileType dinfo,
struct propUseDefStruct *puds)
{
Transform *trans = puds->puds_trans;
Rect *clip = puds->puds_area;
Rect r, rnew;
Plane *plane = puds->puds_plane;
TiToRect(tile, &r);
GeoClip(&r, clip);
if (!GEO_RECTNULL(&r))
{
GeoTransRect(trans, &r, &rnew);
DBPaintPlane(plane, &rnew, CIFPaintTable, (PaintUndoInfo *)NULL);
}
return 0;
}
/* /*
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
* *
@ -413,52 +380,63 @@ dbCopyMaskHintPlaneFunc(Tile *tile,
*/ */
int int
dbCopyMaskHintsFunc(key, proprec, puds) dbCopyMaskHintsFunc(key, value, puds)
char *key; char *key;
PropertyRecord *proprec; ClientData value;
struct propUseDefStruct *puds; struct propUseDefStruct *puds;
{ {
CellDef *dest = puds->puds_dest; CellDef *dest = puds->puds_dest;
Transform *trans = puds->puds_trans; Transform *trans = puds->puds_trans;
Rect *clip = puds->puds_area; char *propstr = (char *)value;
PropertyRecord *parentproprec, *newproprec;
char *parentprop, *newvalue, *vptr; char *parentprop, *newvalue, *vptr;
Rect r, rnew; Rect r, rnew;
bool propfound; bool propfound;
int i, j;
if (!strncmp(key, "MASKHINTS_", 10)) if (!strncmp(key, "MASKHINTS_", 10))
{ {
char *vptr, *lastval; char *vptr, *lastval;
int lastlen; int lastlen;
Plane *plane;
ASSERT(proprec->prop_type == PROPERTY_TYPE_PLANE, "dbCopyMaskHintsFunc"); /* Append to existing mask hint (if any) */
parentprop = (char *)DBPropGet(dest, key, &propfound);
newvalue = (propfound) ? StrDup((char **)NULL, parentprop) : (char *)NULL;
/* Get the existing mask hint plane in the parent cell, and vptr = propstr;
* create it if it does not already exist. while (*vptr != '\0')
*/
parentproprec = (PropertyRecord *)DBPropGet(dest, key, &propfound);
if (propfound)
plane = parentproprec->prop_value.prop_plane;
else
{ {
newproprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord)); if (sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
newproprec->prop_type = PROPERTY_TYPE_PLANE; &r.r_xtop, &r.r_ytop) == 4)
newproprec->prop_len = 0; {
plane = DBNewPlane((ClientData)TT_SPACE); GeoTransRect(trans, &r, &rnew);
newproprec->prop_value.prop_plane = plane;
DBPropPut(dest, key, newproprec);
}
puds->puds_plane = plane;
/* Copy the properties from child to parent */ lastval = newvalue;
DBSrPaintArea(PlaneGetHint(proprec->prop_value.prop_plane), lastlen = (lastval) ? strlen(lastval) : 0;
proprec->prop_value.prop_plane, newvalue = mallocMagic(40 + lastlen);
clip, &CIFSolidBits, dbCopyMaskHintPlaneFunc,
(ClientData)puds); if (lastval)
strcpy(newvalue, lastval);
else
*newvalue = '\0';
sprintf(newvalue + lastlen, "%s%d %d %d %d", (lastval) ? " " : "",
rnew.r_xbot, rnew.r_ybot, rnew.r_xtop, rnew.r_ytop);
if (lastval) freeMagic(lastval);
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
} }
else break;
}
if (newvalue)
DBPropPut(dest, key, newvalue);
}
return 0; return 0;
} }
@ -490,7 +468,6 @@ DBCellCopyMaskHints(child, parent, transform)
puds.puds_source = child->cu_def; puds.puds_source = child->cu_def;
puds.puds_dest = parent; puds.puds_dest = parent;
puds.puds_trans = transform; puds.puds_trans = transform;
puds.puds_area = (Rect *)&TiPlaneRect;
DBPropEnum(child->cu_def, dbCopyMaskHintsFunc, (ClientData)&puds); DBPropEnum(child->cu_def, dbCopyMaskHintsFunc, (ClientData)&puds);
} }
@ -524,7 +501,6 @@ dbFlatCopyMaskHintsFunc(scx, def)
puds.puds_source = scx->scx_use->cu_def; puds.puds_source = scx->scx_use->cu_def;
puds.puds_dest = def; puds.puds_dest = def;
puds.puds_trans = &scx->scx_trans; puds.puds_trans = &scx->scx_trans;
puds.puds_area = &scx->scx_area;
DBPropEnum(use->cu_def, dbCopyMaskHintsFunc, (ClientData)&puds); DBPropEnum(use->cu_def, dbCopyMaskHintsFunc, (ClientData)&puds);
@ -991,15 +967,14 @@ DBCellGenerateSimpleSubstrate(scx, subType, notSubMask, targetDef)
*/ */
int int
dbEraseSubFunc(tile, dinfo, cxp) dbEraseSubFunc(tile, cxp)
Tile *tile; /* Pointer to source tile with shield type */ Tile *tile; /* Pointer to source tile with shield type */
TileType dinfo; /* Split tile information */
TreeContext *cxp; /* Context from DBTreeSrTiles */ TreeContext *cxp; /* Context from DBTreeSrTiles */
{ {
SearchContext *scx; SearchContext *scx;
Rect sourceRect, targetRect; Rect sourceRect, targetRect;
int pNum; int pNum;
TileType newdinfo, loctype, subType; TileType type, loctype, subType;
Plane *plane; Plane *plane;
struct dbCopySubData *csd; /* Client data */ struct dbCopySubData *csd; /* Client data */
@ -1008,14 +983,12 @@ dbEraseSubFunc(tile, dinfo, cxp)
plane = csd->csd_plane; plane = csd->csd_plane;
pNum = csd->csd_pNum; pNum = csd->csd_pNum;
subType = csd->csd_subtype; subType = csd->csd_subtype;
type = TiGetTypeExact(tile);
if (IsSplit(tile)) if (IsSplit(tile))
{ {
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
if (loctype == TT_SPACE) return 0; if (loctype == TT_SPACE) return 0;
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans);
} }
else
newdinfo = (TileType)0;
/* Construct the rect for the tile */ /* Construct the rect for the tile */
TITORECT(tile, &sourceRect); TITORECT(tile, &sourceRect);
@ -1025,7 +998,7 @@ dbEraseSubFunc(tile, dinfo, cxp)
csd->csd_modified = TRUE; csd->csd_modified = TRUE;
return DBNMPaintPlane(plane, newdinfo, &targetRect, DBStdEraseTbl(subType, pNum), return DBNMPaintPlane(plane, type, &targetRect, DBStdEraseTbl(subType, pNum),
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
} }
@ -1037,15 +1010,14 @@ dbEraseSubFunc(tile, dinfo, cxp)
*/ */
int int
dbPaintSubFunc(tile, dinfo, cxp) dbPaintSubFunc(tile, cxp)
Tile *tile; /* Pointer to source tile with shield type */ Tile *tile; /* Pointer to source tile with shield type */
TileType dinfo; /* Split tile information */
TreeContext *cxp; /* Context from DBTreeSrTiles */ TreeContext *cxp; /* Context from DBTreeSrTiles */
{ {
SearchContext *scx; SearchContext *scx;
Rect sourceRect, targetRect; Rect sourceRect, targetRect;
int pNum; int pNum;
TileType newdinfo, loctype, subType; TileType type, loctype, subType;
Plane *plane; Plane *plane;
struct dbCopySubData *csd; /* Client data */ struct dbCopySubData *csd; /* Client data */
@ -1054,14 +1026,12 @@ dbPaintSubFunc(tile, dinfo, cxp)
plane = csd->csd_plane; plane = csd->csd_plane;
pNum = csd->csd_pNum; pNum = csd->csd_pNum;
subType = csd->csd_subtype; subType = csd->csd_subtype;
type = TiGetTypeExact(tile);
if (IsSplit(tile)) if (IsSplit(tile))
{ {
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
if (loctype == TT_SPACE) return 0; if (loctype == TT_SPACE) return 0;
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans);
} }
else
newdinfo = (TileType)0;
/* Construct the rect for the tile */ /* Construct the rect for the tile */
TITORECT(tile, &sourceRect); TITORECT(tile, &sourceRect);
@ -1071,7 +1041,7 @@ dbPaintSubFunc(tile, dinfo, cxp)
csd->csd_modified = TRUE; csd->csd_modified = TRUE;
return DBNMPaintPlane(plane, newdinfo, &targetRect, DBStdPaintTbl(subType, pNum), return DBNMPaintPlane(plane, type, &targetRect, DBStdPaintTbl(subType, pNum),
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
} }
@ -1084,15 +1054,14 @@ dbPaintSubFunc(tile, dinfo, cxp)
*/ */
int int
dbEraseNonSub(tile, dinfo, cxp) dbEraseNonSub(tile, cxp)
Tile *tile; /* Pointer to tile to erase from target */ Tile *tile; /* Pointer to tile to erase from target */
TileType dinfo; /* Split tile information */
TreeContext *cxp; /* Context from DBTreeSrTiles */ TreeContext *cxp; /* Context from DBTreeSrTiles */
{ {
SearchContext *scx; SearchContext *scx;
Rect sourceRect, targetRect; Rect sourceRect, targetRect;
Plane *plane; /* Plane of target data */ Plane *plane; /* Plane of target data */
TileType newdinfo, loctype, subType; TileType type, loctype, subType;
struct dbCopySubData *csd; struct dbCopySubData *csd;
int pNum; int pNum;
@ -1103,14 +1072,12 @@ dbEraseNonSub(tile, dinfo, cxp)
scx = cxp->tc_scx; scx = cxp->tc_scx;
type = TiGetTypeExact(tile);
if (IsSplit(tile)) if (IsSplit(tile))
{ {
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
if (loctype == TT_SPACE) return 0; if (loctype == TT_SPACE) return 0;
newdinfo = DBTransformDiagonal(TiGetTypeExact(tile) | dinfo, &scx->scx_trans);
} }
else
newdinfo = (TileType)0;
/* Construct the rect for the tile */ /* Construct the rect for the tile */
TITORECT(tile, &sourceRect); TITORECT(tile, &sourceRect);
@ -1119,7 +1086,7 @@ dbEraseNonSub(tile, dinfo, cxp)
GEOTRANSRECT(&scx->scx_trans, &sourceRect, &targetRect); GEOTRANSRECT(&scx->scx_trans, &sourceRect, &targetRect);
/* Erase the substrate type from the area of this tile in the target plane. */ /* Erase the substrate type from the area of this tile in the target plane. */
return DBNMPaintPlane(plane, newdinfo, &targetRect, DBStdEraseTbl(subType, pNum), return DBNMPaintPlane(plane, type, &targetRect, DBStdEraseTbl(subType, pNum),
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
} }
@ -1131,9 +1098,8 @@ dbEraseNonSub(tile, dinfo, cxp)
*/ */
int int
dbCopySubFunc(tile, dinfo, csd) dbCopySubFunc(tile, csd)
Tile *tile; /* Pointer to tile to erase from target */ Tile *tile; /* Pointer to tile to erase from target */
TileType dinfo; /* Split tile information */
struct dbCopySubData *csd; /* Client data */ struct dbCopySubData *csd; /* Client data */
{ {
Rect rect; Rect rect;
@ -1143,10 +1109,10 @@ dbCopySubFunc(tile, dinfo, csd)
plane = csd->csd_plane; plane = csd->csd_plane;
pNum = csd->csd_pNum; pNum = csd->csd_pNum;
type = TiGetTypeExact(tile) | dinfo; type = TiGetTypeExact(tile);
if (IsSplit(tile)) if (IsSplit(tile))
{ {
loctype = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
if (loctype == TT_SPACE) return 0; if (loctype == TT_SPACE) return 0;
} }
else else
@ -1467,9 +1433,8 @@ DBCellCopyLabels(scx, mask, xMask, targetUse, pArea)
***/ ***/
int int
dbCopyManhattanPaint(tile, dinfo, cxp) dbCopyManhattanPaint(tile, cxp)
Tile *tile; /* Pointer to tile to copy */ Tile *tile; /* Pointer to tile to copy */
TileType dinfo; /* Split tile information */
TreeContext *cxp; /* Context from DBTreeSrTiles */ TreeContext *cxp; /* Context from DBTreeSrTiles */
{ {
SearchContext *scx = cxp->tc_scx; SearchContext *scx = cxp->tc_scx;
@ -1515,9 +1480,8 @@ dbCopyManhattanPaint(tile, dinfo, cxp)
***/ ***/
int int
dbCopyAllPaint(tile, dinfo, cxp) dbCopyAllPaint(tile, cxp)
Tile *tile; /* Pointer to tile to copy */ Tile *tile; /* Pointer to tile to copy */
TileType dinfo; /* Split tile information */
TreeContext *cxp; /* Context from DBTreeSrTiles */ TreeContext *cxp; /* Context from DBTreeSrTiles */
{ {
SearchContext *scx = cxp->tc_scx; SearchContext *scx = cxp->tc_scx;
@ -1525,7 +1489,7 @@ dbCopyAllPaint(tile, dinfo, cxp)
Rect sourceRect, targetRect; Rect sourceRect, targetRect;
PaintUndoInfo ui; PaintUndoInfo ui;
CellDef *def; CellDef *def;
TileType type = TiGetTypeExact(tile) | dinfo; TileType type = TiGetTypeExact(tile);
int pNum = cxp->tc_plane; int pNum = cxp->tc_plane;
int result; int result;
TileTypeBitMask *typeMask; TileTypeBitMask *typeMask;
@ -1538,13 +1502,13 @@ dbCopyAllPaint(tile, dinfo, cxp)
*/ */
bool splittile = FALSE; bool splittile = FALSE;
TileType newdinfo = 0; TileType dinfo = 0;
if (IsSplit(tile)) if (IsSplit(tile))
{ {
splittile = TRUE; splittile = TRUE;
newdinfo = DBTransformDiagonal(type, &scx->scx_trans); dinfo = DBTransformDiagonal(type, &scx->scx_trans);
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : type = (SplitSide(tile)) ? SplitRightType(tile) :
SplitLeftType(tile); SplitLeftType(tile);
} }
@ -1604,7 +1568,7 @@ dbCopyAllPaint(tile, dinfo, cxp)
Rect rrect, orect; Rect rrect, orect;
int np, i, j; int np, i, j;
GrClipTriangle(&targetRect, &arg->caa_rect, TRUE, newdinfo, points, &np); GrClipTriangle(&targetRect, &arg->caa_rect, TRUE, dinfo, points, &np);
if (np == 0) if (np == 0)
return(0); return(0);
@ -1633,7 +1597,7 @@ dbCopyAllPaint(tile, dinfo, cxp)
rrect.r_ybot = points[0].p_y; rrect.r_ybot = points[0].p_y;
rrect.r_ytop = points[2].p_y; rrect.r_ytop = points[2].p_y;
GeoCanonicalRect(&rrect, &targetRect); GeoCanonicalRect(&rrect, &targetRect);
newdinfo = 0; dinfo = 0;
} }
else if (np >= 4) /* Process extra rectangles in the area */ else if (np >= 4) /* Process extra rectangles in the area */
{ {
@ -1690,7 +1654,7 @@ topbottom:
splitdone: splitdone:
result = (*dbCurPaintPlane)(def, pNum, newdinfo | type, &targetRect, &ui); result = (*dbCurPaintPlane)(def, pNum, dinfo | type, &targetRect, &ui);
if ((result != 0) && (arg->caa_func != NULL)) if ((result != 0) && (arg->caa_func != NULL))
{ {
/* result == 1 used exclusively for DRC off-grid error flagging */ /* result == 1 used exclusively for DRC off-grid error flagging */

View File

@ -117,14 +117,6 @@ DBCellRename(cellname, newname, doforce)
return FALSE; 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, */ /* Disallow renaming if the cell has the READONLY flag set, */
/* because the cellname must match the name in the GDS */ /* because the cellname must match the name in the GDS */
/* file referenced. */ /* file referenced. */
@ -152,9 +144,10 @@ DBCellRename(cellname, newname, doforce)
if (doforce && ((celldef->cd_flags & CDVENDORGDS) == CDVENDORGDS)) if (doforce && ((celldef->cd_flags & CDVENDORGDS) == CDVENDORGDS))
{ {
char *chkgdsfile;
bool isReadOnly; bool isReadOnly;
DBPropGet(celldef, "GDS_FILE", &isReadOnly); chkgdsfile = (char *)DBPropGet(celldef, "GDS_FILE", &isReadOnly);
/* Note that clearing GDS_FILE will also clear CDVENDORGDS flag */ /* Note that clearing GDS_FILE will also clear CDVENDORGDS flag */
if (isReadOnly) DBPropPut(celldef, "GDS_FILE", NULL); if (isReadOnly) DBPropPut(celldef, "GDS_FILE", NULL);
@ -295,7 +288,7 @@ DBCellDelete(cellname, force)
if ((force == FALSE) && if ((force == FALSE) &&
(celldef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED))) (celldef->cd_flags & (CDMODIFIED|CDBOXESCHANGED|CDSTAMPSCHANGED)))
{ {
static const char *yesno[] = { "no", "yes", 0 }; static char *yesno[] = { "no", "yes", 0 };
int code; int code;
char *prompt = TxPrintString("Cell %s has been modified.\n Do you" char *prompt = TxPrintString("Cell %s has been modified.\n Do you"
" want to delete it and lose all changes? ", " want to delete it and lose all changes? ",
@ -319,7 +312,6 @@ DBCellDelete(cellname, force)
/* use. If so, load the window with (UNNAMED). */ /* use. If so, load the window with (UNNAMED). */
UndoDisable(); UndoDisable();
free_magic1_t mm1 = freeMagic1_init();
for (celluse = celldef->cd_parents; celluse != (CellUse *) NULL; for (celluse = celldef->cd_parents; celluse != (CellUse *) NULL;
celluse = celluse->cu_nextuse) celluse = celluse->cu_nextuse)
{ {
@ -328,9 +320,8 @@ DBCellDelete(cellname, force)
WindUnload(celluse); WindUnload(celluse);
freeMagic(celluse->cu_id); freeMagic(celluse->cu_id);
} }
freeMagic1(&mm1, (char *)celluse); freeMagic((char *)celluse);
} }
freeMagic1_end(&mm1);
celldef->cd_parents = (CellUse *)NULL; celldef->cd_parents = (CellUse *)NULL;
DBWResetBox(celldef); DBWResetBox(celldef);
@ -1619,9 +1610,7 @@ dbAbutmentUseFunc(selUse, use, transform, data)
{ {
Rect bbox, refbox; Rect bbox, refbox;
Transform *trans; Transform *trans;
PropertyRecord *proprec;
char *propvalue; char *propvalue;
char *refllx, *reflly, *refurx, *refury;
bool found; bool found;
bool *dolist = (bool *)data; bool *dolist = (bool *)data;
@ -1643,47 +1632,32 @@ dbAbutmentUseFunc(selUse, use, transform, data)
} }
trans = &use->cu_transform; trans = &use->cu_transform;
proprec = DBPropGet(use->cu_def, "FIXED_BBOX", &found); propvalue = (char *)DBPropGet(use->cu_def, "FIXED_BBOX", &found);
if (!found) if (!found)
bbox = use->cu_def->cd_bbox; bbox = use->cu_def->cd_bbox;
else else
{ {
if ((proprec->prop_type == PROPERTY_TYPE_DIMENSION) && if (sscanf(propvalue, "%d %d %d %d", &bbox.r_xbot, &bbox.r_ybot,
(proprec->prop_len == 4)) &bbox.r_xtop, &bbox.r_ytop) != 4)
{
bbox.r_xbot = proprec->prop_value.prop_integer[0];
bbox.r_ybot = proprec->prop_value.prop_integer[1];
bbox.r_xtop = proprec->prop_value.prop_integer[2];
bbox.r_ytop = proprec->prop_value.prop_integer[3];
}
else
{
TxError("Unable to parse the cell's FIXED_BBOX property; using "
"the instance bounding box instead.\n");
bbox = use->cu_def->cd_bbox; bbox = use->cu_def->cd_bbox;
} }
}
GeoTransRect(trans, &bbox, &refbox); 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 #ifdef MAGIC_WRAPPER
if (*dolist) if (*dolist)
{ {
pobj = Tcl_NewListObj(0, NULL); pobj = Tcl_NewListObj(0, NULL);
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refllx, -1)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_xbot));
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(reflly, -1)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_ybot));
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refurx, -1)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_xtop));
Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewStringObj(refury, -1)); Tcl_ListObjAppendElement(magicinterp, pobj, Tcl_NewIntObj(refbox.r_ytop));
Tcl_SetObjResult(magicinterp, pobj); Tcl_SetObjResult(magicinterp, pobj);
} }
else else
#endif #endif
TxPrintf("Abutment box: %s %s %s %s\n", refllx, reflly, refurx, refury); TxPrintf("Abutment box: %d %d %d %d\n", refbox.r_xbot, refbox.r_ybot,
refbox.r_xtop, refbox.r_ytop);
return 0; return 0;
} }
@ -1962,7 +1936,6 @@ DBCellDeleteDef(cellDef)
entry = HashFind(&dbCellDefTable, cellDef->cd_name); entry = HashFind(&dbCellDefTable, cellDef->cd_name);
ASSERT(HashGetValue(entry) == (ClientData) cellDef, "DBCellDeleteDef"); ASSERT(HashGetValue(entry) == (ClientData) cellDef, "DBCellDeleteDef");
HashSetValue(entry, (ClientData) NULL); HashSetValue(entry, (ClientData) NULL);
HashRemove(&dbCellDefTable, cellDef->cd_name);
if (cellDef->cd_props) if (cellDef->cd_props)
DBPropClearAll(cellDef); DBPropClearAll(cellDef);
@ -2024,10 +1997,8 @@ DBCellDefFree(cellDef)
cellDef->cd_planes[pNum] = (Plane *) NULL; cellDef->cd_planes[pNum] = (Plane *) NULL;
} }
free_magic1_t mm1 = freeMagic1_init();
for (lab = cellDef->cd_labels; lab; lab = lab->lab_next) for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
freeMagic1(&mm1, (char *) lab); freeMagic((char *) lab);
freeMagic1_end(&mm1);
SigEnableInterrupts(); SigEnableInterrupts();
HashKill(&cellDef->cd_idHash); HashKill(&cellDef->cd_idHash);
@ -2409,50 +2380,6 @@ DBGenerateUniqueIds(def, warn)
HashKill(&dbUniqueNameTable); HashKill(&dbUniqueNameTable);
} }
/*
* ----------------------------------------------------------------------------
*
* DBSelectionUniqueIds --
*
* This is similar to DBGenerateUniqueIds(), but the purpose is to make
* sure that cell IDs in the selection do not collide with IDs in the
* definition. This is done before copying from Select2Def back to the
* root edit CellDef. Otherwise, any copied cell takes the name of the
* original, and the original gets renamed, which is unexpected behavior.
* Called only from SelectCopy().
*
* Results:
* None.
*
* Side effects:
* May modify the use-id's of the cells in the cell plane of 'selDef'.
*
* ----------------------------------------------------------------------------
*/
void
DBSelectionUniqueIds(selDef, rootDef)
CellDef *selDef; /* Should be Select2Def */
CellDef *rootDef; /* Should be EditRootDef */
{
int dbFindNamesFunc();
int dbGenerateUniqueIdsFunc();
dbWarnUniqueIds = FALSE;
HashInit(&dbUniqueDefTable, 32, 1); /* Indexed by (CellDef *) */
HashInit(&dbUniqueNameTable, 32, 0); /* Indexed by use-id */
/* Build up tables of names */
DBCellEnum(rootDef, dbFindNamesFunc, (ClientData) rootDef);
DBCellEnum(selDef, dbFindNamesFunc, (ClientData) selDef);
/* Assign unique use-ids to all cells in the selection */
DBCellEnum(selDef, dbGenerateUniqueIdsFunc, (ClientData) selDef);
HashKill(&dbUniqueDefTable);
HashKill(&dbUniqueNameTable);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *

View File

@ -83,15 +83,13 @@ struct seeTypesArg
*/ */
int int
DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg) DBSrCellPlaneArea(BPlane *plane, Rect *rect, int (*func)(), ClientData arg)
{ {
BPEnum sbpe;
BPEnum *bpe; BPEnum *bpe;
CellUse *use; CellUse *use;
int rval = 0; int rval = 0;
/* bpe = (BPEnum *)mallocMagic(sizeof(BPEnum)); */ bpe = (BPEnum *)mallocMagic(sizeof(BPEnum));
bpe = &sbpe;
BPEnumInit(bpe, plane, rect, BPE_OVERLAP, "DBSrCellPlaneArea"); BPEnumInit(bpe, plane, rect, BPE_OVERLAP, "DBSrCellPlaneArea");
while ((use = BPEnumNext(bpe))) while ((use = BPEnumNext(bpe)))
@ -104,7 +102,7 @@ DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg
} }
BPEnumTerm(bpe); BPEnumTerm(bpe);
/* freeMagic(bpe); */ freeMagic(bpe);
return rval; return rval;
} }
@ -120,7 +118,6 @@ DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg
* int * int
* func(tile, cxp) * func(tile, cxp)
* Tile *tile; * Tile *tile;
* TileType dinfo;
* TreeContext *cxp; * TreeContext *cxp;
* { * {
* } * }
@ -417,7 +414,6 @@ dbCellUniqueTileSrFunc(scx, fp)
* int * int
* func(tile, cxp) * func(tile, cxp)
* Tile *tile; * Tile *tile;
* TileType dinfo;
* TreeContext *cxp; * TreeContext *cxp;
* { * {
* } * }
@ -588,25 +584,6 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
if (!DBCellRead(def, TRUE, TRUE, NULL)) if (!DBCellRead(def, TRUE, TRUE, NULL))
return 0; return 0;
if (flags & TF_LABEL_REVERSE_SEARCH)
{
/* Search children first */
filter.tf_func = func;
filter.tf_arg = cdarg;
filter.tf_mask = mask;
filter.tf_xmask = xMask;
filter.tf_tpath = tpath;
filter.tf_flags = flags;
scx2 = *scx;
if (scx2.scx_area.r_xbot > TiPlaneRect.r_xbot) scx2.scx_area.r_xbot -= 1;
if (scx2.scx_area.r_ybot > TiPlaneRect.r_ybot) scx2.scx_area.r_ybot -= 1;
if (scx2.scx_area.r_xtop < TiPlaneRect.r_xtop) scx2.scx_area.r_xtop += 1;
if (scx2.scx_area.r_ytop < TiPlaneRect.r_ytop) scx2.scx_area.r_ytop += 1;
if (DBCellSrArea(&scx2, dbCellLabelSrFunc, (ClientData) &filter))
return 1;
}
for (lab = def->cd_labels; lab; lab = lab->lab_next) for (lab = def->cd_labels; lab; lab = lab->lab_next)
{ {
if (SigInterruptPending) break; if (SigInterruptPending) break;
@ -659,8 +636,6 @@ DBTreeSrLabels(scx, mask, xMask, tpath, flags, func, cdarg)
return (1); return (1);
} }
if (flags & TF_LABEL_REVERSE_SEARCH) return 0; /* children already searched */
filter.tf_func = func; filter.tf_func = func;
filter.tf_arg = cdarg; filter.tf_arg = cdarg;
filter.tf_mask = mask; filter.tf_mask = mask;
@ -702,7 +677,7 @@ dbCellLabelSrFunc(scx, fp)
{ {
Label *lab; Label *lab;
Rect *r = &scx->scx_area; Rect *r = &scx->scx_area;
const TileTypeBitMask *mask = fp->tf_mask; TileTypeBitMask *mask = fp->tf_mask;
CellDef *def = scx->scx_use->cu_def; CellDef *def = scx->scx_use->cu_def;
char *tnext; char *tnext;
int result; int result;
@ -732,16 +707,6 @@ dbCellLabelSrFunc(scx, fp)
} }
} }
/* If fp->tf_flags has TF_LABEL_REVERSE_SEARCH, then search child
* uses first, then the parent. This is for display, so that if
* a child cell and parent cell have overlapping labels, the parent
* label is the one on top.
*/
if (fp->tf_flags & TF_LABEL_REVERSE_SEARCH)
if (DBCellSrArea(scx, dbCellLabelSrFunc, (ClientData) fp))
result = 1;
/* Apply the function first to any of the labels in this def. */ /* Apply the function first to any of the labels in this def. */
result = 0; result = 0;
@ -763,9 +728,7 @@ dbCellLabelSrFunc(scx, fp)
} }
} }
/* Now visit each child use recursively, if not doing a reverse search */ /* Now visit each child use recursively */
if (!(fp->tf_flags & TF_LABEL_REVERSE_SEARCH))
if (DBCellSrArea(scx, dbCellLabelSrFunc, (ClientData) fp)) if (DBCellSrArea(scx, dbCellLabelSrFunc, (ClientData) fp))
result = 1; result = 1;
@ -949,9 +912,8 @@ DBSeeTypesAll(rootUse, rootRect, xMask, mask)
*/ */
int int
dbSeeTypesAllSrFunc(tile, dinfo, cxp) dbSeeTypesAllSrFunc(tile, cxp)
Tile *tile; Tile *tile;
TileType dinfo;
TreeContext *cxp; TreeContext *cxp;
{ {
Rect tileRect; Rect tileRect;
@ -962,7 +924,7 @@ dbSeeTypesAllSrFunc(tile, dinfo, cxp)
if (GEO_OVERLAP((&tileRect), area)) if (GEO_OVERLAP((&tileRect), area))
{ {
if (IsSplit(tile)) if (IsSplit(tile))
TTMaskSetType(mask, (dinfo & TT_SIDE) ? TTMaskSetType(mask, SplitSide(tile) ?
SplitRightType(tile) : SplitLeftType(tile)); SplitRightType(tile) : SplitLeftType(tile));
else else
TTMaskSetType(mask, TiGetType(tile)); TTMaskSetType(mask, TiGetType(tile));
@ -1552,22 +1514,19 @@ DBScaleEverything(scalen, scaled)
} }
/* Free the linked CellDef list */ /* Free the linked CellDef list */
free_magic1_t mm1 = freeMagic1_init();
lcd = lhead; lcd = lhead;
while (lcd != NULL) while (lcd != NULL)
{ {
freeMagic1(&mm1, (char *)lcd); freeMagic((char *)lcd);
lcd = lcd->cd_next; lcd = lcd->cd_next;
} }
freeMagic1_end(&mm1);
/* Scale all elements */ /* Scale all elements */
DBWScaleElements(scalen, scaled); DBWScaleElements(scalen, scaled);
#ifdef ROUTE_MODULE
/* Recovery of global plane pointers */ /* Recovery of global plane pointers */
MZAttachHintPlanes(); MZAttachHintPlanes();
#endif
/* Modify root box */ /* Modify root box */
ToolScaleBox(scalen, scaled); ToolScaleBox(scalen, scaled);
@ -1643,9 +1602,8 @@ dbScalePlane(oldplane, newplane, pnum, scalen, scaled, doCIF)
*/ */
int int
dbTileScaleFunc(tile, dinfo, scvals) dbTileScaleFunc(tile, scvals)
Tile *tile; Tile *tile;
TileType dinfo;
struct scaleArg *scvals; struct scaleArg *scvals;
{ {
TileType type; TileType type;
@ -1668,15 +1626,12 @@ dbTileScaleFunc(tile, dinfo, scvals)
return 0; return 0;
} }
type = TiGetTypeExact(tile) | dinfo; type = TiGetTypeExact(tile);
exact = type; exact = type;
if (IsSplit(tile)) if (IsSplit(tile))
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
DBNMPaintPlane(scvals->ptarget, exact, &targetRect, DBNMPaintPlane(scvals->ptarget, exact, &targetRect,
( ((scvals->doCIF) ? CIFPaintTable :
#ifdef CIF_MODULE
(scvals->doCIF) ? CIFPaintTable :
#endif
DBStdPaintTbl(type, scvals->pnum)), DBStdPaintTbl(type, scvals->pnum)),
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
return 0; return 0;
@ -1726,9 +1681,8 @@ dbMovePlane(oldplane, newplane, pnum, origx, origy)
*/ */
int int
dbTileMoveFunc(tile, dinfo, mvvals) dbTileMoveFunc(tile, mvvals)
Tile *tile; Tile *tile;
TileType dinfo;
struct moveArg *mvvals; struct moveArg *mvvals;
{ {
TileType type; TileType type;
@ -1741,12 +1695,12 @@ dbTileMoveFunc(tile, dinfo, mvvals)
DBMovePoint(&targetRect.r_ll, mvvals->origx, mvvals->origy); DBMovePoint(&targetRect.r_ll, mvvals->origx, mvvals->origy);
DBMovePoint(&targetRect.r_ur, mvvals->origx, mvvals->origy); DBMovePoint(&targetRect.r_ur, mvvals->origx, mvvals->origy);
type = TiGetTypeExact(tile) | dinfo; type = TiGetTypeExact(tile);
exact = type; exact = type;
if (IsSplit(tile)) if (IsSplit(tile))
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
DBNMPaintPlane(mvvals->ptarget, exact, &targetRect, DBNMPaintPlane(mvvals->ptarget, exact, &targetRect,
(mvvals->pnum < 0) ? CIFPaintTable : DBStdPaintTbl(type, mvvals->pnum), DBStdPaintTbl(type, mvvals->pnum),
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
return 0; return 0;
} }
@ -1808,14 +1762,12 @@ DBSrCellUses(cellDef, func, arg)
} }
/* Free this linked cellUse structure */ /* Free this linked cellUse structure */
free_magic1_t mm1 = freeMagic1_init();
lu = luhead; lu = luhead;
while (lu != NULL) while (lu != NULL)
{ {
freeMagic1(&mm1, (char *)lu); freeMagic((char *)lu);
lu = lu->cu_next; lu = lu->cu_next;
} }
freeMagic1_end(&mm1);
return retval; return retval;
} }
@ -1839,48 +1791,84 @@ typedef struct _cellpropstruct {
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
int dbScaleProp(name, proprec, cps) int dbScaleProp(name, value, cps)
char *name; char *name;
PropertyRecord *proprec; char *value;
CellPropStruct *cps; CellPropStruct *cps;
{ {
int i, scalen, scaled; int scalen, scaled;
Point p; char *newvalue, *vptr;
Rect r;
/* Only "dimension" and "plane" type properties get scaled */ if ((strlen(name) > 5) && !strncmp(name + strlen(name) - 5, "_BBOX", 5))
{
if (proprec->prop_type == PROPERTY_TYPE_PLANE) if (sscanf(value, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
&r.r_xtop, &r.r_ytop) == 4)
{ {
Plane *newplane;
newplane = DBNewPlane((ClientData)TT_SPACE);
DBClearPaintPlane(newplane);
/* Plane index is unused; arbitrarily substitute -1 */
dbScalePlane(proprec->prop_value.prop_plane, newplane, -1,
scalen, scaled, TRUE);
DBFreePaintPlane(proprec->prop_value.prop_plane);
TiFreePlane(proprec->prop_value.prop_plane);
proprec->prop_value.prop_plane = newplane;
return 0;
}
if (proprec->prop_type != PROPERTY_TYPE_DIMENSION) return 0;
/* Scale numerator held in point X value, */ /* Scale numerator held in point X value, */
/* scale denominator held in point Y value */ /* scale denominator held in point Y value */
scalen = cps->cps_point.p_x; scalen = cps->cps_point.p_x;
scaled = cps->cps_point.p_y; scaled = cps->cps_point.p_y;
for (i = 0; i < proprec->prop_len; i += 2) DBScalePoint(&r.r_ll, scalen, scaled);
{ DBScalePoint(&r.r_ur, scalen, scaled);
if ((i + 1) >= proprec->prop_len) break;
p.p_x = proprec->prop_value.prop_integer[i]; newvalue = (char *)mallocMagic(40);
p.p_y = proprec->prop_value.prop_integer[i + 1]; sprintf(newvalue, "%d %d %d %d", r.r_xbot, r.r_ybot,
DBScalePoint(&p, scalen, scaled); r.r_xtop, r.r_ytop);
proprec->prop_value.prop_integer[i] = p.p_x; DBPropPut(cps->cps_def, name, newvalue);
proprec->prop_value.prop_integer[i + 1] = p.p_y;
} }
}
else if (!strncmp(name, "MASKHINTS_", 10))
{
char *vptr, *lastval;
int lastlen;
newvalue = (char *)NULL;
vptr = value;
while (*vptr != '\0')
{
if (sscanf(vptr, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
&r.r_xtop, &r.r_ytop) == 4)
{
/* Scale numerator held in point X value, */
/* scale denominator held in point Y value */
scalen = cps->cps_point.p_x;
scaled = cps->cps_point.p_y;
DBScalePoint(&r.r_ll, scalen, scaled);
DBScalePoint(&r.r_ur, scalen, scaled);
lastval = newvalue;
lastlen = (lastval) ? strlen(lastval) : 0;
newvalue = mallocMagic(40 + lastlen);
if (lastval)
strcpy(newvalue, lastval);
else
*newvalue = '\0';
sprintf(newvalue + lastlen, "%s%d %d %d %d", (lastval) ? " " : "",
r.r_xbot, r.r_ybot, r.r_xtop, r.r_ytop);
if (lastval) freeMagic(lastval);
/* Parse through the four values and check if there's more */
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
while (*vptr && !isspace(*vptr)) vptr++;
while (*vptr && isspace(*vptr)) vptr++;
}
else break;
}
if (newvalue)
DBPropPut(cps->cps_def, name, newvalue);
}
return 0; /* Keep enumerating through properties */ return 0; /* Keep enumerating through properties */
} }
@ -1896,47 +1884,33 @@ int dbScaleProp(name, proprec, cps)
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
int dbMoveProp(name, proprec, cps) int dbMoveProp(name, value, cps)
char *name; char *name;
PropertyRecord *proprec; char *value;
CellPropStruct *cps; CellPropStruct *cps;
{ {
int i, origx, origy; int origx, origy;
char *newvalue; char *newvalue;
Point p; Rect r;
/* Only "dimension" and "plane" type properties get scaled */ if (((strlen(name) > 5) && !strncmp(name + strlen(name) - 5, "_BBOX", 5))
|| !strncmp(name, "MASKHINTS_", 10))
if (proprec->prop_type == PROPERTY_TYPE_PLANE) {
if (sscanf(value, "%d %d %d %d", &r.r_xbot, &r.r_ybot,
&r.r_xtop, &r.r_ytop) == 4)
{ {
Plane *newplane;
newplane = DBNewPlane((ClientData) TT_SPACE);
DBClearPaintPlane(newplane);
/* Use plane index -1 to indicate use of CIFPaintTable */
dbMovePlane(proprec->prop_value.prop_plane, newplane, -1, origx, origy);
DBFreePaintPlane(proprec->prop_value.prop_plane);
TiFreePlane(proprec->prop_value.prop_plane);
proprec->prop_value.prop_plane = newplane;
return 0;
}
if (proprec->prop_type != PROPERTY_TYPE_DIMENSION) return 0;
origx = cps->cps_point.p_x; origx = cps->cps_point.p_x;
origy = cps->cps_point.p_y; origy = cps->cps_point.p_y;
for (i = 0; i < proprec->prop_len; i += 2) DBMovePoint(&r.r_ll, origx, origy);
{ DBMovePoint(&r.r_ur, origx, origy);
if ((i + 1) >= proprec->prop_len) break;
p.p_x = proprec->prop_value.prop_integer[i]; newvalue = (char *)mallocMagic(40);
p.p_y = proprec->prop_value.prop_integer[i + 1]; sprintf(newvalue, "%d %d %d %d", r.r_xbot, r.r_ybot,
DBMovePoint(&p, origx, origy); r.r_xtop, r.r_ytop);
proprec->prop_value.prop_integer[i] = p.p_x; DBPropPut(cps->cps_def, name, newvalue);
proprec->prop_value.prop_integer[i + 1] = p.p_y; }
} }
return 0; /* Keep enumerating through properties */ return 0; /* Keep enumerating through properties */
} }
@ -2021,14 +1995,12 @@ dbScaleCell(cellDef, scalen, scaled)
BPFree(cellPlaneOrig); BPFree(cellPlaneOrig);
/* Free this linked cellUse structure */ /* Free this linked cellUse structure */
free_magic1_t mm1 = freeMagic1_init();
lu = luhead; lu = luhead;
while (lu != NULL) while (lu != NULL)
{ {
freeMagic1(&mm1, (char *)lu); freeMagic((char *)lu);
lu = lu->cu_next; lu = lu->cu_next;
} }
freeMagic1_end(&mm1);
/* Scale all of the paint tiles in this cell by creating a new plane */ /* 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. */ /* and copying all tiles into the new plane at scaled dimensions. */
@ -2231,14 +2203,12 @@ DBMoveCell(cellDef, origx, origy)
BPFree(cellPlaneOrig); BPFree(cellPlaneOrig);
/* Free this linked cellUse structure */ /* Free this linked cellUse structure */
free_magic1_t mm1 = freeMagic1_init();
lu = luhead; lu = luhead;
while (lu != NULL) while (lu != NULL)
{ {
freeMagic1(&mm1, (char *)lu); freeMagic((char *)lu);
lu = lu->cu_next; lu = lu->cu_next;
} }
freeMagic1_end(&mm1);
/* Move all of the paint tiles in this cell by creating a new plane */ /* 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. */ /* and copying all tiles into the new plane at the new position. */

View File

@ -218,10 +218,8 @@ DBCellClearDef(cellDef)
cellDef->cd_bbox.r_xtop = cellDef->cd_bbox.r_ytop = 1; 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_xbot = cellDef->cd_extended.r_ybot = 0;
cellDef->cd_extended.r_xtop = cellDef->cd_extended.r_ytop = 1; 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) for (lab = cellDef->cd_labels; lab; lab = lab->lab_next)
freeMagic1(&mm1, (char *) lab); freeMagic((char *) lab);
freeMagic1_end(&mm1);
cellDef->cd_labels = (Label *) NULL; cellDef->cd_labels = (Label *) NULL;
cellDef->cd_lastLabel = (Label *) NULL; cellDef->cd_lastLabel = (Label *) NULL;
@ -264,7 +262,7 @@ DBClearPaintPlane(plane)
/* Allocate a new central space tile */ /* Allocate a new central space tile */
newCenterTile = TiAlloc(); newCenterTile = TiAlloc();
PlaneSetHint(plane, newCenterTile); plane->pl_hint = newCenterTile;
TiSetBody(newCenterTile, TT_SPACE); TiSetBody(newCenterTile, TT_SPACE);
dbSetPlaneTile(plane, newCenterTile); dbSetPlaneTile(plane, newCenterTile);
} }

View File

@ -128,6 +128,86 @@ DBInvTransformDiagonal(oldtype, trans)
return dinfo; 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;
extern int dbSrConnectFunc(); /* Forward declaration. */
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, &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, &csa);
SigEnableInterrupts();
return result;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -197,7 +277,9 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
{ {
struct conSrArg csa; struct conSrArg csa;
int startPlane, result; int startPlane, result;
TileAndDinfo start_tad; /* Starting tile and split information */ Tile *startTile; /* Starting tile for search. */
extern int dbSrConnectFunc(); /* Forward declaration. */
extern int dbSrConnectStartFunc();
result = 0; result = 0;
csa.csa_def = def; csa.csa_def = def;
@ -208,18 +290,17 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
* the tile address and returns. * the tile address and returns.
*/ */
start_tad.tad_tile = NULL; startTile = NULL;
start_tad.tad_next = NULL; /* unused */
for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++) for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++)
{ {
csa.csa_pNum = startPlane; csa.csa_pNum = startPlane;
if (DBSrPaintArea((Tile *) NULL, if (DBSrPaintArea((Tile *) NULL,
def->cd_planes[startPlane], startArea, mask, def->cd_planes[startPlane], startArea, mask,
dbSrConnectStartFunc, PTR2CD(&start_tad)) != 0) break; dbSrConnectStartFunc, (ClientData) &startTile) != 0) break;
} }
if (start_tad.tad_tile == NULL) return 0; if (startTile == NULL) return 0;
/* The following lets us call DBSrConnect recursively */ /* The following lets us call DBSrConnect recursively */
else if (start_tad.tad_tile->ti_client == (ClientData)1) return 0; else if (startTile->ti_client == (ClientData)1) return 0;
/* Pass 1. During this pass the client function gets called. */ /* Pass 1. During this pass the client function gets called. */
@ -228,8 +309,7 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
csa.csa_clientDefault = CLIENTDEFAULT; csa.csa_clientDefault = CLIENTDEFAULT;
csa.csa_clear = FALSE; csa.csa_clear = FALSE;
csa.csa_connect = connect; csa.csa_connect = connect;
if (dbSrConnectFunc(start_tad.tad_tile, start_tad.tad_dinfo, if (dbSrConnectFunc(startTile, &csa) != 0) result = 1;
PTR2CD(&csa)) != 0) result = 1;
/* Pass 2. Don't call any client function, just clear the marks. /* Pass 2. Don't call any client function, just clear the marks.
* Don't allow any interruptions. * Don't allow any interruptions.
@ -238,22 +318,18 @@ DBSrConnect(def, startArea, mask, connect, bounds, func, clientData)
SigDisableInterrupts(); SigDisableInterrupts();
csa.csa_clientFunc = NULL; csa.csa_clientFunc = NULL;
csa.csa_clear = TRUE; csa.csa_clear = TRUE;
(void) dbSrConnectFunc(start_tad.tad_tile, start_tad.tad_dinfo, PTR2CD(&csa)); (void) dbSrConnectFunc(startTile, &csa);
SigEnableInterrupts(); SigEnableInterrupts();
return result; return result;
} }
/** @typedef cb_database_srpaintarea_t */
int int
dbSrConnectStartFunc( dbSrConnectStartFunc(tile, pTile)
Tile *tile, /* This will be the starting tile. */ Tile *tile; /* This will be the starting tile. */
TileType dinfo, /* (unused) */ Tile **pTile; /* We store tile's address here. */
ClientData cdata) /* We store tile and split info here. */
{ {
TileAndDinfo *tad = (TileAndDinfo *)CD2PTR(cdata); *pTile = tile;
tad->tad_tile = tile;
tad->tad_dinfo = dinfo;
return 1; return 1;
} }
@ -291,7 +367,9 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
{ {
struct conSrArg csa; struct conSrArg csa;
int startPlane, result; int startPlane, result;
TileAndDinfo tad; Tile *startTile; /* Starting tile for search. */
extern int dbSrConnectFunc(); /* Forward declaration. */
extern int dbSrConnectStartFunc();
result = 0; result = 0;
csa.csa_def = def; csa.csa_def = def;
@ -302,18 +380,17 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
* the tile address and returns. * the tile address and returns.
*/ */
tad.tad_tile = NULL; startTile = NULL;
tad.tad_next = NULL; /* unused */
for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++) for (startPlane = PL_TECHDEPBASE; startPlane < DBNumPlanes; startPlane++)
{ {
csa.csa_pNum = startPlane; csa.csa_pNum = startPlane;
if (DBSrPaintArea((Tile *) NULL, if (DBSrPaintArea((Tile *) NULL,
def->cd_planes[startPlane], startArea, mask, def->cd_planes[startPlane], startArea, mask,
dbSrConnectStartFunc, PTR2CD(&tad)) != 0) break; dbSrConnectStartFunc, (ClientData) &startTile) != 0) break;
} }
if (tad.tad_tile == NULL) return 0; if (startTile == NULL) return 0;
/* The following lets us call DBSrConnect recursively */ /* The following lets us call DBSrConnect recursively */
else if (tad.tad_tile->ti_client == (ClientData)1) return 0; else if (startTile->ti_client == (ClientData)1) return 0;
/* Pass 1. During this pass the client function gets called. */ /* Pass 1. During this pass the client function gets called. */
@ -322,7 +399,7 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
csa.csa_clientDefault = CLIENTDEFAULT; csa.csa_clientDefault = CLIENTDEFAULT;
csa.csa_clear = FALSE; csa.csa_clear = FALSE;
csa.csa_connect = connect; csa.csa_connect = connect;
if (dbSrConnectFunc(tad.tad_tile, tad.tad_dinfo, PTR2CD(&csa)) != 0) result = 1; if (dbSrConnectFunc(startTile, &csa) != 0) result = 1;
return result; return result;
} }
@ -345,15 +422,12 @@ DBSrConnectOnePass(def, startArea, mask, connect, bounds, func, clientData)
*/ */
int int
dbcFindTileFunc(tile, dinfo, arg) dbcFindTileFunc(tile, arg)
Tile *tile; Tile *tile;
TileType dinfo;
ClientData arg; ClientData arg;
{ {
TileAndDinfo *tad = (TileAndDinfo *)arg; Tile **tptr = (Tile **)arg;
*tptr = tile;
tad->tad_tile = tile;
tad->tad_dinfo = dinfo;
return 1; return 1;
} }
@ -391,19 +465,16 @@ dbcFindTileFunc(tile, dinfo, arg)
*/ */
int int
dbSrConnectFunc( dbSrConnectFunc(tile, csa)
Tile *tile, /* Tile that is connected. */ Tile *tile; /* Tile that is connected. */
TileType dinfo, /* Split tile information */ struct conSrArg *csa; /* Contains information about the search. */
ClientData cdata) /* Contains information about the search. */
/* (struct conSrArg *csa) */
{ {
struct conSrArg *csa = (struct conSrArg *)CD2PTR(cdata);
Tile *t2; Tile *t2;
Rect tileArea; Rect tileArea;
int i, pNum; int i, pNum;
int result = 0; int result = 0;
bool callClient; bool callClient;
const TileTypeBitMask *connectMask; TileTypeBitMask *connectMask;
TileType loctype, checktype; TileType loctype, checktype;
PlaneMask planes; PlaneMask planes;
@ -413,13 +484,11 @@ dbSrConnectFunc(
/* Drop the first entry on the stack */ /* Drop the first entry on the stack */
pNum = csa->csa_pNum; pNum = csa->csa_pNum;
STACKPUSH(INT2CD(tile), dbConnectStack); STACKPUSH(INT2CD(tile), dbConnectStack);
STACKPUSH(INT2CD(dinfo), dbConnectStack);
STACKPUSH(INT2CD(pNum), dbConnectStack); STACKPUSH(INT2CD(pNum), dbConnectStack);
while (!StackEmpty(dbConnectStack)) while (!StackEmpty(dbConnectStack))
{ {
pNum = (int)CD2INT(STACKPOP(dbConnectStack)); pNum = (int)CD2INT(STACKPOP(dbConnectStack));
dinfo = (int)CD2INT(STACKPOP(dbConnectStack));
tile = (Tile *)CD2INT(STACKPOP(dbConnectStack)); tile = (Tile *)CD2INT(STACKPOP(dbConnectStack));
if (result == 1) continue; if (result == 1) continue;
@ -453,7 +522,7 @@ dbSrConnectFunc(
if (callClient && (csa->csa_clientFunc != NULL)) if (callClient && (csa->csa_clientFunc != NULL))
{ {
if ((*csa->csa_clientFunc)(tile, dinfo, pNum, csa->csa_clientData) != 0) if ((*csa->csa_clientFunc)(tile, pNum, csa->csa_clientData) != 0)
{ {
result = 1; result = 1;
continue; continue;
@ -467,7 +536,7 @@ dbSrConnectFunc(
if (IsSplit(tile)) if (IsSplit(tile))
{ {
if (dinfo & TT_SIDE) if (SplitSide(tile))
loctype = SplitRightType(tile); loctype = SplitRightType(tile);
else else
loctype = SplitLeftType(tile); loctype = SplitLeftType(tile);
@ -478,7 +547,7 @@ dbSrConnectFunc(
/* Left side: */ /* Left side: */
if (IsSplit(tile) && (dinfo & TT_SIDE)) goto bottomside; if (IsSplit(tile) && SplitSide(tile)) goto bottomside;
for (t2 = BL(tile); BOTTOM(t2) < tileArea.r_ytop; t2 = RT(t2)) for (t2 = BL(tile); BOTTOM(t2) < tileArea.r_ytop; t2 = RT(t2))
{ {
@ -495,11 +564,9 @@ dbSrConnectFunc(
if (t2->ti_client == csa->csa_clientDefault) continue; if (t2->ti_client == csa->csa_clientDefault) continue;
} }
else if (t2->ti_client == (ClientData) 1) continue; else if (t2->ti_client == (ClientData) 1) continue;
STACKPUSH(INT2CD(t2), dbConnectStack);
if (IsSplit(t2)) if (IsSplit(t2))
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack); TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) | TT_SIDE)); /* bit set */
else STACKPUSH(INT2CD(t2), dbConnectStack);
STACKPUSH(INT2CD(0), dbConnectStack);
STACKPUSH(INT2CD(pNum), dbConnectStack); STACKPUSH(INT2CD(pNum), dbConnectStack);
} }
} }
@ -507,7 +574,7 @@ dbSrConnectFunc(
/* Bottom side: */ /* Bottom side: */
bottomside: bottomside:
if (IsSplit(tile) && ((!((dinfo & TT_SIDE) ? 1 : 0)) ^ SplitDirection(tile))) if (IsSplit(tile) && (!(SplitSide(tile) ^ SplitDirection(tile))))
goto rightside; goto rightside;
for (t2 = LB(tile); LEFT(t2) < tileArea.r_xtop; t2 = TR(t2)) for (t2 = LB(tile); LEFT(t2) < tileArea.r_xtop; t2 = TR(t2))
@ -525,17 +592,16 @@ bottomside:
if (t2->ti_client == csa->csa_clientDefault) continue; if (t2->ti_client == csa->csa_clientDefault) continue;
} }
else if (t2->ti_client == (ClientData) 1) continue; else if (t2->ti_client == (ClientData) 1) continue;
STACKPUSH(INT2CD(t2), dbConnectStack);
if (IsSplit(t2)) if (IsSplit(t2))
{ {
if (SplitDirection(t2)) if (SplitDirection(t2))
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack); /* bit set */
TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) | TT_SIDE));
else else
/* bit clear */ /* bit clear */
STACKPUSH(INT2CD(0), dbConnectStack); TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) & ~TT_SIDE));
} }
else STACKPUSH(INT2CD(t2), dbConnectStack);
STACKPUSH(INT2CD(0), dbConnectStack);
STACKPUSH(INT2CD(pNum), dbConnectStack); STACKPUSH(INT2CD(pNum), dbConnectStack);
} }
} }
@ -543,7 +609,7 @@ bottomside:
/* Right side: */ /* Right side: */
rightside: rightside:
if (IsSplit(tile) && !(dinfo & TT_SIDE)) goto topside; if (IsSplit(tile) && !SplitSide(tile)) goto topside;
for (t2 = TR(tile); ; t2 = LB(t2)) for (t2 = TR(tile); ; t2 = LB(t2))
{ {
@ -560,8 +626,9 @@ rightside:
if (t2->ti_client == csa->csa_clientDefault) goto nextRight; if (t2->ti_client == csa->csa_clientDefault) goto nextRight;
} }
else if (t2->ti_client == (ClientData) 1) 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(t2), dbConnectStack);
STACKPUSH(INT2CD(0), dbConnectStack);
STACKPUSH(INT2CD(pNum), dbConnectStack); STACKPUSH(INT2CD(pNum), dbConnectStack);
} }
nextRight: if (BOTTOM(t2) <= tileArea.r_ybot) break; nextRight: if (BOTTOM(t2) <= tileArea.r_ybot) break;
@ -570,8 +637,7 @@ rightside:
/* Top side: */ /* Top side: */
topside: topside:
if (IsSplit(tile) && (((dinfo & TT_SIDE) ? 1 : 0) ^ SplitDirection(tile))) if (IsSplit(tile) && (SplitSide(tile) ^ SplitDirection(tile))) goto donesides;
goto donesides;
for (t2 = RT(tile); ; t2 = BL(t2)) for (t2 = RT(tile); ; t2 = BL(t2))
{ {
@ -588,18 +654,16 @@ topside:
if (t2->ti_client == csa->csa_clientDefault) goto nextTop; if (t2->ti_client == csa->csa_clientDefault) goto nextTop;
} }
else if (t2->ti_client == (ClientData) 1) goto nextTop; else if (t2->ti_client == (ClientData) 1) goto nextTop;
STACKPUSH(INT2CD(t2), dbConnectStack);
if (IsSplit(t2)) if (IsSplit(t2))
{ {
if (SplitDirection(t2)) if (SplitDirection(t2))
/* bit clear */ /* bit clear */
STACKPUSH(INT2CD(0), dbConnectStack); TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) & ~TT_SIDE));
else else
/* bit set */ /* bit set */
STACKPUSH(INT2CD((TileType)TT_SIDE), dbConnectStack); TiSetBody(t2, INT2CD(CD2INT(t2->ti_body) | TT_SIDE));
} }
else STACKPUSH(INT2CD(t2), dbConnectStack);
STACKPUSH(INT2CD(0), dbConnectStack);
STACKPUSH(INT2CD(pNum), dbConnectStack); STACKPUSH(INT2CD(pNum), dbConnectStack);
} }
nextTop: if (LEFT(t2) <= tileArea.r_xbot) break; nextTop: if (LEFT(t2) <= tileArea.r_xbot) break;
@ -618,7 +682,6 @@ donesides:
{ {
Rect newArea; Rect newArea;
GEO_EXPAND(&tileArea, 1, &newArea); GEO_EXPAND(&tileArea, 1, &newArea);
TileAndDinfo tad;
for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++) for (i = PL_TECHDEPBASE; i < DBNumPlanes; i++)
{ {
@ -626,20 +689,18 @@ donesides:
if (IsSplit(tile)) if (IsSplit(tile))
{ {
if (DBSrPaintNMArea((Tile *) NULL, csa->csa_def->cd_planes[i], if (DBSrPaintNMArea((Tile *) NULL, csa->csa_def->cd_planes[i],
TiGetTypeExact(tile) | dinfo, &newArea, connectMask, TiGetTypeExact(tile), &newArea, connectMask,
dbcFindTileFunc, (ClientData)&tad) != 0) dbcFindTileFunc, (ClientData)&t2) != 0)
{ {
STACKPUSH(PTR2CD(tad.tad_tile), dbConnectStack); STACKPUSH(INT2CD(t2), dbConnectStack);
STACKPUSH(INT2CD(tad.tad_dinfo), dbConnectStack);
STACKPUSH(INT2CD(i), dbConnectStack); STACKPUSH(INT2CD(i), dbConnectStack);
} }
} }
else if (DBSrPaintArea((Tile *) NULL, csa->csa_def->cd_planes[i], else if (DBSrPaintArea((Tile *) NULL, csa->csa_def->cd_planes[i],
&newArea, connectMask, dbcFindTileFunc, &newArea, connectMask, dbcFindTileFunc,
(ClientData)&tad) != 0) (ClientData)&t2) != 0)
{ {
STACKPUSH(PTR2CD(tad.tad_tile), dbConnectStack); STACKPUSH(INT2CD(t2), dbConnectStack);
STACKPUSH(INT2CD(tad.tad_dinfo), dbConnectStack);
STACKPUSH(INT2CD(i), dbConnectStack); STACKPUSH(INT2CD(i), dbConnectStack);
} }
} }
@ -670,12 +731,9 @@ donesides:
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
/** @typedef cb_database_srpaintnmarea_t */
/** @typedef cb_database_srpaintarea_t */
int int
dbcUnconnectFunc(tile, dinfo, clientData) dbcUnconnectFunc(tile, clientData)
Tile *tile; /* Current tile */ Tile *tile; /* Current tile */
TileType dinfo; /* Split tile information, unused */
ClientData clientData; /* Unused. */ ClientData clientData; /* Unused. */
{ {
@ -768,8 +826,7 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
CellDef *orig_def = scx->scx_use->cu_def; CellDef *orig_def = scx->scx_use->cu_def;
Label *slab; Label *slab;
int lidx = lab->lab_port; int lidx = lab->lab_port;
bool foundOne; TileTypeBitMask *connectMask;
const TileTypeBitMask *connectMask;
/* Check for equivalent ports. For any found, call */ /* Check for equivalent ports. For any found, call */
/* DBTreeSrTiles recursively on the type and area */ /* DBTreeSrTiles recursively on the type and area */
@ -780,7 +837,6 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
/* are more equivalent ports, they will be found when */ /* are more equivalent ports, they will be found when */
/* processing this label's area. */ /* processing this label's area. */
foundOne = FALSE;
for (slab = orig_def->cd_labels; slab != NULL; slab = slab->lab_next) for (slab = orig_def->cd_labels; slab != NULL; slab = slab->lab_next)
if ((slab->lab_flags & PORT_DIR_MASK) && (slab != lab)) if ((slab->lab_flags & PORT_DIR_MASK) && (slab != lab))
if (slab->lab_port == lidx) if (slab->lab_port == lidx)
@ -841,20 +897,6 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
csa2->csa2_list[csa2->csa2_top].connectMask = connectMask; csa2->csa2_list[csa2->csa2_top].connectMask = connectMask;
csa2->csa2_list[csa2->csa2_top].dinfo = 0; 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 */ /* See above: Process only one equivalent port at a time */
break; break;
} }
@ -889,9 +931,8 @@ dbcConnectLabelFunc(scx, lab, tpath, csa2)
*/ */
int int
dbcConnectFunc(tile, dinfo, cx) dbcConnectFunc(tile, cx)
Tile *tile; /* Tile found. */ Tile *tile; /* Tile found. */
TileType dinfo; /* Split tile information */
TreeContext *cx; /* Describes context of search. The client TreeContext *cx; /* Describes context of search. The client
* data is a pointer to a conSrArg2 record * data is a pointer to a conSrArg2 record
* containing various required information. * containing various required information.
@ -899,13 +940,12 @@ dbcConnectFunc(tile, dinfo, cx)
{ {
struct conSrArg2 *csa2; struct conSrArg2 *csa2;
Rect tileArea, newarea; Rect tileArea, newarea;
const TileTypeBitMask *connectMask; TileTypeBitMask *connectMask, notConnectMask;
TileTypeBitMask notConnectMask;
Rect *srArea; Rect *srArea;
SearchContext *scx = cx->tc_scx; SearchContext *scx = cx->tc_scx;
SearchContext scx2; SearchContext scx2;
TileType loctype = TiGetTypeExact(tile) | dinfo; TileType loctype = TiGetTypeExact(tile);
TileType newdinfo = 0; TileType dinfo = 0;
int retval, i, pNum = cx->tc_plane; int retval, i, pNum = cx->tc_plane;
CellDef *def; CellDef *def;
@ -937,8 +977,8 @@ dbcConnectFunc(tile, dinfo, cx)
if (IsSplit(tile)) if (IsSplit(tile))
{ {
newdinfo = DBTransformDiagonal(loctype, &scx->scx_trans); dinfo = DBTransformDiagonal(loctype, &scx->scx_trans);
loctype = ((dinfo & TT_SIDE)) ? SplitRightType(tile) : SplitLeftType(tile); loctype = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
} }
/* See if the destination cell contains stuff over the whole /* See if the destination cell contains stuff over the whole
@ -976,7 +1016,7 @@ dbcConnectFunc(tile, dinfo, cx)
def = csa2->csa2_use->cu_def; def = csa2->csa2_use->cu_def;
retval = 1; retval = 1;
if (DBSrPaintNMArea((Tile *) NULL, def->cd_planes[pNum], if (DBSrPaintNMArea((Tile *) NULL, def->cd_planes[pNum],
newdinfo, &newarea, &notConnectMask, dbcUnconnectFunc, dinfo, &newarea, &notConnectMask, dbcUnconnectFunc,
(ClientData) NULL) == 0) (ClientData) NULL) == 0)
retval = 0; retval = 0;
@ -985,7 +1025,7 @@ dbcConnectFunc(tile, dinfo, cx)
* the storage for the current list element. * the storage for the current list element.
*/ */
DBNMPaintPlane(def->cd_planes[pNum], newdinfo, DBNMPaintPlane(def->cd_planes[pNum], dinfo,
&newarea, DBStdPaintTbl(loctype, pNum), &newarea, DBStdPaintTbl(loctype, pNum),
(PaintUndoInfo *) NULL); (PaintUndoInfo *) NULL);
@ -1002,14 +1042,14 @@ dbcConnectFunc(tile, dinfo, cx)
/* Only extend those sides bordering the diagonal tile */ /* Only extend those sides bordering the diagonal tile */
if (newdinfo & TT_DIAGONAL) if (dinfo & TT_DIAGONAL)
{ {
if (newdinfo & TT_SIDE) /* right */ if (dinfo & TT_SIDE) /* right */
newarea.r_xtop += 1; newarea.r_xtop += 1;
else /* left */ else /* left */
newarea.r_xbot -= 1; newarea.r_xbot -= 1;
if (((newdinfo & TT_SIDE) >> 1) if (((dinfo & TT_SIDE) >> 1)
== (newdinfo & TT_DIRECTION)) /* top */ == (dinfo & TT_DIRECTION)) /* top */
newarea.r_ytop += 1; newarea.r_ytop += 1;
else /* bottom */ else /* bottom */
newarea.r_ybot -= 1; newarea.r_ybot -= 1;
@ -1037,13 +1077,7 @@ dbcConnectFunc(tile, dinfo, cx)
if (++csa2->csa2_top == CSA2_LIST_SIZE) if (++csa2->csa2_top == CSA2_LIST_SIZE)
{ {
/* Reached list size limit---need to push the list and */ /* Reached list size limit---need to push the list and */
/* start a new one. NOTE: Setting lasttop to -1 means */ /* start a new one. */
/* that some entries may be duplicated between the */
/* stacks, which is a small inefficiency. In theory, */
/* lasttop could be left as is, then if lasttop > top */
/* when searching the last 5 entries, pop the stack, do */
/* the search, and then push the stack again. But it's */
/* a lot easier just to be slightly inefficient. */
conSrArea *newlist; conSrArea *newlist;
@ -1051,12 +1085,11 @@ dbcConnectFunc(tile, dinfo, cx)
StackPush((ClientData)csa2->csa2_list, csa2->csa2_stack); StackPush((ClientData)csa2->csa2_list, csa2->csa2_stack);
csa2->csa2_list = newlist; csa2->csa2_list = newlist;
csa2->csa2_top = 0; csa2->csa2_top = 0;
csa2->csa2_lasttop = -1;
} }
csa2->csa2_list[csa2->csa2_top].area = newarea; csa2->csa2_list[csa2->csa2_top].area = newarea;
csa2->csa2_list[csa2->csa2_top].connectMask = connectMask; csa2->csa2_list[csa2->csa2_top].connectMask = connectMask;
csa2->csa2_list[csa2->csa2_top].dinfo = newdinfo; csa2->csa2_list[csa2->csa2_top].dinfo = dinfo;
return 0; return 0;
} }
@ -1122,7 +1155,7 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, doLabels, destUse)
*/ */
{ {
struct conSrArg2 csa2; struct conSrArg2 csa2;
const TileTypeBitMask *newmask; TileTypeBitMask *newmask;
TileType newtype; TileType newtype;
unsigned char searchtype; unsigned char searchtype;
@ -1211,8 +1244,7 @@ DBTreeCopyConnect(scx, mask, xMask, connect, area, doLabels, destUse)
if (DBTreeSrLabels(scx, newmask, xMask, &tpath, searchtype, if (DBTreeSrLabels(scx, newmask, xMask, &tpath, searchtype,
dbcConnectLabelFunc, (ClientData) &csa2) != 0) dbcConnectLabelFunc, (ClientData) &csa2) != 0)
{ {
TxError("Connection search was interrupted or hit " TxError("Connection search hit memory limit and stopped.\n");
"memory limit and stopped.\n");
break; break;
} }
} }

View File

@ -39,7 +39,6 @@ struct expandArg
{ {
bool ea_deref; /* TRUE if root def dereference flag is set */ bool ea_deref; /* TRUE if root def dereference flag is set */
int ea_xmask; /* Expand mask. */ int ea_xmask; /* Expand mask. */
int ea_type; /* Expand, unexpand, or toggle */
int (*ea_func)(); /* Function to call for each cell whose int (*ea_func)(); /* Function to call for each cell whose
* status is changed. * status is changed.
*/ */
@ -68,22 +67,15 @@ struct expandArg
*/ */
void void
DBExpand(cellUse, expandMask, expandType) DBExpand(cellUse, expandMask, expandFlag)
CellUse *cellUse; CellUse *cellUse;
int expandMask; int expandMask;
int expandType; bool expandFlag;
{ {
CellDef *def; CellDef *def;
bool expandFlag, expandTest;
expandTest = DBDescendSubcell(cellUse, expandMask); if (DBDescendSubcell(cellUse, expandMask) == expandFlag)
if ((expandType & DB_EXPAND_MASK) == DB_EXPAND_TOGGLE) return;
expandFlag = expandTest;
else
{
expandFlag = ((expandType & DB_EXPAND_MASK) == DB_EXPAND) ? TRUE : FALSE;
if (expandFlag == expandTest) return;
}
if (expandFlag) if (expandFlag)
{ {
@ -138,17 +130,17 @@ DBExpand(cellUse, expandMask, expandType)
*/ */
void void
DBExpandAll(rootUse, rootRect, expandMask, expandType, func, cdarg) DBExpandAll(rootUse, rootRect, expandMask, expandFlag, func, cdarg)
CellUse *rootUse; /* Root cell use from which search begins */ CellUse *rootUse; /* Root cell use from which search begins */
Rect *rootRect; /* Area to be expanded, in root coordinates */ Rect *rootRect; /* Area to be expanded, in root coordinates */
int expandMask; /* Window mask in which cell is to be expanded */ int expandMask; /* Window mask in which cell is to be expanded */
int expandType; /* DB_EXPAND, DB_UNEXPAND, DB_EXPAND_TOGGLE */ bool expandFlag; /* TRUE => expand, FALSE => unexpand */
int (*func)(); /* Function to call for each cell whose expansion int (*func)(); /* Function to call for each cell whose expansion
* status is modified. NULL means don't call anyone. * status is modified. NULL means don't call anyone.
*/ */
ClientData cdarg; /* Argument to pass to func. */ ClientData cdarg; /* Argument to pass to func. */
{ {
int dbExpandFunc(); int dbExpandFunc(), dbUnexpandFunc();
SearchContext scontext; SearchContext scontext;
struct expandArg arg; struct expandArg arg;
@ -156,26 +148,29 @@ DBExpandAll(rootUse, rootRect, expandMask, expandType, func, cdarg)
(void) DBCellRead(rootUse->cu_def, TRUE, TRUE, NULL); (void) DBCellRead(rootUse->cu_def, TRUE, TRUE, NULL);
/* /*
* Walk through the area and set the expansion state appropriately. * Walk through the area and set the expansion state
* appropriately.
*/ */
arg.ea_xmask = expandMask; arg.ea_xmask = expandMask;
arg.ea_func = func; arg.ea_func = func;
arg.ea_arg = cdarg; arg.ea_arg = cdarg;
arg.ea_type = expandType;
arg.ea_deref = (rootUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE; arg.ea_deref = (rootUse->cu_def->cd_flags & CDDEREFERENCE) ? TRUE : FALSE;
scontext.scx_use = rootUse; scontext.scx_use = rootUse;
scontext.scx_trans = GeoIdentityTransform; scontext.scx_trans = GeoIdentityTransform;
scontext.scx_area = *rootRect; scontext.scx_area = *rootRect;
if (expandFlag)
DBCellSrArea(&scontext, dbExpandFunc, (ClientData) &arg); DBCellSrArea(&scontext, dbExpandFunc, (ClientData) &arg);
else
DBCellSrArea(&scontext, dbUnexpandFunc, (ClientData) &arg);
} }
/* /*
* dbExpandFunc -- * dbExpandFunc --
* *
* Filter function called by DBCellSrArea on behalf of DBExpandAll above * Filter function called by DBCellSrArea on behalf of DBExpandAll above
* when cells are being expanded, unexpanded, or toggled. * when cells are being expanded.
*/ */
int int
@ -189,23 +184,13 @@ dbExpandFunc(scx, arg)
{ {
CellUse *childUse = scx->scx_use; CellUse *childUse = scx->scx_use;
int n = DBLambda[1]; int n = DBLambda[1];
int expandTest;
int expandType = (arg->ea_type & DB_EXPAND_MASK);
int expandSurround = (arg->ea_type & DB_EXPAND_SURROUND_MASK);
bool surround;
expandTest = DBDescendSubcell(childUse, arg->ea_xmask);
/* /*
* Change the expansion status of this cell if necessary. Call the * Change the expansion status of this cell if necessary. Call the
* client's function if the expansion status has changed. * client's function if the expansion status has changed.
*/ */
if (!expandTest && ((expandType == DB_EXPAND) || (expandType == DB_EXPAND_TOGGLE))) if (!DBDescendSubcell(childUse, arg->ea_xmask))
{
surround = (!GEO_SURROUND(&childUse->cu_def->cd_bbox, &scx->scx_area)
|| GEO_SURROUND(&scx->scx_area, &childUse->cu_def->cd_bbox));
if (surround || (expandSurround == DB_EXPAND_OVERLAP))
{ {
/* If the cell is unavailable, then don't expand it. /* If the cell is unavailable, then don't expand it.
*/ */
@ -222,22 +207,45 @@ dbExpandFunc(scx, arg)
} }
childUse->cu_expandMask |= arg->ea_xmask; childUse->cu_expandMask |= arg->ea_xmask;
expandTest = TRUE;
if (arg->ea_func != NULL) if (arg->ea_func != NULL)
{ {
if ((*arg->ea_func)(childUse, arg->ea_arg) != 0) return 1; if ((*arg->ea_func)(childUse, arg->ea_arg) != 0) return 1;
} }
} }
if (DBCellSrArea(scx, dbExpandFunc, (ClientData) arg))
return 1;
return 2;
} }
else if (expandTest && ((expandType == DB_UNEXPAND) ||
(expandType == DB_EXPAND_TOGGLE))) /*
* dbUnexpandFunc --
*
* Filter function called by DBCellSrArea on behalf of DBExpandAll above
* when cells are being unexpanded.
*/
int
dbUnexpandFunc(scx, arg)
SearchContext *scx; /* Pointer to search context containing
* child use, search area in coor-
* dinates of the child use, and
* transform back to "root".
*/
struct expandArg *arg; /* Client data from caller */
{ {
surround = (!GEO_SURROUND(&childUse->cu_def->cd_bbox, &scx->scx_area) CellUse *childUse = scx->scx_use;
|| GEO_SURROUND(&scx->scx_area, &childUse->cu_def->cd_bbox));
if (surround || (expandSurround == DB_EXPAND_OVERLAP)) /*
* Change the expansion status of this cell if necessary.
*/
if (DBDescendSubcell(childUse, arg->ea_xmask))
{
if (!GEO_SURROUND(&childUse->cu_def->cd_bbox, &scx->scx_area)
|| GEO_SURROUND(&scx->scx_area, &childUse->cu_def->cd_bbox))
{ {
childUse->cu_expandMask &= ~arg->ea_xmask; childUse->cu_expandMask &= ~arg->ea_xmask;
expandTest = FALSE;
/* Call the client's function, if there is one. */ /* Call the client's function, if there is one. */
@ -248,7 +256,11 @@ dbExpandFunc(scx, arg)
} }
} }
if (DBCellSrArea(scx, dbExpandFunc, (ClientData) arg)) /* Don't recursively search things that aren't already expanded. */
else return 2;
if (DBCellSrArea(scx, dbUnexpandFunc, (ClientData) arg))
return 1; return 1;
return 2; return 2;
} }

File diff suppressed because it is too large Load Diff

View File

@ -280,7 +280,6 @@ DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
bool erasedAny = FALSE; bool erasedAny = FALSE;
TileType newType; TileType newType;
free_magic1_t mm1 = freeMagic1_init();
labPrev = NULL; labPrev = NULL;
lab = cellDef->cd_labels; lab = cellDef->cd_labels;
while (lab != NULL) while (lab != NULL)
@ -314,7 +313,7 @@ DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
if ((lab->lab_font >= 0) && areaReturn) if ((lab->lab_font >= 0) && areaReturn)
GeoInclude(&lab->lab_bbox, areaReturn); GeoInclude(&lab->lab_bbox, areaReturn);
freeMagic1(&mm1, (char *) lab); freeMagic((char *) lab);
lab = lab->lab_next; lab = lab->lab_next;
erasedAny = TRUE; erasedAny = TRUE;
continue; continue;
@ -322,7 +321,6 @@ DBEraseGlobLabel(cellDef, area, mask, areaReturn, globmatch)
nextLab: labPrev = lab; nextLab: labPrev = lab;
lab = lab->lab_next; lab = lab->lab_next;
} }
freeMagic1_end(&mm1);
if (erasedAny) if (erasedAny)
cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP; cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
@ -444,7 +442,6 @@ DBEraseLabelsByContent(def, rect, type, text)
{ {
Label *lab, *labPrev; Label *lab, *labPrev;
free_magic1_t mm1 = freeMagic1_init();
for (labPrev = NULL, lab = def->cd_labels; for (labPrev = NULL, lab = def->cd_labels;
lab != NULL; lab != NULL;
labPrev = lab, lab = lab->lab_next) labPrev = lab, lab = lab->lab_next)
@ -460,7 +457,7 @@ DBEraseLabelsByContent(def, rect, type, text)
else labPrev->lab_next = lab->lab_next; else labPrev->lab_next = lab->lab_next;
if (def->cd_lastLabel == lab) if (def->cd_lastLabel == lab)
def->cd_lastLabel = labPrev; def->cd_lastLabel = labPrev;
freeMagic1(&mm1, (char *) lab); freeMagic((char *) lab);
/* Don't iterate through loop, since this will skip a label: /* Don't iterate through loop, since this will skip a label:
* just go back to top. This is tricky! * just go back to top. This is tricky!
@ -470,7 +467,6 @@ DBEraseLabelsByContent(def, rect, type, text)
if (lab == NULL) break; if (lab == NULL) break;
else goto nextCheck; else goto nextCheck;
} }
freeMagic1_end(&mm1);
} }
/* /*
@ -499,7 +495,6 @@ DBRemoveLabel(def, refLab)
{ {
Label *lab, *labPrev; Label *lab, *labPrev;
free_magic1_t mm1 = freeMagic1_init();
for (labPrev = NULL, lab = def->cd_labels; for (labPrev = NULL, lab = def->cd_labels;
lab != NULL; lab != NULL;
labPrev = lab, lab = lab->lab_next) labPrev = lab, lab = lab->lab_next)
@ -513,7 +508,7 @@ DBRemoveLabel(def, refLab)
else labPrev->lab_next = lab->lab_next; else labPrev->lab_next = lab->lab_next;
if (def->cd_lastLabel == lab) if (def->cd_lastLabel == lab)
def->cd_lastLabel = labPrev; def->cd_lastLabel = labPrev;
freeMagic1(&mm1, (char *) lab); freeMagic((char *) lab);
/* Don't iterate through loop, since this will skip a label: /* Don't iterate through loop, since this will skip a label:
* just go back to top. This is tricky! * just go back to top. This is tricky!
@ -523,7 +518,6 @@ DBRemoveLabel(def, refLab)
if (lab == NULL) break; if (lab == NULL) break;
else goto nextCheck; else goto nextCheck;
} }
freeMagic1_end(&mm1);
} }
/* /*
@ -574,8 +568,7 @@ DBReOrientLabel(cellDef, area, newPos)
* dbGetLabelArea --- * dbGetLabelArea ---
* *
* Callback function used by DBAdjustLabels. Find all material under a label * Callback function used by DBAdjustLabels. Find all material under a label
* that is *not* the label type, and return the label area adjusted to leave * that is *not* the label type, and return the
* out that amount.
* *
* Note: This clips in a regular order, and does not consider what is the * Note: This clips in a regular order, and does not consider what is the
* largest rectangular area outside the area that has been clipped out. * largest rectangular area outside the area that has been clipped out.
@ -584,9 +577,8 @@ DBReOrientLabel(cellDef, area, newPos)
*/ */
int int
dbGetLabelArea(tile, dinfo, area) dbGetLabelArea(tile, area)
Tile *tile; /* Tile found. */ Tile *tile; /* Tile found. */
TileType dinfo; /* Split tile information (unused) */
Rect *area; /* Area to be modified. */ Rect *area; /* Area to be modified. */
{ {
Rect r; Rect r;
@ -605,26 +597,6 @@ dbGetLabelArea(tile, dinfo, area)
return 0; return 0;
} }
/*
* ----------------------------------------------------------------------------
*
* dbLabelNotEmpty ---
*
* Callback function used by DBAdjustLabels. Finds any material under a
* label that is the label type, and returns 1 to stop the search.
*
* ----------------------------------------------------------------------------
*/
int
dbLabelNotEmpty(tile, dinfo, clientData)
Tile *tile; /* Tile found. */
TileType dinfo; /* Split tile information (unused) */
ClientData clientData; /* (unused) */
{
return 1;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -682,13 +654,6 @@ DBAdjustLabels(def, area)
TTMaskSetOnlyType(&lmask, lab->lab_type); TTMaskSetOnlyType(&lmask, lab->lab_type);
/* To do: Add compatible types (contact, residue) */ /* To do: Add compatible types (contact, residue) */
/* If there is no material left inside the label area, then
* the label gets reassigned to space.
*/
if (DBSrPaintArea((Tile *) NULL, def->cd_planes[DBPlane(lab->lab_type)],
&lab->lab_rect, &lmask, dbLabelNotEmpty, (ClientData)NULL) == 1)
{
TTMaskCom(&lmask); TTMaskCom(&lmask);
r = lab->lab_rect; r = lab->lab_rect;
@ -697,8 +662,7 @@ DBAdjustLabels(def, area)
if (!GEO_RECTNULL(&r)) if (!GEO_RECTNULL(&r))
{ {
if ((DBVerbose >= DB_VERBOSE_ALL) && if ((DBVerbose >= DB_VERBOSE_ALL) && ((def->cd_flags & CDINTERNAL) == 0))
((def->cd_flags & CDINTERNAL) == 0))
{ {
TxPrintf("Adjusting size of label \"%s\" in cell %s.\n", TxPrintf("Adjusting size of label \"%s\" in cell %s.\n",
lab->lab_text, def->cd_name); lab->lab_text, def->cd_name);
@ -714,7 +678,6 @@ DBAdjustLabels(def, area)
adjusted = TRUE; adjusted = TRUE;
} }
} }
}
if (!adjusted) if (!adjusted)
{ {
@ -797,10 +760,8 @@ DBAdjustLabelsNew(def, area)
def->cd_lastLabel = labPrev; def->cd_lastLabel = labPrev;
DBUndoEraseLabel(def, lab); DBUndoEraseLabel(def, lab);
DBWLabelChanged(def, lab, DBW_ALLWINDOWS); DBWLabelChanged(def, lab, DBW_ALLWINDOWS);
free_magic1_t mm1 = freeMagic1_init(); freeMagic((char *) lab);
freeMagic1(&mm1, (char *) lab);
lab = lab->lab_next; lab = lab->lab_next;
freeMagic1_end(&mm1);
modified = TRUE; modified = TRUE;
continue; continue;
} }
@ -1116,15 +1077,14 @@ DBPickLabelLayer(def, lab, doCalma)
*/ */
int int
dbPickFunc1(tile, dinfo, mask) dbPickFunc1(tile, mask)
Tile *tile; /* Tile found. */ Tile *tile; /* Tile found. */
TileType dinfo; /* Split tile information */
TileTypeBitMask *mask; /* Mask to be modified. */ TileTypeBitMask *mask; /* Mask to be modified. */
{ {
TileType type; TileType type;
if (IsSplit(tile)) if (IsSplit(tile))
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
else else
type = TiGetType(tile); type = TiGetType(tile);
@ -1143,16 +1103,15 @@ dbPickFunc1(tile, dinfo, mask)
*/ */
int int
dbPickFunc2(tile, dinfo, mask) dbPickFunc2(tile, mask)
Tile *tile; /* Tile found. */ Tile *tile; /* Tile found. */
TileType dinfo; /* Split tile information */
TileTypeBitMask *mask; /* Mask to be modified. */ TileTypeBitMask *mask; /* Mask to be modified. */
{ {
TileType type; TileType type;
TileTypeBitMask tmp, *rMask; TileTypeBitMask tmp, *rMask;
if (IsSplit(tile)) if (IsSplit(tile))
type = (dinfo & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile); type = (SplitSide(tile)) ? SplitRightType(tile) : SplitLeftType(tile);
else else
type = TiGetType(tile); type = TiGetType(tile);
@ -1785,10 +1744,8 @@ DBLoadFont(fontfile, scale)
} }
/* Remove the pointlist */ /* Remove the pointlist */
free_magic1_t mm1 = freeMagic1_init();
for (newPath = pathStart; newPath != NULL; newPath = newPath->fp_next) for (newPath = pathStart; newPath != NULL; newPath = newPath->fp_next)
freeMagic1(&mm1, newPath); freeMagic(newPath);
freeMagic1_end(&mm1);
pathStart = NULL; pathStart = NULL;
} }
else else

View File

@ -59,8 +59,6 @@ Tile *TiNMMergeRight();
Tile *TiNMMergeLeft(); Tile *TiNMMergeLeft();
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
void dbPaintShowTile(Tile *tile, PaintUndoInfo *undo, char *str);
int dbPaintDebug = 0; int dbPaintDebug = 0;
#endif /* PAINTDEBUG */ #endif /* PAINTDEBUG */
@ -273,10 +271,9 @@ DBPaintPlane0(plane, area, resultTbl, undo, method)
* search. * search.
*/ */
Tile *delayed = NULL; /* delayed free to extend lifetime */
start.p_x = area->r_xbot; start.p_x = area->r_xbot;
start.p_y = area->r_ytop - 1; start.p_y = area->r_ytop - 1;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &start); GOTOPOINT(tile, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -313,11 +310,6 @@ enumerate:
* Set up the directions in which we will have to * Set up the directions in which we will have to
* merge initially. Clipping can cause some of these * merge initially. Clipping can cause some of these
* to be turned off. * 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; mergeFlags = MRG_TOP | MRG_LEFT;
if (RIGHT(tile) >= area->r_xtop) mergeFlags |= MRG_RIGHT; if (RIGHT(tile) >= area->r_xtop) mergeFlags |= MRG_RIGHT;
@ -347,7 +339,6 @@ enumerate:
* Merging is only necessary if we clip to the left or to * Merging is only necessary if we clip to the left or to
* the right, and then only to the top or the bottom. * the right, and then only to the top or the bottom.
* We do the merge in-line for efficiency. * We do the merge in-line for efficiency.
* Clipping of split tiles is more complicated.
*/ */
/* Clip up */ /* Clip up */
@ -362,16 +353,12 @@ enumerate:
newType = (method == (unsigned char)PAINT_XOR) ? newType = (method == (unsigned char)PAINT_XOR) ?
*resultTbl : resultTbl[oldType]; *resultTbl : resultTbl[oldType];
if (mergeFlags & MRG_LEFT)
tile = TiNMMergeLeft(tile, plane); tile = TiNMMergeLeft(tile, plane);
if ((mergeFlags & MRG_RIGHT) || SplitDirection(newtile) == 1)
TiNMMergeRight(TR(newtile), plane); TiNMMergeRight(TR(newtile), plane);
} }
else else
{ {
if (mergeFlags & MRG_LEFT)
TiNMMergeLeft(newtile, plane); TiNMMergeLeft(newtile, plane);
if ((mergeFlags & MRG_RIGHT) || SplitDirection(tile) == 1)
TiNMMergeRight(TR(tile), plane); TiNMMergeRight(TR(tile), plane);
} }
} }
@ -401,16 +388,12 @@ enumerate:
newType = (method == (unsigned char)PAINT_XOR) ? newType = (method == (unsigned char)PAINT_XOR) ?
*resultTbl : resultTbl[oldType]; *resultTbl : resultTbl[oldType];
if (mergeFlags & MRG_LEFT)
tile = TiNMMergeLeft(tile, plane); tile = TiNMMergeLeft(tile, plane);
if ((mergeFlags & MRG_RIGHT) || SplitDirection(newtile) == 0)
TiNMMergeRight(TR(newtile), plane); TiNMMergeRight(TR(newtile), plane);
} }
else else
{ {
if (mergeFlags & MRG_LEFT)
TiNMMergeLeft(newtile, plane); TiNMMergeLeft(newtile, plane);
if ((mergeFlags & MRG_RIGHT) || SplitDirection(tile) == 0)
TiNMMergeRight(TR(tile), plane); TiNMMergeRight(TR(tile), plane);
} }
} }
@ -440,16 +423,12 @@ enumerate:
newType = (method == (unsigned char)PAINT_XOR) ? newType = (method == (unsigned char)PAINT_XOR) ?
*resultTbl : resultTbl[oldType]; *resultTbl : resultTbl[oldType];
if (mergeFlags & MRG_LEFT)
tile = TiNMMergeLeft(tile, plane); tile = TiNMMergeLeft(tile, plane);
if (mergeFlags & MRG_RIGHT)
TiNMMergeRight(LB(newtile), plane); TiNMMergeRight(LB(newtile), plane);
} }
else else
{ {
if (mergeFlags & MRG_LEFT)
TiNMMergeRight(newtile, plane); TiNMMergeRight(newtile, plane);
if (mergeFlags & MRG_RIGHT)
TiNMMergeLeft(LB(tile), plane); TiNMMergeLeft(LB(tile), plane);
} }
} }
@ -460,11 +439,11 @@ enumerate:
/* Merge the outside tile to its top */ /* Merge the outside tile to its top */
tp = RT(newtile); tp = RT(newtile);
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane); if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
/* Merge the outside tile to its bottom */ /* Merge the outside tile to its bottom */
tp = LB(newtile); tp = LB(newtile);
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane); if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
} }
mergeFlags &= ~MRG_RIGHT; mergeFlags &= ~MRG_RIGHT;
} }
@ -487,13 +466,13 @@ enumerate:
newType = (method == (unsigned char)PAINT_XOR) ? newType = (method == (unsigned char)PAINT_XOR) ?
*resultTbl : resultTbl[oldType]; *resultTbl : resultTbl[oldType];
if (mergeFlags & MRG_LEFT) // tile = TiNMMergeRight(tile, plane);
TiNMMergeLeft(LB(newtile), plane); TiNMMergeLeft(LB(newtile), plane);
} }
else else
{ {
if (mergeFlags & MRG_LEFT)
TiNMMergeLeft(newtile, plane); TiNMMergeLeft(newtile, plane);
// TiNMMergeRight(LB(tile), plane);
} }
} }
else else
@ -504,11 +483,11 @@ enumerate:
/* Merge the outside tile to its top */ /* Merge the outside tile to its top */
tp = RT(newtile); tp = RT(newtile);
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane); if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
/* Merge the outside tile to its bottom */ /* Merge the outside tile to its bottom */
tp = LB(newtile); tp = LB(newtile);
if (CANMERGE_Y(newtile, tp)) TiJoinY1(&delayed, newtile, tp, plane); if (CANMERGE_Y(newtile, tp)) TiJoinY(newtile, tp, plane);
} }
mergeFlags &= ~MRG_LEFT; mergeFlags &= ~MRG_LEFT;
} }
@ -600,7 +579,7 @@ clipdone:
if (mergeFlags & MRG_TOP) if (mergeFlags & MRG_TOP)
{ {
tp = RT(tile); tp = RT(tile);
if (CANMERGE_Y(tile, tp)) TiJoinY1(&delayed, tile, tp, plane); if (CANMERGE_Y(tile, tp)) TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "merged up (CHEAP)"); dbPaintShowTile(tile, undo, "merged up (CHEAP)");
@ -609,7 +588,7 @@ clipdone:
if (mergeFlags & MRG_BOTTOM) if (mergeFlags & MRG_BOTTOM)
{ {
tp = LB(tile); tp = LB(tile);
if (CANMERGE_Y(tile, tp)) TiJoinY1(&delayed, tile, tp, plane); if (CANMERGE_Y(tile, tp)) TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "merged down (CHEAP)"); dbPaintShowTile(tile, undo, "merged down (CHEAP)");
@ -669,7 +648,7 @@ done:
start.p_x = area->r_xbot; start.p_x = area->r_xbot;
start.p_y = area->r_ytop - 1; start.p_y = area->r_ytop - 1;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &start); GOTOPOINT(tile, &start);
while (TOP(tile) > area->r_ybot) while (TOP(tile) > area->r_ybot)
@ -717,8 +696,7 @@ enum2:
} }
done2: done2:
PlaneSetHint(plane, tile); plane->pl_hint = tile;
TiFreeIf(delayed);
return 0; return 0;
} }
@ -741,7 +719,7 @@ DBSplitTile(plane, point, splitx)
int splitx; int splitx;
{ {
Tile *tile, *newtile, *tp; Tile *tile, *newtile, *tp;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, point); GOTOPOINT(tile, point);
if (IsSplit(tile)) /* This should always be true */ if (IsSplit(tile)) /* This should always be true */
@ -815,7 +793,7 @@ DBFracturePlane(plane, area, resultTbl, undo)
start.p_x = area->r_xbot; start.p_x = area->r_xbot;
start.p_y = area->r_ytop - 1; start.p_y = area->r_ytop - 1;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &start); GOTOPOINT(tile, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -1012,7 +990,7 @@ paintdone:
} }
done: done:
PlaneSetHint(plane, tile); plane->pl_hint = tile;
} }
/* /*
@ -1054,12 +1032,11 @@ DBMergeNMTiles0(plane, area, undo, mergeOnce)
int clipTop; int clipTop;
Tile *tile, *tp, *tp2, *newtile, *tpnew; Tile *tile, *tp, *tp2, *newtile, *tpnew;
int aspecta, aspectb; int aspecta, aspectb;
Tile *delayed = NULL; /* delayed free to extend lifetime */
TileType ttype, ltype, rtype; TileType ttype, ltype, rtype;
start.p_x = area->r_xbot; start.p_x = area->r_xbot;
start.p_y = area->r_ytop - 1; start.p_y = area->r_ytop - 1;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &start); GOTOPOINT(tile, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -1144,23 +1121,23 @@ nmenum:
newtile = TiSplitY(tp2, TOP(tile)); newtile = TiSplitY(tp2, TOP(tile));
TiSetBody(newtile, ltype); TiSetBody(newtile, ltype);
if (CANMERGE_X(newtile, BL(newtile))) if (CANMERGE_X(newtile, BL(newtile)))
TiJoinX1(&delayed, newtile, BL(newtile), plane); TiJoinX(newtile, BL(newtile), plane);
if (CANMERGE_X(newtile, TR(newtile))) if (CANMERGE_X(newtile, TR(newtile)))
TiJoinX1(&delayed, newtile, TR(newtile), plane); TiJoinX(newtile, TR(newtile), plane);
if (CANMERGE_Y(newtile, RT(newtile))) if (CANMERGE_Y(newtile, RT(newtile)))
TiJoinY1(&delayed, newtile, RT(newtile), plane); TiJoinY(newtile, RT(newtile), plane);
} }
if (LEFT(tp2) < LEFT(tp)) if (LEFT(tp2) < LEFT(tp))
{ {
newtile = TiSplitX(tp2, LEFT(tp)); newtile = TiSplitX(tp2, LEFT(tp));
TiSetBody(newtile, ltype); TiSetBody(newtile, ltype);
if (CANMERGE_Y(tp2, LB(tp2))) if (CANMERGE_Y(tp2, LB(tp2)))
TiJoinY1(&delayed, tp2, LB(tp2), plane); TiJoinY(tp2, LB(tp2), plane);
if (CANMERGE_Y(tp2, RT(tp2))) if (CANMERGE_Y(tp2, RT(tp2)))
TiJoinY1(&delayed, tp2, RT(tp2), plane); TiJoinY(tp2, RT(tp2), plane);
tp2 = newtile; tp2 = newtile;
} }
TiJoinY1(&delayed, tp2, tp, plane); TiJoinY(tp2, tp, plane);
tp = tp2; tp = tp2;
tp2 = RT(tp2); tp2 = RT(tp2);
} }
@ -1174,11 +1151,11 @@ nmenum:
newtile = TiSplitY(tp2, BOTTOM(tp)); newtile = TiSplitY(tp2, BOTTOM(tp));
TiSetBody(newtile, rtype); TiSetBody(newtile, rtype);
if (CANMERGE_X(tp2, BL(tp2))) if (CANMERGE_X(tp2, BL(tp2)))
TiJoinX1(&delayed, tp2, BL(tp2), plane); TiJoinX(tp2, BL(tp2), plane);
if (CANMERGE_X(tp2, TR(tp2))) if (CANMERGE_X(tp2, TR(tp2)))
TiJoinX1(&delayed, tp2, TR(tp2), plane); TiJoinX(tp2, TR(tp2), plane);
if (CANMERGE_Y(tp2, LB(tp2))) if (CANMERGE_Y(tp2, LB(tp2)))
TiJoinY1(&delayed, tp2, LB(tp2), plane); TiJoinY(tp2, LB(tp2), plane);
tp2 = newtile; tp2 = newtile;
} }
if (RIGHT(tp2) > RIGHT(tile)) if (RIGHT(tp2) > RIGHT(tile))
@ -1186,16 +1163,16 @@ nmenum:
newtile = TiSplitX(tp2, RIGHT(tile)); newtile = TiSplitX(tp2, RIGHT(tile));
TiSetBody(newtile, rtype); TiSetBody(newtile, rtype);
if (CANMERGE_Y(newtile, LB(newtile))) if (CANMERGE_Y(newtile, LB(newtile)))
TiJoinY1(&delayed, newtile, LB(newtile), plane); TiJoinY(newtile, LB(newtile), plane);
if (CANMERGE_Y(newtile, RT(newtile))) if (CANMERGE_Y(newtile, RT(newtile)))
TiJoinY1(&delayed, newtile, RT(newtile), plane); TiJoinY(newtile, RT(newtile), plane);
} }
TiJoinY1(&delayed, tp2, tile, plane); TiJoinY(tp2, tile, plane);
tile = tp2; tile = tp2;
tp2 = LB(tp2); tp2 = LB(tp2);
} }
/* Merge tp and tile */ /* Merge tp and tile */
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
TiSetBody(tile, ttype); TiSetBody(tile, ttype);
} }
else /* split direction 1 */ else /* split direction 1 */
@ -1236,11 +1213,11 @@ nmenum:
newtile = TiSplitY(tp2, BOTTOM(tp)); newtile = TiSplitY(tp2, BOTTOM(tp));
TiSetBody(newtile, ltype); TiSetBody(newtile, ltype);
if (CANMERGE_X(tp2, BL(tp2))) if (CANMERGE_X(tp2, BL(tp2)))
TiJoinX1(&delayed, tp2, BL(tp2), plane); TiJoinX(tp2, BL(tp2), plane);
if (CANMERGE_X(tp2, TR(tp2))) if (CANMERGE_X(tp2, TR(tp2)))
TiJoinX1(&delayed, tp2, TR(tp2), plane); TiJoinX(tp2, TR(tp2), plane);
if (CANMERGE_Y(tp2, LB(tp2))) if (CANMERGE_Y(tp2, LB(tp2)))
TiJoinY1(&delayed, tp2, LB(tp2), plane); TiJoinY(tp2, LB(tp2), plane);
tp2 = newtile; tp2 = newtile;
} }
if (LEFT(tp2) < LEFT(tile)) if (LEFT(tp2) < LEFT(tile))
@ -1248,12 +1225,12 @@ nmenum:
newtile = TiSplitX(tp2, LEFT(tile)); newtile = TiSplitX(tp2, LEFT(tile));
TiSetBody(newtile, ltype); TiSetBody(newtile, ltype);
if (CANMERGE_Y(tp2, LB(tp2))) if (CANMERGE_Y(tp2, LB(tp2)))
TiJoinY1(&delayed, tp2, LB(tp2), plane); TiJoinY(tp2, LB(tp2), plane);
if (CANMERGE_Y(tp2, RT(tp2))) if (CANMERGE_Y(tp2, RT(tp2)))
TiJoinY1(&delayed, tp2, RT(tp2), plane); TiJoinY(tp2, RT(tp2), plane);
tp2 = newtile; tp2 = newtile;
} }
TiJoinY1(&delayed, tp2, tile, plane); TiJoinY(tp2, tile, plane);
tile = tp2; tile = tp2;
tp2 = LB(tp2); tp2 = LB(tp2);
} }
@ -1268,27 +1245,27 @@ nmenum:
newtile = TiSplitY(tp2, TOP(tile)); newtile = TiSplitY(tp2, TOP(tile));
TiSetBody(newtile, rtype); TiSetBody(newtile, rtype);
if (CANMERGE_X(newtile, BL(newtile))) if (CANMERGE_X(newtile, BL(newtile)))
TiJoinX1(&delayed, newtile, BL(newtile), plane); TiJoinX(newtile, BL(newtile), plane);
if (CANMERGE_X(newtile, TR(newtile))) if (CANMERGE_X(newtile, TR(newtile)))
TiJoinX1(&delayed, newtile, TR(newtile), plane); TiJoinX(newtile, TR(newtile), plane);
if (CANMERGE_Y(newtile, RT(newtile))) if (CANMERGE_Y(newtile, RT(newtile)))
TiJoinY1(&delayed, newtile, RT(newtile), plane); TiJoinY(newtile, RT(newtile), plane);
} }
if (RIGHT(tp2) > RIGHT(tp)) if (RIGHT(tp2) > RIGHT(tp))
{ {
newtile = TiSplitX(tp2, RIGHT(tp)); newtile = TiSplitX(tp2, RIGHT(tp));
TiSetBody(newtile, rtype); TiSetBody(newtile, rtype);
if (CANMERGE_Y(newtile, LB(newtile))) if (CANMERGE_Y(newtile, LB(newtile)))
TiJoinY1(&delayed, newtile, LB(newtile), plane); TiJoinY(newtile, LB(newtile), plane);
if (CANMERGE_Y(newtile, RT(newtile))) if (CANMERGE_Y(newtile, RT(newtile)))
TiJoinY1(&delayed, newtile, RT(newtile), plane); TiJoinY(newtile, RT(newtile), plane);
} }
TiJoinY1(&delayed, tp2, tp, plane); TiJoinY(tp2, tp, plane);
tp = tp2; tp = tp2;
tp2 = RT(tp2); tp2 = RT(tp2);
} }
/* Merge tp and tile */ /* Merge tp and tile */
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
TiSetBody(tile, ttype); TiSetBody(tile, ttype);
} }
/* Now repeat until no more merging is possible */ /* Now repeat until no more merging is possible */
@ -1329,8 +1306,7 @@ nmenum:
} }
nmdone: nmdone:
PlaneSetHint(plane, tile); plane->pl_hint = tile;
TiFreeIf(delayed);
return 0; return 0;
} }
@ -1435,6 +1411,10 @@ DBDiagonalProc(oldtype, dinfo)
else else
return -1; return -1;
/* For purposes of "undo" recording, record which side we just painted */
if (dinfo->side)
newtype |= TT_SIDE;
return newtype; return newtype;
} }
@ -1519,7 +1499,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
/* linked list out of them. */ /* linked list out of them. */
lhead = NULL; lhead = NULL;
DBSrPaintArea(PlaneGetHint(plane), plane, area, &DBAllTypeBits, DBSrPaintArea(plane->pl_hint, plane, area, &DBAllTypeBits,
dbNMEnumFunc, (ClientData) &lhead); dbNMEnumFunc, (ClientData) &lhead);
/*--------------------------------------------------------------*/ /*--------------------------------------------------------------*/
@ -1539,7 +1519,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
GeoClip(&lhead->r_r, area); GeoClip(&lhead->r_r, area);
start.p_x = area->r_xbot; start.p_x = area->r_xbot;
start.p_y = area->r_ytop - 1; start.p_y = area->r_ytop - 1;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &start); GOTOPOINT(tile, &start);
/* Ignore tiles that don't interact. This has */ /* Ignore tiles that don't interact. This has */
@ -1628,7 +1608,7 @@ DBNMPaintPlane0(plane, exacttype, area, resultTbl, undo, method)
{ {
result = DBPaintPlane(plane, &(lr->r_r), DBSpecialPaintTbl, result = DBPaintPlane(plane, &(lr->r_r), DBSpecialPaintTbl,
(PaintUndoInfo *)NULL); (PaintUndoInfo *)NULL);
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &(lr->r_r.r_ll)); GOTOPOINT(tile, &(lr->r_r.r_ll));
if (undo && UndoIsEnabled()) if (undo && UndoIsEnabled())
{ {
@ -1788,14 +1768,12 @@ nextrect:
lr = lr->r_next; lr = lr->r_next;
} }
free_magic1_t mm1 = freeMagic1_init();
lr = lhead; lr = lhead;
while (lr != NULL) while (lr != NULL)
{ {
freeMagic1(&mm1, (char *) lr); freeMagic((char *) lr);
lr = lr->r_next; lr = lr->r_next;
} }
freeMagic1_end(&mm1);
} }
else else
result = DBPaintPlane0(plane, area, resultTbl, undo, (method == PAINT_MARK) ? result = DBPaintPlane0(plane, area, resultTbl, undo, (method == PAINT_MARK) ?
@ -1816,15 +1794,14 @@ nextrect:
*/ */
int int
dbNMEnumFunc(tile, dinfo, arg) dbNMEnumFunc(tile, arg)
Tile *tile; Tile *tile;
TileType dinfo;
LinkedRect **arg; LinkedRect **arg;
{ {
LinkedRect *lr; LinkedRect *lr;
/* Ignore the second call to any diagonal---only count once! */ /* Ignore the second call to any diagonal---only count once! */
if (IsSplit(tile) && (dinfo & TT_SIDE)) return 0; if (IsSplit(tile) && SplitSide(tile)) return 0;
lr = (LinkedRect *) mallocMagic(sizeof(LinkedRect)); lr = (LinkedRect *) mallocMagic(sizeof(LinkedRect));
TiToRect(tile, &lr->r_r); TiToRect(tile, &lr->r_r);
@ -1908,7 +1885,6 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
PaintUndoInfo *undo; /* See DBPaintPlane() above */ PaintUndoInfo *undo; /* See DBPaintPlane() above */
bool mark; /* Mark tiles that were processed */ bool mark; /* Mark tiles that were processed */
{ {
Tile *delayed = NULL; /* delayed free to extend lifetime */
Tile *tp, *tpLast; Tile *tp, *tpLast;
int ysplit; int ysplit;
@ -2015,7 +1991,7 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
if (mark) dbMarkClient(tile, area); if (mark) dbMarkClient(tile, area);
} }
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile)); if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged left"); dbPaintShowTile(tile, undo, "(DBMERGE) merged left");
@ -2031,7 +2007,7 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
if (mark) dbMarkClient(tile, area); if (mark) dbMarkClient(tile, area);
} }
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile)); if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged right"); dbPaintShowTile(tile, undo, "(DBMERGE) merged right");
@ -2040,7 +2016,7 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
if (mergeFlags&MRG_TOP) if (mergeFlags&MRG_TOP)
{ {
tp = RT(tile); tp = RT(tile);
if (CANMERGE_Y(tp, tile)) TiJoinY1(&delayed, tile, tp, plane); if (CANMERGE_Y(tp, tile)) TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged up"); dbPaintShowTile(tile, undo, "(DBMERGE) merged up");
@ -2049,14 +2025,13 @@ dbPaintMerge(tile, newType, area, plane, mergeFlags, undo, mark)
if (mergeFlags&MRG_BOTTOM) if (mergeFlags&MRG_BOTTOM)
{ {
tp = LB(tile); tp = LB(tile);
if (CANMERGE_Y(tp, tile)) TiJoinY1(&delayed, tile, tp, plane); if (CANMERGE_Y(tp, tile)) TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged down"); dbPaintShowTile(tile, undo, "(DBMERGE) merged down");
#endif /* PAINTDEBUG */ #endif /* PAINTDEBUG */
} }
TiFreeIf(delayed);
return (tile); return (tile);
} }
@ -2119,10 +2094,9 @@ DBPaintType(plane, area, resultTbl, client, undo, tileMask)
* search. * search.
*/ */
Tile *delayed = NULL; /* delayed free to extend lifetime */
start.p_x = area->r_xbot; start.p_x = area->r_xbot;
start.p_y = area->r_ytop - 1; start.p_y = area->r_ytop - 1;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &start); GOTOPOINT(tile, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -2212,14 +2186,14 @@ enumerate:
if (CANMERGE_Y(newtile, tp) && if (CANMERGE_Y(newtile, tp) &&
( (TiGetClient(tp) == TiGetClient(newtile)) || ( (TiGetClient(tp) == TiGetClient(newtile)) ||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) ) ( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
TiJoinY1(&delayed, newtile, tp, plane); TiJoinY(newtile, tp, plane);
/* Merge the outside tile to its bottom */ /* Merge the outside tile to its bottom */
tp = LB(newtile); tp = LB(newtile);
if (CANMERGE_Y(newtile, tp) && if (CANMERGE_Y(newtile, tp) &&
( (TiGetClient(tp) == TiGetClient(newtile)) || ( (TiGetClient(tp) == TiGetClient(newtile)) ||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) ) ( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
TiJoinY1(&delayed, newtile, tp, plane); TiJoinY(newtile, tp, plane);
} }
/* Clip left */ /* Clip left */
@ -2236,14 +2210,14 @@ enumerate:
if (CANMERGE_Y(newtile, tp) && if (CANMERGE_Y(newtile, tp) &&
( (TiGetClient(tp) == TiGetClient(newtile)) || ( (TiGetClient(tp) == TiGetClient(newtile)) ||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) ) ( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
TiJoinY1(&delayed, newtile, tp, plane); TiJoinY(newtile, tp, plane);
/* Merge the outside tile to its bottom */ /* Merge the outside tile to its bottom */
tp = LB(newtile); tp = LB(newtile);
if (CANMERGE_Y(newtile, tp) && if (CANMERGE_Y(newtile, tp) &&
( (TiGetClient(tp) == TiGetClient(newtile)) || ( (TiGetClient(tp) == TiGetClient(newtile)) ||
( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) ) ( ! TTMaskHasType(tileMask, TiGetTypeExact(tp)) ) ) )
TiJoinY1(&delayed, newtile, tp, plane); TiJoinY(newtile, tp, plane);
} }
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
@ -2302,7 +2276,7 @@ enumerate:
{ {
tp = RT(tile); tp = RT(tile);
if (CANMERGE_Y(tile, tp) && (tp->ti_client == client)) if (CANMERGE_Y(tile, tp) && (tp->ti_client == client))
TiJoinY1(&delayed, tile, tp, plane); TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "merged up (CHEAP)"); dbPaintShowTile(tile, undo, "merged up (CHEAP)");
@ -2312,7 +2286,7 @@ enumerate:
{ {
tp = LB(tile); tp = LB(tile);
if (CANMERGE_Y(tile, tp) && (tp->ti_client == client)) if (CANMERGE_Y(tile, tp) && (tp->ti_client == client))
TiJoinY1(&delayed, tile, tp, plane); TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "merged down (CHEAP)"); dbPaintShowTile(tile, undo, "merged down (CHEAP)");
@ -2359,8 +2333,7 @@ paintdone:
} }
done: done:
PlaneSetHint(plane, tile); plane->pl_hint = tile;
TiFreeIf(delayed);
} }
/* /*
@ -2407,7 +2380,6 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
PaintUndoInfo *undo; /* See DBPaintPlane() above */ PaintUndoInfo *undo; /* See DBPaintPlane() above */
ClientData client; ClientData client;
{ {
Tile *delayed = NULL; /* delayed free to extend lifetime */
Tile *tp, *tpLast; Tile *tp, *tpLast;
int ysplit; int ysplit;
@ -2509,7 +2481,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
TiSetClient(tpLast, client); TiSetClient(tpLast, client);
} }
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile)); if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged left"); dbPaintShowTile(tile, undo, "(DBMERGE) merged left");
@ -2525,7 +2497,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
TiSetClient(tpLast, client); TiSetClient(tpLast, client);
} }
if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile)); if (BOTTOM(tp) < BOTTOM(tile)) tp = TiSplitY(tp, BOTTOM(tile));
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged right"); dbPaintShowTile(tile, undo, "(DBMERGE) merged right");
@ -2534,7 +2506,7 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
if (mergeFlags&MRG_TOP) if (mergeFlags&MRG_TOP)
{ {
tp = RT(tile); tp = RT(tile);
if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY1(&delayed, tile, tp, plane); if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged up"); dbPaintShowTile(tile, undo, "(DBMERGE) merged up");
@ -2543,14 +2515,13 @@ dbMergeType(tile, newType, plane, mergeFlags, undo, client)
if (mergeFlags&MRG_BOTTOM) if (mergeFlags&MRG_BOTTOM)
{ {
tp = LB(tile); tp = LB(tile);
if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY1(&delayed, tile, tp, plane); if (CANMERGE_Y(tp, tile) && (tp->ti_client == client)) TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged down"); dbPaintShowTile(tile, undo, "(DBMERGE) merged down");
#endif /* PAINTDEBUG */ #endif /* PAINTDEBUG */
} }
TiFreeIf(delayed);
return (tile); return (tile);
} }
@ -2610,10 +2581,9 @@ DBPaintPlaneVert(plane, area, resultTbl, undo)
* search. * search.
*/ */
Tile *delayed = NULL; /* delayed free to extend lifetime */
start.p_x = area->r_xbot; start.p_x = area->r_xbot;
start.p_y = area->r_ytop - 1; start.p_y = area->r_ytop - 1;
tile = PlaneGetHint(plane); tile = plane->pl_hint;
GOTOPOINT(tile, &start); GOTOPOINT(tile, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -2692,11 +2662,11 @@ enumerate:
/* Merge the outside tile to its left */ /* Merge the outside tile to its left */
tp = BL(newtile); tp = BL(newtile);
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane); if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
/* Merge the outside tile to its right */ /* Merge the outside tile to its right */
tp = TR(newtile); tp = TR(newtile);
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane); if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
} }
/* Clip down */ /* Clip down */
@ -2708,11 +2678,11 @@ enumerate:
/* Merge the outside tile to its left */ /* Merge the outside tile to its left */
tp = BL(newtile); tp = BL(newtile);
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane); if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
/* Merge the outside tile to its right */ /* Merge the outside tile to its right */
tp = TR(newtile); tp = TR(newtile);
if (CANMERGE_X(newtile, tp)) TiJoinX1(&delayed, newtile, tp, plane); if (CANMERGE_X(newtile, tp)) TiJoinX(newtile, tp, plane);
} }
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
@ -2770,7 +2740,7 @@ enumerate:
if (mergeFlags & MRG_LEFT) if (mergeFlags & MRG_LEFT)
{ {
tp = BL(tile); tp = BL(tile);
if (CANMERGE_X(tile, tp)) TiJoinX1(&delayed, tile, tp, plane); if (CANMERGE_X(tile, tp)) TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "merged left (CHEAP)"); dbPaintShowTile(tile, undo, "merged left (CHEAP)");
@ -2779,7 +2749,7 @@ enumerate:
if (mergeFlags & MRG_RIGHT) if (mergeFlags & MRG_RIGHT)
{ {
tp = TR(tile); tp = TR(tile);
if (CANMERGE_X(tile, tp)) TiJoinX1(&delayed, tile, tp, plane); if (CANMERGE_X(tile, tp)) TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "merged right (CHEAP)"); dbPaintShowTile(tile, undo, "merged right (CHEAP)");
@ -2826,8 +2796,7 @@ paintdone:
} }
done: done:
PlaneSetHint(plane, tile); plane->pl_hint = tile;
TiFreeIf(delayed);
return 0; return 0;
} }
@ -2880,7 +2849,6 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
int mergeFlags; /* Specify which directions to merge */ int mergeFlags; /* Specify which directions to merge */
PaintUndoInfo *undo; /* See DBPaintPlane() above */ PaintUndoInfo *undo; /* See DBPaintPlane() above */
{ {
Tile *delayed = NULL; /* delayed free to extend lifetime */
Tile *tp, *tpLast; Tile *tp, *tpLast;
int xsplit; int xsplit;
@ -2975,7 +2943,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
if (LEFT(tp) < LEFT(tile)) tp = TiSplitX(tp, LEFT(tile)); if (LEFT(tp) < LEFT(tile)) tp = TiSplitX(tp, LEFT(tile));
if (RIGHT(tp) > RIGHT(tile)) if (RIGHT(tp) > RIGHT(tile))
tpLast = TiSplitX(tp, RIGHT(tile)), TiSetBody(tpLast, newType); tpLast = TiSplitX(tp, RIGHT(tile)), TiSetBody(tpLast, newType);
TiJoinY1(&delayed, tile, tp, plane); TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged up"); dbPaintShowTile(tile, undo, "(DBMERGE) merged up");
@ -2988,7 +2956,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
if (LEFT(tp) < LEFT(tile)) tp = TiSplitX(tp, LEFT(tile)); if (LEFT(tp) < LEFT(tile)) tp = TiSplitX(tp, LEFT(tile));
if (RIGHT(tp) > RIGHT(tile)) if (RIGHT(tp) > RIGHT(tile))
tpLast = TiSplitX(tp, RIGHT(tile)), TiSetBody(tpLast, newType); tpLast = TiSplitX(tp, RIGHT(tile)), TiSetBody(tpLast, newType);
TiJoinY1(&delayed, tile, tp, plane); TiJoinY(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged down"); dbPaintShowTile(tile, undo, "(DBMERGE) merged down");
@ -2998,7 +2966,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
if (mergeFlags&MRG_LEFT) if (mergeFlags&MRG_LEFT)
{ {
tp = BL(tile); tp = BL(tile);
if (CANMERGE_X(tp, tile)) TiJoinX1(&delayed, tile, tp, plane); if (CANMERGE_X(tp, tile)) TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged left"); dbPaintShowTile(tile, undo, "(DBMERGE) merged left");
@ -3007,14 +2975,13 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
if (mergeFlags&MRG_RIGHT) if (mergeFlags&MRG_RIGHT)
{ {
tp = TR(tile); tp = TR(tile);
if (CANMERGE_X(tp, tile)) TiJoinX1(&delayed, tile, tp, plane); if (CANMERGE_X(tp, tile)) TiJoinX(tile, tp, plane);
#ifdef PAINTDEBUG #ifdef PAINTDEBUG
if (dbPaintDebug) if (dbPaintDebug)
dbPaintShowTile(tile, undo, "(DBMERGE) merged right"); dbPaintShowTile(tile, undo, "(DBMERGE) merged right");
#endif /* PAINTDEBUG */ #endif /* PAINTDEBUG */
} }
TiFreeIf(delayed);
return (tile); return (tile);
} }
@ -3037,7 +3004,7 @@ dbPaintMergeVert(tile, newType, plane, mergeFlags, undo)
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
#include "utils/styles.h" #include "styles.h"
void void
dbPaintShowTile(tile, undo, str) dbPaintShowTile(tile, undo, str)
@ -3060,16 +3027,6 @@ dbPaintShowTile(tile, undo, str)
TxPrintf("%s --more--", str); fflush(stdout); TxPrintf("%s --more--", str); fflush(stdout);
(void) TxGetLine(answer, sizeof answer); (void) TxGetLine(answer, sizeof answer);
DBWFeedbackClear(NULL); 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 */ #endif /* PAINTDEBUG */
@ -3359,7 +3316,6 @@ TiNMMergeRight(tile, plane)
Tile *tile; Tile *tile;
Plane *plane; Plane *plane;
{ {
Tile *delayed = NULL; /* delayed free to extend lifetime */
TileType ttype = TiGetTypeExact(tile); TileType ttype = TiGetTypeExact(tile);
Tile *tp, *tp2, *newtile; Tile *tp, *tp2, *newtile;
@ -3391,7 +3347,7 @@ TiNMMergeRight(tile, plane)
else else
newtile = tile; newtile = tile;
// Join tp to newtile // Join tp to newtile
TiJoinX1(&delayed, newtile, tp, plane); TiJoinX(newtile, tp, plane);
} }
tp = tp2; tp = tp2;
} }
@ -3408,13 +3364,11 @@ TiNMMergeRight(tile, plane)
newtile = TiSplitY(tp, BOTTOM(tile)); newtile = TiSplitY(tp, BOTTOM(tile));
TiSetBody(newtile, ttype); TiSetBody(newtile, ttype);
// join newtile to tile // join newtile to tile
TiJoinX1(&delayed, tile, newtile, plane); TiJoinX(tile, newtile, plane);
// merge up if possible // merge up if possible
if (CANMERGE_Y(tile, RT(tile))) TiJoinY1(&delayed, tile, RT(tile), plane); if (CANMERGE_Y(tile, RT(tile))) TiJoinY(tile, RT(tile), plane);
} }
} }
TiFreeIf(delayed);
return tile; return tile;
} }
@ -3442,7 +3396,6 @@ TiNMMergeLeft(tile, plane)
Tile *tile; Tile *tile;
Plane *plane; Plane *plane;
{ {
Tile *delayed = NULL; /* delayed free to extend lifetime */
TileType ttype = TiGetTypeExact(tile); TileType ttype = TiGetTypeExact(tile);
Tile *tp, *tp2, *newtile; Tile *tp, *tp2, *newtile;
@ -3475,7 +3428,7 @@ TiNMMergeLeft(tile, plane)
else else
newtile = tile; newtile = tile;
// Join tp to tile // Join tp to tile
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
tile = newtile; tile = newtile;
} }
tp = tp2; tp = tp2;
@ -3493,16 +3446,14 @@ TiNMMergeLeft(tile, plane)
newtile = TiSplitY(tp, TOP(tile)); newtile = TiSplitY(tp, TOP(tile));
TiSetBody(newtile, ttype); TiSetBody(newtile, ttype);
// join tp to tile // join tp to tile
TiJoinX1(&delayed, tile, tp, plane); TiJoinX(tile, tp, plane);
} }
} }
else else
{ {
// Merge up if possible // Merge up if possible
if (CANMERGE_Y(tile, tp)) TiJoinY1(&delayed, tile, tp, plane); if (CANMERGE_Y(tile, tp)) TiJoinY(tile, tp, plane);
} }
TiFreeIf(delayed);
return tile; return tile;
} }

View File

@ -119,9 +119,8 @@ DBPaint (cellDef, rect, type)
*/ */
int int
dbResolveImages(tile, dinfo, cellDef) dbResolveImages(tile, cellDef)
Tile *tile; Tile *tile;
TileType dinfo;
CellDef *cellDef; CellDef *cellDef;
{ {
Rect rect; Rect rect;
@ -131,7 +130,7 @@ dbResolveImages(tile, dinfo, cellDef)
/* Recursive call back to DBPaint---this will ensure that */ /* Recursive call back to DBPaint---this will ensure that */
/* all of the planes of the image type are painted. */ /* all of the planes of the image type are painted. */
DBPaint(cellDef, &rect, TiGetTypeExact(tile) | dinfo); DBPaint(cellDef, &rect, TiGetTypeExact(tile));
return 0; return 0;
} }

View File

@ -32,16 +32,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "database/database.h" #include "database/database.h"
#include "utils/malloc.h" #include "utils/malloc.h"
/* Global variable */
bool DBPropCompat = TRUE; /* If TRUE, then always save properties to
* .mag files as type "string" for backwards
* compatibility. If FALSE, then properties
* are saved to the .mag file along with their
* type. Regardless of the setting, properties
* which are reserved keywords are converted
* to the best internal representation on input.
*/
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* *
@ -59,14 +49,14 @@ void
DBPropPut(cellDef, name, value) DBPropPut(cellDef, name, value)
CellDef *cellDef; /* Pointer to definition of cell. */ CellDef *cellDef; /* Pointer to definition of cell. */
char *name; /* The name of the property desired. */ char *name; /* The name of the property desired. */
PropertyRecord *value; /* MUST point to a malloc'ed structure, or NULL. ClientData value; /* MUST point to a malloc'ed structure, or NULL.
* This will be freed when the CellDef is freed. * This will be freed when the CellDef is freed.
*/ */
{ {
HashTable *htab; HashTable *htab;
HashEntry *entry; HashEntry *entry;
PropertyRecord *oldvalue; char *oldvalue;
/* Honor the NOEDIT flag. Note that the caller always assumes that */ /* Honor the NOEDIT flag. Note that the caller always assumes that */
/* the value would be saved in the hash table, so if it is not */ /* the value would be saved in the hash table, so if it is not */
@ -105,23 +95,12 @@ DBPropPut(cellDef, name, value)
} }
entry = HashFind(htab, name); entry = HashFind(htab, name);
oldvalue = (PropertyRecord *)HashGetValue(entry); oldvalue = (char *)HashGetValue(entry);
/* All properties are allocated as a single block and can just be freed, if (oldvalue != NULL) freeMagic(oldvalue);
* except for plane properties, which require freeing the plane. if (value == (ClientData)NULL)
*/
if (oldvalue != NULL)
{
if (oldvalue->prop_type == PROPERTY_TYPE_PLANE)
{
DBFreePaintPlane(oldvalue->prop_value.prop_plane);
TiFreePlane(oldvalue->prop_value.prop_plane);
}
freeMagic((char *)oldvalue);
}
if (value == (PropertyRecord *)NULL)
HashRemove(htab, name); HashRemove(htab, name);
else else
HashSetValue(entry, PTR2CD(value)); HashSetValue(entry, value);
} }
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
@ -131,13 +110,13 @@ DBPropPut(cellDef, name, value)
* Get a property from a celldef. * Get a property from a celldef.
* *
* Results: * Results:
* NULL if the property didn't exist, or if the property record was NULL. * NULL if the property didn't exist, or if the property value was NULL.
* Otherwise, returns a pointer to the property record. * Otherwise, ClientData that represents the property.
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
PropertyRecord * ClientData
DBPropGet(cellDef, name, found) DBPropGet(cellDef, name, found)
CellDef *cellDef; /* Pointer to definition of cell. */ CellDef *cellDef; /* Pointer to definition of cell. */
char *name; /* The name of the property desired. */ char *name; /* The name of the property desired. */
@ -145,12 +124,12 @@ DBPropGet(cellDef, name, found)
* exists. * exists.
*/ */
{ {
PropertyRecord *result; ClientData result;
bool haveit; bool haveit;
HashTable *htab; HashTable *htab;
HashEntry *entry; HashEntry *entry;
result = (PropertyRecord *)NULL; result = (ClientData) NULL;
haveit = FALSE; haveit = FALSE;
htab = (HashTable *) cellDef->cd_props; htab = (HashTable *) cellDef->cd_props;
if (htab == (HashTable *) NULL) goto done; if (htab == (HashTable *) NULL) goto done;
@ -159,7 +138,7 @@ DBPropGet(cellDef, name, found)
if (entry != NULL) if (entry != NULL)
{ {
haveit = TRUE; haveit = TRUE;
result = (PropertyRecord *)HashGetValue(entry); result = (ClientData) HashGetValue(entry);
} }
done: done:
@ -167,109 +146,6 @@ done:
return result; return result;
} }
/* ----------------------------------------------------------------------------
*
* DBPropGetString --
*
* Get a string property from a celldef.
*
* Results:
* NULL if the property didn't exist, or if the property record was NULL.
* Otherwise, returns a pointer to the property's string record.
*
* Notes:
* This is basically the original DBPropGet(), when properties were only
* allowed to be strings.
*
* ----------------------------------------------------------------------------
*/
char *
DBPropGetString(cellDef, name, found)
CellDef *cellDef; /* Pointer to definition of cell. */
char *name; /* The name of the property desired. */
bool *found; /* If not NULL, filled in with TRUE iff the property
* exists.
*/
{
char *result = NULL;
PropertyRecord *proprec;
bool haveit;
HashTable *htab;
HashEntry *entry;
haveit = FALSE;
htab = (HashTable *) cellDef->cd_props;
if (htab == (HashTable *) NULL) goto pdone;
entry = HashLookOnly(htab, name);
if (entry != NULL)
{
proprec = (PropertyRecord *)HashGetValue(entry);
if (proprec->prop_type == PROPERTY_TYPE_STRING)
{
haveit = TRUE;
result = proprec->prop_value.prop_string;
}
}
pdone:
if (found != (bool *) NULL) *found = haveit;
return result;
}
/* ----------------------------------------------------------------------------
*
* DBPropGetDouble --
*
* Get a single double-long integer property from a celldef.
*
* Results:
* NULL if the property didn't exist, or if the property record was NULL.
* Otherwise, returns a pointer to the property's value record.
*
* ----------------------------------------------------------------------------
*/
dlong
DBPropGetDouble(cellDef, name, found)
CellDef *cellDef; /* Pointer to definition of cell. */
char *name; /* The name of the property desired. */
bool *found; /* If not NULL, filled in with TRUE iff the property
* exists.
*/
{
dlong result = 0;
PropertyRecord *proprec;
bool haveit;
HashTable *htab;
HashEntry *entry;
haveit = FALSE;
htab = (HashTable *) cellDef->cd_props;
if (htab == (HashTable *) NULL) goto ddone;
entry = HashLookOnly(htab, name);
if (entry != NULL)
{
proprec = (PropertyRecord *)HashGetValue(entry);
if (proprec->prop_type == PROPERTY_TYPE_DOUBLE)
{
haveit = TRUE;
result = proprec->prop_value.prop_double[0];
}
else if (proprec->prop_type == PROPERTY_TYPE_STRING)
{
haveit = TRUE;
sscanf(proprec->prop_value.prop_string, "%"DLONG_PREFIX"d", &result);
}
}
ddone:
if (found != (bool *) NULL) *found = haveit;
return result;
}
/* ---------------------------------------------------------------------------- /* ----------------------------------------------------------------------------
* *
* DBPropEnum -- * DBPropEnum --
@ -292,7 +168,7 @@ DBPropEnum(cellDef, func, cdata)
* *
* int foo(name, value, cdata) * int foo(name, value, cdata)
* char *name; * char *name;
* PropertyRecord *value; * ClientData value;
* ClientData cdata; * ClientData cdata;
* { * {
* -- return 0 to continue, * -- return 0 to continue,
@ -313,7 +189,7 @@ DBPropEnum(cellDef, func, cdata)
HashStartSearch(&hs); HashStartSearch(&hs);
while ((entry = HashNext(htab, &hs)) != NULL) while ((entry = HashNext(htab, &hs)) != NULL)
{ {
res = (*func)(entry->h_key.h_name, (PropertyRecord *)entry->h_pointer, cdata); res = (*func)(entry->h_key.h_name, (ClientData) entry->h_pointer, cdata);
if (res != 0) return res; if (res != 0) return res;
} }

View File

@ -327,11 +327,11 @@ DBTechNoisyNamePlane(planename)
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
const char * char *
DBTypeShortName( DBTypeShortName(type)
TileType type) TileType type;
{ {
const NameList *tbl; NameList *tbl;
for (tbl = dbTypeNameLists.sn_next; for (tbl = dbTypeNameLists.sn_next;
tbl != &dbTypeNameLists; tbl != &dbTypeNameLists;
@ -347,11 +347,11 @@ DBTypeShortName(
return ("???"); return ("???");
} }
const char * char *
DBPlaneShortName( DBPlaneShortName(pNum)
int pNum) int pNum;
{ {
const NameList *tbl; NameList *tbl;
for (tbl = dbPlaneNameLists.sn_next; for (tbl = dbPlaneNameLists.sn_next;
tbl != &dbPlaneNameLists; tbl != &dbPlaneNameLists;
@ -478,7 +478,7 @@ DBTechPrintTypes(mask, dolist)
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_AppendResult(magicinterp, " ", (char *)NULL); Tcl_AppendResult(magicinterp, " ", (char *)NULL);
#else #else
TxPrintf(" "); TxPrintf(" ", keepname);
#endif #endif
} }
} }
@ -530,7 +530,7 @@ DBTechPrintTypes(mask, dolist)
#ifdef MAGIC_WRAPPER #ifdef MAGIC_WRAPPER
Tcl_AppendResult(magicinterp, " ", (char *)NULL); Tcl_AppendResult(magicinterp, " ", (char *)NULL);
#else #else
TxPrintf(" "); TxPrintf(" ", keepname);
#endif #endif
} }
} }

View File

@ -38,14 +38,14 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
/* Types and their names */ /* Types and their names */
int DBNumTypes; int DBNumTypes;
const char *DBTypeLongNameTbl[NT]; char *DBTypeLongNameTbl[NT];
int DBTypePlaneTbl[NT]; /* Normally accessed as macro "DBPlane(x)" */ int DBTypePlaneTbl[NT]; /* Normally accessed as macro "DBPlane(x)" */
NameList dbTypeNameLists = {NULL, NULL, NULL, (ClientData)0, FALSE}; NameList dbTypeNameLists = {NULL, NULL, NULL, (ClientData)0, FALSE};
HashTable DBTypeAliasTable; HashTable DBTypeAliasTable;
/* Planes and their names */ /* Planes and their names */
int DBNumPlanes; int DBNumPlanes;
const char *DBPlaneLongNameTbl[PL_MAXTYPES]; char *DBPlaneLongNameTbl[PL_MAXTYPES];
NameList dbPlaneNameLists = {NULL, NULL, NULL, (ClientData)0, FALSE}; NameList dbPlaneNameLists = {NULL, NULL, NULL, (ClientData)0, FALSE};
@ -116,24 +116,22 @@ NameList *dbTechNameAddOne();
*/ */
void void
DBTechInitPlane(void) DBTechInitPlane()
{ {
DefaultPlane *dpp; DefaultPlane *dpp;
const char *cp; char *cp;
/* Clear out any old information */ /* Clear out any old information */
if (dbPlaneNameLists.sn_next != NULL) if (dbPlaneNameLists.sn_next != NULL)
{ {
NameList *tbl; NameList *tbl;
free_magic1_t mm1 = freeMagic1_init();
for (tbl = dbPlaneNameLists.sn_next; tbl != &dbPlaneNameLists; for (tbl = dbPlaneNameLists.sn_next; tbl != &dbPlaneNameLists;
tbl = tbl->sn_next) tbl = tbl->sn_next)
{ {
freeMagic(tbl->sn_name); freeMagic(tbl->sn_name);
freeMagic1(&mm1, tbl); freeMagic(tbl);
} }
freeMagic1_end(&mm1);
} }
/* Tables of short names */ /* Tables of short names */
@ -207,14 +205,12 @@ DBTechInitType()
{ {
NameList *tbl; NameList *tbl;
free_magic1_t mm1 = freeMagic1_init();
for (tbl = dbTypeNameLists.sn_next; tbl != &dbTypeNameLists; for (tbl = dbTypeNameLists.sn_next; tbl != &dbTypeNameLists;
tbl = tbl->sn_next) tbl = tbl->sn_next)
{ {
freeMagic(tbl->sn_name); freeMagic(tbl->sn_name);
freeMagic1(&mm1, tbl); freeMagic(tbl);
} }
freeMagic1_end(&mm1);
} }
/* Tables of short names */ /* Tables of short names */
@ -268,12 +264,12 @@ DBTechInitType()
/*ARGSUSED*/ /*ARGSUSED*/
bool bool
DBTechAddPlane( DBTechAddPlane(sectionName, argc, argv)
const char *sectionName, char *sectionName;
int argc, int argc;
char *argv[]) char *argv[];
{ {
const char *cp; char *cp;
if (DBNumPlanes >= PL_MAXTYPES) if (DBNumPlanes >= PL_MAXTYPES)
{ {

View File

@ -44,296 +44,6 @@ struct dbCheck
int dbCheckMaxHFunc(), dbCheckMaxVFunc(); 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 */
}
}
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* *
@ -346,7 +56,6 @@ DBTestNMInteract(Rect *rect1,
* int * int
* func(tile, cdata) * func(tile, cdata)
* Tile *tile; * Tile *tile;
* TileType dinfo;
* ClientData cdata; * ClientData cdata;
* { * {
* } * }
@ -383,7 +92,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
* provide a hint tile in case hintTile == NULL. * provide a hint tile in case hintTile == NULL.
* The hint tile in the plane is updated to be * The hint tile in the plane is updated to be
* the last tile visited in the area * the last tile visited in the area
* enumeration, if plane is non-NULL. * enumeration.
*/ */
TileType ttype; /* Information about the non-manhattan area to TileType ttype; /* Information about the non-manhattan area to
* search; zero if area is manhattan. * search; zero if area is manhattan.
@ -402,7 +111,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
TileType tpt; TileType tpt;
int rheight, rwidth, rmax; int rheight, rwidth, rmax;
dlong f1, f2, f3, f4; dlong f1, f2, f3, f4;
int ignore_sides; bool ignore_sides;
/* If the search area is not diagonal, return the result of the */ /* If the search area is not diagonal, return the result of the */
/* standard (manhattan) search function. */ /* standard (manhattan) search function. */
@ -412,7 +121,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
start.p_x = rect->r_xbot; start.p_x = rect->r_xbot;
start.p_y = rect->r_ytop - 1; start.p_y = rect->r_ytop - 1;
tp = hintTile ? hintTile : PlaneGetHint(plane); tp = hintTile ? hintTile : plane->pl_hint;
GOTOPOINT(tp, &start); GOTOPOINT(tp, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -420,7 +129,7 @@ DBSrPaintNMArea(hintTile, plane, ttype, rect, mask, func, arg)
{ {
/* Each iteration enumerates another tile */ /* Each iteration enumerates another tile */
nm_enum: nm_enum:
if (plane != (Plane *)NULL) PlaneSetHint(plane, tp); plane->pl_hint = tp;
if (SigInterruptPending) if (SigInterruptPending)
return (1); return (1);
@ -428,26 +137,147 @@ nm_enum:
/* the tile enumeration if it is not. */ /* the tile enumeration if it is not. */
/* Watch for calculations involving (M)INFINITY in tile (tp)! */ /* Watch for calculations involving (M)INFINITY in tile (tp)! */
if (IsSplit(tp)) rheight = rect->r_ytop - rect->r_ybot;
{ rwidth = rect->r_xtop - rect->r_xbot;
TileType tpdi = TiGetTypeExact(tp); 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 (TTMaskHasType(mask, SplitLeftType(tp))) if (ttype & TT_SIDE)
if (DBTestNMInteract(rect, ttype, tp, tpdi, TRUE)) {
if ((*func)(tp, (TileType)TT_DIAGONAL, arg)) /* Outside-of-triangle check---ignore sub-integer slivers */
return 1; if (RIGHT(tp) < INFINITY - 2)
if (TTMaskHasType(mask, SplitRightType(tp))) {
if (DBTestNMInteract(rect, ttype, tp, tpdi | TT_SIDE, TRUE)) f3 = (dlong)(rect->r_xtop - RIGHT(tp)) * rheight;
if ((*func)(tp, (TileType)TT_DIAGONAL | TT_SIDE, arg)) f3 += rmax;
return 1; }
else
f3 = DLONG_MIN;
if ((ttype & TT_DIRECTION) ? (f2 < f3) : (f1 < f3))
goto enum_next;
} }
else else
{ {
if (TTMaskHasType(mask, TiGetType(tp))) /* Outside-of-triangle check---ignore sub-integer slivers */
if (DBTestNMInteract(rect, ttype, tp, (TileType)0, TRUE)) if (LEFT(tp) > MINFINITY + 2)
if ((*func)(tp, (TileType)0, arg)) {
return 1; 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;
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);
}
}
else
if (TTMaskHasType(mask, TiGetType(tp)) && (*func)(tp, arg))
return (1);
enum_next: enum_next:
tpnew = TR(tp); tpnew = TR(tp);
@ -495,7 +325,6 @@ enum_next:
* int * int
* func(tile, cdata) * func(tile, cdata)
* Tile *tile; * Tile *tile;
* TileType dinfo;
* ClientData cdata; * ClientData cdata;
* { * {
* } * }
@ -543,7 +372,7 @@ DBSrPaintArea(hintTile, plane, rect, mask, func, arg)
start.p_x = rect->r_xbot; start.p_x = rect->r_xbot;
start.p_y = rect->r_ytop - 1; start.p_y = rect->r_ytop - 1;
tp = hintTile ? hintTile : PlaneGetHint(plane); tp = hintTile ? hintTile : plane->pl_hint;
GOTOPOINT(tp, &start); GOTOPOINT(tp, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -551,7 +380,7 @@ DBSrPaintArea(hintTile, plane, rect, mask, func, arg)
{ {
/* Each iteration enumerates another tile */ /* Each iteration enumerates another tile */
enumerate: enumerate:
PlaneSetHint(plane, tp); plane->pl_hint = tp;
if (SigInterruptPending) if (SigInterruptPending)
return (1); return (1);
@ -587,7 +416,9 @@ enumerate:
(dlong)(rect->r_xbot - LEFT(tp)) * theight : DLONG_MIN; (dlong)(rect->r_xbot - LEFT(tp)) * theight : DLONG_MIN;
if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4)) if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4))
{ {
if ((*func)(tp, (TileType)TT_DIAGONAL, arg)) return (1); TiSetBody(tp, INT2CD((TileType)CD2INT(TiGetBody(tp))
& ~TT_SIDE)); /* bit clear */
if ((*func)(tp, arg)) return (1);
} }
} }
@ -598,12 +429,14 @@ enumerate:
(dlong)(RIGHT(tp) - rect->r_xtop) * theight : DLONG_MIN; (dlong)(RIGHT(tp) - rect->r_xtop) * theight : DLONG_MIN;
if (SplitDirection(tp) ? (f2 > f3) : (f1 > f3)) if (SplitDirection(tp) ? (f2 > f3) : (f1 > f3))
{ {
if ((*func)(tp, (TileType)TT_DIAGONAL | TT_SIDE, arg)) return (1); TiSetBody(tp, INT2CD((TileType)CD2INT(TiGetBody(tp))
| TT_SIDE)); /* bit set */
if ((*func)(tp, arg)) return (1);
} }
} }
} }
else else
if (TTMaskHasType(mask, TiGetType(tp)) && (*func)(tp, (TileType)0, arg)) if (TTMaskHasType(mask, TiGetType(tp)) && (*func)(tp, arg))
return (1); return (1);
tpnew = TR(tp); tpnew = TR(tp);
@ -652,7 +485,6 @@ enumerate:
* int * int
* func(tile, cdata) * func(tile, cdata)
* Tile *tile; * Tile *tile;
* TileType dinfo;
* ClientData cdata; * ClientData cdata;
* { * {
* } * }
@ -700,7 +532,7 @@ DBSrPaintClient(hintTile, plane, rect, mask, client, func, arg)
start.p_x = rect->r_xbot; start.p_x = rect->r_xbot;
start.p_y = rect->r_ytop - 1; start.p_y = rect->r_ytop - 1;
tp = hintTile ? hintTile : PlaneGetHint(plane); tp = hintTile ? hintTile : plane->pl_hint;
GOTOPOINT(tp, &start); GOTOPOINT(tp, &start);
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
@ -708,7 +540,7 @@ DBSrPaintClient(hintTile, plane, rect, mask, client, func, arg)
{ {
/* Each iteration enumerates another tile */ /* Each iteration enumerates another tile */
enumerate: enumerate:
PlaneSetHint(plane, tp); plane->pl_hint = tp;
if (SigInterruptPending) if (SigInterruptPending)
return (1); return (1);
@ -744,7 +576,9 @@ enumerate:
(dlong)(rect->r_xbot - LEFT(tp)) * (dlong)theight : DLONG_MIN; (dlong)(rect->r_xbot - LEFT(tp)) * (dlong)theight : DLONG_MIN;
if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4)) if (SplitDirection(tp) ? (f1 > f4) : (f2 > f4))
{ {
if ((tp->ti_client == client) && (*func)(tp, (TileType)TT_DIAGONAL, arg)) TiSetBody(tp, INT2CD((TileType)CD2INT(TiGetBody(tp))
& ~TT_SIDE)); /* bit clear */
if ((tp->ti_client == client) && (*func)(tp, arg))
return (1); return (1);
} }
} }
@ -756,15 +590,16 @@ enumerate:
(dlong)(RIGHT(tp) - rect->r_xtop) * (dlong)theight : DLONG_MIN; (dlong)(RIGHT(tp) - rect->r_xtop) * (dlong)theight : DLONG_MIN;
if (SplitDirection(tp) ? (f2 > f3) : (f1 > f3)) if (SplitDirection(tp) ? (f2 > f3) : (f1 > f3))
{ {
if ((tp->ti_client == client) && (*func)(tp, (TileType)TT_DIAGONAL TiSetBody(tp, INT2CD((TileType)CD2INT(TiGetBody(tp))
| TT_SIDE, arg)) | TT_SIDE)); /* bit set */
if ((tp->ti_client == client) && (*func)(tp, arg))
return (1); return (1);
} }
} }
} }
else else
if (TTMaskHasType(mask, TiGetType(tp)) && tp->ti_client == client if (TTMaskHasType(mask, TiGetType(tp)) && tp->ti_client == client
&& (*func)(tp, (TileType)0, arg)) && (*func)(tp, arg))
return (1); return (1);
tpnew = TR(tp); tpnew = TR(tp);
@ -822,7 +657,7 @@ DBResetTilePlane(plane, cdata)
ClientData cdata; ClientData cdata;
{ {
Tile *tp, *tpnew; Tile *tp, *tpnew;
const Rect *rect = &TiPlaneRect; Rect *rect = &TiPlaneRect;
/* Start with the leftmost non-infinity tile in the plane */ /* Start with the leftmost non-infinity tile in the plane */
tp = TR(plane->pl_left); tp = TR(plane->pl_left);
@ -830,7 +665,7 @@ DBResetTilePlane(plane, cdata)
/* Each iteration visits another tile on the LHS of the search area */ /* Each iteration visits another tile on the LHS of the search area */
while (TOP(tp) > rect->r_ybot) while (TOP(tp) > rect->r_ybot)
{ {
/* Each iteration resets another tile */ /* Each iteration frees another tile */
enumerate: enumerate:
tp->ti_client = cdata; tp->ti_client = cdata;
@ -866,88 +701,6 @@ 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 */;
}
}
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* *
@ -970,7 +723,9 @@ enumerate:
* *
* This procedure uses a carfully constructed non-recursive area * This procedure uses a carfully constructed non-recursive area
* enumeration algorithm. Care is taken to not access a tile that has * enumeration algorithm. Care is taken to not access a tile that has
* been deallocated. * 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.
* *
* -------------------------------------------------------------------- * --------------------------------------------------------------------
*/ */
@ -980,12 +735,11 @@ DBFreePaintPlane(plane)
Plane *plane; /* Plane whose storage is to be freed */ Plane *plane; /* Plane whose storage is to be freed */
{ {
Tile *tp, *tpnew; Tile *tp, *tpnew;
const Rect *rect = &TiPlaneRect; Rect *rect = &TiPlaneRect;
/* Start with the bottom-right non-infinity tile in the plane */ /* Start with the bottom-right non-infinity tile in the plane */
tp = BL(plane->pl_right); tp = BL(plane->pl_right);
Tile *delayed = NULL;
/* Each iteration visits another tile on the RHS of the search area */ /* Each iteration visits another tile on the RHS of the search area */
while (BOTTOM(tp) < rect->r_ytop) while (BOTTOM(tp) < rect->r_ytop)
{ {
@ -1008,9 +762,9 @@ enumerate:
/* Each iteration returns one tile further to the right */ /* Each iteration returns one tile further to the right */
while (RIGHT(tp) < rect->r_xtop) while (RIGHT(tp) < rect->r_xtop)
{ {
TiFree1(&delayed, tp); TiFree(tp);
tpnew = RT(tp); /* deref of delayed */ tpnew = RT(tp);
tp = TR(tp); /* deref of delayed */ tp = TR(tp);
if (CLIP_TOP(tpnew) <= CLIP_TOP(tp) && BOTTOM(tpnew) < rect->r_ytop) if (CLIP_TOP(tpnew) <= CLIP_TOP(tp) && BOTTOM(tpnew) < rect->r_ytop)
{ {
tp = tpnew; tp = tpnew;
@ -1018,14 +772,13 @@ enumerate:
} }
} }
TiFree1(&delayed, tp); TiFree(tp);
/* At right edge -- walk up to next tile along the right edge */ /* At right edge -- walk up to next tile along the right edge */
tp = RT(tp); /* deref of delayed */ tp = RT(tp);
if (BOTTOM(tp) < rect->r_ytop) { if (BOTTOM(tp) < rect->r_ytop) {
while(LEFT(tp) >= rect->r_xtop) tp = BL(tp); while(LEFT(tp) >= rect->r_xtop) tp = BL(tp);
} }
} }
TiFreeIf(delayed);
} }
/* /*
@ -1165,9 +918,8 @@ DBCheckMaxHStrips(plane, area, proc, cdata)
*/ */
int int
dbCheckMaxHFunc(tile, dinfo, dbc) dbCheckMaxHFunc(tile, dbc)
Tile *tile; Tile *tile;
TileType dinfo; /* (unused) */
struct dbCheck *dbc; struct dbCheck *dbc;
{ {
Tile *tp; Tile *tp;
@ -1258,9 +1010,8 @@ DBCheckMaxVStrips(plane, area, proc, cdata)
*/ */
int int
dbCheckMaxVFunc(tile, dinfo, dbc) dbCheckMaxVFunc(tile, dbc)
Tile *tile; Tile *tile;
TileType dinfo; /* (unused) */
struct dbCheck *dbc; struct dbCheck *dbc;
{ {
Tile *tp; Tile *tp;

View File

@ -137,10 +137,8 @@ DBFixMismatch()
cellDef = mismatch->mm_cellDef; cellDef = mismatch->mm_cellDef;
oldArea = mismatch->mm_oldArea; oldArea = mismatch->mm_oldArea;
free_magic1_t mm1 = freeMagic1_init(); freeMagic((char *) mismatch);
freeMagic1(&mm1, (char *) mismatch);
mismatch = mismatch->mm_next; mismatch = mismatch->mm_next;
freeMagic1_end(&mm1);
if (cellDef->cd_flags & CDPROCESSED) continue; if (cellDef->cd_flags & CDPROCESSED) continue;
(void) DBCellRead(cellDef, TRUE, TRUE, NULL); (void) DBCellRead(cellDef, TRUE, TRUE, NULL);
@ -184,15 +182,13 @@ DBFixMismatch()
} }
SigEnableInterrupts(); SigEnableInterrupts();
TxPrintf("Timestamp mismatches found in these cells: "); TxPrintf("Timestamp mismatches found in these cells: ");
free_magic1_t mm1 = freeMagic1_init();
while (cl != NULL) while (cl != NULL)
{ {
TxPrintf("%s", cl->cl_cell->cd_name); TxPrintf("%s", cl->cl_cell->cd_name);
if (cl->cl_next != NULL) TxPrintf(", "); if (cl->cl_next != NULL) TxPrintf(", ");
freeMagic1(&mm1, cl); freeMagic(cl);
cl = cl->cl_next; cl = cl->cl_next;
} }
freeMagic1_end(&mm1);
TxPrintf(".\n"); TxPrintf(".\n");
TxFlush(); TxFlush();
if (redisplay) WindAreaChanged((MagWindow *) NULL, (Rect *) NULL); if (redisplay) WindAreaChanged((MagWindow *) NULL, (Rect *) NULL);
@ -231,18 +227,16 @@ DBUpdateStamps(def)
else if (def->cd_flags & CDGETNEWSTAMP) else if (def->cd_flags & CDGETNEWSTAMP)
{ {
if (def->cd_flags & (CDNOEDIT | CDFIXEDSTAMP)) if (def->cd_flags & CDFIXEDSTAMP)
def->cd_flags &= ~CDGETNEWSTAMP; def->cd_flags &= ~CDGETNEWSTAMP;
else else
dbStampFunc(def); dbStampFunc(def);
} }
} }
/*ARGSUSED*/
int int
dbStampFunc(cellDef, cdata) dbStampFunc(cellDef)
CellDef *cellDef; CellDef *cellDef;
ClientData cdata; /* UNUSED */
{ {
CellUse *cu; CellUse *cu;
CellDef *cd; CellDef *cd;
@ -253,26 +247,6 @@ dbStampFunc(cellDef, cdata)
if (cellDef->cd_timestamp == timestamp) return 0; 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)) if (!(cellDef->cd_flags & CDFIXEDSTAMP))
cellDef->cd_timestamp = timestamp; cellDef->cd_timestamp = timestamp;

View File

@ -15,18 +15,6 @@ SRCS = DBbound.c DBcell.c DBcellbox.c DBcellcopy.c \
include ${MAGICDIR}/defs.mak include ${MAGICDIR}/defs.mak
LIB_OBJS += ${MAGICDIR}/tiles/libtiles.o ${MAGICDIR}/utils/libutils.o LIB_OBJS += ${MAGICDIR}/tiles/libtiles.o ${MAGICDIR}/utils/libutils.o
# database.h is managed by the toplevel Makefile, because it has a build dependency CLEANS += database.h
# 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 include ${MAGICDIR}/rules.mak

View File

@ -1,62 +0,0 @@
/*
* 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 */

View File

@ -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 $" * rcsid "$Header: /usr/cvsroot/magic-8.0/database/database.h.in,v 1.8 2010/08/25 17:33:55 tim Exp $"
*/ */
#ifndef _MAGIC__DATABASE__DATABASE_H #ifndef _DATABASE_H
#define _MAGIC__DATABASE__DATABASE_H #define _DATABASE_H
#ifndef _MAGIC__TILES__TILE_H #ifndef _TILES_H
#include "tiles/tile.h" #include "tiles/tile.h"
#endif #endif /* _TILES_H */
#ifndef _MAGIC__UTILS__HASH_H #ifndef _HASH_H
#include "utils/hash.h" #include "utils/hash.h"
#endif #endif /* _HASH_H */
#ifndef _MAGIC__UTILS__STACK_H #ifndef _STACK_H
#include "utils/stack.h" #include "utils/stack.h"
#endif #endif /* _STACK_H */
#ifndef _MAGIC__BPLANE__BPLANE_H #ifndef _BPLANE_H
#include "bplane/bplane.h" #include "bplane/bplane.h"
#endif #endif /* _BPLANE_H */
/* ----------------------- Tunable constants -------------------------- */ /* ----------------------- Tunable constants -------------------------- */
@ -303,14 +303,9 @@ typedef struct label
#define PORT_SHAPE_RING 0x1000 /* Port is a ring shape */ #define PORT_SHAPE_RING 0x1000 /* Port is a ring shape */
#define PORT_SHAPE_THRU 0x1800 /* Port is a feedthrough shape */ #define PORT_SHAPE_THRU 0x1800 /* Port is a feedthrough shape */
#define LABEL_STICKY 0x2000 /* Label does not change layers */ #define PORT_VISITED 0x2000 /* Bit for checking if a port */
#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. */ /* has been previously visited. */
#define LABEL_STICKY 0x4000 /* Label does not change layers */
#define LABEL_GENERATE 0x8000 /* Auto-generated label */ #define LABEL_GENERATE 0x8000 /* Auto-generated label */
/* /*
@ -408,9 +403,6 @@ typedef struct celldef
* is added to the magic database. The flag is used to identify * is added to the magic database. The flag is used to identify
* whether the cell has been processed when forcing the GDS * whether the cell has been processed when forcing the GDS
* stream data to be read in post-order. * 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 * CDVENDORGDS indicates that the cell was read from a GDS stream
* with the option "gds readonly true". * with the option "gds readonly true".
* CDVISITED indicates that at least one instance of the cell was * CDVISITED indicates that at least one instance of the cell was
@ -442,15 +434,53 @@ typedef struct celldef
#define CDFLATGDS 0x00400 #define CDFLATGDS 0x00400
#define CDFLATTENED 0x00800 #define CDFLATTENED 0x00800
#define CDPROCESSEDGDS 0x01000 #define CDPROCESSEDGDS 0x01000
#define CDPRELOADED 0x02000 #define CDVENDORGDS 0x02000
#define CDVENDORGDS 0x04000 #define CDVISITED 0x04000
#define CDVISITED 0x08000 #define CDDEREFERENCE 0x08000
#define CDDEREFERENCE 0x10000 #define CDFIXEDSTAMP 0x10000
#define CDFIXEDSTAMP 0x20000 #define CDNOEXTRACT 0x20000
#define CDNOEXTRACT 0x40000 #define CDDONTUSE 0x40000
#define CDDONTUSE 0x80000
#include "database/arrayinfo.h" /* ArrayInfo */ /*
* 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;
/* /*
* Since a cell may be used in an orientation different from that * Since a cell may be used in an orientation different from that
@ -556,18 +586,6 @@ typedef struct diag_info
bool side; bool side;
} DiagInfo; } 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. */ /* 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. */ /* Used in selOps.c but also passed back to CmdRS.c for select command. */
@ -578,20 +596,6 @@ typedef struct extRectList
struct extRectList *r_next; struct extRectList *r_next;
} ExtRectList; } ExtRectList;
/* Structure similar to the above, but adding a pointer to a cell use ID
* and a client data record which can be used to hold a region pointer.
*/
typedef struct extConnList
{
char *r_useid; /* Cell Use being connected to */
TileType r_type; /* Connecting tile type in the parent */
Rect r_r; /* Area of connection */
ClientData r_upnode; /* Parent node making the connection */
ClientData r_downnode; /* Child node making the connection */
struct extConnList *r_next; /* Next item in the linked list */
} ExtConnList;
/* -------------------- Search context information -------------------- */ /* -------------------- Search context information -------------------- */
/* Search contexts are used in hierarchical searches */ /* Search contexts are used in hierarchical searches */
@ -643,7 +647,7 @@ typedef struct treeFilter
{ {
int (*tf_func)(); /* Client's filter function */ int (*tf_func)(); /* Client's filter function */
ClientData tf_arg; /* Client's argument to pass to filter */ ClientData tf_arg; /* Client's argument to pass to filter */
const TileTypeBitMask *tf_mask; /* Only process tiles with these types */ TileTypeBitMask *tf_mask; /* Only process tiles with these types */
int tf_xmask; /* Expand mask */ int tf_xmask; /* Expand mask */
PlaneMask tf_planes; /* Mask of planes which will be visited */ PlaneMask tf_planes; /* Mask of planes which will be visited */
TileType tf_dinfo; /* Info for processing triangular areas */ TileType tf_dinfo; /* Info for processing triangular areas */
@ -665,7 +669,6 @@ typedef struct treeFilter
#define TF_LABEL_ATTACH_NOT_SE 0x10 /* Same as above, ignore tile SE corner */ #define TF_LABEL_ATTACH_NOT_SE 0x10 /* Same as above, ignore tile SE corner */
#define TF_LABEL_ATTACH_NOT_SW 0x20 /* Same as above, ignore tile SW corner */ #define TF_LABEL_ATTACH_NOT_SW 0x20 /* Same as above, ignore tile SW corner */
#define TF_LABEL_ATTACH_CORNER 0x3C /* Mask of the four types above */ #define TF_LABEL_ATTACH_CORNER 0x3C /* Mask of the four types above */
#define TF_LABEL_REVERSE_SEARCH 0x40 /* Search children before parent */
/* To do: Make the tpath entries dynamically allocated */ /* To do: Make the tpath entries dynamically allocated */
#define FLATTERMSIZE 4096 /* Used for generating flattened labels */ #define FLATTERMSIZE 4096 /* Used for generating flattened labels */
@ -682,7 +685,7 @@ struct conSrArg
{ {
CellDef *csa_def; /* Definition being searched. */ CellDef *csa_def; /* Definition being searched. */
int csa_pNum; /* Index of plane being searched */ int csa_pNum; /* Index of plane being searched */
const TileTypeBitMask *csa_connect; /* Table indicating what connects TileTypeBitMask *csa_connect; /* Table indicating what connects
* to what. * to what.
*/ */
int (*csa_clientFunc)(); /* Client function to call. */ int (*csa_clientFunc)(); /* Client function to call. */
@ -697,19 +700,19 @@ struct conSrArg
typedef struct typedef struct
{ {
Rect area; /* Area to process */ Rect area; /* Area to process */
const TileTypeBitMask *connectMask; /* Connection mask for search */ TileTypeBitMask *connectMask; /* Connection mask for search */
TileType dinfo; /* Info about triangular search areas */ TileType dinfo; /* Info about triangular search areas */
} conSrArea; } conSrArea;
struct conSrArg2 struct conSrArg2
{ {
CellUse *csa2_use; /* Destination use */ CellUse *csa2_use; /* Destination use */
const TileTypeBitMask *csa2_connect;/* Table indicating what connects TileTypeBitMask *csa2_connect; /* Table indicating what connects
* to what. * to what.
*/ */
SearchContext *csa2_topscx; /* Original top-level search context */ SearchContext *csa2_topscx; /* Original top-level search context */
int csa2_xMask; /* Cell window mask for search */ int csa2_xMask; /* Cell window mask for search */
const Rect *csa2_bounds; /* Area that limits the search */ Rect *csa2_bounds; /* Area that limits the search */
Stack *csa2_stack; /* Stack of full csa2_list entries */ Stack *csa2_stack; /* Stack of full csa2_list entries */
conSrArea *csa2_list; /* List of areas to process */ conSrArea *csa2_list; /* List of areas to process */
@ -719,25 +722,6 @@ struct conSrArg2
#define CSA2_LIST_SIZE 65536 /* Number of entries per list */ #define CSA2_LIST_SIZE 65536 /* Number of entries per list */
/* ------------------------ Properties ------------------------------ */
/* Note that the property record is a single allocated block large enough
* to hold the string or integer list, and can be freed as a single block.
* The array bounds, like those of lab_text for labels, are placeholders.
*/
typedef struct
{
int prop_type; /* See codes below; e.g., PROPERTY_TYPE_STRING */
int prop_len; /* String length or number of values */
union {
char prop_string[8]; /* For PROPERTY_TYPE_STRING */
int prop_integer[2]; /* For PROPERTY_TYPE_INTEGER or _DIMENSION */
dlong prop_double[1]; /* For PROPERTY_TYPE_DOUBLE */
Plane *prop_plane; /* For PROPERTY_TYPE_PLANE */
} prop_value;
} PropertyRecord;
/* -------------- Undo information passed to DBPaintPlane ------------- */ /* -------------- Undo information passed to DBPaintPlane ------------- */
typedef struct typedef struct
@ -770,14 +754,6 @@ typedef struct
#define PAINT_MARK 1 /* Mark tiles that are painted */ #define PAINT_MARK 1 /* Mark tiles that are painted */
#define PAINT_XOR 2 /* Use with XOR function to prevent double-painting */ #define PAINT_XOR 2 /* Use with XOR function to prevent double-painting */
/* ---------------------- Codes for properties -------------------------*/
#define PROPERTY_TYPE_STRING 0 /* ASCII string property */
#define PROPERTY_TYPE_INTEGER 1 /* Fixed integer property */
#define PROPERTY_TYPE_DIMENSION 2 /* Integer property that scales with units */
#define PROPERTY_TYPE_DOUBLE 3 /* Double-long integer (for file positions) */
#define PROPERTY_TYPE_PLANE 4 /* A tile plane structure */
/* -------------------- Exported procedure headers -------------------- */ /* -------------------- Exported procedure headers -------------------- */
/* Painting/erasing */ /* Painting/erasing */
@ -832,7 +808,7 @@ extern void DBTechInit();
extern bool DBTechSetTech(); extern bool DBTechSetTech();
extern void DBTechInitVersion(); extern void DBTechInitVersion();
extern bool DBTechSetVersion(); extern bool DBTechSetVersion();
extern bool DBTechAddPlane(const char *sectionName, int argc, char *argv[]); extern bool DBTechAddPlane();
extern bool DBTechAddType(); extern bool DBTechAddType();
extern bool DBTechAddAlias(); extern bool DBTechAddAlias();
extern void DBTechFinalType(); extern void DBTechFinalType();
@ -844,7 +820,7 @@ extern int DBTechNamePlane(), DBTechNoisyNamePlane();
extern PlaneMask DBTechNameMask(), DBTechNoisyNameMask(); extern PlaneMask DBTechNameMask(), DBTechNoisyNameMask();
extern PlaneMask DBTechTypesToPlanes(); extern PlaneMask DBTechTypesToPlanes();
extern bool DBTechTypesOnPlane(); extern bool DBTechTypesOnPlane();
extern void DBTechInitPlane(void); extern void DBTechInitPlane();
extern void DBTypeInit(); extern void DBTypeInit();
extern void DBTechInitType(); extern void DBTechInitType();
extern void DBTechInitCompose(); extern void DBTechInitCompose();
@ -903,7 +879,7 @@ extern void DBSetTrans();
extern void DBArrayOverlap(); extern void DBArrayOverlap();
extern void DBComputeArrayArea(); extern void DBComputeArrayArea();
extern Transform *DBGetArrayTransform(); extern Transform *DBGetArrayTransform();
extern char *DBPrintUseId(SearchContext *scx, char *name, int size, bool display_only); extern char *DBPrintUseId();
/* Massive copying */ /* Massive copying */
extern void DBCellCopyPaint(); extern void DBCellCopyPaint();
@ -963,9 +939,7 @@ extern void DBFreePaintPlane();
/* Cell properties */ /* Cell properties */
extern void DBPropPut(); extern void DBPropPut();
extern PropertyRecord *DBPropGet(); extern ClientData DBPropGet();
extern char *DBPropGetString();
extern dlong DBPropGetDouble();
extern int DBPropEnum(); extern int DBPropEnum();
extern void DBPropClearAll(); extern void DBPropClearAll();
@ -981,10 +955,6 @@ extern int DBArraySr();
extern bool DBNearestLabel(); extern bool DBNearestLabel();
extern int DBSrLabelLoc(); extern int DBSrLabelLoc();
extern TileType DBTransformDiagonal(); extern TileType DBTransformDiagonal();
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 */ /* C99 compat */
extern void DBEraseValid(); extern void DBEraseValid();
@ -1000,7 +970,7 @@ extern void DBUndoPutLabel();
extern bool DBCellRename(); extern bool DBCellRename();
extern bool DBCellDelete(); extern bool DBCellDelete();
extern int DBCellSrArea(); extern int DBCellSrArea();
extern int DBSrCellPlaneArea(BPlane *plane, const Rect *rect, int (*func)(), ClientData arg); extern int DBSrCellPlaneArea();
extern int DBMoveCell(); extern int DBMoveCell();
extern bool DBReLinkCell(); extern bool DBReLinkCell();
extern int DBBoundCellPlane(); extern int DBBoundCellPlane();
@ -1013,7 +983,6 @@ extern int DBScaleCell();
extern TileType DBTechNameTypes(); extern TileType DBTechNameTypes();
extern void DBTreeFindUse(); extern void DBTreeFindUse();
extern void DBGenerateUniqueIds(); extern void DBGenerateUniqueIds();
extern void DBSelectionUniqueIds();
extern TileType DBInvTransformDiagonal(); extern TileType DBInvTransformDiagonal();
extern bool DBIsSubcircuit(); extern bool DBIsSubcircuit();
extern int DBSrPaintNMArea(); extern int DBSrPaintNMArea();
@ -1031,10 +1000,10 @@ extern int dbIsPrimary();
extern void dbTechMatchResidues(); extern void dbTechMatchResidues();
extern void DBUndoInit(); extern void DBUndoInit();
extern void DBResetTilePlane(); extern void DBResetTilePlane();
extern void DBResetTilePlaneSpecial();
extern void DBNewYank(); extern void DBNewYank();
extern int DBSrPaintClient(); extern int DBSrPaintClient();
extern int DBSrConnect(); extern int DBSrConnect();
extern int DBSrConnectOnePlane();
extern char *dbFgets(); extern char *dbFgets();
extern void DBAdjustLabelsNew(); extern void DBAdjustLabelsNew();
extern bool DBScaleValue(); extern bool DBScaleValue();
@ -1063,7 +1032,6 @@ extern int DBLambda[2];
/* -------------------- Exported magic file suffix -------------------- */ /* -------------------- Exported magic file suffix -------------------- */
extern char *DBSuffix; /* Suffix appended to all Magic cell names */ extern char *DBSuffix; /* Suffix appended to all Magic cell names */
extern bool DBPropCompat; /* Backwards-compatible properties */
/* -------------------- User Interface Stuff -------------------------- */ /* -------------------- User Interface Stuff -------------------------- */
@ -1076,19 +1044,6 @@ extern unsigned char DBVerbose; /* If 0, don't print any messages */
#define DB_VERBOSE_WARN 2 #define DB_VERBOSE_WARN 2
#define DB_VERBOSE_ALL 3 #define DB_VERBOSE_ALL 3
/* ---------- Definitions for expanding/unexpanding cells --------------*/
/* Selection expansion flags */
#define DB_EXPAND_MASK 3 /* 1 = expand, 0 = unexpand, 2 = toggle */
#define DB_EXPAND_SURROUND_MASK 4 /* 1 = surround, 0 = touch */
/* Selection expansion values */
#define DB_EXPAND 0
#define DB_UNEXPAND 1
#define DB_EXPAND_TOGGLE 2
#define DB_EXPAND_SURROUND 4
#define DB_EXPAND_OVERLAP 0
/* ------------------ Exported technology variables ------------------- */ /* ------------------ Exported technology variables ------------------- */
/*** /***
@ -1135,10 +1090,10 @@ extern int DBNumPlanes;
extern HashTable DBTypeAliasTable; extern HashTable DBTypeAliasTable;
/* Gives the official long name of each plane: */ /* Gives the official long name of each plane: */
extern const char *DBPlaneLongNameTbl[NP]; extern char *DBPlaneLongNameTbl[NP];
/* Gives a short name for each plane: */ /* Gives a short name for each plane: */
extern const char *DBPlaneShortName(); extern char *DBPlaneShortName();
/* Gives for each plane a mask of all tile types stored in that plane: */ /* Gives for each plane a mask of all tile types stored in that plane: */
extern TileTypeBitMask DBPlaneTypes[NP]; extern TileTypeBitMask DBPlaneTypes[NP];
@ -1197,10 +1152,10 @@ extern int DBTypePlaneTbl[TT_MAXTYPES];
extern PlaneMask DBTypePlaneMaskTbl[TT_MAXTYPES]; extern PlaneMask DBTypePlaneMaskTbl[TT_MAXTYPES];
/* Gives the long name for each tile type: */ /* Gives the long name for each tile type: */
extern const char *DBTypeLongNameTbl[TT_MAXTYPES]; extern char *DBTypeLongNameTbl[TT_MAXTYPES];
/* Gives a short name for a tile type: */ /* Gives a short name for a tile type: */
extern const char *DBTypeShortName(TileType type); extern char *DBTypeShortName();
/* /*
* The following give masks of all planes that may be affected * The following give masks of all planes that may be affected

View File

@ -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 $ * rcsid $Header: /usr/cvsroot/magic-8.0/database/databaseInt.h,v 1.3 2010/06/24 12:37:15 tim Exp $
*/ */
#ifndef _MAGIC__DATABASE__DATABASEINT_H #ifndef _DATABASEINT_H
#define _MAGIC__DATABASE__DATABASEINT_H #define _DATABASEINT_H
#include "database/database.h" #include "database/database.h"
@ -194,8 +194,6 @@ typedef struct
extern int dbNumSavedRules; extern int dbNumSavedRules;
extern Rule dbSavedRules[]; extern Rule dbSavedRules[];
extern HashTable dbCellDefTable; /* Exported for diagnostics */
/* -------------------- Internal procedure headers -------------------- */ /* -------------------- Internal procedure headers -------------------- */
extern void DBUndoPutLabel(); extern void DBUndoPutLabel();
@ -249,4 +247,4 @@ extern TileTypeBitMask dbNotDefaultPaintTbl[];
#define ERASEAFFECTS(t, s) \ #define ERASEAFFECTS(t, s) \
((t) != TT_SPACE && DBStdEraseEntry((t), (s), DBPlane(t)) != (t)) ((t) != TT_SPACE && DBStdEraseEntry((t), (s), DBPlane(t)) != (t))
#endif /* _MAGIC__DATABASE__DATABASEINT_H */ #endif /* _DATABASEINT_H */

View File

@ -10,12 +10,12 @@
* rcsid "$$" * rcsid "$$"
*/ */
#ifndef _MAGIC__DATABASE__FONTS_H #ifndef _FONTS_H
#define _MAGIC__DATABASE__FONTS_H #define _FONTS_H
#ifndef _MAGIC__TILES__TILE_H #ifndef _TILES_H
#include "tiles/tile.h" #include "tiles/tile.h"
#endif #endif /* _TILES_H */
/* ---------------------------- Fonts --------------------------------- */ /* ---------------------------- Fonts --------------------------------- */
@ -39,4 +39,4 @@ typedef struct
extern MagicFont **DBFontList; /* List of loaded font vectors */ extern MagicFont **DBFontList; /* List of loaded font vectors */
extern int DBNumFonts; /* Number of loaded fonts */ extern int DBNumFonts; /* Number of loaded fonts */
#endif /* _MAGIC__DATABASE__FONTS_H */ #endif /* _FONTS_H */

View File

@ -27,7 +27,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "tcltk/tclmagic.h"
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/geometry.h" #include "utils/geometry.h"
#include "tiles/tile.h" #include "tiles/tile.h"
@ -59,7 +58,7 @@ static char *dbwButtonDoc[MAXBUTTONHANDLERS];
/* A documentation string for each handler: tells /* A documentation string for each handler: tells
* what the button pushes and releases mean. * what the button pushes and releases mean.
*/ */
static cb_database_buttonhandler_t dbwButtonProcs[MAXBUTTONHANDLERS]; static void (*dbwButtonProcs[MAXBUTTONHANDLERS])();
/* A procedure for each handler that is invoked /* A procedure for each handler that is invoked
* on button presses and releases when that handler * on button presses and releases when that handler
* is the current one. * is the current one.
@ -69,7 +68,7 @@ static int dbwButtonCursors[MAXBUTTONHANDLERS];
static int dbwButtonCurrentIndex; static int dbwButtonCurrentIndex;
/* Index of current handler. */ /* Index of current handler. */
cb_database_buttonhandler_t DBWButtonCurrentProc; void (*DBWButtonCurrentProc)();
/* Current button-handling procedure. */ /* Current button-handling procedure. */
static int buttonCorner = TOOL_ILG; /* Nearest corner when button went static int buttonCorner = TOOL_ILG; /* Nearest corner when button went
@ -109,19 +108,18 @@ static int buttonCorner = TOOL_ILG; /* Nearest corner when button went
*/ */
void void
DBWAddButtonHandler( DBWAddButtonHandler(name, proc, cursor, doc)
const char *name, /* Name of this button handler. This name char *name; /* Name of this button handler. This name
* is what's passed to DBWChangeButtonHandler * is what's passed to DBWChangeButtonHandler
* to activate the handler. * to activate the handler.
*/ */
const cb_database_buttonhandler_t proc, void (*proc)(); /* Procedure to call on button actions when
/* Procedure to call on button actions when
* this handler is active. * this handler is active.
*/ */
int cursor, /* Cursor shape (e.g. STYLE_CURS_NORMAL) to int cursor; /* Cursor shape (e.g. STYLE_CURS_NORMAL) to
* use when this handler is active. * use when this handler is active.
*/ */
const char *doc) /* A documentation string for this handler: char *doc; /* A documentation string for this handler:
* describes what the button pushes do when * describes what the button pushes do when
* this handler is active. * this handler is active.
*/ */
@ -131,11 +129,8 @@ DBWAddButtonHandler(
for (i = 0; i < MAXBUTTONHANDLERS; i++) for (i = 0; i < MAXBUTTONHANDLERS; i++)
{ {
if (dbwButtonHandlers[i] != NULL) continue; if (dbwButtonHandlers[i] != NULL) continue;
StrDup(&dbwButtonHandlers[i], name); (void) StrDup(&dbwButtonHandlers[i], name);
if (doc != NULL) (void) StrDup(&dbwButtonDoc[i], doc);
StrDup(&dbwButtonDoc[i], doc);
else
dbwButtonDoc[i] = (char *)NULL;
dbwButtonProcs[i] = proc; dbwButtonProcs[i] = proc;
dbwButtonCursors[i] = cursor; dbwButtonCursors[i] = cursor;
return; return;
@ -244,69 +239,6 @@ DBWChangeButtonHandler(name)
return oldName; 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];
}
/*
* ----------------------------------------------------------------------------
*
* DBWButtonHandlerIndex()
*
* Given a string, return the index of the button handler. If the
* string does not correspond to any button handler name, then
* return -1.
*
* Results:
* Index of button handler, if it exists; -1 otherwise.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
int
DBWButtonHandlerIndex(char *toolName)
{
int i;
for (i = 0; i < MAXBUTTONHANDLERS; i++)
{
if (dbwButtonHandlers[i] == NULL) return -1;
else if (!strcmp(toolName, dbwButtonHandlers[i])) return i;
}
return -1;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -328,10 +260,7 @@ DBWButtonHandlerIndex(char *toolName)
void void
DBWPrintButtonDoc() DBWPrintButtonDoc()
{ {
if (dbwButtonDoc[dbwButtonCurrentIndex])
TxPrintf("%s", dbwButtonDoc[dbwButtonCurrentIndex]); TxPrintf("%s", dbwButtonDoc[dbwButtonCurrentIndex]);
else
TxPrintf("(no usage information)\n");
} }

View File

@ -38,7 +38,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
* Standard DBWind command set * Standard DBWind command set
*/ */
extern void CmdAddPath(), CmdAntennaCheck(), CmdArchive(), CmdArray(); extern void CmdAddPath(), CmdAntennaCheck(), CmdArray();
extern void CmdBox(), CmdCellname(), CmdClockwise(); extern void CmdBox(), CmdCellname(), CmdClockwise();
extern void CmdContact(), CmdCopy(), CmdCorner(); extern void CmdContact(), CmdCopy(), CmdCorner();
extern void CmdCrash(), CmdCrosshair(); extern void CmdCrash(), CmdCrosshair();
@ -54,7 +54,7 @@ extern void CmdRandom(), CmdSave(), CmdScaleGrid(), CmdSee();
extern void CmdSelect(), CmdSetLabel(), CmdSideways(); extern void CmdSelect(), CmdSetLabel(), CmdSideways();
extern void CmdShell(), CmdSnap(); extern void CmdShell(), CmdSnap();
extern void CmdStretch(), CmdStraighten(); extern void CmdStretch(), CmdStraighten();
extern void CmdTech(), CmdTool(), CmdUnexpand(), CmdUnits(); extern void CmdTech(), CmdTool(), CmdUnexpand();
extern void CmdUpsidedown(), CmdWhat(), CmdWire(), CmdWriteall(); extern void CmdUpsidedown(), CmdWhat(), CmdWire(), CmdWriteall();
extern void CmdGoto(), CmdFlatten(), CmdXload(), CmdXor(); extern void CmdGoto(), CmdFlatten(), CmdXload(), CmdXor();
@ -75,7 +75,6 @@ extern void CmdExtResis();
extern void CmdPsearch(); extern void CmdPsearch();
extern void CmdPlowTest(); extern void CmdPlowTest();
extern void CmdShowtech(); extern void CmdShowtech();
extern void CmdShowmem();
extern void CmdTilestats(); extern void CmdTilestats();
extern void CmdTsearch(); extern void CmdTsearch();
extern void CmdWatch(); extern void CmdWatch();
@ -149,9 +148,6 @@ extern void CmdAutoExtToSpice();
#else #else
extern void CmdExtToSpice(); extern void CmdExtToSpice();
#endif #endif
#else /* !MAGIC_WRAPPER */
extern void CmdExtToSim();
extern void CmdExtToSpice();
#endif #endif
/* /*
@ -212,9 +208,6 @@ DBWInitCommands()
WindAddCommand(DBWclientID, WindAddCommand(DBWclientID,
"*psearch plane count invoke point search over box area", "*psearch plane count invoke point search over box area",
CmdPsearch, FALSE); CmdPsearch, FALSE);
WindAddCommand(DBWclientID,
"*showmem [file] print internal memory usage",
CmdShowmem, FALSE);
WindAddCommand(DBWclientID, WindAddCommand(DBWclientID,
"*showtech [file] print internal technology tables", "*showtech [file] print internal technology tables",
CmdShowtech, FALSE); CmdShowtech, FALSE);
@ -230,15 +223,9 @@ DBWInitCommands()
WindAddCommand(DBWclientID, WindAddCommand(DBWclientID,
"addpath [path] append to current search path", "addpath [path] append to current search path",
CmdAddPath, FALSE); CmdAddPath, FALSE);
#ifdef LEF_MODULE
WindAddCommand(DBWclientID, WindAddCommand(DBWclientID,
"antennacheck [path] check for antenna violations", "antennacheck [path] check for antenna violations",
CmdAntennaCheck, FALSE); CmdAntennaCheck, FALSE);
#endif
WindAddCommand(DBWclientID,
"archive write|read file\n"
" write or read the archive file \"file\".",
CmdArchive, FALSE);
WindAddCommand(DBWclientID, WindAddCommand(DBWclientID,
"array xsize ysize OR\n" "array xsize ysize OR\n"
"array xlo xhi ylo yhi\n" "array xlo xhi ylo yhi\n"
@ -477,9 +464,6 @@ DBWInitCommands()
WindAddCommand(DBWclientID, WindAddCommand(DBWclientID,
"unexpand unexpand subcells under box", "unexpand unexpand subcells under box",
CmdUnexpand, FALSE); CmdUnexpand, FALSE);
WindAddCommand(DBWclientID,
"units [type] set type of units parsed and displayed",
CmdUnits, FALSE);
WindAddCommand(DBWclientID, WindAddCommand(DBWclientID,
"upsidedown flip selection and box upside down", "upsidedown flip selection and box upside down",
CmdUpsidedown, FALSE); CmdUpsidedown, FALSE);
@ -572,24 +556,6 @@ DBWInitCommands()
" type\n\t\t\t\"ext2spice help\" for information on options", " type\n\t\t\t\"ext2spice help\" for information on options",
CmdExtToSpice, FALSE); CmdExtToSpice, FALSE);
#endif /* EXT2SPICE_AUTO */ #endif /* EXT2SPICE_AUTO */
#else /* !MAGIC_WRAPPER */
/* In non-Tcl builds (e.g. WASM), register the C implementations directly */
WindAddCommand(DBWclientID,
"exttosim [args] convert extracted file(s) to a sim format file;"
" type\n\t\t\t\"exttosim help\" for information on options",
CmdExtToSim, FALSE);
WindAddCommand(DBWclientID,
"ext2sim [args] convert extracted file(s) to a sim format file;"
" type\n\t\t\t\"ext2sim help\" for information on options",
CmdExtToSim, FALSE);
WindAddCommand(DBWclientID,
"exttospice [args] convert extracted file(s) to a SPICE format file;"
" type\n\t\t\t\"exttospice help\" for information on options",
CmdExtToSpice, FALSE);
WindAddCommand(DBWclientID,
"ext2spice [args] convert extracted file(s) to a SPICE format file;"
" type\n\t\t\t\"ext2spice help\" for information on options",
CmdExtToSpice, FALSE);
#endif /* MAGIC_WRAPPER */ #endif /* MAGIC_WRAPPER */

View File

@ -421,8 +421,7 @@ DBWredisplay(w, rootArea, clipArea)
/* Set style information beforehand */ /* Set style information beforehand */
GrSetStuff(STYLE_LABEL); GrSetStuff(STYLE_LABEL);
(void) DBTreeSrLabels(&scontext, &DBAllTypeBits, bitMask, (void) DBTreeSrLabels(&scontext, &DBAllTypeBits, bitMask,
(TerminalPath *) NULL, (TerminalPath *) NULL, TF_LABEL_DISPLAY | TF_LABEL_ATTACH,
TF_LABEL_DISPLAY | TF_LABEL_ATTACH | TF_LABEL_REVERSE_SEARCH,
dbwLabelFunc, (ClientData)(&crec->dbw_visibleLayers)); dbwLabelFunc, (ClientData)(&crec->dbw_visibleLayers));
GrClipTo(&rootClip); GrClipTo(&rootClip);
} }
@ -572,9 +571,8 @@ DBWredisplay(w, rootArea, clipArea)
*/ */
int int
dbwPaintFunc(tile, dinfo, cxp) dbwPaintFunc(tile, cxp)
Tile *tile; /* Tile to be redisplayed. */ Tile *tile; /* Tile to be redisplayed. */
TileType dinfo; /* Split tile information */
TreeContext *cxp; /* From DBTreeSrTiles */ TreeContext *cxp; /* From DBTreeSrTiles */
{ {
SearchContext *scx = cxp->tc_scx; SearchContext *scx = cxp->tc_scx;
@ -654,7 +652,7 @@ dbwPaintFunc(tile, dinfo, cxp)
/* whether to render the outline with a fast rectangle- */ /* whether to render the outline with a fast rectangle- */
/* drawing routine or to render it segment by segment. */ /* drawing routine or to render it segment by segment. */
GrBox(dbwWindow, &scx->scx_trans, tile, dinfo); GrBox(dbwWindow, &scx->scx_trans, tile);
return 0; return 0;
} }
@ -1077,10 +1075,8 @@ dbwBBoxFunc(scx)
*/ */
int int
dbwTileFunc(tile, dinfo, clientdata) dbwTileFunc(tile)
Tile *tile; /* A tile to be redisplayed. */ Tile *tile; /* A tile to be redisplayed. */
TileType dinfo; /* Split tile information (unused) */
ClientData clientdata; /* (unused) */
{ {
Rect r, r2; Rect r, r2;
int xoffset, yoffset; int xoffset, yoffset;

View File

@ -588,12 +588,10 @@ DBWElementDelete(MagWindow *w, char *name)
if (elem->flags & DBW_ELEMENT_PERSISTENT) if (elem->flags & DBW_ELEMENT_PERSISTENT)
elem->rootDef->cd_flags |= CDMODIFIED; elem->rootDef->cd_flags |= CDMODIFIED;
free_magic1_t mm1 = freeMagic1_init();
for (stylePtr = elem->stylelist; stylePtr != NULL; stylePtr = stylePtr->next) for (stylePtr = elem->stylelist; stylePtr != NULL; stylePtr = stylePtr->next)
{ {
freeMagic1(&mm1, stylePtr); freeMagic(stylePtr);
} }
freeMagic1_end(&mm1);
if (elem->type == ELEMENT_TEXT) if (elem->type == ELEMENT_TEXT)
freeMagic(elem->text); freeMagic(elem->text);
@ -867,11 +865,8 @@ dbwelemGetTransform(use, transform, cdarg)
return 1; return 1;
} }
/*ARGSUSED*/
int int
dbwElementAlways1(w, clientData) dbwElementAlways1()
MagWindow *w; /* UNUSED */
ClientData clientData; /* UNUSED */
{ {
return 1; return 1;
} }
@ -1161,10 +1156,8 @@ DBWElementStyle(MagWindow *w, char *ename, int style, bool add)
(elem->stylelist->style == style)) (elem->stylelist->style == style))
{ {
dbwElementUndraw(w, elem); dbwElementUndraw(w, elem);
free_magic1_t mm1 = freeMagic1_init(); freeMagic(elem->stylelist);
freeMagic1(&mm1, elem->stylelist);
elem->stylelist = elem->stylelist->next; elem->stylelist = elem->stylelist->next;
freeMagic1_end(&mm1);
if (elem->stylelist == NULL) if (elem->stylelist == NULL)
TxPrintf("Warning: Element %s has no styles!\n", ename); TxPrintf("Warning: Element %s has no styles!\n", ename);
} }
@ -1176,10 +1169,8 @@ DBWElementStyle(MagWindow *w, char *ename, int style, bool add)
else if (sptr->next != NULL) else if (sptr->next != NULL)
{ {
dbwElementUndraw(w, elem); dbwElementUndraw(w, elem);
free_magic1_t mm1 = freeMagic1_init(); freeMagic(sptr->next);
freeMagic1(&mm1, sptr->next);
sptr->next = sptr->next->next; sptr->next = sptr->next->next;
freeMagic1_end(&mm1);
} }
} }
/* mark element's cell as having been modified */ /* mark element's cell as having been modified */
@ -1288,10 +1279,8 @@ DBWElementClearDef(cellDef)
if (!elem) continue; if (!elem) continue;
if (elem->rootDef != cellDef) continue; if (elem->rootDef != cellDef) continue;
free_magic1_t mm1 = freeMagic1_init();
for (stylePtr = elem->stylelist; stylePtr != NULL; stylePtr = stylePtr->next) for (stylePtr = elem->stylelist; stylePtr != NULL; stylePtr = stylePtr->next)
freeMagic1(&mm1, stylePtr); freeMagic(stylePtr);
freeMagic1_end(&mm1);
if (elem->type == ELEMENT_TEXT) if (elem->type == ELEMENT_TEXT)
freeMagic(elem->text); freeMagic(elem->text);

View File

@ -249,10 +249,7 @@ DBWFeedbackRedraw(window, plane)
} }
int int
dbwFeedbackAlways1( dbwFeedbackAlways1()
Tile *tile, /* (unused) */
TileType dinfo, /* (unused) */
ClientData clientdata) /* (unused) */
{ {
return 1; return 1;
} }
@ -531,11 +528,8 @@ dbwfbGetTransform(use, transform, cdarg)
* cell. * cell.
*/ */
/*ARGSUSED*/
int int
dbwfbWindFunc(w, clientData) dbwfbWindFunc()
MagWindow *w; /* UNUSED */
ClientData clientData; /* UNUSED */
{ {
return 1; return 1;
} }

View File

@ -357,11 +357,9 @@ DBWHLRedrawPrepWindow(MagWindow *window, Rect *area)
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
/*ARGSUSED*/
int int
DBWHLRedrawWind(window, clientData) DBWHLRedrawWind(window)
MagWindow *window; /* Window in which to redraw highlights. */ MagWindow *window; /* Window in which to redraw highlights. */
ClientData clientData; /* UNUSED */
{ {
int i; int i;
DBWclientRec *crec; DBWclientRec *crec;
@ -394,9 +392,8 @@ DBWHLRedrawWind(window, clientData)
*/ */
int int
dbwhlEraseFunc(tile, dinfo, window) dbwhlEraseFunc(tile, window)
Tile *tile; /* Tile describing area to be erased. */ Tile *tile; /* Tile describing area to be erased. */
TileType dinfo; /* Split tile information (unused) */
MagWindow *window; /* Window that is being altered. */ MagWindow *window; /* Window that is being altered. */
{ {
Rect area; Rect area;

View File

@ -25,7 +25,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "tcltk/tclmagic.h"
#include "utils/main.h" #include "utils/main.h"
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/geometry.h" #include "utils/geometry.h"
@ -34,7 +33,6 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "utils/hash.h" #include "utils/hash.h"
#include "database/database.h" #include "database/database.h"
#include "utils/main.h" #include "utils/main.h"
#include "cif/cif.h"
#include "commands/commands.h" #include "commands/commands.h"
#include "dbwind/dbwind.h" #include "dbwind/dbwind.h"
#include "graphics/graphics.h" #include "graphics/graphics.h"
@ -546,12 +544,12 @@ DBWloadWindow(window, name, flags)
newEditUse = DBCellNewUse(newEditDef, (char *) NULL); newEditUse = DBCellNewUse(newEditDef, (char *) NULL);
(void) StrDup(&(newEditUse->cu_id), "Topmost cell in the window"); (void) StrDup(&(newEditUse->cu_id), "Topmost cell in the window");
DBExpand(newEditUse, DBExpand(newEditUse,
((DBWclientRec *)window->w_clientData)->dbw_bitmask, DB_EXPAND); ((DBWclientRec *)window->w_clientData)->dbw_bitmask, TRUE);
if (expand) if (expand)
DBExpandAll(newEditUse, &(newEditUse->cu_bbox), DBExpandAll(newEditUse, &(newEditUse->cu_bbox),
((DBWclientRec *)window->w_clientData)->dbw_bitmask, ((DBWclientRec *)window->w_clientData)->dbw_bitmask,
DB_UNEXPAND, UnexpandFunc, FALSE, UnexpandFunc,
INT2CD(((DBWclientRec *)window->w_clientData)->dbw_bitmask)); INT2CD(((DBWclientRec *)window->w_clientData)->dbw_bitmask));
if (newEdit) if (newEdit)
@ -655,311 +653,6 @@ DBWexit()
return (CmdWarnWrite() == 1); 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);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *

Some files were not shown because too many files have changed in this diff Show More