Compare commits

..

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

992 changed files with 50468 additions and 102513 deletions

View File

@ -1 +0,0 @@
./appimage

View File

@ -1,14 +0,0 @@
#! /usr/bin/env bash
FILE="$(basename $1)"
GIT_DATE="$(git log -n1 --pretty=%ai -- $1)"
GIT_AUTHOR="$(git log -n1 --pretty=%ae -- $1)"
GIT_HASH="$(git log -n1 --pretty=%h -- $1)"
GIT_REV="$(git describe --long --always ${GIT_HASH})"
sed \
-e"s@\\\$Date\\\$@\\\$Date: ${GIT_DATE}\\\$@" \
-e"s|\\\$Author\\\$|\\\$Author: ${GIT_AUTHOR}\\\$|" \
-e"s@\\\$Id\\\$@\\\$Id: ${GIT_REV}\\\$@" \
-e"s@\\\$Revision\\\$@\\\$Revision: ${GIT_REV}\\\$@" \
-e"s|\\\$Header\\\$|\\\$Header: ${FILE} ${GIT_REV} ${GIT_DATE} ${GIT_AUTHOR} \\\$|"

8
.gitattributes vendored
View File

@ -1,8 +0,0 @@
*.c filter=header
*.h filter=header
*.cpp filter=header
*.tcl filter=header
*.scm filter=header
Makefile filter=header
*.gds diff=gds

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

@ -1,291 +0,0 @@
name: CI-canary-matrix
on:
push:
tags:
- "*"
workflow_dispatch:
jobs:
canary:
strategy:
max-parallel: 3
matrix:
os: [ubuntu-24.04, ubuntu-22.04]
# Configure Options
# X11 OGL CAIRO
pkgs: [all, none, no_tk_tcl_rl, no_tk_tcl_brl, no_zlib, no_gc_gl_gu, no_gc, no_gl_gu]
# Toolchain
# ubuntu-20.04 [gcc-9, clang-10]
# ubuntu-22.04 [gcc-11, clang-14]
# ubuntu-24.04 [gcc-13, clang-18]
tc: [default, gcc-10, gcc-11, gcc-12, gcc-13, gcc-14, clang-14, clang-15, clang-17, clang-18, clang-19]
exclude:
- os: ubuntu-22.04
tc: gcc-13
- os: ubuntu-22.04
tc: gcc-14
- os: ubuntu-22.04
tc: clang-17
- os: ubuntu-22.04 # some sources show this as present but not found
tc: clang-18
- os: ubuntu-22.04
tc: clang-19
- os: ubuntu-24.04
tc: gcc-10
- os: ubuntu-24.04
tc: gcc-11
- os: ubuntu-24.04
tc: clang-14
- os: ubuntu-24.04
tc: clang-15
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Matrix Check
env:
MATRIX_OS: ${{ matrix.os }}
MATRIX_PKGS: ${{ matrix.pkgs }}
MATRIX_TC: ${{ matrix.tc }}
run: |
# This takes the macros params ENV and processes into options list
if [ "${MATRIX_PKGS}" = "none" ]
then
pkgs=""
cfgs=""
else
pkgs="kcnrzCLUX"
cfgs=""
fi
# z no.*_zl zlib1g-dev
# n no.*_nc libncurses-dev
# r no.*_rl libreadline-dev
# R no.*_brl --enable-readline-bundled
# c no.*_tcl tcl-dev
# k no.*_tk tk-dev
# C no.*_gc libcairo-dev
# L no.*_gl libgl-dev
# U no.*_gu libglu1-mesa-dev # GLU requires GL
# X no.*_gx libx11-dev
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#z##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_nc"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#n##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_brl"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#r#R#'); fi # replace
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_rl"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#r##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#c##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tk"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#k##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gc"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#C##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gl"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#L##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gu"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#U##'); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gx"; then
pkgs=$(echo -n "$pkgs" | sed -e 's#X##'); fi
_package_list=()
echo -n $pkgs | grep -q "z" && _package_list+=(zlib1g-dev)
echo -n $pkgs | grep -q "n" && _package_list+=(libncurses-dev)
echo -n $pkgs | grep -q "r" && _package_list+=(libreadline-dev)
echo -n $pkgs | grep -q "c" && _package_list+=(tcl-dev)
echo -n $pkgs | grep -q "k" && _package_list+=(tk-dev)
echo -n $pkgs | grep -q "C" && _package_list+=(libcairo-dev)
echo -n $pkgs | grep -q "L" && _package_list+=(libgl-dev)
echo -n $pkgs | grep -q "U" && _package_list+=(libglu1-mesa-dev)
echo -n $pkgs | grep -q "X" && _package_list+=(libx11-dev)
echo "PACKAGE_LIST=${_package_list[*]}" >> $GITHUB_ENV
#
_configure_args=()
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then
_configure_args+=(--disable-compression); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_brl"; then
_configure_args+=(--enable-readline-bundled); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_rl"; then
_configure_args+=(--disable-readline); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tcl"; then
_configure_args+=(--without-tcl); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_tk"; then
_configure_args+=(--without-tk); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gc"; then
_configure_args+=(--without-cairo); fi
if echo -n "$MATRIX_PKGS" | grep -q "^no.*_gl"; then
_configure_args+=(--without-opengl); fi
echo "CONFIGURE_ARGS=${_configure_args[*]}" >> $GITHUB_ENV
- name: Setup Toolchain
env:
MATRIX_TC: ${{ matrix.tc }}
run: |
# decode settings
BUILD_GCC_VERSION=$( echo -n "$MATRIX_TC" | grep -i "^gcc" | sed -e 's#^gcc\-\?##i')
BUILD_CLANG_VERSION=$(echo -n "$MATRIX_TC" | grep -i "^clang" | sed -e 's#^clang\-\?##i')
echo "BUILD_GCC_VERSION=$BUILD_GCC_VERSION" >> $GITHUB_ENV
echo "BUILD_CLANG_VERSION=$BUILD_CLANG_VERSION" >> $GITHUB_ENV
sudo apt-get update
if [ -n "$BUILD_GCC_VERSION" ]
then
GCCV=$BUILD_GCC_VERSION
# https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
sudo apt-get install gcc-${GCCV} g++-${GCCV} cpp-${GCCV}
gcc-${GCCV} -v
g++-${GCCV} -v
cpp-${GCCV} -v < /dev/null
ls -l /usr/bin/g++ /usr/bin/g++-[0-9]* /usr/bin/gcc /usr/bin/gcc-[0-9]* /usr/bin/cpp-* /usr/bin/*-gnu-cpp* || true
update-alternatives --list gcc || true
update-alternatives --list g++ || true
update-alternatives --list cpp || true
update-alternatives --query gcc || true
update-alternatives --query g++ || true
update-alternatives --query cpp || true
ls -l /usr/bin/g++ /usr/bin/g++-[0-9]* /usr/bin/gcc /usr/bin/gcc-[0-9]* /usr/bin/cpp-* /usr/bin/*-gnu-cpp* || true
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCCV} 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-${GCCV} 50
sudo update-alternatives --install "/usr/bin/$(uname -m)-linux-gnu-cpp" cpp "/usr/bin/$(uname -m)-linux-gnu-cpp-${GCCV}" 50
ls -l /usr/bin/g++ /usr/bin/g++-[0-9]* /usr/bin/gcc /usr/bin/gcc-[0-9]* /usr/bin/cpp-* /usr/bin/*-gnu-cpp* || true
update-alternatives --list gcc || true
update-alternatives --list g++ || true
update-alternatives --list cpp || true
hash -r
gcc -v
elif [ -n "$BUILD_CLANG_VERSION" ]
then
CLANGV=$BUILD_CLANG_VERSION
# https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
sudo apt-get install clang-${CLANGV} clang++-${CLANGV} #clang-cpp-${CLANGV}
clang-${CLANGV} -v
clang++-${CLANGV} -v
clang-cpp-${CLANGV} -v < /dev/null
ls -l /usr/bin/clang++ /usr/bin/clang++-[0-9]* /usr/bin/clang /usr/bin/clang-[0-9]* /usr/bin/clang-cpp-* /usr/bin/clang-cpp* || true
update-alternatives --list clang || true
update-alternatives --list clang++ || true
update-alternatives --list clang-cpp || true
update-alternatives --query clang || true
update-alternatives --query clang++ || true
update-alternatives --query clang-cpp || true
ls -l /usr/bin/clang++ /usr/bin/clang++-[0-9]* /usr/bin/clang /usr/bin/clang-[0-9]* /usr/bin/clang-cpp-* /usr/bin/clang-cpp* || true
sudo update-alternatives --install /usr/bin/clang clang /usr/bin/clang-${CLANGV} 50
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-${CLANGV} 50
sudo update-alternatives --install "/usr/bin/clang-cpp" clang-cpp "/usr/bin/clang-cpp-${CLANGV}" 50
ls -l /usr/bin/clang++ /usr/bin/clang++-[0-9]* /usr/bin/clang /usr/bin/clang-[0-9]* /usr/bin/clang-cpp-* /usr/bin/clang-cpp* || true
update-alternatives --list clang || true
update-alternatives --list clang++ || true
update-alternatives --list clang-cpp || true
hash -r
clang -v
fi
- name: Get Dependencies
run: |
if [ -n "$PACKAGE_LIST" ]
then
sudo apt-get install -y ${PACKAGE_LIST}
fi
- name: Build
run: |
if [ -n "$BUILD_CLANG_VERSION" ]
then
export CC="clang-${BUILD_CLANG_VERSION}"
export CXX="clang++-${BUILD_CLANG_VERSION}"
export CPP="clang-cpp-${BUILD_CLANG_VERSION}"
fi
set -o pipefail # due to pipe inside CI
./configure $CONFIGURE_ARGS 2>&1 | tee CONFIGURE.LOG
egrep "^(CPP|CXX|CC)\s" defs.mak
# Add -Wall for CI loggings
sed -e 's# -Werror=# -Wall -Werror=#' -i defs.mak
# Non security/reliability related warnings
#sed -e 's# -Werror=# -Wno-unused-variable -Werror=#' -i defs.mak
#sed -e 's# -Werror=# -Wno-unused-local-typedefs -Werror=#' -i defs.mak
#sed -e 's# -Werror=# -Wno-unused-label -Werror=#' -i defs.mak
#sed -e 's# -Werror=# -Wno-unused-but-set-variable -Werror=#' -i defs.mak
make database/database.h
make -j$(nproc) 2>&1 | tee MAKE.LOG
- name: Summary
env:
MATRIX_OS: ${{ matrix.os }}
MATRIX_PKGS: ${{ matrix.pkgs }}
run: |
set +e
grep "error:" MAKE.LOG > MAKE_error.LOG
grep "warning:" MAKE.LOG > MAKE_warning.LOG
# Less important warnings relating to codesmell more than security (filter out of headline)
grep -v "Wunused-variable" MAKE_warning.LOG |
grep -v "Wunused-local-typedefs" |
grep -v "Wunused-label" |
grep -v "Wunused-but-set-variable" > MAKE_warning_filtered.LOG
ls -l
wc -l *.LOG
error_count=$( grep -c "error:" MAKE_error.LOG)
filtered_warning_count=$(grep -c "warning:" MAKE_warning_filtered.LOG)
title="### $(cat VERSION) ${MATRIX_OS} ${MATRIX_TC} ${MATRIX_PKGS} :: "
if [ "$error_count" -gt 0 ]
then
title="$title $error_count error(s)"
fi
if [ "$filtered_warning_count" -gt 0 ]
then
title="$title $filtered_warning_count warning(s)"
fi
(
total_error_count=$( wc -l MAKE_error.LOG | cut -d' ' -f1)
total_warning_count=$(wc -l MAKE_warning.LOG | cut -d' ' -f1)
echo "$title"
echo ""
echo "PACKAGE_LIST=$PACKAGE_LIST"
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS"
echo ""
if [ "$BUILD_CLANG_VERSION" ]
then
"clang-${BUILD_CLANG_VERSION}" --version | head -n1
if ! update-alternatives --list clang
then
update-alternatives --list "clang-${BUILD_CLANG_VERSION}"
fi
else
gcc --version | head -n1
if ! update-alternatives --list gcc
then
update-alternatives --list "gcc-${BUILD_GCC_VERSION}"
fi
fi
echo ""
echo "total ${total_error_count} error(s) ${total_warning_count} warning(s) :"
echo "|Count|Warning Group (-j build log inaccuracies)|"
echo "|--:|:--|"
# due to -j build the log lines might get corrupted, so missing/incorrect/bogus entries might be seen
# so we add extra: egrep "\[\-W.*\]" (to try to remove that)
sed -e 's#.*\(\[\-W\)#\1#' -e 's#\(\]\).*$#\1#' MAKE_warning.LOG | egrep "\[\-W.*\]" | sort | uniq -c | sort -n | tr -s ' ' | tr ' ' '|' | awk '{print $0"|"}'
echo ""
sed -e '0,/Configuration Summary/d' -e '/\---/,//d' CONFIGURE.LOG | egrep "^.*:"
echo ""
grep DCAD_DIR MAKE.LOG | tail -n1
) >> $GITHUB_STEP_SUMMARY

View File

@ -1,61 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: CI-aarch64
# Controls when the workflow will run
on:
push:
pull_request:
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
simple_build_linux_arm:
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
- name: Get Dependencies
run: |
sudo apt-get update
sudo apt-get install -y tcl-dev tk-dev libcairo-dev
- name: Build
run: |
./configure
make database/database.h
make -j$(nproc)
simple_build_wasm_arm:
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@v4
- name: Get Dependencies
run: |
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
- name: 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
run: |
source ./emsdk/emsdk_env.sh
# The --without and --disable in these build options is due to no WASM library being available for that feature
CFLAGS="--std=c17 -D_DEFAULT_SOURCE=1 -DEMSCRIPTEN=1 -g" emconfigure ./configure --without-cairo --without-opengl --without-x --without-tk --without-tcl --disable-readline --disable-compression --target=asmjs-unknown-emscripten
echo "===== defs.mak ====="
cat defs.mak
echo "===== defs.mak ====="
emmake make
- name: archive wasm bundle
uses: actions/upload-artifact@v4
with:
name: magic-wasm-bundle-arm
path: |
${{ github.workspace }}/magic/magic.wasm

View File

@ -1,475 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: CI-macos
# Controls when the workflow will run
on:
push:
pull_request:
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
simple_build_macos15:
runs-on: macos-15-intel # only and last supported intel MacOS
timeout-minutes: 45 # x86_64 seems non-SSD based (slower)
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get Dependencies
shell: bash # default shell has unwanted broken pipe indication
run: |
brew install --cask xquartz
PACKAGE_LIST="xquartz"
brew install cairo tcl-tk@8 tcsh gnu-sed
_package_list="cairo tcl-tk@8 tcsh gnu-sed"
# These seem needed maybe they are being provided from somewhere else GHA runner
# or brew transitive depend either way doesn't hurt to confirm they are installed.
_package_list="$_package_list libglu freeglut"
if [ -n "$PACKAGE_LIST" ]
then
brew install $PACKAGE_LIST
fi
PACKAGE_LIST="$PACKAGE_LIST $_package_list"
echo "PACKAGE_LIST=$PACKAGE_LIST" >> $GITHUB_ENV
echo "UNAME_M=$(uname -m)" >> $GITHUB_ENV
set +e
set +o pipefail # macosx this is on by default (turn it off)
(
echo "### $(uname -s) $(uname -m) $(uname -r)"
echo ""
set +e
set +o pipefail # macosx this is on by default (turn it off)
export HOMEBREW_NO_COLOR=true
export HOMEBREW_NO_EMOKI=true
# output to $TMPFILE first, then head, instead of using pipeline directly
# this removes unwanted GHA SIGPIPE error/warning indicators from GHA logs
# brew maybe a nodejs command which has a known issue in this area on macosx
TMPFILE=/tmp/shell0$$.tmp
brew info xquartz > $TMPFILE && head -n1 $TMPFILE
brew info cairo > $TMPFILE && head -n1 $TMPFILE
brew info libglu > $TMPFILE && head -n1 $TMPFILE
brew info freeglut > $TMPFILE && head -n1 $TMPFILE
brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE
brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE
brew info tcsh > $TMPFILE && head -n1 $TMPFILE
brew info gnu-sed > $TMPFILE && head -n1 $TMPFILE
echo ""
cc -v 2>&1
echo ""
xcodebuild -version
echo ""
xcodebuild -showsdks | grep macOS
) >> $GITHUB_STEP_SUMMARY
- name: Search
run: |
set +e
( # designed to speed up this process in a single scan
echo "#!/bin/sh"
echo "echo \$*"
echo "ls -ld -- \$*"
echo "shasum -a 1 \$* </dev/null"
echo "echo \"\""
echo "exit 0"
) > search.sh
echo "=== search.sh"
cat search.sh
chmod a+x search.sh
find /opt /usr $HOME \( -iname "libX11.*dylib" -or -iname "Xlib.h" -or -iname "libtcl*dylib" -or -iname "tcl.h" \) -exec ./search.sh {} \; 2>/dev/null
#
# Example symbols that were found missing from the tcl-tk X11 implementation
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XCreateGC" {} \; 2>/dev/null || true
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XGetVisualInfo" {} \; 2>/dev/null || true
#for i in /usr/X11/include/X11/Xlib.h /opt/X11/include/X11/Xlib.h /usr/local/include/X11/Xlib.h;
#do
# echo "====== $i"
# head -n 50 "$i"
# echo "==="
# tail -n 50 "$i"
# echo "======"
#done
# Different GHA platforms have different layouts (x86_64/arm64)
echo "=== /opt"
ls -l /opt
if [ -d /opt/homebrew ]
then
echo "=== /opt/homebrew"
ls -l /opt/homebrew
fi
echo "=== /usr/local/opt"
ls -l /usr/local/opt
echo "=== /usr/local/opt/runner"
ls -l /usr/local/opt/runner
echo "Done"
- name: Build
run: |
export PATH="/opt/X11/bin:$PATH"
./scripts/configure_mac 2>&1 | tee CONFIGURE.LOG
config_log=""
if [ -f scripts/config.log ]
then
config_log="scripts/config.log"
elif [ -f build-magic/config.log ]
then
config_log="build-magic/config.log"
fi
if [ -n "$config_log" ]
then
CONFIGURE_ARGS=$(head -n 10 $config_log | egrep "./configure" | sed -e 's#^ *\$ ##' -e 's#./configure ##')
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS" >> $GITHUB_ENV
fi
echo "===== defs.mak ====="
cat defs.mak
echo "===== defs.mak ====="
make database/database.h
make -j$(sysctl -n hw.ncpu) 2>&1 | tee MAKE.LOG
- name: Install
run: |
sudo make install
- name: Kick The Tyres
run: |
set +e
echo "=== ls -l"
ls -l
find . -type f \( -name "*.dylib" -or -name "magic" -or -name "magicexec" -or -name "magicdnull" \)
echo "=== find /usr/local/bin"
find /usr/local/bin -mtime 0
echo "=== find /usr/local/share"
find /usr/local/share -mtime 0
echo "=== find /usr/local/lib/magic"
find /usr/local/lib/magic -mtime 0
echo "=== otool -L magic/tclmagic.dylib"
otool -L magic/tclmagic.dylib
echo "=== otool -L tcltk/magicexec"
otool -L tcltk/magicexec
echo "=== otool -L tcltk/magicdnull"
otool -L tcltk/magicdnull
set +o pipefail # macosx this is on by default (turn it off)
echo "=== magic --version"
magic --version
echo "=== magic -d help -noconsole"
magic -d help -noconsole
echo "=== magic -d null -noconsole -nowindow -T scmos"
echo "version ; quit" | magic -d null -noconsole -nowindow -T scmos
echo "=== magic -d null -noconsole -T scmos"
echo "version ; quit" | magic -d null -noconsole -T scmos
- name: Summary
if: always()
run: |
set +e
ls -l
touch MAKE.LOG # just in case it did not even build
grep "error:" MAKE.LOG > MAKE_error.LOG
grep "warning:" MAKE.LOG > MAKE_warning.LOG
# Less important warnings relating to codesmell more than security (filter out of headline)
grep -v "Wunused-variable" MAKE_warning.LOG |
grep -v "Wunused-local-typedefs" |
grep -v "Wunused-label" |
grep -v "Wunused-but-set-variable" > MAKE_warning_filtered.LOG
wc -l *.LOG
error_count=$( grep -c "error:" MAKE_error.LOG)
filtered_warning_count=$(grep -c "warning:" MAKE_warning_filtered.LOG)
title="### $(cat VERSION) ${MATRIX_OS} ${MATRIX_TC} ${MATRIX_PKGS} :: "
if [ "$error_count" -gt 0 ]
then
title="$title $error_count error(s)"
fi
if [ "$filtered_warning_count" -gt 0 ]
then
title="$title $filtered_warning_count warning(s)"
fi
(
total_error_count=$( wc -l MAKE_error.LOG | cut -d' ' -f1)
total_warning_count=$(wc -l MAKE_warning.LOG | cut -d' ' -f1)
echo "---"
echo "$title"
echo ""
[ -f scripts/config.log ] && grep "./configure" scripts/config.log | head -n1
echo ""
echo "PACKAGE_LIST=$PACKAGE_LIST"
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS"
echo ""
if [ -s MAKE.LOG ]
then
echo "total ${total_error_count} error(s) ${total_warning_count} warning(s) :"
echo "|Count|Warning Group (-j build log inaccuracies)|"
echo "|--:|:--|"
# due to -j build the log lines might get corrupted, so missing/incorrect/bogus entries might be seen
# so we add extra: egrep "\[\-W.*\]" (to try to remove that)
sed -e 's#.*\(\[\-W\)#\1#' -e 's#\(\]\).*$#\1#' MAKE_warning.LOG | egrep "\[\-W.*\]" | sort | uniq -c | sort -n | tr -s ' ' | tr ' ' '|' | awk '{print $0"|"}'
echo ""
fi
grep -A100 "Configuration Summary" CONFIGURE.LOG | grep -v "Configuration Summary" | egrep "^.*:" | sed -e '/\---/,//d'
echo ""
grep DCAD_DIR MAKE.LOG | tail -n1
) >> $GITHUB_STEP_SUMMARY
- name: Prepare archive
run: |
mkdir -p dist
make install "DESTDIR=$(pwd)/dist"
# Diagnostic details about this build
mkdir -p dist/BUILD-INFO
set +e
cp */config.log dist/BUILD-INFO/
cp *.mak dist/BUILD-INFO/
cp *.LOG dist/BUILD-INFO/
- name: Upload archive magic-macos15
uses: actions/upload-artifact@v4
with:
name: magic-macos15
path: |
${{ github.workspace }}/dist
simple_build_macos:
runs-on: macos-latest
timeout-minutes: 30 # arm64 seems SSD based (faster)
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Get Dependencies
shell: bash # default shell has unwanted broken pipe indication
run: |
brew install --cask xquartz
PACKAGE_LIST="xquartz"
brew install cairo tcl-tk@8 tcsh gnu-sed
_package_list="cairo tcl-tk@8 tcsh gnu-sed"
# These seem needed maybe they are being provided from somewhere else GHA runner
# or brew transitive depend either way doesn't hurt to confirm they are installed.
_package_list="$_package_list libglu freeglut"
if [ -n "$PACKAGE_LIST" ]
then
brew install $PACKAGE_LIST
fi
PACKAGE_LIST="$PACKAGE_LIST $_package_list"
echo "PACKAGE_LIST=$PACKAGE_LIST" >> $GITHUB_ENV
echo "UNAME_M=$(uname -m)" >> $GITHUB_ENV
set +e
set +o pipefail # macosx this is on by default (turn it off)
(
echo "### $(uname -s) $(uname -m) $(uname -r)"
echo ""
set +e
set +o pipefail # macosx this is on by default (turn it off)
export HOMEBREW_NO_COLOR=true
export HOMEBREW_NO_EMOKI=true
# output to $TMPFILE first, then head, instead of using pipeline directly
# this removes unwanted GHA SIGPIPE error/warning indicators from GHA logs
# brew maybe a nodejs command which has a known issue in this area on macosx
TMPFILE=/tmp/shell0$$.tmp
brew info xquartz > $TMPFILE && head -n1 $TMPFILE
brew info cairo > $TMPFILE && head -n1 $TMPFILE
brew info libglu > $TMPFILE && head -n1 $TMPFILE
brew info freeglut > $TMPFILE && head -n1 $TMPFILE
brew info tcl-tk > $TMPFILE && head -n1 $TMPFILE
brew info tcl-tk@8 > $TMPFILE && head -n1 $TMPFILE
brew info tcsh > $TMPFILE && head -n1 $TMPFILE
brew info gnu-sed > $TMPFILE && head -n1 $TMPFILE
echo ""
cc -v 2>&1
echo ""
xcodebuild -version
echo ""
xcodebuild -showsdks | grep macOS
) >> $GITHUB_STEP_SUMMARY
- name: Search
run: |
set +e
( # designed to speed up this process in a single scan
echo "#!/bin/sh"
echo "echo \$*"
echo "ls -ld -- \$*"
echo "shasum -a 1 \$* </dev/null"
echo "echo \"\""
echo "exit 0"
) > search.sh
echo "=== search.sh"
cat search.sh
chmod a+x search.sh
find /opt /usr $HOME \( -iname "libX11.*dylib" -or -iname "Xlib.h" -or -iname "libtcl*dylib" -or -iname "tcl.h" \) -exec ./search.sh {} \; 2>/dev/null
#
# Example symbols that were found missing from the tcl-tk X11 implementation
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XCreateGC" {} \; 2>/dev/null || true
#find /opt /usr $HOME -iname "x*.h" -exec grep -Hn "XGetVisualInfo" {} \; 2>/dev/null || true
#for i in /usr/X11/include/X11/Xlib.h /opt/X11/include/X11/Xlib.h /usr/local/include/X11/Xlib.h;
#do
# echo "====== $i"
# head -n 50 "$i"
# echo "==="
# tail -n 50 "$i"
# echo "======"
#done
# Different GHA platforms have different layouts (x86_64/arm64)
echo "=== /opt"
ls -l /opt
if [ -d /opt/homebrew ]
then
echo "=== /opt/homebrew"
ls -l /opt/homebrew
fi
echo "=== /usr/local/opt"
ls -l /usr/local/opt
echo "=== /usr/local/opt/runner"
ls -l /usr/local/opt/runner
echo "Done"
- name: Build
run: |
export PATH="/opt/X11/bin:$PATH"
./scripts/configure_mac 2>&1 | tee CONFIGURE.LOG
config_log=""
if [ -f scripts/config.log ]
then
config_log="scripts/config.log"
elif [ -f build-magic/config.log ]
then
config_log="build-magic/config.log"
fi
if [ -n "$config_log" ]
then
CONFIGURE_ARGS=$(head -n 10 $config_log | egrep "./configure" | sed -e 's#^ *\$ ##' -e 's#./configure ##')
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS" >> $GITHUB_ENV
fi
echo "===== defs.mak ====="
cat defs.mak
echo "===== defs.mak ====="
make database/database.h
make -j$(sysctl -n hw.ncpu) 2>&1 | tee MAKE.LOG
- name: Install
run: |
sudo make install
- name: Kick The Tyres
run: |
set +e
echo "=== ls -l"
ls -l
find . -type f \( -name "*.dylib" -or -name "magic" -or -name "magicexec" -or -name "magicdnull" \)
echo "=== find /usr/local/bin"
find /usr/local/bin -mtime 0
echo "=== find /usr/local/share"
find /usr/local/share -mtime 0
echo "=== find /usr/local/lib/magic"
find /usr/local/lib/magic -mtime 0
echo "=== otool -L magic/tclmagic.dylib"
otool -L magic/tclmagic.dylib
echo "=== otool -L tcltk/magicexec"
otool -L tcltk/magicexec
echo "=== otool -L tcltk/magicdnull"
otool -L tcltk/magicdnull
set +o pipefail # macosx this is on by default (turn it off)
echo "=== magic --version"
magic --version
echo "=== magic -d help -noconsole"
magic -d help -noconsole
echo "=== magic -d null -noconsole -nowindow -T scmos"
echo "version ; quit" | magic -d null -noconsole -nowindow -T scmos
echo "=== magic -d null -noconsole -T scmos"
echo "version ; quit" | magic -d null -noconsole -T scmos
- name: Summary
if: always()
run: |
set +e
ls -l
touch MAKE.LOG # just in case it did not even build
grep "error:" MAKE.LOG > MAKE_error.LOG
grep "warning:" MAKE.LOG > MAKE_warning.LOG
# Less important warnings relating to codesmell more than security (filter out of headline)
grep -v "Wunused-variable" MAKE_warning.LOG |
grep -v "Wunused-local-typedefs" |
grep -v "Wunused-label" |
grep -v "Wunused-but-set-variable" > MAKE_warning_filtered.LOG
wc -l *.LOG
error_count=$( grep -c "error:" MAKE_error.LOG)
filtered_warning_count=$(grep -c "warning:" MAKE_warning_filtered.LOG)
title="### $(cat VERSION) ${MATRIX_OS} ${MATRIX_TC} ${MATRIX_PKGS} :: "
if [ "$error_count" -gt 0 ]
then
title="$title $error_count error(s)"
fi
if [ "$filtered_warning_count" -gt 0 ]
then
title="$title $filtered_warning_count warning(s)"
fi
(
total_error_count=$( wc -l MAKE_error.LOG | cut -d' ' -f1)
total_warning_count=$(wc -l MAKE_warning.LOG | cut -d' ' -f1)
echo "---"
echo "$title"
echo ""
[ -f scripts/config.log ] && grep "./configure" scripts/config.log | head -n1
echo ""
echo "PACKAGE_LIST=$PACKAGE_LIST"
echo "CONFIGURE_ARGS=$CONFIGURE_ARGS"
echo ""
if [ -s MAKE.LOG ]
then
echo "total ${total_error_count} error(s) ${total_warning_count} warning(s) :"
echo "|Count|Warning Group (-j build log inaccuracies)|"
echo "|--:|:--|"
# due to -j build the log lines might get corrupted, so missing/incorrect/bogus entries might be seen
# so we add extra: egrep "\[\-W.*\]" (to try to remove that)
sed -e 's#.*\(\[\-W\)#\1#' -e 's#\(\]\).*$#\1#' MAKE_warning.LOG | egrep "\[\-W.*\]" | sort | uniq -c | sort -n | tr -s ' ' | tr ' ' '|' | awk '{print $0"|"}'
echo ""
fi
grep -A100 "Configuration Summary" CONFIGURE.LOG | grep -v "Configuration Summary" | egrep "^.*:" | sed -e '/\---/,//d'
echo ""
grep DCAD_DIR MAKE.LOG | tail -n1
) >> $GITHUB_STEP_SUMMARY
- name: Prepare archive
run: |
mkdir -p dist
make install "DESTDIR=$(pwd)/dist"
# Diagnostic details about this build
mkdir -p dist/BUILD-INFO
set +e
cp */config.log dist/BUILD-INFO/
cp *.mak dist/BUILD-INFO/
cp *.LOG dist/BUILD-INFO/
- name: Upload archive magic-macos
uses: actions/upload-artifact@v4
with:
name: magic-macos
path: |
${{ github.workspace }}/dist

View File

@ -1,60 +0,0 @@
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the workflow will run
on:
push:
pull_request:
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
simple_build_linux:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Get Dependencies
run: |
sudo apt-get install -y tcl-dev tk-dev libcairo-dev
- name: Build
run: |
./configure
make database/database.h
make -j$(nproc)
simple_build_wasm:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Get Dependencies
run: |
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
- name: 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
run: |
source ./emsdk/emsdk_env.sh
# The --without and --disable in these build options is due to no WASM library being available for that feature
CFLAGS="--std=c17 -D_DEFAULT_SOURCE=1 -DEMSCRIPTEN=1 -g" emconfigure ./configure --without-cairo --without-opengl --without-x --without-tk --without-tcl --disable-readline --disable-compression --target=asmjs-unknown-emscripten
echo "===== defs.mak ====="
cat defs.mak
echo "===== defs.mak ====="
emmake make
- name: archive wasm bundle
uses: actions/upload-artifact@v4
with:
name: magic-wasm-bundle
path: |
${{ github.workspace }}/magic/magic.wasm

30
.gitignore vendored
View File

@ -1,34 +1,10 @@
defs.mak defs.mak
*/Depend Depend
config.cache config.cache
config.log config.log
scripts/config.log
scripts/config.status
scripts/defs.mak
.*.swp
*.o *.o
*.so *.so
*~ *~
scmos/cif_template/objs/* scmos/cif_template/objs/*
database/database.h UPDATE_ME
install.log VERSION
magic/proto.magicrc
make.log
scmos/gdsquery.tech
scmos/minimum.tech
scmos/scmos-sub.tech
scmos/scmos-tm.tech
scmos/scmos.tech
scmos/scmosWR.tech
scmos/nmos.tech
tcltk/magic.sh
tcltk/magic.tcl
tcltk/magicdnull
tcltk/magicexec
tcltk/ext2spice.sh
tcltk/ext2sim.sh
magic/tclmagic.dylib
tcltk/magicdnull.dSYM/
tcltk/magicexec.dSYM/
reconfigure.sh
pfx/

View File

@ -7,8 +7,6 @@ Autoconf Capsule Summary:
make make
make install make install
Note: Remember to use 'gmake' on FreeBSD.
Autoconf options (use "./configure --help" for a complete list): Autoconf options (use "./configure --help" for a complete list):
--prefix=DIR Indicates the install directory. Determines the --prefix=DIR Indicates the install directory. Determines the
@ -47,12 +45,6 @@ Autoconf Capsule Summary:
Disable threaded X11 and OpenGL graphics. Disable threaded X11 and OpenGL graphics.
Normally enabled. Normally enabled.
--disable-compression
Disable reading and writing of compressed
(gzipped) GDS files and reading of compressed
.mag files. Normally enabled, if the zlib
development package is installed.
Notes to Magic maintainers: Notes to Magic maintainers:
-------------------------- --------------------------

View File

@ -1,79 +0,0 @@
# Installing Magic on macOS (Tested on Big Sur)
## With Brew
Get [Homebrew](https://brew.sh).
```sh
brew install cairo tcl-tk@8 python3 gnu-sed
brew install --cask xquartz
./scripts/configure_mac
# If you have both TCL8 and TCL9 installed you may need to verify which was selected.
make database/database.h
make -j$(sysctl -n hw.ncpu)
make install # may need sudo depending on your setup
```
## Without Brew
Get [XQuartz](https://github.com/XQuartz/XQuartz)
### Build Tcl for X11
We are following the instructions from xschem (https://github.com/StefanSchippers/xschem/blob/master/README_MacOS.md).
* Download Tcl from https://prdownloads.sourceforge.net/tcl/tcl8.6.10-src.tar.gz
We are using not `opt` but `opt2` so that this Tcl does not interfere with `tcl-tk` from HomeBrew.
Extract the Tcl sources and then go to the unix folder and execute the following commands::
```
./configure --prefix=/usr/local/opt2/tcl-tk
make
make install
```
### Build Tk for X11
* Download Tk from https://prdownloads.sourceforge.net/tcl/tk8.6.10-src.tar.gz
Extract Tk source and then go to the unix folder:
NOTE: before running 'make' inspect the Makefile and ensure the LIB_RUNTIME_DIR is set as follows. Make the correction if not:
```
LIB_RUNTIME_DIR = $(libdir)
```
```
./configure --prefix=/usr/local/opt2/tcl-tk \
--with-tcl=/usr/local/opt2/tcl-tk/lib --with-x \
--x-includes=/opt/X11/include --x-libraries=/opt/X11/lib
make
make install
```
### Build magic
We need to provide this `tcl-tk` and suppress compilation errors.
```
./configure --with-tcl=/usr/local/opt2/tcl-tk/lib \
--with-tk=/usr/local/opt2/tcl-tk/lib \
--x-includes=/opt/X11/include \
--x-libraries=/opt/X11/lib \
CFLAGS=-Wno-error=implicit-function-declaration
make
make install
```
## If facing issue with layout window not opening / XQuartz:
Make sure that the output of the following command is ```:0```.
```
echo $DISPLAY
```
if the above command doesn't display ```:0``` then add the following line in ```.zshrc```.
```
export PATH="/opt/X11/bin:$PATH"
```
Close & reopen terminal to load the path. Then set display manually to ```0``` by using the following command.
```
export DISPLAY=:0
```
Now ```echo DISPLAY``` should give ```:0``` as output.

10
LICENSE
View File

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

142
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 = cmwind commands database dbwind debug drc extflat extract \
extract graphics netmenu plow resis select sim textio tiles \ graphics netmenu plow resis select sim textio tiles utils \
utils windows wiring 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 2>&1 | tee -a make.log | egrep -i "(.c:|Stop.|---)"
tcl: tcllibrary tcl:
@echo --- errors and warnings logged in file make.log
@${MAKE} tcllibrary 2>&1 | tee -a make.log | egrep -i "(.c:|Stop.|---)"
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
@ -38,70 +36,38 @@ config:
tcllibrary: database/database.h modules tcllibrary: database/database.h modules
@echo --- making Tcl shared libraries @echo --- making Tcl shared libraries
for dir in ${PROGRAMS}; do \ for dir in ${PROGRAMS}; do \
(cd $$dir && ${MAKE} tcl-main) || exit 1; done (cd $$dir && ${MAKE} tcl-main); done
mains: database/database.h modules libs mains: database/database.h modules libs
@echo --- making main programs @echo --- making main programs
for dir in ${PROGRAMS}; do \ for dir in ${PROGRAMS}; do \
(cd $$dir && ${MAKE} main) || exit 1; done (cd $$dir && ${MAKE} main); 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:
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); done
.PHONY: FORCE libs:
${MODULES_SUBDIR}: FORCE @echo --- making libraries
@${MAKE} -C $(dir $@) module for dir in ${LIBRARIES}; do \
(cd $$dir && ${MAKE} lib); done
.PHONY: modules depend: database/database.h
modules: database/database.h depend ${MODULES_SUBDIR} ${RM} */Depend
for dir in ${MODULES} ${UNUSED_MODULES} ${PROGRAMS}; do \
${LIBS_SUBDIR}: FORCE (cd $$dir && ${MAKE} depend); done
@${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
${MAKE} -C $(dir $@) depend
.PHONY: depend
depend: defs.mak ${SUBDIRS_DEPEND}
.PHONY: techs
techs: depend
@echo --- making techs
for dir in ${TECHS}; do \
(cd $$dir && ${MAKE} all) || exit 1; done
install: $(INSTALL_TARGET) install: $(INSTALL_TARGET)
install-magic: install-magic:
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR} @echo --- installing executable to $(DESTDIR)${BINDIR}
@echo --- installing runtime files to $(DESTDIR)${INSTALL_LIBDIR} @echo --- installing runtime files to $(DESTDIR)${LIBDIR}
@${MAKE} install-real @${MAKE} install-real 2>&1 >> install.log
install-real: install-dirs install-real: install-dirs
for dir in ${INSTALL_CAD_DIRS}; do \ for dir in ${INSTALL_CAD_DIRS}; do \
@ -110,26 +76,24 @@ install-real: install-dirs
(cd $$dir && ${MAKE} install); done (cd $$dir && ${MAKE} install); done
install-tcl-dirs: install-tcl-dirs:
${MAGICDIR}/scripts/mkdirs $(DESTDIR)${INSTALL_BINDIR} \ ${MAGICDIR}/scripts/mkdirs $(DESTDIR)${BINDIR} $(DESTDIR)${MANDIR} \
$(DESTDIR)${INSTALL_MANDIR} $(DESTDIR)${INSTALL_SYSDIR} \ $(DESTDIR)${SYSDIR} $(DESTDIR)${TCLDIR} $(DESTDIR)${TCLDIR}/bitmaps
$(DESTDIR)${INSTALL_TCLDIR} $(DESTDIR)${INSTALL_TCLDIR}/bitmaps
install-dirs: install-dirs:
${MAGICDIR}/scripts/mkdirs $(DESTDIR)${INSTALL_BINDIR} \ ${MAGICDIR}/scripts/mkdirs $(DESTDIR)${BINDIR} $(DESTDIR)${MANDIR} \
$(DESTDIR)${INSTALL_MANDIR} $(DESTDIR)${INSTALL_SYSDIR} \ $(DESTDIR)${SYSDIR} $(DESTDIR)${SCMDIR}
$(DESTDIR)${INSTALL_SCMDIR}
install-tcl: install-tcl:
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR} @echo --- installing executable to $(DESTDIR)${BINDIR}
@echo --- installing runtime files to $(DESTDIR)${INSTALL_LIBDIR} @echo --- installing runtime files to $(DESTDIR)${LIBDIR}
@${MAKE} install-tcl-real @${MAKE} install-tcl-real 2>&1 >> install.log
install-tcl-real: install-tcl-dirs install-tcl-real: install-tcl-dirs
for dir in ${INSTALL_CAD_DIRS} ${PROGRAMS}; do \ for dir in ${INSTALL_CAD_DIRS} ${PROGRAMS}; do \
(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 +103,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 ${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 \
@ -164,10 +127,3 @@ tags:
TAGS: TAGS:
${RM} TAGS ${RM} TAGS
find . ${MODULES} ${PROGRAMS} -name "*.[ch]" -maxdepth 1 | xargs etags -o TAGS find . ${MODULES} ${PROGRAMS} -name "*.[ch]" -maxdepth 1 | xargs etags -o TAGS
setup-git:
git config --local include.path ../.gitconfig
git stash save
${RM} .git/index
git checkout HEAD -- "$$(git rev-parse --show-toplevel)"
git stash pop

View File

@ -1,57 +1,25 @@
![Continuous Integration](https://github.com/RTimothyEdwards/magic/actions/workflows/main.yml/badge.svg)
# MAGIC
1. General Information: 1. General Information:
--------------------------------- ---------------------------------
Use your World Wide Web browser to read: Use your World Wide Web browser to read:
http://opencircuitdesign.com/magic/ http://opencircuitdesign.com/magic/
http://vlsi.csl.cornell.edu/magic/
http://www.research.digital.com/wrl/magic/magic.html
Primary documentation is on the opencircuitdesign.com website under Primary documentation is on the opencircuitdesign.com website under
various links, including "Download", "Compile", and "Install" for the "Documentation" link.
information on obtaining, compiling, and installing the tool from
source; "Code History" for detailed comments on all code changes;
"Using Magic" for basic usage information including a complete on-line
command reference; "Technology Files" for essential documentation on how
to understand, edit, or write technology files for Magic; "Documentation"
for miscellaneous papers and historical documentation converted to HTML
format.
The current distribution version of magic is maintained by Tim Edwards
<tim@opencircuitdesign.com>. Please let me know of any problems/bugs
you find through the github Issues tracker.
Additional information from developer Rajit Manohar:
https://csl.yale.edu/~rajit/magic/
Of mainly historical interest only, now (available through the WayBack machine):
https://web.archive.org/web/20051217204815/http://www.research.compaq.com:80/wrl/projects/magic/magic.html
The current development versions of magic are maintained by Tim Edwards
<tim@opencircuitdesign.com> and the current distribution version is
maintained by Rajit Manohar <rajit@csl.cornell.edu>. Please let us
know of any problems/bugs you find. Development of versions 7.2 and
newer is generously funded by MultiGiG, Inc.
2. Compilation and Installation: 2. Compilation and Installation:
--------------------------------- ---------------------------------
See the file "INSTALL" in this directory, or "INSTALL_MacOS.md" for MacOS. See the file "INSTALL" in this directory.
3. Version 8.3 Release Notes: 3. Version 8.2 Release Notes:
---------------------------------
During the course of version 8.2, magic moved to a git-oriented
development. There are no longer "stable" and "distribution"
versions. There is only the git repo with various development
branches.
First release contains the "bplane" implementation for the cell
plane pulled from the open source code for micromagic. This is
much more efficient than using the corner-stitched tile plane
for cells, and speeds up a number of methods, such as extraction,
by a factor of 3 to 5 or so, depending on the amount of hierarchy
in the design.
4. Version 8.2 Release Notes:
--------------------------------- ---------------------------------
As of the release of version 8.2, Version 8.1 is now the new stable As of the release of version 8.2, Version 8.1 is now the new stable
@ -59,28 +27,7 @@
development push over 8.1 is to add a Cairo (2D hardware-accelerated development push over 8.1 is to add a Cairo (2D hardware-accelerated
graphics) interface ("magic -d CAIRO" or "magic -d XR"). graphics) interface ("magic -d CAIRO" or "magic -d XR").
October, 2017: DRC changes correctly handle DRC errors in a child 4. Version 8.1 Release Notes:
cell that are effectively corrected by geometry in the parent cell.
March, 2018: Added better version handling of subcells. "Use"
records contain a path (relative or absolute) to the library used
by the subcell, and this path is honored as long as it can be
found.
April, 2018: Added the "plow" function back to the level of
capability it originally had. This does not include handling of
magic extensions since version 7, including non-manhattan geometry,
stacked contacts, and DRC rule extensions.
Extended the extraction method to allow multiple extracted device
types per magic layer, depending on the surrounding context
(connecting layers, substrate, identifier layers, etc.).
Corrected the "extresist" method for non-FET devices, although it
continues to need fundamental work to remove its dependence on the
".sim" format files.
5. Version 8.1 Release Notes:
--------------------------------- ---------------------------------
As of the release of version 8.1, Version 8.0 is now the new stable As of the release of version 8.1, Version 8.0 is now the new stable
@ -94,7 +41,7 @@
name without any understanding of a substrate node and name without any understanding of a substrate node and
connectivity. connectivity.
6. Version 8.0 Release Notes: 5. Version 8.0 Release Notes:
--------------------------------- ---------------------------------
As of the release of version 8.0, Version 7.5 is now the new stable As of the release of version 8.0, Version 7.5 is now the new stable
@ -122,7 +69,7 @@
7) New extraction method "msubcircuit" with methods for specifying 7) New extraction method "msubcircuit" with methods for specifying
parameter names for source/drain area and perimeter. parameter names for source/drain area and perimeter.
7. Version 7.5 Release Notes: 6. Version 7.5 Release Notes:
--------------------------------- ---------------------------------
Version 7.5 is the development branch. Version 7.5.0 is the same as Version 7.5 is the development branch. Version 7.5.0 is the same as
@ -177,7 +124,7 @@
See the online release notes for a more thorough list of features. See the online release notes for a more thorough list of features.
8. Version 7.4 Release Notes: 7. Version 7.4 Release Notes:
--------------------------------- ---------------------------------
Version 7.4 is the new stable distribution version of magic. Version 7.4 is the new stable distribution version of magic.
@ -189,7 +136,7 @@
not be a "What's new in 7.4" section, as there is not supposed not be a "What's new in 7.4" section, as there is not supposed
to be anything new in version 7.4. to be anything new in version 7.4.
9. Version 7.3 Release Notes: 8. Version 7.3 Release Notes:
--------------------------------- ---------------------------------
Magic release 7.3 incorporates a stacked contact model which is, Magic release 7.3 incorporates a stacked contact model which is,
@ -237,7 +184,7 @@
28) New method for crash backups, including restore with "magic -r" 28) New method for crash backups, including restore with "magic -r"
29) A number of other technology file additions and enhancements 29) A number of other technology file additions and enhancements
10. Version 7.2 Release Notes: 9. Version 7.2 Release Notes:
--------------------------------- ---------------------------------
Magic release 7.2 incorporates the capability to run magic from the Tcl Magic release 7.2 incorporates the capability to run magic from the Tcl
@ -295,7 +242,7 @@
26) Improved techfile format with asterisk-notation and DRC 26) Improved techfile format with asterisk-notation and DRC
"surround", "overhang", and "rect_only" statements. "surround", "overhang", and "rect_only" statements.
11. Version 7.1 Release Notes: 10. Version 7.1 Release Notes:
--------------------------------- ---------------------------------
Magic release 7.1 consolidates all known patches/features Magic release 7.1 consolidates all known patches/features
@ -323,7 +270,7 @@
- tons of other small things that hopefully make the build process - tons of other small things that hopefully make the build process
nicer. nicer.
12. Releases prior to version 7: 11. Releases prior to version 7:
--------------------------------- ---------------------------------
What's new in 6.5.2: What's new in 6.5.2:

36
TODO
View File

@ -1,32 +1,8 @@
I. Bugs to fix I. Bugs to fix (also in magic-7.5 [stable]):
1. The "extresist" code needs to extract substrate networks. Moreover, 1. The "extresist" code only recognizes original "fet" types, not
the "extresist" code really needs to have the dependence on the new "device" types in the extract file.
ext2sim removed, and instead read directly from .ext files. The
.sim format has no substrate connections, so this cannot be properly
represented. Also, there is nothing that is read from the .sim file
that is not already present in the .ext file.
2. "plow" should derive its rules from the DRC decks (using the new 2. "plow" has been broken for some time. It should derive its rules
routines that are meant for just that sort of thing). from the DRC decks (using the new routines that are meant for just
that sort of thing).
3. It is possible to trick the net selection into an infinite loop in
unusual geometry situations. That these situations would be DRC
errors does not excuse the infinite loop behavior. The geometry
required is unusual enough that this is not a high priority item.
4. The LEF read/write should operate from the GDS rules and layers, not
the magic database layers. LEF setup should be put in the cifinput
and cifoutput sections in the techfile, not in its own section.
5. Implement a CRC checksum to replace (or complement) timestamps.
Cells are marked as invalid only if the checksum fails to match, not
if the timestamp is outdated. This helps with two problems: (1)
PDKs which are reinstalled but not changed, and (2) libraries which
are copied from one place to another but not changed.
6. Implement tile planes that can be defined as either maximum horizontal
stripes (default) or maximum vertical stripes. The latter, if applied
to vertically oriented route layers, vastly speeds up searches on
those layers. The code for manipulating tile planes with maximum
vertical stripes exists but is used only in by the maze router.

View File

@ -1 +1 @@
8.3.637 8.2.8

4
appimage/.gitignore vendored
View File

@ -1,4 +0,0 @@
*.tar.gz
prefix/
*.AppImage
appimagetool

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,68 +0,0 @@
FROM centos/python-38-centos7:20210726-fad62e9
USER root
# CentOS7 went EOL on June 30, 2024 this builds out of vault.centos.org
RUN ls -l /etc/yum.repos.d/ \
&& cp /etc/yum.repos.d/CentOS-Base.repo /tmp/CentOS-Base.repo.old \
&& sed -e 's/mirror.centos.org/vault.centos.org/g' -i /etc/yum.repos.d/*.repo \
&& sed -e 's/^#.*baseurl=http/baseurl=http/g' -i /etc/yum.repos.d/*.repo \
&& sed -e 's/^mirrorlist=http/#mirrorlist=http/g' -i /etc/yum.repos.d/*.repo \
&& diff -u /tmp/CentOS-Base.repo.old /etc/yum.repos.d/CentOS-Base.repo; \
yum clean all \
&& yum -y update \
&& rm -f /tmp/CentOS-Base.repo.old
# Build Dependencies (and dump version to logging)
RUN yum install -y cairo-devel freeglut-devel gcc make tcsh \
&& echo "### rpm -qa:" \
&& rpm -qa | sort \
&& echo ""
# Tcl/Tk
WORKDIR /tcl
RUN curl -L https://prdownloads.sourceforge.net/tcl/tcl8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \
&& cd unix \
&& ./configure --prefix=/prefix \
&& make \
&& make install
WORKDIR /tk
RUN curl -L https://prdownloads.sourceforge.net/tcl/tk8.6.16-src.tar.gz | tar --strip-components=1 -xzC . \
&& cd unix \
&& ./configure --prefix=/prefix --with-tcl=/prefix/lib \
&& make \
&& make install
WORKDIR /prefix/bin
RUN cp ./wish8.6 ./wish
RUN cp ./tclsh8.6 ./tclsh
# Magic
WORKDIR /magic
COPY . .
RUN ./configure \
--prefix=/prefix \
--with-tcl=/prefix/lib \
--with-tk=/prefix/lib \
--without-opengl \
&& make clean \
&& make database/database.h \
&& make -j$(nproc) \
&& make install
# Produce summary of what was created and confirm their DSOs
RUN echo "### filesystem:" \
find /prefix -printf "%y/%M/%m %i/%n %l %u/%U %g/%G %s/%b %T+/%T@\t%p\n"; \
ls -lR /prefix; \
find /prefix -type f -perm /111 -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
for name in libgcc_s libstdc++ libpng liblzma libxml2 libz libcairo libGL libGLU; do \
find /lib64 /usr/lib64 -maxdepth 2 -name "*.so" -name "${name}*" -exec bash -c "echo \#\#\# {}; ldd -v {}" \; 2>/dev/null; \
done; \
echo "###"
WORKDIR /
RUN tar -czf /prefix.tar.gz -C ./prefix .
CMD ["/bin/bash"]

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

@ -1,39 +0,0 @@
#!/usr/bin/env bash
export CURDIR=$(dirname $(readlink -f "${0}"))
export PATH="${CURDIR}/bin":$PATH
export LD_LIBRARY_PATH=${CURDIR}/lib:$LD_LIBRARY_PATH
export CAD_ROOT="${CURDIR}/lib"
export MAGIC_WISH="${CURDIR}/bin/wish"
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,8 +0,0 @@
[Desktop Entry]
Type=Application
Name=Magic
Icon=magic
Exec=magic
Comment=Magic - A VLSI Layout System
Categories=Development;
Terminal=true

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 464.731 464.731" style="enable-background:new 0 0 464.731 464.731;" xml:space="preserve">
<g id="XMLID_207_">
<path id="XMLID_212_" d="M463.056,441.971l-45.894-43.145l29.759-55.521c0.8-1.508,0.379-3.398-1.029-4.395
c-1.388-1.011-3.305-0.832-4.487,0.424l-43.146,45.895l-55.533-29.746c-1.515-0.803-3.399-0.377-4.395,1.027
c-1.017,1.392-0.815,3.309,0.438,4.488l45.911,43.162l-29.747,55.518c-0.816,1.525-0.378,3.401,1.01,4.412
c1.41,0.996,3.326,0.816,4.502-0.438l43.149-45.912l55.507,29.746c1.506,0.802,3.393,0.378,4.393-1.027
C464.506,445.072,464.308,443.136,463.056,441.971z"/>
<path id="XMLID_211_" d="M369.086,94.641l-20.273,37.826c-1.04,1.918-0.479,4.307,1.285,5.588c1.783,1.271,4.215,1.029,5.71-0.559
l29.417-31.269l37.78,20.26c1.921,1.024,4.323,0.484,5.589-1.285c1.271-1.783,1.048-4.215-0.555-5.709l-31.245-29.385
l20.274-37.814c1.028-1.918,0.466-4.307-1.297-5.59c-1.766-1.268-4.216-1.025-5.713,0.558l-29.381,31.257l-37.814-20.273
c-1.936-1.026-4.325-0.467-5.589,1.301c-1.273,1.766-1.042,4.214,0.544,5.711L369.086,94.641z"/>
<path id="XMLID_210_" d="M123.956,360.06l-44.659,6.239l-17.611-41.484c-0.906-2.113-3.217-3.232-5.423-2.631
c-2.226,0.623-3.626,2.78-3.313,5.051l6.239,44.639L17.69,389.489c-2.1,0.908-3.23,3.217-2.614,5.424
c0.609,2.219,2.767,3.629,5.032,3.31l44.657-6.241l17.611,41.5c0.896,2.118,3.218,3.236,5.425,2.629
c2.206-0.617,3.626-2.765,3.312-5.043l-6.238-44.658l41.5-17.617c2.099-0.904,3.234-3.217,2.612-5.423
C128.383,361.147,126.221,359.745,123.956,360.06z"/>
<path id="XMLID_209_" d="M4.908,45.161l34.646,9.537l-0.23,35.832c-0.012,2.01,1.449,3.704,3.447,3.99
c1.976,0.271,3.851-0.969,4.377-2.901l9.521-34.565l35.923,0.225c2.01,0.016,3.702-1.447,3.992-3.441
c0.271-1.982-0.97-3.853-2.905-4.383l-34.627-9.547l0.213-35.881c0.018-2.01-1.466-3.701-3.441-3.988
c-1.983-0.273-3.856,0.965-4.383,2.901l-9.533,34.608L5.996,37.324c-1.991,0-3.701,1.463-3.974,3.441
C1.751,42.747,2.992,44.633,4.908,45.161z"/>
<path id="XMLID_208_" d="M278.019,234.519l139.775-18.477c1.586-0.21,2.762-1.555,2.762-3.143c0-1.587-1.176-2.928-2.762-3.142
L278.019,191.28l20.476-57.755c0.857-2.446,0.235-5.183-1.603-7.009c-1.828-1.844-4.567-2.445-7.01-1.586l-57.697,20.484
L213.708,5.688c-0.194-1.588-1.554-2.764-3.14-2.764c-1.584,0-2.935,1.176-3.146,2.764l-18.457,139.744l-57.772-20.502
c-2.448-0.875-5.181-0.258-7.014,1.586c-1.84,1.826-2.46,4.563-1.586,7.009l20.489,57.772l-139.73,18.46
c-1.584,0.214-2.762,1.555-2.762,3.142c0,1.588,1.178,2.933,2.762,3.143l139.73,18.461l-20.489,57.742
c-0.874,2.447-0.254,5.182,1.586,7.01c1.833,1.842,4.565,2.462,7.014,1.582l57.772-20.467l18.457,139.743
c0.212,1.583,1.563,2.764,3.146,2.764c1.586,0,2.945-1.181,3.14-2.764l18.477-139.743l57.727,20.486
c2.441,0.876,5.181,0.256,7.009-1.589c1.845-1.825,2.461-4.562,1.584-7.007L278.019,234.519z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.3 KiB

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

@ -1,10 +0,0 @@
#
# rcsid "$Header: /usr/cvsroot/magic-8.0/drc/Makefile,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"
#
MODULE = bplane
MAGICDIR = ..
SRCS = bpDump.c bpUtils.c bpBins.c bpEnum.c bpMain.c bpStat.c
include ${MAGICDIR}/defs.mak
include ${MAGICDIR}/rules.mak

View File

@ -1,38 +0,0 @@
TODO
----
NOTE: nested enums are broken do to dynamic binning.
Don't rebuild entire bplane when bbox grows.
unsubbing sometimes.
Some (remaining) bplane design issues:
groups?
idea: support small number of groups by having
separate bplane for each group. Do selection this
way. Logically layered on top of bplanes - but may
want to integrate.
DECISION: defer for now.
pack/unpack?
Seems incompatible with user alloc/dealloc.
Complicated.
DECISION: Forget it.
coarse/fine with cache.
can be added later. should fit in nicely.
no special support needed.
integrated find/add?
can add later.
don't worry about it now.
May want to add attributes, via external hash.

View File

@ -1,719 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpBins.c
*
* Routines for creating and manipulating bin arrays.
*
*/
#include <stdio.h>
#include <math.h>
#include "utils/utils.h"
#include "utils/malloc.h"
#include "database/database.h"
#include "utils/geometry.h"
#include "bplane/bplaneInt.h"
/* debug */
#define BPD 0
/* Tcl linked Parameters */
int bpMinBAPop = 10; /* don't sub(bin) when count less than this */
double bpMinAvgBinPop = 1.0; /* try to keep average bin pop at or
* below this
*/
/*
* ----------------------------------------------------------------------------
*
* roundUp -- Round up a number to a grid.
*
* ----------------------------------------------------------------------------
*/
static __inline__ int roundUp(int i, int res)
{
int r = (i % res);
/* Subtract negative number */
if (r > 0) r = r - res;
return i - r;
}
/*
* ----------------------------------------------------------------------------
*
* bpBinArrayNew -- allocate new bin array.
*
* ----------------------------------------------------------------------------
*/
static BinArray *bpBinArrayNew(int dx, /* x diameter of bins */
int dy, /* y diameter of bins */
Rect *bbox) /* area covered */
{
BinArray *new;
Rect abbox;
int w, h, dimX, dimY, numBins;
int size;
/* compute array dimensions */
w = roundUp(GEO_WIDTH(bbox),dx);
h = roundUp(GEO_HEIGHT(bbox),dy);
dimX = w/dx;
dimY = h/dy;
numBins = dimX*dimY;
/* allocate array */
size = sizeof(BinArray) + numBins*(sizeof(void *));
new = (BinArray *)callocMagic(1, size);
/* initial */
new->ba_bbox = *bbox;
new->ba_dx = dx;
new->ba_dy = dy;
new->ba_dimX = dimX;
new->ba_numBins = numBins;
/* pull bbox back one from top-edge, right-edge, to simplify index
* computation in bpEnumPush
*/
new->ba_bbox.r_xtop --;
new->ba_bbox.r_ytop --;
return new;
}
/*
* ----------------------------------------------------------------------------
*
* bpBinAdd -- add element to bin array
*
* ----------------------------------------------------------------------------
*/
void bpBinAdd(BinArray *ba,
Element *e)
{
int i; /* bin index */
/* compute bin index */
if(GEO_WIDTH(&e->e_rect) >= ba->ba_dx ||
GEO_HEIGHT(&e->e_rect) >= ba->ba_dy)
{
/* oversized */
i = ba->ba_numBins;
}
else
{
/* x and y indices */
int xi = (e->e_rect.r_xbot - ba->ba_bbox.r_xbot) / ba->ba_dx;
int yi = (e->e_rect.r_ybot - ba->ba_bbox.r_ybot) / ba->ba_dy;
i = xi + yi*ba->ba_dimX ;
}
/* add element */
if(bpBinType(ba,i) == BT_ARRAY)
{
/* sub-binned */
bpBinAdd(bpSubArray(ba,i), e);
}
else
{
/* simple list */
Element *next = bpBinList(ba,i);
/* link with next */
e->e_link = next;
if(next) next->e_linkp = &e->e_link;
/* link to head */
ba->ba_bins[i] = e;
e->e_linkp = (Element **) &ba->ba_bins[i];
}
}
/*
* ----------------------------------------------------------------------------
*
* bpBinArrayUnbuild - remove elements from bin array and Free the array
*
* Returns: (singly linked) list of elements formerly in the array
*
* ----------------------------------------------------------------------------
*/
static Element *bpBinArrayUnbuild(BinArray *ba)
{
Element *elements = NULL;
int numBins = ba->ba_numBins;
int i;
/* empty the bins */
for(i=0;i<=numBins;i++)
{
Element *l;
if(bpBinType(ba,i) == BT_ARRAY)
{
/* sub-array, unbuild recursively */
l = bpBinArrayUnbuild(bpSubArray(ba,i));
}
else
{
/* Simple list */
l = bpBinList(ba,i);
}
/* collect elements */
while(l)
{
Element *e = l;
l = e->e_link;
e->e_link = elements;
elements = e;
}
}
/* free the array */
freeMagic((char *)ba);
return elements;
}
/*
* ----------------------------------------------------------------------------
* bpListExceedsQ --
*
* check if element list exceeds given length
*
* Returns size of list.
*
* ----------------------------------------------------------------------------
*/
static __inline__ int
bpListExceedsQ(Element *e, /* list */
int n) /* length to check against */
{
n++;
while(e && n)
{
n--;
e = e->e_link;
}
return n==0;
}
/*
* ----------------------------------------------------------------------------
*
* bpBinArraySizeIt -- choose bin sizes for new bin array.
*
* RESULT:
*
* normally returns TRUE,
* returns FALSE on failure: could not come up with binning that
* makes progress.
*
* NOTE: the various 'return' parameters are not set on failure.
*
* ----------------------------------------------------------------------------
*/
static __inline__ bool
bpBinArraySizeIt(Rect *bbox, /* bin array bbox */
Element *elements, /* initial elements */
int *dxp, /* return bin x-diameter here */
int *dyp, /* return bin y-diameter here */
int *maxDXp,
int *maxDYp,
int *numBinsp, /* return number of bins here */
int *countp) /* return number of elements here */
{
BinArray *ba;
int count;
double numBins; /* need double to avoid overflow on tentative calc. */
int h = GEO_HEIGHT(bbox);
int w = GEO_WIDTH(bbox);
int dx,dy; /* individual bin diameter */
int maxEX, maxEY; /* max element dimensions */
int maxDX, maxDY; /* max bin diameter allowed */
int xDim, yDim; /* array dimensions */
int maxBins; /* max number of bins
* (due to bpMinAvgBinPop)
*/
/* compute max element dimensions
* (would like bins coarser than max dimensisons)
*/
{
Element *e;
maxEX = 0;
maxEY = 0;
count = 0;
for(e=elements; e; e=e->e_link)
{
int ew = GEO_WIDTH(&e->e_rect);
int eh = GEO_HEIGHT(&e->e_rect);
maxEX = MAX(maxEX,ew);
maxEY = MAX(maxEY,eh);
count++;
}
}
/* if too few elements, don't bother with binning */
if(count < bpMinBAPop) return FALSE;
/* if too tiny don't subbin,
* avoid nasty corner-cases in code below
*/
if(h<2 || w<2) return FALSE;
/* tentatively choose bin size to fit all elements */
dx = maxEX+1;
dy = maxEY+1;
/* ensure we get at least two bins, so that
* subbining of sparse designs will work.
*/
maxDX = (w+1)/2;
maxDY = (h+1)/2;
/*
fprintf(stderr,"bpBinArraySizeIt, initial "
"maxEX=%d maxEY=%d maxDX=%d maxDY=%d dx=%d dy=%d\n",
maxEX,maxEY,maxDX,maxDY,dx,dy);
*/
if(dx <= maxDX)
{
/* x is cool */
if(dy <= maxDY)
{
/* totally cool */
;
}
else
{
/* y-dim too big for two bins, but x-dim cool,
* just reduce in x this time.
*/
dy = h+1;
}
}
else
{
/* x-dim too big for two bins */
if(dy <= maxDY)
{
/* x-dim too big for two bins but y=dim cool,
* just reduce in y this time
*/
dx = w+1;
}
else
{
/* BOTH x-dim and y-dim too big for two bins.
* We are screwed: will have some oversized.
*
* Choose betwen splitting in two horizontally or
* vertically, by which ever method results in the minimum
* number of oversized elements.
*/
int xOver=0; /* number of oversized if we reduce x-dim. */
int yOver=0; /* number of oversized if we reduce y-dim. */
Element *e;
/* count potential oversized */
for(e=elements; e; e=e->e_link)
{
int ew = GEO_WIDTH(&e->e_rect);
int eh = GEO_HEIGHT(&e->e_rect);
if(ew >= maxDX) xOver++;
if(eh >= maxDY) yOver++;
}
if(xOver<yOver)
{
/* reduce x-dim to minimize oversized */
dx = maxDX;
dy = h+1;
}
else
{
/* are we making progress? */
if(yOver == count) return FALSE;
/* reduce y-dim to minimize oversized */
dx = w+1;
dy = maxDY;
}
}
}
/* tentative number of bins */
xDim = roundUp(w,dx)/dx;
yDim = roundUp(h,dy)/dy;
numBins = xDim*((double)yDim);
/* if too many bins, need to increase at least one dimension */
/* (note this step will NOT reduce dimensions) */
maxBins = MAX(count / bpMinAvgBinPop,1);
/*
fprintf(stderr,"DEBUG numBins = %g count= %d bpMinAvgBinPop=%f maxBins= %d\n",
numBins,count,bpMinAvgBinPop,maxBins);
*/
if(numBins>maxBins)
{
if(dx == w+1)
{
/* can't increase x-dim, so try increasing y-dim */
int yDimTarget = maxBins/xDim;
dy = (h+1) / MAX(yDimTarget,1);
dy = MIN(dy,maxDY);
}
else if (dy == h+1)
{
/* can't increase y-dim, so try increasing x-dim */
int xDimTarget = maxBins/yDim;
dx = (w+1) / MAX(xDimTarget,1);
dx = MIN(dx,maxDX);
}
else
{
/* try for square bins */
double area = h * (w + 0.0);
int d = MAX(sqrt(area/maxBins),1);
if(d<dx)
{
/* target d too small in x-dim
* leave xdim fixed and just increase y-dim
*/
int yDimTarget = maxBins/xDim;
dy = (h+1) / MAX(yDimTarget,1);
dy = MIN(dy,maxDY);
}
else if (d<dy)
{
/* target d too small in y-dim
* leave xdim fixed and just increase y-dim
*/
int xDimTarget = maxBins/yDim;
dx = (w+1) / MAX(xDimTarget,1);
dx = MIN(dx,maxDX);
}
else if(d>maxDX)
{
/* d too big for x-dim
* (this can happen for tall skinny bins)
*
* make x-dim maximal, and adjust y accordingly
*/
dx = w+1;
dy = MAX((h+1)/maxBins,dy);
dy = MIN(dy,maxDY);
}
else if(d>maxDY)
{
/* d too big for y-dim
* (this can happen for long squat bins)
*
* make y-dim maximal, and adjust x-dim accordingly
*/
dy = h+1;
dx = MAX((w+1)/maxBins,dx);
dx = MIN(dx,maxDX);
}
else
{
/* we're cool, create square bins */
dx = d;
dy = d;
}
}
/* update numBins */
xDim = roundUp(w,dx)/dx;
yDim = roundUp(h,dy)/dy;
numBins = xDim*yDim;
}
/* DEBUG */
if(BPD)
{
fprintf(stderr,"\nDEBUG bpBinArraySizeIt DONE, count=%d h=%d w=%d\n"
"\tmaxDX=%d maxDY=%d maxBins=%d\n"
"\tnumBins=%g dx=%d dy=%d\n",
count,h,w,
maxDX,maxDY,maxBins,
numBins,dx,dy);
}
/* set results */
if(dxp) *dxp = dx;
if(dyp) *dyp = dy;
if(maxDXp) *maxDXp = maxDX;
if(maxDYp) *maxDYp = maxDY;
if(numBinsp) *numBinsp = numBins;
if(countp) *countp = count;
/* success */
return TRUE;
}
/*
* ----------------------------------------------------------------------------
*
* bpBinArrayBuild1 -- build and populate bin array of given area and
* bin size.
*
* Returns: pointer to new bin array.
*
* ----------------------------------------------------------------------------
*/
static BinArray *bpBinArrayBuild1(Rect *bbox,
Element *elements, /* initial elements */
int dx, /* bin diameter */
int dy)
{
BinArray *ba;
/* build bin array */
ba = bpBinArrayNew(dx, dy, bbox);
/* transfer elements to bin array */
while(elements)
{
Element *e;
/* pop list */
e = elements;
elements = e->e_link;
bpBinAdd(ba, e);
}
return ba;
}
/*
* ----------------------------------------------------------------------------
*
* bpBinArrayBuild -- build and populate bin array of given area,
*
* NOTE: optimal bin size determined by trial and error.
* oversized subbinned, as indicated.
*
* Returns: pointer to new bin array, NULL on failure.
*
* ----------------------------------------------------------------------------
*/
BinArray *bpBinArrayBuild(Rect bbox,
Element *elements, /* initial elements */
bool subbin) /* subbin as needed */
{
BinArray *ba;
int dx,dy; /* individual bin diameter */
int maxDX, maxDY;
int numBins;
int count;
/* Added by Tim, 2/19/2024 */
/* This line is not supposed to be needed? */
if ((!subbin) && ((pointertype)elements & BT_ARRAY)) return NULL;
if(BPD) DumpRect("#### bpBinArrayBuild, TOP bbox= ", &bbox);
/* figure out good bin dimensions */
if(!bpBinArraySizeIt(&bbox,
elements,
&dx,
&dy,
&maxDX,
&maxDY,
&numBins,
&count)) return NULL;
/* build the bin array */
ba = bpBinArrayBuild1(&bbox, elements, dx, dy);
if(!subbin) return ba;
/* sub-bin normal bins */
{
int dimX = ba->ba_dimX;
int i;
for(i=0;i<numBins;i++)
{
BinArray *sub;
sub = bpBinArrayBuild(bpBinArea(ba,i),
bpBinList(ba, i),
TRUE);
if(sub)
{
ba->ba_bins[i] =
(void *) ((pointertype) sub | BT_ARRAY);
}
}
}
/* sub-bin oversized */
{
BinArray *sub;
sub = bpBinArrayBuild(bbox,
bpBinList(ba, numBins),
TRUE);
if(sub)
{
ba->ba_bins[numBins] =
(void *) ((pointertype) sub | BT_ARRAY);
}
}
if(BPD)
{
DumpRect("\n#### bpBinArrayBuild, DONE bbox= ", &bbox);
fprintf(stderr,"\n");
}
return ba;
}
/*
* ----------------------------------------------------------------------------
*
* bpBinsUpdate -- update bplane bins
*
* Called prior to enumerations.
*
* ----------------------------------------------------------------------------
*/
int bpBinLife = 0;
void bpBinsUpdate(BPlane *bp)
{
Rect bbox;
bool oldBins;
/* rebuild whenever inbox gets big */
if(!bpListExceedsQ(bp->bp_inBox, bpMinBAPop-1)) return;
/* fprintf(stderr,"DEBUG bpBinsUpdate - rebuilding bins.\n"); */
/* do bins already exist ? */
oldBins = (bp->bp_rootNode != 0);
/* if bins exist, dissolve them */
if(oldBins)
{
Element *elist = bpBinArrayUnbuild(bp->bp_rootNode);
/* add inbox to list */
while(bp->bp_inBox)
{
/* pop from inbox */
Element *e = bp->bp_inBox;
bp->bp_inBox = e->e_link;
/* add to elist */
e->e_link = elist;
elist = e;
}
bp->bp_inBox = elist;
}
/* compute accurate bbox */
{
Element *e = bp->bp_inBox;
bbox = e->e_rect;
for(e=bp->bp_inBox; e; e=e->e_link)
{
GeoIncludeRectInBBox(&e->e_rect, &bbox);
}
}
/* if rebuild, double bounding box, to avoid too many rebuilds */
if(oldBins)
{
int dx = GEO_WIDTH(&bbox)/2;
int dy = GEO_HEIGHT(&bbox)/2;
bbox.r_xbot -= dx;
bbox.r_ybot -= dy;
bbox.r_xtop += dx;
bbox.r_ytop += dy;
}
/* build and populate bin array */
bp->bp_rootNode = bpBinArrayBuild(bbox, bp->bp_inBox, TRUE);
if(bp->bp_rootNode) bp->bp_inBox = NULL;
bp->bp_binArea = bbox;
bp->bp_binLife = bpBinLife;
bp->bp_inAdds = 0;
/* if(BPD) bpDump(bp, 0); */
}

View File

@ -1,328 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpDump.c
*
* routines to dump bin system (for debugging)
*
*/
#include <stdio.h>
#include "utils/utils.h"
#include "database/database.h"
#include "utils/geometry.h"
#include "cif/cif.h"
#include "bplane/bplaneInt.h"
static int bpDumpFlags; /* set by bpDump, used by subroutines */
/*
* ----------------------------------------------------------------------------
* bpIndent --
*
* tab over n spaces on stderr
*
* ----------------------------------------------------------------------------
*/
static void bpIndent(int n)
{
int i;
for(i=0;i<n;i++) fprintf(stderr," ");
}
/*
* ----------------------------------------------------------------------------
* bpDumpRect --
*
* list rects.
*
* ----------------------------------------------------------------------------
*/
void bpDumpRect(Rect *r)
{
if(bpDumpFlags & BPD_INTERNAL_UNITS)
{
fprintf(stderr,"%d ",
r->r_xbot);
fprintf(stderr,"%d ",
r->r_ybot);
fprintf(stderr,"%d ",
r->r_xtop);
fprintf(stderr,"%d",
r->r_ytop);
}
#ifdef CIF_MODULE
else
{
float oscale;
oscale = CIFGetOutputScale(1000);
fprintf(stderr,"%f ",
oscale * (float)r->r_xbot);
fprintf(stderr,"%f ",
oscale * (float)r->r_ybot);
fprintf(stderr,"%f ",
oscale * (float)r->r_xtop);
fprintf(stderr,"%f",
oscale * (float)r->r_ytop);
}
#endif
}
/*
* ----------------------------------------------------------------------------
* bpDumpElements --
*
* list rects.
*
* ----------------------------------------------------------------------------
*/
void bpDumpElements(Element *list, int indent)
{
Element *e;
for(e = list; e; e=e->e_link)
{
bpIndent(indent);
fprintf(stderr,"{element ");
if(bpDumpFlags & BPD_LABELED)
{
LabeledElement *le = (LabeledElement *) e;
fprintf(stderr,"%s ", le->le_text);
}
bpDumpRect(&e->e_rect);
fprintf(stderr,"}\n");
}
}
/*
* ----------------------------------------------------------------------------
* bpDumpEnums --
*
* list active enumerations
*
* ----------------------------------------------------------------------------
*/
void bpDumpEnums(BPEnum *bpe, int indent)
{
for(; bpe; bpe=bpe->bpe_next)
{
bpIndent(indent);
fprintf(stderr,"{enum \"%s\"}",
bpe->bpe_id);
}
}
/*
* ----------------------------------------------------------------------------
* bpBinArrayDump --
*
* recursively dump hierarchical bin system
*
* ----------------------------------------------------------------------------
*/
static void bpBinArrayDump(BinArray *ba, int indent)
{
int numBins = ba->ba_numBins;
int dx = ba->ba_dx;
int dy = ba->ba_dy;
int dimX = ba->ba_dimX;
int dimY = numBins/dimX;
Rect *bbox = &ba->ba_bbox;
int xi,yi;
/* open */
bpIndent(indent);
fprintf(stderr,"{bin-array ");
if(bpDumpFlags & BPD_INTERNAL_UNITS)
{
fprintf(stderr,"{dx %d} {dy %d} ",
dx,dy);
}
#ifdef CIF_MODULE
else
{
float oscale;
oscale = CIFGetOutputScale(1000);
fprintf(stderr,"{dx %f} ",
(float)dx * oscale);
fprintf(stderr,"{dy %f} ",
(float)dy * oscale);
}
#endif
fprintf(stderr,"{dimX %d} {dimY %d} { bbox ",
dimX,
dimY);
bpDumpRect(bbox);
fprintf(stderr," }\n");
/* bins */
for(yi=0; yi<dimY; yi++)
{
for(xi=0; xi<dimX; xi++)
{
Rect area;
int i = xi + yi*dimX;
area.r_xbot = bbox->r_xbot + xi*dx;
area.r_ybot = bbox->r_ybot + yi*dy;
area.r_xtop = area.r_xbot + dx;
area.r_ytop = area.r_ybot + dy;
/* skip empty bins */
if(bpBinEmpty(ba,i)) continue;
/* open bin */
bpIndent(indent+2);
fprintf(stderr,"{bin {number %d} { bbox ",
i);
bpDumpRect(&area);
fprintf(stderr," }\n");
/* list bin contents */
if(bpBinType(ba,i) == BT_ARRAY)
{
/* dump sub array */
bpBinArrayDump( bpSubArray(ba,i),
indent+4);
}
else
{
/* list elements */
bpDumpElements(bpBinList(ba,i),indent+4);
}
/* close bin */
bpIndent(indent+2);
fprintf(stderr,"}\n");
}
}
/* oversized */
if(!bpBinEmpty(ba,numBins))
{
/* open oversized */
bpIndent(indent+2);
fprintf(stderr,"{oversized {bbox ");
bpDumpRect(bbox);
fprintf(stderr,"}\n");
/* list bin contents */
if(bpBinType(ba,numBins) == BT_ARRAY)
{
/* dump sub array */
bpBinArrayDump( bpSubArray(ba,numBins),
indent+4);
}
else
{
/* list elements */
bpDumpElements(bpBinList(ba,numBins),indent+4);
}
/* close oversized */
bpIndent(indent+2);
fprintf(stderr,"}\n");
}
/* close bin array */
bpIndent(indent);
fprintf(stderr,"}\n");
}
/*
* ----------------------------------------------------------------------------
* bpDump --
*
* dump bplane (for debugging)
*
* ----------------------------------------------------------------------------
*/
void bpDump(BPlane *bp, int flags)
{
fprintf(stderr, "======= BPLANE DUMP ======\n");
bpDumpFlags = flags;
/* open bplane */
fprintf(stderr,"{bplane {count %d} {bbox ",
bp->bp_count);
bpDumpRect(&bp->bp_bbox);
fprintf(stderr,"}\n");
/* list in box rects */
bpIndent(2);
fprintf(stderr,"{in_box\n");
bpDumpElements(bp->bp_inBox,4);
bpIndent(2);
fprintf(stderr,"}\n");
/*** bins ***/
bpIndent(2);
fprintf(stderr,"{binned {area ");
bpDumpRect(&bp->bp_binArea);
fprintf(stderr,"}\n");
if(bp->bp_rootNode) bpBinArrayDump(bp->bp_rootNode, 4);
bpIndent(2);
fprintf(stderr,"}\n");
/*** enums ***/
bpIndent(2);
fprintf(stderr,"{enums\n");
bpDumpEnums(bp->bp_enums,4);
bpIndent(2);
fprintf(stderr,"}\n");
/* close bplane */
fprintf(stderr,"}\n");
}

View File

@ -1,166 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpEnum.c -
*
* Search routines for bplanes
*
*/
#include <stdio.h>
#include "utils/utils.h"
#include "database/database.h"
#include "utils/geometry.h"
#include "bplane/bplaneInt.h"
/*
* ----------------------------------------------------------------------------
* BPEnumInit --
*
* set up search.
*
* ----------------------------------------------------------------------------
*/
void BPEnumInit(BPEnum *bpe, /* enum to initialize */
BPlane *bp,
const Rect *area, /* search area */
int match,
const char *id) /* for debugging */
{
bool inside = FALSE;
bpe->bpe_plane = bp;
bpe->bpe_id = id;
bpe->bpe_match = match;
bpe->bpe_top = bpe->bpe_stack;
/*
fprintf(stderr,"DEBUG bpEnumInit, match=%d id=%s\n",
match, id);
*/
/* link enum to bplane */
bpe->bpe_next = bp->bp_enums;
bp->bp_enums = bpe;
switch (match)
{
case BPE_EQUAL:
GeoCanonicalRect(area, &bpe->bpe_srchArea);
bpe->bpe_nextElement = IHashLookUp(bp->bp_hashTable, &bpe->bpe_srchArea);
bpe->bpe_top->bps_state = BPS_HASH;
/* don't need to setup stack, just return */
return;
case BPE_ALL:
/* If we start 'INSIDE', no match checks will be done */
bpe->bpe_top->bps_state = BPS_BINS_INSIDE;
inside = TRUE;
break;
case BPE_TOUCH:
GeoCanonicalRect(area, &bpe->bpe_srchArea);
inside = GEO_SURROUND(&bpe->bpe_srchArea, &bp->bp_bbox);
if(inside)
{
bpe->bpe_top->bps_state = BPS_BINS_INSIDE;
}
else
{
bpe->bpe_top->bps_state = BPS_BINS;
bpe->bpe_subBinMinX = GEO_WIDTH(&bpe->bpe_srchArea)/2;
bpe->bpe_subBinMinY = GEO_HEIGHT(&bpe->bpe_srchArea)/2;
bpBinsUpdate(bp);
}
break;
case BPE_OVERLAP:
GeoCanonicalRect(area, &bpe->bpe_srchArea);
GEO_EXPAND(&bpe->bpe_srchArea, -1, &bpe->bpe_srchArea);
inside = GEO_SURROUND(&bpe->bpe_srchArea, &bp->bp_bbox);
if(inside)
{
bpe->bpe_top->bps_state = BPS_BINS_INSIDE;
}
else
{
bpe->bpe_top->bps_state = BPS_BINS;
bpe->bpe_subBinMinX = GEO_WIDTH(&bpe->bpe_srchArea)/2;
bpe->bpe_subBinMinY = GEO_HEIGHT(&bpe->bpe_srchArea)/2;
bpBinsUpdate(bp);
}
break;
default:
ASSERT(FALSE,"BPEnumInit, bad match value");
}
/* push rootnode */
if(bp->bp_rootNode)
{
bpEnumPush(bpe, bp->bp_rootNode, inside);
bpe->bpe_nextElement = NULL;
}
else
{
/* no bins, go straight to inbox */
bpe->bpe_top->bps_state = BPS_INBOX | inside;
bpe->bpe_nextElement = bp->bp_inBox;
}
}
/*
* ----------------------------------------------------------------------------
* BPEnumTerm --
*
* terminate enumeration
*
* ----------------------------------------------------------------------------
*/
void BPEnumTerm(BPEnum *bpe)
{
BPEnum **linkp;
/*
fprintf(stderr,"DEBUG bpEnumTerm, id=%s\n",
bpe->bpe_id);
*/
/* unlink */
linkp = &bpe->bpe_plane->bp_enums;
while(*linkp && *linkp != bpe) linkp = &(*linkp)->bpe_next;
ASSERT(*linkp==bpe,"BPEnumTerm");
*linkp = bpe->bpe_next;
}

View File

@ -1,537 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
#ifndef _MAGIC__BPLANE__BPENUM_H
#define _MAGIC__BPLANE__BPENUM_H
/* bpEnum.h --
*
* inlined Search routines for bplanes (see also bpEnum.c)
*
*/
#include <stdio.h>
#include "utils/utils.h"
#include "utils/geometry.h"
#include "utils/geofast.h"
#include "bplane/bplane.h"
#include "bplane/bplaneInt.h"
extern void DumpRect(char *msg, Rect *r);
/* state machine states */
#define BPS_BINS 0
#define BPS_BINS_INSIDE 1
#define BPS_INBOX 2
#define BPS_INBOX_INSIDE 3
#define BPS_HASH 4
#define BPS_DONE 5
/* range code */
#define R_LEFT 1
#define R_RIGHT 2
#define R_BOT 4
#define R_TOP 8
/*
* ----------------------------------------------------------------------------
*
* bpBinArea -- compute area covered by given bin.
*
* Returns: bin area.
*
* ----------------------------------------------------------------------------
*/
static __inline__ Rect bpBinArea(BinArray *ba, int i)
{
int dimX = ba->ba_dimX;
int dx = ba->ba_dx;
int dy = ba->ba_dy;
int xi = i % dimX;
int yi = i / dimX;
Rect area;
area.r_xbot = ba->ba_bbox.r_xbot + dx*xi;
area.r_ybot = ba->ba_bbox.r_ybot + dy*yi;
area.r_xtop = area.r_xbot + dx;
area.r_ytop = area.r_ybot + dy;
return area;
}
/*
* ----------------------------------------------------------------------------
* bpEnumRange --
*
* Determine which edges of search area bin overlaps.
*
* (Used to make match checks as efficient as possible, for example if bin
* does not extend past srch area in any direction, no match checking is
* required)
*
* Returns: int encoding 'range'.
*
* ----------------------------------------------------------------------------
*/
static __inline__ int
bpEnumRange(Rect *bin, Rect *srch)
{
int range = 0;
if (bin->r_xbot < srch->r_xbot) range |= R_LEFT;
if (bin->r_xtop > srch->r_xtop) range |= R_RIGHT;
if (bin->r_ybot < srch->r_ybot) range |= R_BOT;
if (bin->r_ytop > srch->r_ytop) range |= R_TOP;
return range;
}
/*
* ----------------------------------------------------------------------------
* bpEnumMatchQ -
*
* Check if element intersects search area
*
* range specifies which search area boundaries the element
* can potentially extend beyond.
*
* We rely on the optimizing compiler to remove unnecessary checks
* based on compile time knowledge of range value.
*
* Returns: TRUE on match, FALSE otherwise.
*
* ----------------------------------------------------------------------------
*/
static __inline__ bool
bpEnumMatchQ(BPEnum *bpe, Element *e)
{
Rect *area = &bpe->bpe_srchArea;
Rect *r = &e->e_rect;
if(r->r_xtop < area->r_xbot) return FALSE;
if(r->r_xbot > area->r_xtop) return FALSE;
if(r->r_ytop < area->r_ybot) return FALSE;
if(r->r_ybot > area->r_ytop) return FALSE;
return TRUE;
}
/*
* ----------------------------------------------------------------------------
* bpEnumPushInside --
*
* called by bpEnumPush when the binarray is entirely inside the search area
*
* push a bin array onto an enum stack.
*
* ----------------------------------------------------------------------------
*/
static __inline__ bool bpEnumPushInside(BPEnum *bpe,
BinArray *ba)
{
BPStack *bps;
/* push stack */
++bpe->bpe_top;
bps = bpe->bpe_top;
bps->bps_node = ba;
bps->bps_state = BPS_BINS_INSIDE;
/* set up indices to scan entire bin array */
bps->bps_i = -1;
bps->bps_max = ba->ba_numBins;
return TRUE;
}
/*
* ----------------------------------------------------------------------------
* bpEnumPush --
*
* push a bin array onto an enum stack.
*
* normally returns TRUE, returns FALSE on (possible) state change.
*
* ----------------------------------------------------------------------------
*/
static __inline__ bool bpEnumPush(BPEnum *bpe,
BinArray *ba,
bool inside)
{
Rect area;
Rect *bbox;
int dx;
int dy;
BPStack *bps;
/*
fprintf(stderr,"DEBUG bpEnumPush, inside=%d\n", inside);
*/
/* special case inside */
if(inside) return bpEnumPushInside(bpe,ba);
bbox = &ba->ba_bbox;
if(GEO_SURROUND(&bpe->bpe_srchArea,bbox))
{
bpEnumPushInside(bpe,ba);
return FALSE; /* state change */
}
/* push stack */
++bpe->bpe_top;
bps = bpe->bpe_top;
bps->bps_node = ba;
bps->bps_state = BPS_BINS;
bps->bps_subbin = FALSE;
bps->bps_rejects = 0;
/* compute search area for this bin array */
dx = ba->ba_dx;
dy = ba->ba_dy;
area.r_xbot = bpe->bpe_srchArea.r_xbot - dx;
area.r_xtop = bpe->bpe_srchArea.r_xtop + 1;
area.r_ybot = bpe->bpe_srchArea.r_ybot - dy;
area.r_ytop = bpe->bpe_srchArea.r_ytop + 1;
GEOCLIP(&area,bbox);
if(GEO_RECTNULL(&area))
{
/* only need to check oversized */
bps->bps_i = 0;
bps->bps_rowMax = 0;
bps->bps_max = 0;
}
else
{
/* setup indices for this array and search area */
int dimX = ba->ba_dimX;
int i;
/* make area relative to bin bbox */
area.r_xbot -= bbox->r_xbot;
area.r_xtop -= bbox->r_xbot;
area.r_ybot -= bbox->r_ybot;
area.r_ytop -= bbox->r_ybot;
/* DumpRect("area relative to bin bbox = ",&area); */
area.r_xbot /= ba->ba_dx;
area.r_xtop /= ba->ba_dx;
area.r_ybot /= ba->ba_dy;
area.r_ytop /= ba->ba_dy;
i = area.r_ybot*dimX + area.r_xbot; /* next index */
bps->bps_i = i-1;
bps->bps_rowMax = i + area.r_xtop - area.r_xbot;
bps->bps_max = area.r_ytop*dimX + area.r_xtop;
bps->bps_rowDelta = dimX + area.r_xbot - area.r_xtop;
bps->bps_dimX = dimX;
/* consider subbinning? */
if(dx >= bpe->bpe_subBinMinX || dy >= bpe->bpe_subBinMinY)
{
bps->bps_subbin = TRUE;
}
}
return TRUE;
}
/*
* ----------------------------------------------------------------------------
* bpEnumNextBin1 --
*
* called by bpEnumNextBin() after indexes for new bin are setup
*
* returns: normally returns TRUE, returns FALSE on state change.
*
* ----------------------------------------------------------------------------
*/
static __inline__ bool
bpEnumNextBin1(BPEnum *bpe, BPStack *bps, bool inside)
{
if(bpBinType(bps->bps_node,bps->bps_i) != BT_ARRAY)
{
bpe->bpe_nextElement = bpBinList(bps->bps_node,bps->bps_i);
return TRUE;
}
/* array, push into it */
return bpEnumPush(bpe, bpSubArray(bps->bps_node,bps->bps_i), inside);
}
/*
* ----------------------------------------------------------------------------
* bpEnumNextBin --
*
* called by bpEnumNextBINS to advance to next bin (bucket).
*
* cycles through normal bins first, then oversized,
* finally, for toplevel, sets INBOX state.
*
* sets bpe->bpe_nextElement to first element in next bin.
*
* returns: normally returns TRUE, returns FALSE on state change.
*
* ----------------------------------------------------------------------------
*/
static __inline__ bool
bpEnumNextBin(BPEnum *bpe, bool inside)
{
BPStack *bps = bpe->bpe_top;
#ifdef BPARANOID
ASSERT(bps,"bpEnumNextBin");
ASSERT(!bpe->bpe_nextElement,"bpEnumNextBin");
#endif
/*
fprintf(stderr,"DEBUG bpEnumNextBin TOP inside=%d nextElement=%x\n",
inside, bpe->bpe_nextElement);
*/
/* consider subbining this bin before advancing to next */
if(!inside)
{
if(bps->bps_rejects >= bpMinBAPop
&& (bps->bps_subbin || bps->bps_i == bps->bps_node->ba_numBins))
{
int i = bps->bps_i;
BinArray *ba = bps->bps_node;
BinArray *sub;
/* fprintf(stderr,"DEBUG, subbining!\n"); */
sub = bpBinArrayBuild(bpBinArea(ba,i),
bpBinList(ba,i),
FALSE); /* don't recursively subbin! */
if(sub)
{
ba->ba_bins[i] =
(void *) ((pointertype) sub | BT_ARRAY);
}
}
bps->bps_rejects = 0;
}
/* handle inside case first */
if(inside)
{
/* Inside case, cycle through all bins */
/* next bin */
if(bps->bps_i<bps->bps_max)
{
bps->bps_i += 1;
return bpEnumNextBin1(bpe,bps,inside);
}
}
else
{
/* cycle only through relevant bins */
/* next in row */
if(bps->bps_i<bps->bps_rowMax)
{
bps->bps_i += 1;
goto bin;
}
/* next row */
if(bps->bps_i<bps->bps_max)
{
bps->bps_i += bps->bps_rowDelta;
bps->bps_rowMax += bps->bps_dimX;
goto bin;
}
/* oversized */
if(bps->bps_i == bps->bps_max)
{
bps->bps_i = bps->bps_node->ba_numBins;
goto bin;
}
}
/* pop stack */
/* fprintf(stderr,"DEBUG BPEnumNextBin Pop.\n"); */
bpe->bpe_top--;
if(bpe->bpe_top>bpe->bpe_stack) return FALSE; /* state may have changed */
/* inbox */
/* fprintf(stderr,"DEBUG BPEnumNextBin INBOX.\n"); */
bpe->bpe_nextElement = bpe->bpe_plane->bp_inBox;
bpe->bpe_top->bps_state = BPS_INBOX | inside;
return FALSE; /* state change */
/* dive into indexed bin */
bin:
return bpEnumNextBin1(bpe,bps,inside);
}
/*
* ----------------------------------------------------------------------------
* bpEnumNextBINS --
*
* Handle BINS state for BPEnumNext()
*
* (bin enumeration.)
*
* ----------------------------------------------------------------------------
*/
static __inline__ Element* bpEnumNextBINS(BPEnum *bpe, bool inside)
{
/* bin by bin */
do
{
/* search this bin */
Element *e = bpe->bpe_nextElement;
while(e && !inside && !bpEnumMatchQ(bpe,e))
{
bpe->bpe_top->bps_rejects++;
e = e->e_link;
}
if(e)
{
bpe->bpe_nextElement = e->e_link;
/* DumpRect("DEBUG e_rect= ",&e->e_rect); */
return e;
}
bpe->bpe_nextElement = NULL;
}
while(bpEnumNextBin(bpe,inside));
/* next state */
return NULL;
}
/*
* ----------------------------------------------------------------------------
* bpEnumNextINBOX --
*
* Handle INBOX states for BPEnumNext()
*
* unbinned enumeration.
*
* ----------------------------------------------------------------------------
*/
static __inline__ Element *bpEnumNextINBOX(BPEnum *bpe,
bool inside)
{
Element *e = bpe->bpe_nextElement;
while(e && !inside && !bpEnumMatchQ(bpe,e)) e = e->e_link;
if(e)
{
bpe->bpe_nextElement = e->e_link;
return e;
}
/* done */
bpe->bpe_top->bps_state = BPS_DONE;
return NULL;
}
/*
* ----------------------------------------------------------------------------
* bpEnumNextHASH --
*
* Handle HASH state for BPEnumNext()
*
* (hash based (EQUALS) enumerations.)
*
* ----------------------------------------------------------------------------
*/
static __inline__ Element *bpEnumNextHASH(BPEnum *bpe)
{
Element *e = bpe->bpe_nextElement;
if(e)
{
bpe->bpe_nextElement =
IHashLookUpNext(bpe->bpe_plane->bp_hashTable, e);
}
else
{
bpe->bpe_top->bps_state = BPS_DONE;
}
return e;
}
/*
* ----------------------------------------------------------------------------
* BPEnumNext --
*
* get next element in enumeration.
*
* ----------------------------------------------------------------------------
*/
static __inline__ void *BPEnumNext(BPEnum *bpe)
{
Element *e;
while(TRUE)
{
/*
fprintf(stderr,"DEBUG state=%d\n",bpe->bpe_top->bps_state);
*/
switch (bpe->bpe_top->bps_state)
{
case BPS_BINS:
if((e=bpEnumNextBINS(bpe, 0))) return e;
break;
case BPS_BINS_INSIDE:
if((e=bpEnumNextBINS(bpe, 1))) return e;
break;
case BPS_INBOX:
if((e=bpEnumNextINBOX(bpe, 0))) return e;
break;
case BPS_INBOX_INSIDE:
if((e=bpEnumNextINBOX(bpe, 1))) return e;
break;
case BPS_HASH:
if((e=bpEnumNextHASH(bpe))) return e;
break;
case BPS_DONE:
return NULL;
default:
ASSERT(FALSE,"BPEnumNext, bad state");
}
}
}
#endif /* _MAGIC__BPLANE__BPENUM_H */

View File

@ -1,280 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpMain.c
*
* Top-level routines for BPlanes
* (interface to other modules)
*
* See bpEnum.c for enum routines.
* See bpTcl.c for tcl-level interface.
*/
#include <stdio.h>
#include <stddef.h>
#include "utils/utils.h"
#include "utils/malloc.h"
#include "database/database.h"
#include "textio/textio.h"
#include "utils/geometry.h"
#include "bplane/bplaneInt.h"
/*
* ----------------------------------------------------------------------------
* BPNew --
*
* Return newly created BPlane.
*
* ----------------------------------------------------------------------------
*/
BPlane *BPNew(void)
{
BPlane *new;
new = (BPlane *)mallocMagic(sizeof(BPlane));
new->bp_bbox = GeoNullRect;
new->bp_bbox_exact = TRUE;
new->bp_count = 0;
/* ENUMS */
new->bp_enums = NULL;
/* HASH TABLE */
new->bp_hashTable = IHashInit(4, /* initial buckets */
offsetof(Element, e_rect), /* key */
offsetof(Element, e_hashLink),
IHash4WordKeyHash,
IHash4WordKeyEq);
/* IN BOX */
new->bp_inBox = NULL;
/* BINS */
new->bp_binLife = 0;
new->bp_inAdds = 0;
new->bp_binArea = GeoNullRect;
new->bp_rootNode = NULL;
return new;
}
/*
* ----------------------------------------------------------------------------
* BPFree --
*
* free (empty) BPlane
*
* ----------------------------------------------------------------------------
*/
void BPFree(BPlane *bp)
{
ASSERT(bp->bp_count == 0,"BPFree");
IHashFree(bp->bp_hashTable);
freeMagic((char *)bp);
}
/*
* ----------------------------------------------------------------------------
* BPAdd --
*
* Add element to the given bplane
*
* NOTE: e_rect better be canonical!
*
* ----------------------------------------------------------------------------
*/
void BPAdd(BPlane *bp, void *element)
{
int size;
int binDim;
Element * e = element;
Rect *r = &e->e_rect;
/* Don't allow adds during active enumerations.
* This is confusing, since newly added elements may or may not
* be enumerated in on going enumerations, is not particularly
* useful, since elements to add can just be stored up on a local
* list and added after the enumeration completes.
*/
ASSERT(!bp->bp_enums,
"BPAdd, attempted during active enumerations");
/* element rect must be canonical! */
#ifdef BPARANOID
ASSERT(GeoIsCanonicalRect(r),"BPAdd, rect must be canonical.");
#endif
bp->bp_count++;
/* update hash table */
IHashAdd(bp->bp_hashTable, element);
/* update bbox */
if(bp->bp_count == 1)
{
bp->bp_bbox = *r;
}
else
{
GeoIncludeRectInBBox(r,&bp->bp_bbox);
}
/* no bins? */
if(!bp->bp_rootNode) goto inBox;
/* doesn't fit inside bins ? */
if(!GEO_SURROUND(&bp->bp_binArea,r)) goto inBox;
/* bin element */
bpBinAdd(bp->bp_rootNode, e);
return;
/* add to in box */
inBox:
bp->bp_inAdds++;
e->e_link = bp->bp_inBox;
bp->bp_inBox = e;
/* maintain back pointers */
e->e_linkp = &bp->bp_inBox;
if(e->e_link) e->e_link->e_linkp = &e->e_link;
}
/*
* ----------------------------------------------------------------------------
* BPDelete --
*
* remove element from bplane
*
* ----------------------------------------------------------------------------
*/
void BPDelete(BPlane *bp, void *element)
{
Element *e = element;
ASSERT(e,"BPDelete");
if (bp->bp_count == 0)
{
TxError("Error: Attempt to delete instance from empty cell!\n");
return;
}
bp->bp_count--;
/* if element was on edge of bbox, bbox may no longer
* be exact.
*/
if(bp->bp_bbox_exact &&
(bp->bp_bbox.r_xbot == e->e_rect.r_xbot ||
bp->bp_bbox.r_xtop == e->e_rect.r_xtop ||
bp->bp_bbox.r_ybot == e->e_rect.r_ybot ||
bp->bp_bbox.r_ytop == e->e_rect.r_ytop))
{
bp->bp_bbox_exact = FALSE;
}
/* advance any nextElement pointers at e */
{
BPEnum *bpe;
for(bpe=bp->bp_enums; bpe; bpe=bpe->bpe_next)
{
if(bpe->bpe_nextElement != e) continue;
if(bpe->bpe_match == BPE_EQUAL)
{
bpe->bpe_nextElement = IHashLookUpNext(bp->bp_hashTable, e);
}
else
{
bpe->bpe_nextElement = e->e_link;
}
}
}
IHashDelete(bp->bp_hashTable, e);
/* next pointer of prev element */
*e->e_linkp = e->e_link;
/* back pointer of next element */
if(e->e_link) e->e_link->e_linkp = e->e_linkp;
}
/*
* ----------------------------------------------------------------------------
* BPBBox --
*
* Get current bplane bbox.
*
* returns: current bplane bbox
* (returns an inverted rect, if bplane is empty)
*
* ----------------------------------------------------------------------------
*/
Rect BPBBox(BPlane *bp)
{
if(bp->bp_count == 0) return GeoInvertedRect;
/* if bbox is not up-to-date, recompute */
if(!bp->bp_bbox_exact)
{
BPEnum bpe;
Element *e;
bp->bp_bbox_exact = TRUE;
BPEnumInit(&bpe,
bp,
NULL,
BPE_ALL,
"BPBBox");
e = BPEnumNext(&bpe);
bp->bp_bbox = e->e_rect;
while((e = BPEnumNext(&bpe)))
{
GeoIncludeRectInBBox(&e->e_rect, &bp->bp_bbox);
}
}
return bp->bp_bbox;
}

View File

@ -1,195 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
#ifndef _MAGIC__BPLANE__BPOPAQUE_H
#define _MAGIC__BPLANE__BPOPAQUE_H
#ifndef _MAGIC__UTILS__IHASH_H
#include "utils/ihash.h"
#endif
/*
* bpOpaque.h --
*
* This file contains strucs directly or indirectly referenced by
* clients of bplane module, whose internals should be treated
* as opaque by clients.
*
* It is included by bplane.h
*
*/
/* data element, stored in BPlane
*
* Storage managed by caller.
* Inital part must correspond to below.
*/
typedef struct element
{
struct element *e_hashLink;
struct element *e_link;
struct element **e_linkp; /* back pointer for quick deletes */
Rect e_rect;
/* client data goes here */
} Element;
/* number of link fields in element
*
* user code should not depend on more than 1 link.
* (and should only use/ref that link when element is not in a bplane)
*/
#define BP_NUM_LINKS 3
/* bin array */
typedef struct binarray
{
Rect ba_bbox; /* area covered by array */
int ba_dx; /* dimensions of a single bin */
int ba_dy;
int ba_dimX; /* number of bins in a row */
int ba_numBins; /* number of regular bins (size of array - 1) */
void *ba_bins[1]; /* low order bit(s) used to encode type info.
* DON'T ACCESS DIRECTLY, USE MACROS BELOW
*
* (last bin is for oversized)
*/
} BinArray;
/* bin types
*
* NOTE: its important that simple lists have type 0, i.e. are
* just standard pointers. This is so that the list head
* 'link' can be treated just as any other link, during
* deletion etc.
*/
#define BT_TYPE_MASK 1
#define BT_LIST 0
#define BT_ARRAY 1
static __inline__ bool bpBinEmpty(BinArray *ba, int i)
{
return ba->ba_bins[i] == NULL;
}
static __inline__ bool bpBinType(BinArray *ba, int i)
{
return (bool) (((pointertype) ba->ba_bins[i]) & BT_TYPE_MASK);
}
static __inline__ Element *bpBinList(BinArray *ba, int i)
{
#ifdef BPARANOID
ASSERT(bpBinType(ba,i)==BT_LIST,"bpBinList");
#endif
return (Element *) ba->ba_bins[i];
}
static __inline__ Element **bpBinListHead(BinArray *ba, int i)
{
#ifdef BPARANOID
ASSERT(bpBinType(ba,i)==BT_LIST,"bpBinList");
#endif
return (Element **) &ba->ba_bins[i];
}
static __inline__ BinArray *bpSubArray(BinArray *ba, int i)
{
#ifdef BPARANOID
ASSERT(bpBinType(ba,i)==BT_ARRAY,"bpSubArray");
#endif
return (BinArray *) ((pointertype) ba->ba_bins[i] & ~BT_TYPE_MASK);
}
/* BPlane - toplevel struc */
typedef struct bplane
{
Rect bp_bbox; /* bbox (bin + in) */
bool bp_bbox_exact; /* if set bp_bbox, is exact,
* if reset bp_bbox may be over-sized.
*/
int bp_count; /* total number of elements in bplane */
struct bpenum *bp_enums; /* list of active enums */
/* HASH TABLE */
IHashTable *bp_hashTable; /* hash table
* (for expediting BP_EQUAL searches) */
/* IN BOX */
Element *bp_inBox; /* elements not yet added to bin system */
/* BINS */
int bp_binLife; /* set to binCount when bin system
* built, decremented on add/delete ops.
* bin system rebuilt when zero reached.
*/
int bp_inAdds; /* additions to inBox since last rebuild */
Rect bp_binArea; /* area covered by bin arrays */
BinArray *bp_rootNode; /* top bin node */
} BPlane;
/* context for BPlane enumeration */
typedef struct bpStack
{
int bps_state; /* where we are at rolled in one convenient
* number (see BPS_* defs in bpEnum.h)
*/
BinArray *bps_node; /* current bin array */
int bps_i; /* current index */
int bps_rowMax; /* max index for this row */
int bps_rowDelta; /* increment from end of one row to beginning
* of next.
*/
int bps_max; /* max index */
int bps_dimX; /* row length */
bool bps_subbin; /* if set consider subbinning */
int bps_rejects; /* number of unmatching elements in current
* bin, used to decide when to subbin.
*/
} BPStack;
/* enumeration 'handle' */
typedef struct bpenum
{
struct bpenum *bpe_next; /* all enums for bplane linked together */
BPlane *bpe_plane; /* plane being searched */
Rect bpe_srchArea; /* area being searched */
int bpe_match; /* match criteria */
const char *bpe_id; /* for debug */
int bpe_subBinMinX;
int bpe_subBinMinY; /* consider subbinning
* for bins bigger than this.
*/
Element *bpe_nextElement; /* next element in current list */
BPStack *bpe_top; /* top of stack */
BPStack bpe_stack[10000]; /* stack for tree traversal during enum */
} BPEnum;
#endif /* _MAGIC__BPLANE__BPOPAQUE_H */

View File

@ -1,304 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpStat.c
*
* routines to get bplane statistics.
*
*/
#include <stdio.h>
#include <limits.h>
#include "utils/utils.h"
#include "database/database.h"
#include "utils/geometry.h"
#include "bplane/bplaneInt.h"
/*
* ----------------------------------------------------------------------------
* bpCount --
*
* count list of elements.
*
* Returns size of list.
*
* ----------------------------------------------------------------------------
*/
int bpCount(Element *e)
{
int i = 0;
while(e)
{
i++;
e = e->e_link;
}
return i;
}
/*
* ----------------------------------------------------------------------------
* bpStatBA --
*
* compute bin array statistics.
* (includes sub-arrays)
*
*
* Returns memory used by bplane (excluding elements)
*
* ----------------------------------------------------------------------------
*/
unsigned int bpStatBA(BinArray *ba,
int *totCount, /* total number of elements */
int *totBins, /* ret tot num of bins */
int *emptyBins, /* ret num of empty bins */
int *binArraysp, /* ret num of bin arrays */
int *maxEffp, /* ret max effective list length */
int *maxBinCount, /* ret max count for regular bin */
int *totUnbinned, /* ret tot num of e's not binned */
int *maxDepth) /* ret max bin array depth */
{
Rect *bbox = &ba->ba_bbox;
int dx = ba->ba_dx;
int dy = ba->ba_dy;
int numBins = ba->ba_numBins;
int dimX = ba->ba_dimX;
int dimY = numBins/dimX;
int w = GEO_WIDTH(bbox);
int h = GEO_HEIGHT(bbox);
/* initial statistics */
unsigned int mem = 0;
int tot = 0;
int bins = 0;
int emptys = 0;
int binArrays = 1;
int maxCount = 0;
int maxEff = 0;
int maxEffSub = 0;
int maxSubCount = 0;
int unbinned = 0;
int depth = 1;
int maxDepthSub = 0;
int i;
/* add bins in this array */
bins += numBins;
/* add memory usage for this array (sub arrays already tabulated) */
if(ba) mem += sizeof(BinArray) + numBins*sizeof(void*);
/* gather stats bin by bin */
for(i=0;i<numBins;i++)
{
if(bpBinType(ba,i) != BT_ARRAY)
{
/* simple bin */
int count = bpCount(bpBinList(ba,i));
tot += count;
if(count>maxCount) maxCount = count;
if(count==0) emptys++;
}
else
{
/* arrayed, recurse */
int sMem, sTot, sBins, sEmptys, sBinArrays;
int sMaxEff, sMaxCount, sUnbinned, sDepth;
sMem = bpStatBA(bpSubArray(ba,i),
&sTot, /* total number of elements */
&sBins, /* ret tot num of bins */
&sEmptys, /* ret num of empty bins */
&sBinArrays, /* ret num bin arrays */
&sMaxEff, /* ret max effective list length */
&sMaxCount, /* ret max count for regular bin */
&sUnbinned, /* ret tot num of e's not binned */
&sDepth); /* ret max bin array depth */
mem += sMem;
tot += sTot;
bins += sBins;
emptys += sEmptys;
binArrays += sBinArrays;
if(sMaxEff > maxEffSub) maxEffSub = sMaxEff;
if(sMaxCount > maxCount) maxCount = sMaxCount;
if(sUnbinned > maxCount) maxCount = sUnbinned;
if(sDepth > maxDepthSub) maxDepthSub = sDepth;
}
}
maxEff += MAX(maxCount,maxEffSub);
depth += maxDepthSub;
/* oversized */
if(bpBinType(ba,numBins) != BT_ARRAY)
{
/* oversized unbinned */
int over = bpCount(bpBinList(ba,numBins));
tot += over;
unbinned += over;
maxEff += over;
}
else
{
/* oversized is arrayed, recurse */
int sMem, sTot, sBins, sEmptys, sBinArrays;
int sMaxEff, sMaxCount, sUnbinned, sDepth;
sMem = bpStatBA(bpSubArray(ba,numBins),
&sTot, /* total number of elements */
&sBins, /* ret tot num of bins */
&sEmptys, /* ret num of empty bins */
&sBinArrays, /* ret num bin arrays */
&sMaxEff, /* ret max effective list length */
&sMaxCount, /* ret max count for regular bin */
&sUnbinned, /* ret tot num of e's not binned */
&sDepth); /* ret max bin array depth */
mem += sMem;
tot += sTot;
bins += sBins;
emptys += sEmptys;
binArrays += sBinArrays;
maxEff += sMaxEff;
if(sMaxCount > maxCount) maxCount = sMaxCount;
unbinned += sUnbinned;
depth += sDepth;
}
/* set results */
if(totCount) *totCount = tot;
if(totBins) *totBins = bins;
if(emptyBins) *emptyBins = emptys;
if(binArraysp) *binArraysp = binArrays;
if(maxEffp) *maxEffp = maxEff;
if(maxBinCount) *maxBinCount = maxCount;
if(totUnbinned) *totUnbinned = unbinned;
if(maxDepth) *maxDepth = depth;
return mem;
}
/*
* ----------------------------------------------------------------------------
* BPStat --
*
* compute bplane statistics.
*
* Returns memory used by bplane (excluding elements)
*
* ----------------------------------------------------------------------------
*/
unsigned int BPStat(BPlane *bp,
int *totCount, /* total number of elements */
int *inBox, /* ret num of elements in inBox */
int *totBins, /* ret tot num of bins */
int *emptyBins, /* ret num of empty bins */
int *binArraysp, /* ret tot num of bin arrays */
int *maxEffp, /* ret max effective list length */
int *maxBinCount, /* ret max count for regular bin */
int *totUnbinned, /* ret tot num of e's not binned */
int *maxDepth) /* ret max bin array depth */
{
BinArray *ba = bp->bp_rootNode;
int numBins;
unsigned int mem = 0;
int tot = 0;
int bins = 0;
int emptys = 0;
int binArrays = 0;
int maxEff = 0;
int maxCount = 0;
int unbinned = 0;
int depth = 0;
int in;
/* bin arrays */
if(ba)
{
mem += bpStatBA(bp->bp_rootNode,
&tot, /* total number of elements */
&bins, /* ret tot num of bins */
&emptys, /* ret tot num of empty bins */
&binArrays, /* ret tot num of bin arrays */
&maxEff, /* ret max effective list length */
&maxCount, /* ret max count for regular bin */
&unbinned, /* ret tot num of e's not binned */
&depth); /* ret max bin array depth */
}
/* inbox */
in = bpCount(bp->bp_inBox);
tot += in;
maxEff += in;
unbinned += in;
/* add in memory usage for bplane */
mem += sizeof(BPlane);
mem += IHashStats2(bp->bp_hashTable,NULL,NULL);
/* set results */
if(totCount) *totCount = tot;
if(inBox) *inBox = in;
if(totBins) *totBins = bins;
if(emptyBins) *emptyBins = emptys;
if(binArraysp) *binArraysp = binArrays;
if(maxEffp) *maxEffp = maxEff;
if(maxBinCount) *maxBinCount = maxCount;
if(totUnbinned) *totUnbinned = unbinned;
if(maxDepth) *maxDepth = depth;
return mem;
}
/*
* ----------------------------------------------------------------------------
* BPStatMemory --
*
* returns memory usage of BPlane in bytes
* (exclusive of elements contained by the BPlane)
*
* ----------------------------------------------------------------------------
*/
unsigned int BPStatMemory(BPlane *bp)
{
return BPStat(bp,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
}

View File

@ -1,361 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpTest.c
*
* (regression) tests of bplane code
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "utils.h"
#include "message.h"
#include "database.h"
#include "geometry.h"
#include "bplane.h"
#include "bplaneInt.h"
#include "debug.h"
#include "cifInt.h"
/*
* elements used by test code.
*/
typedef struct rectc
{
struct rectc *rc_links[BP_NUM_LINKS];
Rect rc_rect;
} RectC;
/*
* ----------------------------------------------------------------------------
* bpRand --
* generate a random int in given range.
*
* side effects: sets coords of input rect.
* ----------------------------------------------------------------------------
*/
int bpRand(int min, int max)
{
double f = rand()/ (double) RAND_MAX; /* random number in unit interval */
return min + (int) ((max-min+1)*f);
}
/*
* ----------------------------------------------------------------------------
* bpTestRandRect --
* generate a random unit rectangle inside bbox
*
* side effects: sets coords of input rect.
* ----------------------------------------------------------------------------
*/
static void bpTestRandRect(Rect *r, Rect *bbox)
{
r->r_xbot = bpRand(bbox->r_xbot,bbox->r_xtop-1);
r->r_ybot = bpRand(bbox->r_ybot,bbox->r_ytop-1);
r->r_xtop = r->r_xbot+1;
r->r_ytop = r->r_ybot+1;
}
/* ====== GOLD snow test.
* ====== linked list implementation (to determine 'right' answer)
*/
/*
* ----------------------------------------------------------------------------
* bpTestIntersectGold --
*
* check whether rc intersects list
* ----------------------------------------------------------------------------
*/
static bool bpTestIntersectGold(RectC *rc, RectC *list)
{
while(list)
{
if(GEO_TOUCH(&rc->rc_rect,&list->rc_rect)) return TRUE;
list=list->rc_links[0];
}
return FALSE;
}
/*
* ----------------------------------------------------------------------------
* bpTestSnowGold --
* populate square of dimension 'size' with non-overlapping random unit
* rectangles. Keep adding rectangles until failures exceed successes.
* (stop when maxFailures reached.)
*
* coded with simple linked list.
*
* ---------------------------------------------------------------------------- */
void bpTestSnowGold(int size, bool trace)
{
int failures = 0;
int successes = 0;
int i = 0;
int crc = 0;
RectC *result = NULL;
RectC *rc = NULL;
Rect area;
fprintf(stderr,"BEGIN Snow GOLD, size=%d\n", size);
/* set up area */
area.r_xbot = 0;
area.r_ybot = 0;
area.r_xtop = size;
area.r_ytop = size;
while(failures<=successes)
{
i++;
if(!rc) rc = MALLOC_TAG(RectC *,rc, sizeof(RectC), "RectC");
bpTestRandRect(&rc->rc_rect, &area);
if(!bpTestIntersectGold(rc,result))
{
if(trace) DumpRect("success ",&rc->rc_rect);
crc ^= i+ 3*rc->rc_rect.r_xbot+ 5*rc->rc_rect.r_ybot;
rc->rc_links[0] = result;
result = rc;
rc = NULL;
successes++;
}
else
{
if(trace) DumpRect("failure ",&rc->rc_rect);
failures++;
}
}
/* clean up */
while(result)
{
/* pop */
rc=result;
result=rc->rc_links[0];
/* free */
FREE(rc);
}
fprintf(stderr,"END Snow GOLD, size=%d failures=%d successes=%d crc=%d\n",
size,
failures,
successes,
crc);
}
/* ====== bplane snow test.
*/
/*
* ----------------------------------------------------------------------------
* bpTestIntersect --
*
* check whether rc intersects list
* ----------------------------------------------------------------------------
*/
static bool bpTestIntersect(RectC *rc, BPlane *bp)
{
BPEnum bpe;
int result;
BPEnumInit(&bpe,bp, &rc->rc_rect, BPE_TOUCH,"bpTestIntersect");
result = (BPEnumNext(&bpe)!=NULL);
BPEnumTerm(&bpe);
return result;
}
/*
* ----------------------------------------------------------------------------
* bpTestSnow --
* populate area with non-overlapping random unit rectangles.
*
* using bplane.
*
* ----------------------------------------------------------------------------
*/
BPlane *bpTestSnow(int size, bool trace)
{
int failures = 0;
int successes = 0;
int i = 0;
int crc = 0;
RectC *result = NULL;
RectC *rc = NULL;
BPlane *bp = BPNew();
Rect area;
fprintf(stderr,"BEGIN Snow, size=%d\n", size);
/* set up area */
area.r_xbot = 0;
area.r_ybot = 0;
area.r_xtop = size;
area.r_ytop = size;
while(failures<=successes)
{
i++;
if(!rc) rc = MALLOC_TAG(RectC *,rc, sizeof(RectC), "RectC");
bpTestRandRect(&rc->rc_rect, &area);
if(!bpTestIntersect(rc,bp))
{
if(trace) DumpRect("success ",&rc->rc_rect);
crc ^= i+ 3*rc->rc_rect.r_xbot+ 5*rc->rc_rect.r_ybot;
BPAdd(bp,rc);
rc = NULL;
successes++;
}
else
{
if(trace) DumpRect("failure ",&rc->rc_rect);
failures++;
}
}
fprintf(stderr,"END Snow, size=%d failures=%d success=%d crc=%d\n",
size,
failures,
successes,
crc);
return bp;
}
/* ====== Tile Plane based snow test.
*/
/*
* ----------------------------------------------------------------------------
* bpTestIntersectTile --
*
* check whether r intersects existing tiles
*
* ----------------------------------------------------------------------------
*/
int bpTestIntersectTileFunc(Tile *tile, ClientData cd)
{
return 1;
}
static bool bpTestIntersectTile(Rect *r, Plane *plane)
{
Rect area;
/* catch touching tiles */
area = *r;
area.r_xbot -= 1;
area.r_ybot -= 1;
area.r_xtop += 1;
area.r_ytop += 1;
return DBPlaneEnumAreaPaint((Tile *) NULL,
plane,
&area,
&DBAllButSpaceBits,
bpTestIntersectTileFunc,
NULL);
}
/*
* ----------------------------------------------------------------------------
* bpTestSnowTile --
* populate area with non-overlapping random unit rectangles.
*
* using tile plane
*
* ----------------------------------------------------------------------------
*/
Plane *bpTestSnowTile(int size, bool trace)
{
int failures = 0;
int successes = 0;
int i = 0;
int crc = 0;
RectC *result = NULL;
RectC *rc = NULL;
Plane *plane = DBPlaneNew((ClientData) TT_SPACE);
Rect area;
fprintf(stderr,"BEGIN Snow Tile, size=%d\n", size);
/* set up area */
area.r_xbot = 0;
area.r_ybot = 0;
area.r_xtop = size;
area.r_ytop = size;
while(failures<=successes)
{
Rect r;
i++;
bpTestRandRect(&r, &area);
if(!bpTestIntersectTile(&r,plane))
{
if(trace) DumpRect("success ",&r);
crc ^= i+ 3*r.r_xbot + 5*r.r_ybot;
DBPaintPlane(plane, &r, CIFPaintTable, (PaintUndoInfo *) NULL);
rc = NULL;
successes++;
}
else
{
if(trace) DumpRect("failure ",&r);
failures++;
}
}
fprintf(stderr,"END Snow Tile, size=%d failures=%d success=%d crc=%d\n",
size,
failures,
successes,
crc);
return plane;
}

View File

@ -1,77 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/* bpUtils.c --
*
* shared low-level routines for this module.
*
*/
#include <stdio.h>
#include "utils/utils.h"
#include "database/database.h"
#include "utils/geometry.h"
#include "bplane/bplaneInt.h"
/*
* ----------------------------------------------------------------------------
* bpRectDim --
*
* return dimension of rectangle in xDir
*
* ----------------------------------------------------------------------------
*/
int bpRectDim(Rect *r, bool xDir)
{
return xDir ? r->r_xtop - r->r_xbot : r->r_ytop - r->r_ybot;
}
/*
* ----------------------------------------------------------------------------
* bpBinIndices --
*
* compute bin indices corresponding to area.
*
* ----------------------------------------------------------------------------
*/
static __inline__ void
bpBinIndices(Rect area, /* area */
Rect binArea, /* lower left corner of bin system */
int indexBits,
int dim,
bool xDir, /* TRUE for x bin, FALSE for y bin */
int *min, /* results go here */
int *max)
{
int ref, coord;
int index;
}

View File

@ -1,235 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
#ifndef _MAGIC__BPLANE__BPLANE_H
#define _MAGIC__BPLANE__BPLANE_H
/*
* bplane.h --
*
* This file defines the interface between the bplane
* module and the rest of max.
*
* BUGS
* ====
*
* NOTE nested enums are currently broken do to dynamic binning.
*
* OVERVIEW OF BPLANES
* ===================
*
* BPlanes ('Binned' Planes) are a data-structure for storing, sorting,
* and accessing two dimensional geometric objects.
*
* BPlanes are an alternative to Planes, i.e. corner-stitched tile planes,
* defined in the tile module.
*
* Differences between Planes and BPlanes:
* --------------------------------------
*
* 1. BPlanes are more memory efficient.
* Three pointers (+ a modest amount of binning overhead)
* replaces approximately 8 pointers (4/tile, approx. 1 space
* tile for each data tile).
*
* 2. BPlanes use a 'next' procedure for enumeration, instead of
* function call-backs. This allows client code to be simpler
* and more readable, partcularly with regard to passing state info.
* In addition gprof results are easier to interpet, since
* there is not confusion about which client procedures belong to
* a given "loop".
*
* 3. Planes fundamentally assume objects don't overlap, while BPlanes
* make no such assumption. This makes BPlanes more generally useful.
* In particular they are a natural choice for instance uses,
* labels, and non-manhattan polygons (sorted on bounding boxes).
*
* 4. Planes are optimized for merging (merging recangles
* into maximal horizontal strips) and neighbor access
* (finding nearest elements to current element). BPlanes are less
* efficient for these operations.
*
* 5. Planes generally cannot be safely modified during an enumeration,
* but BPlanes can. This makes operations such as delete, copy, and
* move simpler in BPlanes.
*
* Interface
* ---------
*
* 1. The structure of elements to be stored in BPlanes must be as
* follows:
*
* typedef struct foo
* {
* struct void *foo_bpLinks[BP_NUM_LINKS];
* Rect foo_rect;
* <client fields go here>
* } Foo
*
* 2. It is the clients responsiblity to alloc/free elements.
*
* 3. The client must set foo_rect before adding the element
* to a BPlane. foo_rect must be canonical: not inverted.
*
* 4. The BPlane module does not access or modify any client fields.
*
* 5. The client may access/modify client fields at any time.
*
* 6. As long as an element belongs to a BPlane (i.e. has been
* added via BPAdd() and not removed via BPDelete()):
*
* a. The client should not reference/modify the foo_bpLinks[] fields.
* b. The client may reference but should not modify the foo_rect
* field.
* c. The client should not call BPAdd() for the element
* (an element can only belong to one BPlane at at time).
* d. The client should not free the element!
*
* 7. The client may assume tht BP_NUM_LINKS is at least one, and
* may use foo_bpLinks[0], for his own purposes as long as an
* element does not belong to a bplane.
*
* 8. Concurrent (nested) enumerations of a bplane are permitted.
*
* 9. Elements may not be added to a bplane during active enumeration(s)
* on that bplane.
*
* 10. An element may be deleted from a bplane at any time, including
* during active enumeration(s) of that bplane. After an element
* has been deleted from a bplane, it will not be enumerated
* (i.e. returned by BPEnumNext() on that bplane).
*
* Example
* -------
*
* Here is a procedure that takes an array of id'ed rectangles and an
* area as input, and prints the ids of all rectangles impinging on the
* area.
*
* typedef struct rid
* {
* struct rid *rid_bpLinks[BP_NUM_LINKS];
* Rect rid_rect;
* char *rid_id;
* } RId;
*
* void findRects(RId data[], // ided rects
* int n, // number of rects in data
* Rect *area) // area to search
* {
* int i;
* BPEnum bpe;
* BPlane *bp;
* RId *rid;
*
* bp = BPNew();
* for(i=0;i<n;i++) BPAdd(bp,&data[i]);
*
* BPEnumInit(&bpe,bp,area,BPE_OVERLAP,"findRects");
* while(rid = BPEnumNext(&bpe))
* {
* printf("%s\n", rid->rid_id);
* }
* BPEnumTerm(&bpe);
*
*/
/* data-structures opaque to clients */
#include "bplane/bpOpaque.h"
/* create a new BPlane */
extern BPlane *BPNew(void);
/* free storate assoicated with a BPlane
* (The BPlane must be empty.)
*/
extern void BPFree(BPlane *bp);
/* add an element to a BPlane */
extern void BPAdd(BPlane *bp,
void *element);
/* remove an element from a BPlane */
extern void BPDelete(BPlane *bp,
void *element);
/* begin an enumeration */
extern void BPEnumInit(BPEnum *bpe, /* this procedure initializes this
* client supplied 'handle' for the
* enumeration.
*/
BPlane *bp, /* bplane to search */
const Rect *area, /* area to search */
int match, /* see below */
const char *id); /* for debugging */
/* match values */
/* enum all elements in the bplane (area arg must be null) */
#define BPE_ALL 0
/* element need only touch area */
#define BPE_TOUCH 1
/* some part of element must be inside (not just on boundary of) area */
#define BPE_OVERLAP 2
/* elements rect must be identical to area */
#define BPE_EQUAL 3
/* return next element in enumeration (returns NULL if none) */
#include "bplane/bpEnum.h"
/* inlined extern void *BPEnumNext(BPEnum *bpe); */
/* terminate enumeration
*
* (unterminated enumerations can cause great inefficiency since
* all active enumerations for a bplane must be considered whenever
* an element is added or deleted.)
*/
extern void BPEnumTerm(BPEnum *bpe);
/* get current bounding box of BPlane */
extern Rect BPBBox(BPlane *bp);
/* compute number of bytes used by BPlane
* (does not count memory of the elements themselves)
*/
extern unsigned int BPStatMemory(BPlane *bp);
/* tabulate statistics on a bplane */
extern unsigned int
BPStat(BPlane *bp,
int *totCount, /* ret total number of elements */
int *inBox, /* ret num of elements in inBox */
int *totBins, /* ret tot num of bins */
int *emptyBins, /* ret num of empty bins */
int *binArraysp, /* ret num of bin arrays */
int *maxEffp, /* ret max effective list length */
int *maxBinCount, /* ret max count for regular bin */
int *totUnbinned, /* ret tot num of e's not binned */
int *maxDepth); /* ret max bin array depth */
#endif /* _MAGIC__BPLANE__BPLANE_H */

View File

@ -1,82 +0,0 @@
// ************************************************************************
//
// Copyright (c) 1995-2002 Juniper Networks, Inc. All rights reserved.
//
// Permission is hereby granted, without written agreement and without
// license or royalty fees, to use, copy, modify, and distribute this
// software and its documentation for any purpose, provided that the
// above copyright notice and the following three paragraphs appear in
// all copies of this software.
//
// IN NO EVENT SHALL JUNIPER NETWORKS, INC. BE LIABLE TO ANY PARTY FOR
// DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
// JUNIPER NETWORKS, INC. HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
// DAMAGE.
//
// JUNIPER NETWORKS, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
// NON-INFRINGEMENT.
//
// THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND JUNIPER
// NETWORKS, INC. HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
//
// ************************************************************************
/*
* bplaneInt.h --
*
* This file defines constants and datastructures used internally by the
* bplane module, but not exported to the rest of the world.
*/
#ifndef _MAGIC__BPLANE__BPLANEINT_H
#define _MAGIC__BPLANE__BPLANEINT_H
/* Tcl linked Parameters */
extern int bpMinBAPop; /* don't sub(bin) when count less than this
*/
extern double bpMinAvgBinPop; /* try to keep average bin pop at or
* below this
*/
/* LabeledElement
*
* Used in this module as elements for test bplanes.
*/
typedef struct labeledelement
{
struct element *le_links[BP_NUM_LINKS];
Rect le_rect;
/* client data goes here */
char * le_text;
} LabeledElement;
/* bins */
extern void bpBinsUpdate(BPlane *bp);
extern void bpBinAdd(BinArray *ba, Element *e);
extern BinArray *bpBinArrayBuild(Rect bbox,
Element *elements, /* initial elements */
bool subbin); /* subbin as needed */
/* dump (for debug) */
extern void bpDumpRect(Rect *r);
extern void bpDump(BPlane *bp, int flags);
/* bpDump flags */
/* labeled elements */
# define BPD_LABELED 1
# define BPD_INTERNAL_UNITS 2
/* test */
void bpTestSnowGold(int size, bool trace);
extern BPlane *bpTestSnow(int size, bool trace);
extern Plane *bpTestSnowTile(int size, bool trace);
extern int bpRand(int min, int max);
#endif /* _MAGIC__BPLANE__BPLANEINT_H */

File diff suppressed because it is too large Load Diff

View File

@ -18,12 +18,11 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdio.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdio.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <time.h>
#include <netinet/in.h> #include <netinet/in.h>
@ -46,14 +45,11 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "textio/textio.h" #include "textio/textio.h"
#include "calma/calmaInt.h" #include "calma/calmaInt.h"
/* C99 compat */
#include "calma/calma.h"
/* Forward declarations */ /* Forward declarations */
bool calmaReadR8(double *pd); bool calmaReadR8();
bool calmaSkipBytes(int nbytes); bool calmaSkipBytes();
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -73,9 +69,9 @@ bool calmaSkipBytes(int nbytes);
*/ */
bool bool
calmaReadTransform( calmaReadTransform(ptrans, name)
Transform *ptrans, /* Fill in this transform */ Transform *ptrans; /* Fill in this transform */
char *name) /* Name of subcell (for errors) */ char *name; /* Name of subcell (for errors) */
{ {
int nbytes, rtype, flags, angle; int nbytes, rtype, flags, angle;
double dangle; double dangle;
@ -114,8 +110,8 @@ calmaReadTransform(
if (dmag != (double)((int)(dmag + 0.5))) if (dmag != (double)((int)(dmag + 0.5)))
{ {
CalmaReadError("Non-integer magnification (%g) in transform\n", dmag); calmaReadError("Non-integer magnification (%g) in transform\n", dmag);
CalmaReadError("Rounding to %d.\n", (int)(dmag + 0.5)); calmaReadError("Rounding to %d.\n", (int)(dmag + 0.5));
} }
GeoScaleTrans(ptrans, (int)(dmag + 0.5), &t); GeoScaleTrans(ptrans, (int)(dmag + 0.5), &t);
*ptrans = t; *ptrans = t;
@ -148,13 +144,13 @@ calmaReadTransform(
case 0: case 90: case 180: case 270: case 0: case 90: case 180: case 270:
break; break;
default: default:
CalmaReadError("Non-Manhattan angle (%d) in transform\n", angle); calmaReadError("Non-Manhattan angle (%d) in transform\n", angle);
if (angle < 45) angle = 0; if (angle < 45) angle = 0;
else if (angle < 135) angle = 90; else if (angle < 135) angle = 90;
else if (angle < 225) angle = 180; else if (angle < 225) angle = 180;
else if (angle < 315) angle = 270; else if (angle < 315) angle = 270;
else angle = 0; else angle = 0;
CalmaReadError(" Rounding to %d degrees.\n", angle); calmaReadError(" Rounding to %d degrees.\n", angle);
} }
/* /*
@ -184,7 +180,7 @@ calmaReadTransform(
return (TRUE); return (TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -205,9 +201,9 @@ calmaReadTransform(
*/ */
bool bool
calmaReadI2Record( calmaReadI2Record(type, pvalue)
int type, /* Type of record expected */ int type; /* Type of record expected */
int *pvalue) /* Store value here */ int *pvalue; /* Store value here */
{ {
int nbytes, rtype, n; int nbytes, rtype, n;
@ -222,15 +218,15 @@ calmaReadI2Record(
/* Read the value */ /* Read the value */
READI2(n); READI2(n);
if (FEOF(calmaInputFile)) goto eof; if (feof(calmaInputFile)) goto eof;
*pvalue = n; *pvalue = n;
return (TRUE); return (TRUE);
eof: eof:
CalmaReadError("Unexpected EOF.\n"); calmaReadError("Unexpected EOF.\n");
return (FALSE); return (FALSE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -250,9 +246,9 @@ eof:
*/ */
bool bool
calmaReadI4Record( calmaReadI4Record(type, pvalue)
int type, /* Type of record expected */ int type; /* Type of record expected */
int *pvalue) /* Store value here */ int *pvalue; /* Store value here */
{ {
int nbytes, rtype, n; int nbytes, rtype, n;
@ -267,90 +263,15 @@ calmaReadI4Record(
/* Read the value */ /* Read the value */
READI4(n); READI4(n);
if (FEOF(calmaInputFile)) goto eof; if (feof(calmaInputFile)) goto eof;
*pvalue = n; *pvalue = n;
return (TRUE); return (TRUE);
eof: eof:
CalmaReadError("Unexpected EOF.\n"); calmaReadError("Unexpected EOF.\n");
return (FALSE); return (FALSE);
} }
/*
* ----------------------------------------------------------------------------
*
* calmaReadStampRecord --
*
* Read a record that contains a pair of timestamps for creation and
* modification dates.
*
* Results:
* TRUE on success, FALSE if the record type we read is not
* what we're expecting.
*
* Side effects:
* Consumes input.
* Translates the creation timestamp from GDS format to a standard
* UNIX (time.h) timestamp (seconds since the epoch).
* Stores the result in the integer pointed to by 'stampptr'.
*
* ----------------------------------------------------------------------------
*/
bool
calmaReadStampRecord(
int type,
int *stampptr)
{
int nbytes, rtype;
struct tm gds_timestamp;
READRH(nbytes, rtype);
if (nbytes < 0)
goto eof;
if (type != rtype)
{
calmaUnexpected(type, rtype);
return (FALSE);
}
nbytes -= CALMAHEADERLENGTH;
if (nbytes != 24)
{
/* Not dealing with any timestamp that is not in I2 format */
calmaSkipBytes(nbytes);
if (stampptr) *stampptr = 0;
CalmaReadError("Unknown timestamp format; setting timestamp to zero.\n");
return TRUE;
}
gds_timestamp.tm_wday = 0; /* Not used by mktime() */
gds_timestamp.tm_yday = 0; /* Not used by mktime() */
gds_timestamp.tm_isdst = -1;
READI2(gds_timestamp.tm_year);
READI2(gds_timestamp.tm_mon);
READI2(gds_timestamp.tm_mday);
READI2(gds_timestamp.tm_hour);
READI2(gds_timestamp.tm_min);
READI2(gds_timestamp.tm_sec);
/* GDS timestamps differ from UNIX time structure only by a */
/* difference of 1 in the month count. */
gds_timestamp.tm_mon--;
/* Skip the modification date timestamp */
(void) calmaSkipBytes(nbytes - 12);
if (stampptr) *stampptr = (int)mktime(&gds_timestamp);
return (TRUE);
eof:
CalmaReadError("Unexpected EOF.\n");
return (FALSE);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -371,9 +292,9 @@ eof:
*/ */
bool bool
calmaReadStringRecord( calmaReadStringRecord(type, str)
int type, int type;
char **str) char **str;
{ {
int nbytes, rtype; int nbytes, rtype;
@ -389,17 +310,17 @@ calmaReadStringRecord(
nbytes -= CALMAHEADERLENGTH; nbytes -= CALMAHEADERLENGTH;
*str = (char *) mallocMagic(nbytes + 1); *str = (char *) mallocMagic(nbytes + 1);
if (magicFREAD(*str, sizeof (char), nbytes, calmaInputFile) != nbytes) if (fread(*str, sizeof (char), nbytes, calmaInputFile) != nbytes)
goto eof; goto eof;
*(*str + nbytes) = '\0'; *(*str + nbytes) = '\0';
return (TRUE); return (TRUE);
eof: eof:
CalmaReadError("Unexpected EOF.\n"); calmaReadError("Unexpected EOF.\n");
return (FALSE); return (FALSE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -420,21 +341,21 @@ eof:
*/ */
bool bool
calmaReadR8( calmaReadR8(pd)
double *pd) /* Store result in *pd */ double *pd; /* Store result in *pd */
{ {
int i, exponent; int i, exponent;
unsigned char dchars[8]; unsigned char dchars[8];
double mantissa, d; double mantissa, d;
bool isneg; bool isneg;
if (magicFREAD((char *) dchars, sizeof (char), sizeof dchars, if (fread((char *) dchars, sizeof (char), sizeof dchars,
calmaInputFile) != sizeof dchars) calmaInputFile) != sizeof dchars)
return (FALSE); return (FALSE);
/* Extract the sign and exponent */ /* Extract the sign and exponent */
exponent = dchars[0]; exponent = dchars[0];
if ((isneg = (exponent & 0x80))) if (isneg = (exponent & 0x80))
exponent &= ~0x80; exponent &= ~0x80;
exponent -= 64; exponent -= 64;
@ -466,7 +387,7 @@ calmaReadR8(
*pd = d; *pd = d;
return (TRUE); return (TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -489,10 +410,10 @@ calmaReadR8(
*/ */
void void
calmaSkipSet( calmaSkipSet(skipwhat)
const int *skipwhat) int *skipwhat;
{ {
const int *skipp; int *skipp;
int nbytes, rtype; int nbytes, rtype;
for (;;) for (;;)
@ -512,7 +433,7 @@ skipit:
(void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -533,8 +454,8 @@ skipit:
*/ */
bool bool
calmaSkipExact( calmaSkipExact(type)
int type) int type;
{ {
int nbytes, rtype; int nbytes, rtype;
@ -557,10 +478,10 @@ calmaSkipExact(
return (TRUE); return (TRUE);
eof: eof:
CalmaReadError("Unexpected EOF.\n"); calmaReadError("Unexpected EOF.\n");
return (FALSE); return (FALSE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -579,8 +500,8 @@ eof:
*/ */
bool bool
calmaSkipTo( calmaSkipTo(what)
int what) int what;
{ {
int nbytes, rtype; int nbytes, rtype;
@ -594,7 +515,7 @@ calmaSkipTo(
return (TRUE); return (TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -615,11 +536,11 @@ calmaSkipTo(
*/ */
bool bool
calmaSkipBytes( calmaSkipBytes(nbytes)
int nbytes) /* Skip this many bytes */ int nbytes; /* Skip this many bytes */
{ {
while (nbytes-- > 0) while (nbytes-- > 0)
if (FGETC(calmaInputFile) < 0) if (getc(calmaInputFile) < 0)
return (FALSE); return (FALSE);
return (TRUE); return (TRUE);

View File

@ -18,7 +18,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdpt.c,v 1.7 2010/08/25 17:33:54 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdpt.c,v 1.7 2010/08/25 17:33:54 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -48,17 +48,13 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "calma/calmaInt.h" #include "calma/calmaInt.h"
#include "calma/calma.h" #include "calma/calma.h"
/* C99 compat */
#include "drc/drc.h"
extern int calmaNonManhattan; extern int calmaNonManhattan;
extern int CalmaPolygonCount; extern int CalmaPolygonCount;
extern int CalmaPathCount;
extern HashTable calmaDefInitHash; extern HashTable calmaDefInitHash;
extern void calmaLayerError(char *mesg, int layer, int dt); extern void calmaLayerError();
CIFPath *calmaReadPath(int iscale); bool calmaReadPath();
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -82,9 +78,8 @@ CIFPath *calmaReadPath(int iscale);
*/ */
void void
calmaInputRescale( calmaInputRescale(n, d)
int n, int n, d;
int d)
{ {
HashEntry *h; HashEntry *h;
HashSearch hs; HashSearch hs;
@ -102,9 +97,7 @@ calmaInputRescale(
{ {
/* Scale the GDS planes in this cell's cd_client record */ /* Scale the GDS planes in this cell's cd_client record */
Plane **gdsplanes = (Plane **)def->cd_client; Plane **gdsplanes = (Plane **)def->cd_client;
/* Should not happen, but punt if client record is not set; */ CIFScalePlanes(n, d, gdsplanes);
if (def->cd_client != (ClientData)0)
CIFScalePlanes(n, d, gdsplanes);
} }
} }
@ -114,8 +107,6 @@ calmaInputRescale(
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* calmaReadX ---
* calmaReadY ---
* calmaReadPoint --- * calmaReadPoint ---
* *
* Read a point from the input. * Read a point from the input.
@ -134,19 +125,13 @@ 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(p, iscale)
Point *p, Point *p;
int iscale) int iscale;
{ {
int rescale; int rescale;
@ -157,7 +142,7 @@ calmaReadX(
rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_x)); rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_x));
if ((calmaReadScale1 * rescale) > CIFRescaleLimit) if ((calmaReadScale1 * rescale) > CIFRescaleLimit)
{ {
CalmaReadError("Warning: calma units at max scale; value rounded\n"); calmaReadError("Warning: calma units at max scale; value rounded\n");
if (p->p_x < 0) if (p->p_x < 0)
p->p_x -= ((calmaReadScale2 - 1) >> 1); p->p_x -= ((calmaReadScale2 - 1) >> 1);
else else
@ -171,15 +156,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);
@ -188,7 +164,7 @@ calmaReadY(
rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_y)); rescale = calmaReadScale2 / FindGCF(calmaReadScale2, abs(p->p_y));
if ((calmaReadScale1 * rescale) > CIFRescaleLimit) if ((calmaReadScale1 * rescale) > CIFRescaleLimit)
{ {
CalmaReadError("Warning: calma units at max scale; value rounded\n"); calmaReadError("Warning: calma units at max scale; value rounded\n");
if (p->p_y < 0) if (p->p_y < 0)
p->p_y -= ((calmaReadScale2 - 1) >> 1); p->p_y -= ((calmaReadScale2 - 1) >> 1);
else else
@ -205,16 +181,7 @@ calmaReadY(
p->p_y /= calmaReadScale2; p->p_y /= calmaReadScale2;
} }
void
calmaReadPoint(
Point *p,
int iscale)
{
calmaReadX(p, iscale);
calmaReadY(p, iscale);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -232,14 +199,14 @@ calmaReadPoint(
*/ */
void void
calmaElementBoundary(void) calmaElementBoundary()
{ {
int dt, layer, ciftype; int dt, layer, ciftype;
CIFPath *pathheadp; CIFPath *pathheadp;
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);
@ -248,7 +215,7 @@ calmaElementBoundary(void)
if (!calmaReadI2Record(CALMA_LAYER, &layer) if (!calmaReadI2Record(CALMA_LAYER, &layer)
|| !calmaReadI2Record(CALMA_DATATYPE, &dt)) || !calmaReadI2Record(CALMA_DATATYPE, &dt))
{ {
CalmaReadError("Missing layer or datatype in boundary/box.\n"); calmaReadError("Missing layer or datatype in boundary/box.\n");
return; return;
} }
@ -263,11 +230,10 @@ 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");
return; return;
} }
@ -275,27 +241,23 @@ calmaElementBoundary(void)
/* so we need to set it again. */ /* so we need to set it again. */
if (ciftype >= 0) plane = cifCurReadPlanes[ciftype]; if (ciftype >= 0) plane = cifCurReadPlanes[ciftype];
/* Save non-Manhattan polygons in their own subcells. */ /* Convert the polygon to rectangles. */
/* NOTE: CALMA_POLYGON_TEMP and CALMA_POLYGON_KEEP read in polygons much
* faster, but that interferes with boolean processing. This method
* needs to be reworked.
*/
if ((CalmaSubcellPolygons != CALMA_POLYGON_NONE) && (calmaNonManhattan > 0)) if (CalmaSubcellPolygons && (calmaNonManhattan > 0))
{ {
/* Place the polygon in its own subcell */ /* Place the polygon in its own subcell */
char newname[20]; char newname[] = "polygonXXXXX";
HashEntry *he; HashEntry *he;
savedef = cifReadCellDef; savedef = cifReadCellDef;
/* Make up name for cell */ /* Make up name for cell */
snprintf(newname, sizeof(newname), "polygon%05d", ++CalmaPolygonCount); sprintf(newname + 7, "%05d", ++CalmaPolygonCount);
he = HashFind(&calmaDefInitHash, newname); he = HashFind(&calmaDefInitHash, newname);
if (!HashGetValue(he)) if (!HashGetValue(he))
{ {
newdef = calmaFindCell(newname, NULL, NULL); newdef = calmaFindCell(newname, NULL);
cifReadCellDef = newdef; cifReadCellDef = newdef;
DBCellClearDef(cifReadCellDef); DBCellClearDef(cifReadCellDef);
DBCellSetAvail(cifReadCellDef); DBCellSetAvail(cifReadCellDef);
@ -309,95 +271,20 @@ calmaElementBoundary(void)
} }
} }
/* Convert the polygon to rectangles. */ rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL);
rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL, TRUE);
CIFFreePath(pathheadp); CIFFreePath(pathheadp);
/* If the input layer is designated for ports by a "label" */
/* statement in the cifinput section, then find any label */
/* bounded by the path and attach the path to it. Note */
/* that this assumes two things: (1) that labels can only */
/* be attached to simple rectangles, and (2) that the */
/* rectangle appears in the GDS stream after the label. If */
/* either assumption is violated, this method needs to be */
/* re-coded. */
if (rp != NULL)
{
Rect rpc;
int savescale;
/* Convert rp to magic database units to compare to label rects */
rpc = rp->r_r;
rpc.r_xbot /= cifCurReadStyle->crs_scaleFactor;
rpc.r_xtop /= cifCurReadStyle->crs_scaleFactor;
rpc.r_ybot /= cifCurReadStyle->crs_scaleFactor;
rpc.r_ytop /= cifCurReadStyle->crs_scaleFactor;
if ((ciftype >= 0) &&
(cifCurReadStyle->crs_labelSticky[ciftype] != LABEL_TYPE_NONE))
{
Label *lab;
TileType type;
type = cifCurReadStyle->crs_labelLayer[ciftype];
for (lab = cifReadCellDef->cd_labels; lab; lab = lab->lab_next)
{
if ((GEO_SURROUND(&rpc, &lab->lab_rect)) && (lab->lab_type == type))
{
lab->lab_rect = rpc; /* Replace with larger rectangle */
break;
}
}
if (lab == NULL)
{
/* There was no label in the area. Create a placeholder label */
lab = DBPutLabel(cifReadCellDef, &rpc, GEO_CENTER, "", type, 0, 0);
}
if ((cifCurReadStyle->crs_labelSticky[ciftype] == LABEL_TYPE_PORT)
&& ((lab->lab_flags & PORT_DIR_MASK) == 0))
{
/* Label was read previously as a text type, but the pin layer
* causes it to be recast as a port, or corresponding label has
* not yet been seen.
*/
int i, idx;
Label *sl;
/* Order ports as encountered. */
i = -1;
for (sl = cifReadCellDef->cd_labels; sl != NULL; sl = sl->lab_next)
{
idx = sl->lab_port;
if (idx > i) i = idx;
if ((idx > 0) && (sl != lab) && !strcmp(sl->lab_text, lab->lab_text))
{
i = idx - 1;
break;
}
}
i++;
lab->lab_port = i;
lab->lab_flags |= PORT_DIR_NORTH | PORT_DIR_SOUTH |
PORT_DIR_EAST | PORT_DIR_WEST;
}
}
}
/* Paint the rectangles (if any) */ /* 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)
{ {
CIFPaintCurrent(FILE_CALMA); CIFPaintCurrent();
DBReComputeBbox(cifReadCellDef); DBReComputeBbox(cifReadCellDef);
DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox); DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox);
DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox, DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox,
@ -413,7 +300,7 @@ calmaElementBoundary(void)
DBPlaceCell(use, cifReadCellDef); DBPlaceCell(use, cifReadCellDef);
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -436,7 +323,7 @@ calmaElementBoundary(void)
*/ */
void void
calmaElementBox(void) calmaElementBox()
{ {
int nbytes, rtype, npoints, savescale; int nbytes, rtype, npoints, savescale;
int dt, layer, ciftype; int dt, layer, ciftype;
@ -451,7 +338,7 @@ calmaElementBox(void)
if (!calmaReadI2Record(CALMA_LAYER, &layer) if (!calmaReadI2Record(CALMA_LAYER, &layer)
|| !calmaReadI2Record(CALMA_BOXTYPE, &dt)) || !calmaReadI2Record(CALMA_BOXTYPE, &dt))
{ {
CalmaReadError("Missing layer or datatype in boundary/box.\n"); calmaReadError("Missing layer or datatype in boundary/box.\n");
return; return;
} }
@ -475,7 +362,7 @@ calmaElementBox(void)
READRH(nbytes, rtype); READRH(nbytes, rtype);
if (nbytes < 0) if (nbytes < 0)
{ {
CalmaReadError("EOF when reading box.\n"); calmaReadError("EOF when reading box.\n");
return; return;
} }
if (rtype != CALMA_XY) if (rtype != CALMA_XY)
@ -488,7 +375,7 @@ calmaElementBox(void)
npoints = (nbytes - CALMAHEADERLENGTH) / 8; npoints = (nbytes - CALMAHEADERLENGTH) / 8;
if (npoints != 5) if (npoints != 5)
{ {
CalmaReadError("Box doesn't have 5 points.\n"); calmaReadError("Box doesn't have 5 points.\n");
(void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH); (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
return; return;
} }
@ -531,9 +418,9 @@ calmaElementBox(void)
*/ */
void void
calmaElementPath(void) calmaElementPath()
{ {
int nbytes = -1, rtype = 0, extend1, extend2; int nbytes, rtype, extend1, extend2;
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;
@ -541,7 +428,7 @@ calmaElementPath(void)
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);
@ -556,10 +443,9 @@ calmaElementPath(void)
if (nbytes > 0 && rtype == CALMA_PATHTYPE) if (nbytes > 0 && rtype == CALMA_PATHTYPE)
if (!calmaReadI2Record(CALMA_PATHTYPE, &pathtype)) return; if (!calmaReadI2Record(CALMA_PATHTYPE, &pathtype)) return;
if (pathtype != CALMAPATH_SQUAREFLUSH && pathtype != CALMAPATH_SQUAREPLUS && if (pathtype != CALMAPATH_SQUAREFLUSH && pathtype != CALMAPATH_SQUAREPLUS)
pathtype != CALMAPATH_CUSTOM)
{ {
CalmaReadError("Warning: pathtype %d unsupported (ignored).\n", pathtype); calmaReadError("Warning: pathtype %d unsupported (ignored).\n", pathtype);
pathtype = CALMAPATH_SQUAREFLUSH; pathtype = CALMAPATH_SQUAREFLUSH;
} }
@ -573,35 +459,28 @@ calmaElementPath(void)
{ {
if (!calmaReadI4Record(CALMA_WIDTH, &width)) if (!calmaReadI4Record(CALMA_WIDTH, &width))
{ {
CalmaReadError("Error in reading WIDTH in calmaElementPath()\n") ; calmaReadError("Error in reading WIDTH in calmaElementPath()\n") ;
return; return;
} }
} }
width *= calmaReadScale1; width *= calmaReadScale1;
if (width % calmaReadScale2 != 0) if (width % calmaReadScale2 != 0)
CalmaReadError("Wire width snapped to nearest integer boundary.\n"); calmaReadError("Wire width snapped to nearest integer boundary.\n");
width /= calmaReadScale2; width /= calmaReadScale2;
/* Set path extensions based on path type. Note that SQUARE endcaps */
/* are handled automatically by the CIFPaintWirePath routine. */
/* Round endcaps are not really handled other than assuming they're */
/* the same as square. All others are truncated to zero and any */
/* custom endcap is added to the path here. */
extend1 = extend2 = 0;
/* Handle BGNEXTN, ENDEXTN */ /* Handle BGNEXTN, ENDEXTN */
extend1 = extend2 = 0;
PEEKRH(nbytes, rtype); PEEKRH(nbytes, rtype);
if (nbytes > 0 && rtype == CALMA_BGNEXTN) if (nbytes > 0 && rtype == CALMA_BGNEXTN)
{ {
if (!calmaReadI4Record(CALMA_BGNEXTN, &extend1)) if (!calmaReadI4Record(CALMA_BGNEXTN, &extend1))
CalmaReadError("Error in reading BGNEXTN in path (ignored)\n") ; calmaReadError("Error in reading BGNEXTN in path (ignored)\n") ;
else else
{ {
extend1 *= calmaReadScale1; extend1 *= calmaReadScale1;
if (extend1 % calmaReadScale2 != 0) if (extend1 % calmaReadScale2 != 0)
CalmaReadError("Wire extension snapped to nearest integer boundary.\n"); calmaReadError("Wire extension snapped to nearest integer boundary.\n");
extend1 *= 2; extend1 *= 2;
extend1 /= calmaReadScale2; extend1 /= calmaReadScale2;
} }
@ -611,12 +490,12 @@ calmaElementPath(void)
if (nbytes > 0 && rtype == CALMA_ENDEXTN) if (nbytes > 0 && rtype == CALMA_ENDEXTN)
{ {
if (!calmaReadI4Record(CALMA_ENDEXTN, &extend2)) if (!calmaReadI4Record(CALMA_ENDEXTN, &extend2))
CalmaReadError("Error in reading ENDEXTN in path (ignored)\n") ; calmaReadError("Error in reading ENDEXTN in path (ignored)\n") ;
else else
{ {
extend2 *= calmaReadScale1; extend2 *= calmaReadScale1;
if (extend2 % calmaReadScale2 != 0) if (extend2 % calmaReadScale2 != 0)
CalmaReadError("Wire extension snapped to nearest integer boundary.\n"); calmaReadError("Wire extension snapped to nearest integer boundary.\n");
extend2 *= 2; extend2 *= 2;
extend2 /= calmaReadScale2; extend2 /= calmaReadScale2;
} }
@ -624,10 +503,9 @@ 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;
} }
if (savescale != calmaReadScale1) if (savescale != calmaReadScale1)
@ -690,21 +568,21 @@ calmaElementPath(void)
{ {
plane = cifCurReadPlanes[ciftype]; plane = cifCurReadPlanes[ciftype];
if (CalmaSubcellPaths) if (CalmaSubcellPolygons && (calmaNonManhattan > 0))
{ {
/* Place the path in its own subcell */ /* Place the polygon in its own subcell */
char newname[16]; char newname[] = "polygonXXXXX";
HashEntry *he; HashEntry *he;
savedef = cifReadCellDef; savedef = cifReadCellDef;
/* Make up name for cell */ /* Make up name for cell */
snprintf(newname, sizeof(newname), "path%05d", ++CalmaPathCount); sprintf(newname + 7, "%05d", ++CalmaPolygonCount);
he = HashFind(&calmaDefInitHash, newname); he = HashFind(&calmaDefInitHash, newname);
if (!HashGetValue(he)) if (!HashGetValue(he))
{ {
newdef = calmaFindCell(newname, NULL, NULL); newdef = calmaFindCell(newname, NULL);
cifReadCellDef = newdef; cifReadCellDef = newdef;
DBCellClearDef(cifReadCellDef); DBCellClearDef(cifReadCellDef);
DBCellSetAvail(cifReadCellDef); DBCellSetAvail(cifReadCellDef);
@ -718,19 +596,13 @@ 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");
CIFPaintWirePath(pathheadp, width, CIFPaintWirePath(pathheadp, width,
(pathtype == CALMAPATH_SQUAREFLUSH || pathtype == CALMAPATH_CUSTOM) ? (pathtype == CALMAPATH_SQUAREFLUSH) ? FALSE : TRUE,
FALSE : TRUE, plane, CIFPaintTable, (PaintUndoInfo *)NULL); plane, CIFPaintTable, (PaintUndoInfo *)NULL);
if (cifCurReadPlanes == cifEditCellPlanes) if (cifCurReadPlanes == cifEditCellPlanes)
{ {
CIFPaintCurrent(FILE_CALMA); CIFPaintCurrent();
DBReComputeBbox(cifReadCellDef); DBReComputeBbox(cifReadCellDef);
DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox); DRCCheckThis(cifReadCellDef, TT_CHECKPAINT, &cifReadCellDef->cd_bbox);
DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox, DBWAreaChanged(cifReadCellDef, &cifReadCellDef->cd_bbox,
@ -765,16 +637,17 @@ calmaElementPath(void)
*/ */
void void
calmaElementText(void) calmaElementText()
{ {
static const int ignore[] = { CALMA_PATHTYPE, CALMA_WIDTH, -1 }; static int ignore[] = { CALMA_PATHTYPE, CALMA_WIDTH, -1 };
char *textbody = NULL; char *textbody = NULL;
int nbytes = -1, rtype = 0; int nbytes, rtype;
int layer, textt, cifnum, textpres; int layer, textt, cifnum;
TileType type; TileType type;
Rect r; Rect r;
unsigned short textpres;
double dval; double dval;
int size, micron, angle, font, pos, portnum, idx; int size, angle, font, pos;
/* Skip CALMA_ELFLAGS, CALMA_PLEX */ /* Skip CALMA_ELFLAGS, CALMA_PLEX */
calmaSkipSet(calmaElementIgnore); calmaSkipSet(calmaElementIgnore);
@ -785,7 +658,7 @@ calmaElementText(void)
cifnum = CIFCalmaLayerToCifLayer(layer, textt, cifCurReadStyle); cifnum = CIFCalmaLayerToCifLayer(layer, textt, cifCurReadStyle);
if (cifnum < 0) if (cifnum < 0)
{ {
if (cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS) if(cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS)
type = -1; type = -1;
else { else {
calmaLayerError("Label on unknown layer/datatype", layer, textt); calmaLayerError("Label on unknown layer/datatype", layer, textt);
@ -796,29 +669,10 @@ calmaElementText(void)
font = -1; font = -1;
angle = 0; angle = 0;
portnum = 0;
/* Use the minimum width of the layer on which the text is placed /* Default size is 1um */
* as the default text size, or 1um, whichever is smaller. Account size = (int)((800 * cifCurReadStyle->crs_multiplier)
* for the 8/10 difference encoded in the rendered font height.
*/
size = 0;
if (type > 0)
{
size = DRCGetDefaultLayerWidth(type);
if (size > 0)
{
size *= (calmaReadScale2 * cifCurReadStyle->crs_multiplier * 8);
size /= (calmaReadScale1 * cifCurReadStyle->crs_scaleFactor * 10);
}
}
/* Default or maximum size is 1um */
micron = (int)((800 * cifCurReadStyle->crs_multiplier)
/ cifCurReadStyle->crs_scaleFactor); / cifCurReadStyle->crs_scaleFactor);
if ((size == 0) || (size > micron))
size = micron;
/* Default position is bottom-right (but what the spec calls "top-left"!) */ /* Default position is bottom-right (but what the spec calls "top-left"!) */
pos = GEO_SOUTHEAST; pos = GEO_SOUTHEAST;
@ -864,31 +718,6 @@ calmaElementText(void)
else if (nbytes > 0 && rtype != CALMA_STRANS) else if (nbytes > 0 && rtype != CALMA_STRANS)
calmaSkipSet(ignore); calmaSkipSet(ignore);
/* NOTE: Record may contain both PRESENTATION and WIDTH */
PEEKRH(nbytes, rtype);
if (nbytes > 0 && rtype == CALMA_WIDTH)
{
int width;
/* Use WIDTH value to set the font size */
if (!calmaReadI4Record(CALMA_WIDTH, &width))
{
CalmaReadError("Error in reading WIDTH in calmaElementText()\n") ;
return;
}
width *= calmaReadScale1;
if (width % calmaReadScale2 != 0)
CalmaReadError("Text width snapped to nearest integer boundary.\n");
width /= calmaReadScale2;
/* Convert to database units, because dimension goes to PutLabel */
/* and is not converted through CIFPaintCurrent(). */
size = CIFScaleCoord(width, COORD_ANY);
}
else if (nbytes > 0 && rtype != CALMA_STRANS)
calmaSkipSet(ignore);
READRH(nbytes, rtype); READRH(nbytes, rtype);
if (nbytes > 0 && rtype == CALMA_STRANS) if (nbytes > 0 && rtype == CALMA_STRANS)
{ {
@ -899,20 +728,10 @@ calmaElementText(void)
if (nbytes > 0 && rtype == CALMA_MAG) if (nbytes > 0 && rtype == CALMA_MAG)
{ {
calmaReadR8(&dval); calmaReadR8(&dval);
/* Sanity check on dval (must be nonzero positive) */ /* Assume that MAG is the label size in microns */
if ((dval <= 0) || (dval > 10000)) /* "size" is the label size in 8 * (database units) */
{ size = (int)((dval * 800 * cifCurReadStyle->crs_multiplier)
CalmaReadError("Invalid text magnification %lg.\n", dval); / cifCurReadStyle->crs_scaleFactor);
/* Keep default size */
}
else
/* Assume that MAG is the label size in microns */
/* "size" is the label size in 10 * (database units) */
/* The "calma magscale" option can be used to */
/* reinterpret the size for any specific GDS file. */
size = (int)(0.5 + ((dval * 1000 * CalmaMagScale
* cifCurReadStyle->crs_multiplier)
/ cifCurReadStyle->crs_scaleFactor));
} }
else else
UNREADRH(nbytes, rtype); UNREADRH(nbytes, rtype);
@ -941,7 +760,7 @@ calmaElementText(void)
nbytes -= CALMAHEADERLENGTH; nbytes -= CALMAHEADERLENGTH;
if (nbytes < 8) if (nbytes < 8)
{ {
CalmaReadError("Not enough bytes in point record.\n"); calmaReadError("Not enough bytes in point record.\n");
} }
else else
{ {
@ -991,15 +810,15 @@ calmaElementText(void)
} }
} }
if (changed) { if (changed) {
CalmaReadError("Warning: improper characters fixed in label '%s'\n", calmaReadError("Warning: improper characters fixed in label '%s'\n",
savstring); savstring);
if (!algmsg) { if (!algmsg) {
algmsg = TRUE; algmsg = TRUE;
CalmaReadError(" (algorithm used: trailing <CR> dropped, " calmaReadError(" (algorithm used: trailing <CR> dropped, "
"<CR> and ' ' changed to '_', \n" "<CR> and ' ' changed to '_', \n"
" other non-printables changed to '?')\n"); " other non-printables changed to '?')\n");
} }
CalmaReadError(" modified label is '%s'\n", textbody); calmaReadError(" modified label is '%s'\n", textbody);
freeMagic(savstring); freeMagic(savstring);
} }
} }
@ -1009,119 +828,47 @@ calmaElementText(void)
/* Place the label */ /* Place the label */
if (strlen(textbody) == 0) if (strlen(textbody) == 0)
{ {
CalmaReadError("Warning: Ignoring empty string label at (%d, %d)\n", calmaReadError("Warning: Ignoring empty string label at (%d, %d)\n",
r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor, r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor,
r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor); r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor);
} }
else if (cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_CELLID)
{
/* Special handling of label layers marked "cellid" in the techfile. */
/* The actual cellname is the ID string, not the GDS structure name. */
DBCellRenameDef(cifReadCellDef, textbody);
}
else if (type < 0) else if (type < 0)
{ {
if (!(cifCurReadStyle->crs_flags & CRF_IGNORE_UNKNOWNLAYER_LABELS)) calmaReadError("Warning: label \"%s\" at (%d, %d) is on unhandled"
CalmaReadError("Warning: label \"%s\" at (%d, %d) is on unhandled" " layer:purpose pair %d:%d and will be discarded.\n", textbody,
" layer:purpose pair %d:%d and will be discarded.\n", textbody, r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor,
r.r_ll.p_x * cifCurReadStyle->crs_scaleFactor, r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor, layer, textt);
r.r_ll.p_y * cifCurReadStyle->crs_scaleFactor, layer, textt);
} }
else else
{ {
int flags, i; int flags, i;
Label *lab;
Label *sl;
if (type == TT_SPACE) /* Find the style layer record corresponding to the label type */
/* Assigning GDS layer to space prevents making the label sticky */ layer = -1;
flags = 0; for (i = 0; i < cifCurReadStyle->crs_nLayers; i++)
else if (cifnum >= 0 && (cifCurReadStyle->crs_labelSticky[cifnum] != LABEL_TYPE_NONE)) if (cifCurReadStyle->crs_layers[i]->crl_magicType == type) {
layer = i;
break;
}
if (layer >= 0 && cifCurReadStyle->crs_labelSticky[layer])
flags = LABEL_STICKY;
else if (cifCurReadStyle->crs_flags & CRF_NO_RECONNECT_LABELS)
flags = LABEL_STICKY; flags = LABEL_STICKY;
else else
flags = 0; flags = 0;
/* If there is an empty-string label surrounding the label position */
/* then replace the position with the larger one and remove the */
/* empty label. */
sl = NULL;
for (lab = cifReadCellDef->cd_labels; lab != NULL; lab = lab->lab_next)
{
if (lab->lab_text[0] == '\0')
{
if ((GEO_SURROUND(&lab->lab_rect, &r)) && (lab->lab_type == type))
{
r = lab->lab_rect;
if (sl == NULL)
cifReadCellDef->cd_labels = lab->lab_next;
else
sl->lab_next = lab->lab_next;
if (cifReadCellDef->cd_lastLabel == lab)
cifReadCellDef->cd_lastLabel = sl;
/* Port number from the placeholder is ignored; find
* a new valid port number for the new label name.
*/
i = -1;
for (sl = cifReadCellDef->cd_labels; sl != NULL; sl = sl->lab_next)
{
idx = sl->lab_port;
if (idx > i) i = idx;
if ((idx > 0) && (sl != lab) && !strcmp(sl->lab_text, textbody))
{
i = idx - 1;
break;
}
}
i++;
portnum = i;
flags |= PORT_DIR_NORTH | PORT_DIR_SOUTH |
PORT_DIR_EAST | PORT_DIR_WEST;
freeMagic((char *)lab);
break;
}
}
sl = lab;
}
if (font < 0) if (font < 0)
lab = DBPutLabel(cifReadCellDef, &r, pos, textbody, type, flags, portnum); DBPutLabel(cifReadCellDef, &r, pos, textbody, type, flags);
else else
lab = DBPutFontLabel(cifReadCellDef, &r, font, size, angle, DBPutFontLabel(cifReadCellDef, &r, font, size, angle,
&GeoOrigin, pos, textbody, type, flags, portnum); &GeoOrigin, pos, textbody, type, flags);
if ((lab != NULL) && (cifnum >= 0) &&
(cifCurReadStyle->crs_labelSticky[cifnum] == LABEL_TYPE_PORT))
{
/* No port information can be encoded in the GDS file, so */
/* assume defaults, and assume that the port order is the */
/* order in which labels arrive in the GDS stream. If */
/* ports have the same text, then give them the same index. */
i = -1;
for (sl = cifReadCellDef->cd_labels; sl != NULL; sl = sl->lab_next)
{
idx = sl->lab_port;
if (idx > i) i = idx;
if ((idx > 0) && (sl != lab) && !strcmp(sl->lab_text, textbody))
{
i = idx - 1;
break;
}
}
i++;
lab->lab_port = i;
lab->lab_flags |= PORT_DIR_NORTH | PORT_DIR_SOUTH |
PORT_DIR_EAST | PORT_DIR_WEST;
}
} }
/* done with textbody */ /* done with textbody */
if (textbody != NULL) freeMagic(textbody); if (textbody != NULL) freeMagic(textbody);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1133,24 +880,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(pathheadpp, iscale)
int iscale) CIFPath **pathheadpp;
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,13 +907,13 @@ calmaReadPath(
READRH(nbytes, rtype); READRH(nbytes, rtype);
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) */
@ -1175,7 +924,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)
{ {
@ -1185,13 +934,13 @@ calmaReadPath(
} }
} }
if (ABS(path.cifp_x) > 0x0fffffff || ABS(path.cifp_y) > 0x0fffffff) { if (ABS(path.cifp_x) > 0x0fffffff || ABS(path.cifp_y) > 0x0fffffff) {
CalmaReadError("Warning: Very large point in path: (%d, %d)\n", calmaReadError("Warning: Very large point in path: (%d, %d)\n",
path.cifp_x, path.cifp_y); path.cifp_x, path.cifp_y);
} }
if (FEOF(calmaInputFile)) if (feof(calmaInputFile))
{ {
CIFFreePath(pathheadp); CIFFreePath(*pathheadpp);
return (NULL); return (FALSE);
} }
if (iscale != 0) if (iscale != 0)
@ -1199,7 +948,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
@ -1220,13 +969,13 @@ calmaReadPath(
} }
pathtailp->cifp_next = newpathp; pathtailp->cifp_next = newpathp;
} }
else pathheadp = newpathp; else *pathheadpp = newpathp;
pathtailp = newpathp; pathtailp = newpathp;
} }
} }
return (pathheadp); return (*pathheadpp != NULL);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1249,29 +998,20 @@ calmaReadPath(
*/ */
void void
calmaLayerError( calmaLayerError(mesg, layer, dt)
char *mesg, char *mesg;
int layer, int layer;
int dt) int dt;
{ {
CalmaLayerType clt; CalmaLayerType clt;
HashEntry *he; HashEntry *he;
/* Ignore errors for cells that are marked as read-only, since */
/* these are normally expected to have unhandled layer types, */
/* since the purpose of read-only cells is to preserve exactly */
/* layout in the cell which may not be represented in the tech */
/* file. */
if ((cifReadCellDef->cd_flags & CDVENDORGDS) == CDVENDORGDS)
return;
clt.clt_layer = layer; clt.clt_layer = layer;
clt.clt_type = dt; clt.clt_type = dt;
he = HashFind(&calmaLayerHash, (char *) &clt); he = HashFind(&calmaLayerHash, (char *) &clt);
if (HashGetValue(he) == NULL) if (HashGetValue(he) == NULL)
{ {
HashSetValue(he, (ClientData) 1); HashSetValue(he, (ClientData) 1);
CalmaReadError("%s, layer=%d type=%d\n", mesg, layer, dt); calmaReadError("%s, layer=%d type=%d\n", mesg, layer, dt);
} }
} }

View File

@ -17,10 +17,9 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRead.c,v 1.3 2010/06/24 12:37:15 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRead.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
@ -28,12 +27,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include <netinet/in.h> #include <netinet/in.h>
/*
* C99 compat
* Mind: tcltk/tclmagic.h must be included prior to all the other headers
*/
#include "tcltk/tclmagic.h"
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/geometry.h" #include "utils/geometry.h"
#include "tiles/tile.h" #include "tiles/tile.h"
@ -53,41 +46,25 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "textio/textio.h" #include "textio/textio.h"
#include "calma/calmaInt.h" #include "calma/calmaInt.h"
#include "commands/commands.h" /* for CmdGetRootPoint */ #include "commands/commands.h" /* for CmdGetRootPoint */
#include "utils/main.h" /* for EditCellUse */
#include "utils/undo.h" #include "utils/undo.h"
/* C99 compat */
#include "calma/calma.h"
/* Globals for Calma reading */ /* Globals for Calma reading */
FILETYPE calmaInputFile = NULL; /* Read from this stream */ FILE *calmaInputFile = NULL; /* Read from this stream */
FILE *calmaErrorFile = NULL; /* Write error output here */ FILE *calmaErrorFile = NULL; /* Write error output here */
unsigned char CalmaSubcellPolygons = CALMA_POLYGON_NONE; bool CalmaSubcellPolygons = FALSE; /* Put non-Manhattan polygons
/* Read non-Manhattan polygons as-is */ * in their own subcells.
*/
int CalmaPolygonCount; int CalmaPolygonCount;
bool CalmaSubcellPaths = FALSE; /* Put paths in their own subcells. */
int CalmaPathCount;
bool CalmaFlattenUses = FALSE; /* If TRUE, small cells in the input bool CalmaFlattenUses = FALSE; /* If TRUE, small cells in the input
* stream are flattened when encountered * stream are flattened when encountered
* as uses. This improves magic's * as uses. This improves magic's
* performance when handling contacts * performance when handling contacts
* saved as subcell arrays. * saved as subcell arrays.
*/ */
char **CalmaFlattenUsesByName = NULL; /* NULL-terminated list of strings
* to do glob-style pattern matching
* to determine what cells to flatten
* by cellname.
*/
bool CalmaReadOnly = FALSE; /* Set files to read-only and bool CalmaReadOnly = FALSE; /* Set files to read-only and
* retain file position information * retain file position information
* so cells can be written verbatim. * so cells can be written verbatim.
*/ */
float CalmaMagScale = 1.0; /* Scale by which to interpret the MAG
* record in GDS text records. The
* default is to treat the value as
* the text height in microns. This
* value reinterprets the scale.
*/
bool CalmaNoDRCCheck = FALSE; /* If TRUE, don't mark cells as needing bool CalmaNoDRCCheck = FALSE; /* If TRUE, don't mark cells as needing
* a DRC check; they will be assumed * a DRC check; they will be assumed
* DRC clean. * DRC clean.
@ -98,21 +75,9 @@ bool CalmaPostOrder = FALSE; /* If TRUE, forces the GDS parser to
* flatten cells that are contact cuts. * flatten cells that are contact cuts.
* Added by Nishit 8/16/2004 * Added by Nishit 8/16/2004
*/ */
bool CalmaNoDuplicates = FALSE; /* If TRUE, then if a cell exists in extern void calmaUnexpected();
* memory with the same name as a cell
* in the GDS file, then the cell in
* the GDS file is skipped.
*/
bool CalmaUnique = FALSE; /* If TRUE, then if a cell exists in
* memory with the same name as a cell
* in the GDS file, then the cell in
* memory is renamed to a unique
* identifier with a _N suffix.
*/
extern bool CalmaDoLibrary; /* Also used by GDS write */
extern void calmaUnexpected(int wanted, int got); bool calmaParseUnits();
extern int calmaWriteInitFunc(CellDef *def);
/* /*
* Scaling. * Scaling.
@ -147,8 +112,8 @@ HashTable calmaLayerHash;
HashTable calmaDefInitHash; HashTable calmaDefInitHash;
/* Common stuff to ignore */ /* Common stuff to ignore */
const int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 }; int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 };
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -167,24 +132,18 @@ const int calmaElementIgnore[] = { CALMA_ELFLAGS, CALMA_PLEX, -1 };
*/ */
void void
CalmaReadFile( CalmaReadFile(file, filename)
FILETYPE file, /* File from which to read Calma */ FILE *file; /* File from which to read Calma */
char *filename) /* The real name of the file read */ char *filename; /* The real name of the file read */
{ {
int k, version; int k, version;
char *libname = NULL, *libnameptr = NULL; char *libname = NULL;
MagWindow *mw; MagWindow *mw;
static const int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS, static int hdrSkip[] = { CALMA_FORMAT, CALMA_MASK, CALMA_ENDMASKS,
CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE, CALMA_REFLIBS, CALMA_FONTS, CALMA_ATTRTABLE,
CALMA_STYPTABLE, CALMA_GENERATIONS, -1 }; CALMA_STYPTABLE, CALMA_GENERATIONS, -1 };
static const int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME, static int skipBeforeLib[] = { CALMA_LIBDIRSIZE, CALMA_SRFNAME,
CALMA_LIBSECUR, -1 }; CALMA_LIBSECUR, -1 };
if (EditCellUse == (CellUse *)NULL)
{
TxError("Cannot read GDS: There is no edit cell.\n");
return;
}
/* We will use full cell names as keys in this hash table */ /* We will use full cell names as keys in this hash table */
CIFReadCellInit(0); CIFReadCellInit(0);
@ -209,13 +168,6 @@ CalmaReadFile(
calmaTotalErrors = 0; calmaTotalErrors = 0;
CalmaPolygonCount = 0; CalmaPolygonCount = 0;
CalmaPathCount = 0;
/* Reset cd_client pointers (using init function from CalmaWrite.c) */
/* This is in case a cell already in memory is being referenced; */
/* it is probably better to avoid those kinds of naming collisions */
/* though. . . */
(void) DBCellSrDefs(0, calmaWriteInitFunc, (ClientData) NULL);
HashInit(&calmaDefInitHash, 32, 0); HashInit(&calmaDefInitHash, 32, 0);
calmaLApresent = FALSE; calmaLApresent = FALSE;
@ -231,43 +183,15 @@ CalmaReadFile(
if (!calmaSkipExact(CALMA_BGNLIB)) goto done; if (!calmaSkipExact(CALMA_BGNLIB)) goto done;
calmaSkipSet(skipBeforeLib); calmaSkipSet(skipBeforeLib);
if (!calmaReadStringRecord(CALMA_LIBNAME, &libname)) goto done; if (!calmaReadStringRecord(CALMA_LIBNAME, &libname)) goto done;
if ((libname != NULL) && (libname[0] != '\0'))
/* Use CalmaDoLibrary similarly for input as for output; if set to */
/* TRUE, the library name is considered meaningless and discarded; */
/* the GDS file contents are read into memory but no view is loaded */
if (CalmaDoLibrary)
libnameptr = NULL;
else
libnameptr = libname;
if ((libnameptr != NULL) && (libname[0] != '\0'))
{ {
bool modified = FALSE;
char *sptr;
/* Avoid generating a magic name with spaces in it. . . */ /* Avoid generating a magic name with spaces in it. . . */
/* (added by Mike Godfrey, 7/17/05) */ /* (added by Mike Godfrey, 7/17/05) */
for (k = 0; k < strlen(libname); k++) for (k = 0; k < strlen(libname); k++)
if (libname[k] == ' ') if (libname[k] == ' ')
{
libname[k] = '_'; libname[k] = '_';
modified = TRUE; TxPrintf("Library name: %s\n", libname);
}
/* Avoid generating a magic name with slashes in it. . . */
/* (added by Tim, 8/26/2022) */
if ((sptr = strrchr(libname, '/')) != NULL)
{
libnameptr = sptr + 1;
modified = TRUE;
}
if (modified)
TxPrintf("Library name modified to make legal cell name syntax.\n");
TxPrintf("Library name: %s\n", libnameptr);
} }
/* Skip the reflibs, fonts, etc. cruft */ /* Skip the reflibs, fonts, etc. cruft */
@ -292,28 +216,24 @@ done:
/* top-level cell, so magic-produced GDS can be read back */ /* top-level cell, so magic-produced GDS can be read back */
/* with the expected cell appearing in the layout window. */ /* with the expected cell appearing in the layout window. */
if (libnameptr != NULL) if (libname != NULL)
{ {
mw = CmdGetRootPoint((Point *)NULL, (Rect *)NULL); mw = CmdGetRootPoint((Point *)NULL, (Rect *)NULL);
if (mw == NULL) if (mw == NULL)
windCheckOnlyWindow(&mw, DBWclientID); windCheckOnlyWindow(&mw, DBWclientID);
if (mw != NULL) if (mw != NULL)
{ {
if (calmaLookCell(libnameptr) != (CellDef *)NULL) if (calmaLookCell(libname, NULL) != (CellDef *)NULL)
DBWloadWindow(mw, libnameptr, 0); DBWloadWindow(mw, libname, FALSE);
} }
freeMagic(libname); freeMagic(libname);
} }
CIFReadCellCleanup(FILE_CALMA); CIFReadCellCleanup(1);
HashKill(&calmaDefInitHash); HashKill(&calmaDefInitHash);
UndoEnable(); UndoEnable();
if (calmaErrorFile != NULL) if (calmaErrorFile != NULL) fclose(calmaErrorFile);
{
fclose(calmaErrorFile);
calmaErrorFile = NULL;
}
} }
/* /*
@ -347,13 +267,12 @@ done:
*/ */
bool bool
calmaParseUnits(void) calmaParseUnits()
{ {
int nbytes, rtype = 0; int nbytes, rtype;
double metersPerDBUnit; double metersPerDBUnit;
double userUnitsPerDBUnit; double userUnitsPerDBUnit;
double cuPerDBUnit; double cuPerDBUnit;
bool compatible;
READRH(nbytes, rtype); READRH(nbytes, rtype);
#ifdef lint #ifdef lint
@ -372,39 +291,6 @@ calmaParseUnits(void)
/* Read meters per database unit */ /* Read meters per database unit */
if (!calmaReadR8(&metersPerDBUnit)) return (FALSE); if (!calmaReadR8(&metersPerDBUnit)) return (FALSE);
/* Important! When CalmaReadOnly is TRUE, then this file will have its
* contents output verbatim. But if the database units don't match,
* then it will get output at the wrong scale. Setting a magnification
* factor on the instance when generating output might (?) work. For
* now, prohibiting a GDS read in read-only mode when the database units
* don't match. This forces the user either to reconsider the read-only
* status or to rewrite the GDS at a compatible scalefactor.
*/
compatible = TRUE;
if (CalmaReadOnly == TRUE)
{
if (CIFCurStyle->cs_flags & CWF_ANGSTROMS)
{
if ((int)(0.5 + metersPerDBUnit * 1e12) != 100)
{
CalmaReadError("Incompatible scale factor of %g, must be 1e-10.\n",
metersPerDBUnit);
TxError("Cannot read this file in read-only mode.\n");
return FALSE;
}
}
else
{
if ((int)(0.5 + metersPerDBUnit * 1e11) != 100)
{
CalmaReadError("Incompatible scale factor of %g, must be 1e-9.\n",
metersPerDBUnit);
TxError("Cannot read this file in read-only mode.\n");
return FALSE;
}
}
}
#ifdef notdef #ifdef notdef
TxPrintf("1 database unit equals %e user units\n", userUnitsPerDBUnit); TxPrintf("1 database unit equals %e user units\n", userUnitsPerDBUnit);
TxPrintf("1 database unit equals %e meters\n", metersPerDBUnit); TxPrintf("1 database unit equals %e meters\n", metersPerDBUnit);
@ -437,11 +323,11 @@ calmaParseUnits(void)
return (TRUE); return (TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* CalmaReadError -- * calmaReadError --
* *
* This procedure is called to print out error messages during * This procedure is called to print out error messages during
* Calma file reading. * Calma file reading.
@ -459,38 +345,31 @@ calmaParseUnits(void)
*/ */
void void
CalmaReadError(const char *format, ...) /*VARARGS1*/
calmaReadError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
char *format;
char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8, *a9, *a10;
{ {
va_list args;
OFFTYPE filepos;
calmaTotalErrors++; calmaTotalErrors++;
if (CIFWarningLevel == CIF_WARN_NONE) return; if (CIFWarningLevel == CIF_WARN_NONE) return;
if ((calmaTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT)) if ((calmaTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT))
{ {
filepos = FTELL(calmaInputFile);
if (CIFWarningLevel == CIF_WARN_REDIRECT) if (CIFWarningLevel == CIF_WARN_REDIRECT)
{ {
if (calmaErrorFile != NULL) if (calmaErrorFile != NULL)
{ {
fprintf(calmaErrorFile, "Error while reading cell \"%s\" ", fprintf(calmaErrorFile, "Error while reading cell \"%s\": ",
cifReadCellDef->cd_name); cifReadCellDef->cd_name);
fprintf(calmaErrorFile, "(byte position %"DLONG_PREFIX"d): ", fprintf(calmaErrorFile, format, a1, a2, a3, a4, a5, a6, a7,
(dlong)filepos); a8, a9, a10);
va_start(args, format);
Vfprintf(calmaErrorFile, format, args);
va_end(args);
} }
} }
else else
{ {
TxError("Error while reading cell \"%s\" ", cifReadCellDef->cd_name); TxError("Error while reading cell \"%s\": ", cifReadCellDef->cd_name);
TxError("(byte position %"DLONG_PREFIX"d): ", (dlong)filepos); TxError(format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
va_start(args, format);
TxErrorV(format, args);
va_end(args);
} }
} }
else if ((calmaTotalErrors == 100) && (CIFWarningLevel == CIF_WARN_LIMIT)) else if ((calmaTotalErrors == 100) && (CIFWarningLevel == CIF_WARN_LIMIT))
@ -498,7 +377,7 @@ CalmaReadError(const char *format, ...)
TxError("Error limit set: Remaining errors will not be reported.\n"); TxError("Error limit set: Remaining errors will not be reported.\n");
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -516,11 +395,11 @@ CalmaReadError(const char *format, ...)
*/ */
void void
calmaUnexpected( calmaUnexpected(wanted, got)
int wanted, /* Type of record we wanted */ int wanted; /* Type of record we wanted */
int got) /* Type of record we got */ int got; /* Type of record we got */
{ {
CalmaReadError("Unexpected record type in input: \n"); calmaReadError("Unexpected record type in input: \n");
if (CIFWarningLevel == CIF_WARN_NONE) return; if (CIFWarningLevel == CIF_WARN_NONE) return;
if (calmaTotalErrors < 100 || (CIFWarningLevel != CIF_WARN_LIMIT)) if (calmaTotalErrors < 100 || (CIFWarningLevel != CIF_WARN_LIMIT))
@ -541,7 +420,7 @@ calmaUnexpected(
} }
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -558,12 +437,12 @@ calmaUnexpected(
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
const char * char *
calmaRecordName( calmaRecordName(rtype)
int rtype) int rtype;
{ {
static char numeric[10]; static char numeric[10];
static const char * const calmaRecordNames[] = static char *calmaRecordNames[] =
{ {
"HEADER", "BGNLIB", "LIBNAME", "UNITS", "HEADER", "BGNLIB", "LIBNAME", "UNITS",
"ENDLIB", "BGNSTR", "STRNAME", "ENDSTR", "ENDLIB", "BGNSTR", "STRNAME", "ENDSTR",
@ -590,7 +469,7 @@ calmaRecordName(
return (calmaRecordNames[rtype]); return (calmaRecordNames[rtype]);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -608,28 +487,8 @@ calmaRecordName(
*/ */
void void
CalmaTechInit(void) CalmaTechInit()
{ {
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 */
/* when CalmaContactArrays behaves like the non-arrayed */
/* function and can be enabled by default. */
/* Initialize CalmaFlattenByName to have one entry for */
/* "*_CDNS_*" to match the name style used by many foundry */
/* cells and which corresponds to pcells that often split */
/* layers between cells in ways that magic can't cope with; */
/* and whose original parameterized functions cannot be */
/* recovered by magic anyway. When necessary, this default */
/* can be overridden by the "gds flatglob none" command */
/* option. */
if (CalmaFlattenUsesByName == (char **)NULL)
{
CalmaFlattenUsesByName = (char **)mallocMagic(2 * sizeof(char *));
*CalmaFlattenUsesByName = StrDup((char **)NULL, "*_CDNS_*");
*(CalmaFlattenUsesByName + 1) = NULL;
}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

30
calma/Depend Normal file
View File

@ -0,0 +1,30 @@
CalmaRead.o: CalmaRead.c ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/utils.h ../utils/hash.h ../database/database.h \
../database/databaseInt.h ../utils/malloc.h ../utils/tech.h ../cif/cif.h \
../cif/CIFint.h ../cif/CIFread.h ../utils/signals.h ../windows/windows.h \
../dbwind/dbwind.h ../utils/styles.h ../textio/textio.h \
../calma/calmaInt.h ../commands/commands.h ../utils/undo.h
CalmaRdcl.o: CalmaRdcl.c ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/utils.h ../utils/hash.h ../database/database.h \
../database/databaseInt.h ../utils/malloc.h ../utils/tech.h ../cif/cif.h \
../cif/CIFint.h ../cif/CIFread.h ../utils/signals.h ../windows/windows.h \
../dbwind/dbwind.h ../utils/styles.h ../textio/textio.h \
../calma/calmaInt.h ../calma/calma.h
CalmaRdio.o: CalmaRdio.c ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/utils.h ../utils/hash.h ../database/database.h \
../database/databaseInt.h ../utils/malloc.h ../utils/tech.h ../cif/cif.h \
../cif/CIFint.h ../cif/CIFread.h ../utils/signals.h ../windows/windows.h \
../dbwind/dbwind.h ../utils/styles.h ../textio/textio.h \
../calma/calmaInt.h
CalmaRdpt.o: CalmaRdpt.c ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/utils.h ../utils/hash.h ../database/database.h \
../database/databaseInt.h ../utils/malloc.h ../utils/tech.h ../cif/cif.h \
../cif/CIFint.h ../cif/CIFread.h ../utils/signals.h ../windows/windows.h \
../dbwind/dbwind.h ../utils/styles.h ../textio/textio.h \
../calma/calmaInt.h ../calma/calma.h
CalmaWrite.o: CalmaWrite.c ../utils/magic.h ../utils/malloc.h \
../utils/geometry.h ../tiles/tile.h ../utils/utils.h ../utils/hash.h \
../database/database.h ../database/databaseInt.h ../utils/tech.h \
../cif/cif.h ../cif/CIFint.h ../utils/signals.h ../windows/windows.h \
../dbwind/dbwind.h ../utils/styles.h ../textio/textio.h \
../calma/calmaInt.h ../utils/main.h ../utils/stack.h

View File

@ -4,7 +4,7 @@
MODULE = calma MODULE = calma
MAGICDIR = .. MAGICDIR = ..
SRCS = CalmaRead.c CalmaRdcl.c CalmaRdio.c CalmaRdpt.c CalmaWrite.c CalmaWriteZ.c SRCS = CalmaRead.c CalmaRdcl.c CalmaRdio.c CalmaRdpt.c CalmaWrite.c
include ${MAGICDIR}/defs.mak include ${MAGICDIR}/defs.mak
include ${MAGICDIR}/rules.mak include ${MAGICDIR}/rules.mak

View File

@ -19,85 +19,27 @@
* 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"
/* Externally visible variables */ /* Externally visible variables */
extern unsigned char CalmaSubcellPolygons; extern bool CalmaSubcellPolygons;
extern bool CalmaSubcellPaths;
extern bool CalmaDoLabels; extern bool CalmaDoLabels;
extern bool CalmaDoLibrary;
extern bool CalmaDoLower; extern bool CalmaDoLower;
extern bool CalmaAddendum;
extern bool CalmaNoDuplicates;
extern time_t *CalmaDateStamp;
extern bool CalmaUnique;
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 float CalmaMagScale;
extern char **CalmaFlattenUsesByName;
extern bool CalmaReadOnly; extern bool CalmaReadOnly;
extern bool CalmaContactArrays; extern bool CalmaContactArrays;
#ifdef HAVE_ZLIB
extern int CalmaCompression;
#endif
extern bool CalmaPostOrder; extern bool CalmaPostOrder;
extern bool CalmaAllowUndefined;
extern bool CalmaAllowAbstract;
/* Definitions used by the return value for CalmaSubcellPolygons */
/* CALMA_POLYGON_NONE: Process polygons immediately */
/* CALMA_POLYGON_TEMP: Create temporary polygon subcells */
/* CALMA_POLYGON_KEEP: Keep polygons in subcells */
#define CALMA_POLYGON_NONE 0
#define CALMA_POLYGON_TEMP 1
#define CALMA_POLYGON_KEEP 2
/* Externally-visible procedures: */ /* Externally-visible procedures: */
extern bool CalmaWrite(CellDef *rootDef, FILE *f); extern bool CalmaWrite();
extern void CalmaReadFile(FILETYPE file, char *filename); extern void CalmaReadFile();
extern void CalmaTechInit(void); extern void CalmaTechInit();
extern bool CalmaGenerateArray(FILE *f, TileType type, int llx, int lly, int pitch, int cols, int rows); extern bool CalmaGenerateArray();
extern void CalmaReadError(const char *format, ...) ATTR_FORMAT_PRINTF_1;
/* C99 compat */ #endif /* _CALMA_H */
extern void calmaDelContacts(void);
extern void calmaElementBoundary(void);
extern void calmaElementBox(void);
extern void calmaElementPath(void);
extern void calmaElementText(void);
extern bool calmaIsUseNameDefault(char *defName, char *useName);
extern bool calmaParseStructure(char *filename);
extern int calmaProcessDef(CellDef *def, FILE *outf, bool do_library);
#ifdef HAVE_ZLIB
extern int calmaProcessDefZ(CellDef *def, gzFile outf, bool do_library);
#endif
extern bool calmaReadI2Record(int type, int *pvalue);
extern bool calmaReadI4Record(int type, int *pvalue);
extern void calmaReadX(Point *p, int iscale);
extern void calmaReadY(Point *p, int iscale);
extern void calmaReadPoint(Point *p, int iscale);
extern bool calmaReadR8(double *pd);
extern bool calmaReadStampRecord(int type, int *stampptr);
extern bool calmaReadStringRecord(int type, char **str);
extern bool calmaReadStringRecord(int type, char **str);
extern bool calmaReadTransform(Transform *ptrans, char *name);
extern bool calmaSkipBytes(int nbytes);
extern bool calmaSkipExact(int type);
extern bool calmaSkipTo(int what);
extern void calmaUnexpected(int wanted, int got);
#ifdef HAVE_ZLIB
extern bool CalmaWriteZ(CellDef *rootDef, gzFile f);
extern bool CalmaGenerateArrayZ(gzFile f, TileType type, int llx, int lly, int pitch, int cols, int rows);
#endif
#endif /* _MAGIC__CALMA__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"
@ -99,7 +99,6 @@
#define CALMA_NUMRECORDTYPES 60 /* Number of above types */ #define CALMA_NUMRECORDTYPES 60 /* Number of above types */
/* Property types defined for magic */ /* Property types defined for magic */
#define CALMA_PROP_USENAME_STD 61 /* To record non-default cell use ids */
#define CALMA_PROP_USENAME 98 /* To record non-default cell use ids */ #define CALMA_PROP_USENAME 98 /* To record non-default cell use ids */
#define CALMA_PROP_ARRAY_LIMITS 99 /* To record non-default array limits */ #define CALMA_PROP_ARRAY_LIMITS 99 /* To record non-default array limits */
@ -111,7 +110,6 @@
#define CALMAPATH_SQUAREFLUSH 0 /* Square end flush with endpoint */ #define CALMAPATH_SQUAREFLUSH 0 /* Square end flush with endpoint */
#define CALMAPATH_ROUND 1 /* Round end */ #define CALMAPATH_ROUND 1 /* Round end */
#define CALMAPATH_SQUAREPLUS 2 /* Square end plus half-width extent */ #define CALMAPATH_SQUAREPLUS 2 /* Square end plus half-width extent */
#define CALMAPATH_CUSTOM 4 /* Endcaps at specified lengths */
/* Largest calma layer or data type numbers */ /* Largest calma layer or data type numbers */
#define CALMA_LAYER_MAX 255 #define CALMA_LAYER_MAX 255
@ -131,17 +129,10 @@ typedef struct
/* Length of record header */ /* Length of record header */
#define CALMAHEADERLENGTH 4 #define CALMAHEADERLENGTH 4
/* Label types
* The intention is all the values can be stored/converted with unsigned char type,
* C23 allows us to be explicit with the type but C99 does not, so a comment for now.
*/
typedef enum /* : unsigned char */ { LABEL_TYPE_NONE, LABEL_TYPE_TEXT, LABEL_TYPE_PORT, LABEL_TYPE_CELLID } labelType;
/* ------------------------- Input macros ----------------------------- */ /* ------------------------- Input macros ----------------------------- */
/* Globals for Calma reading */ /* Globals for Calma reading */
extern FILETYPE calmaInputFile; extern FILE *calmaInputFile;
extern FILE *calmaInputFileNoCompression;
extern char *calmaFilename; extern char *calmaFilename;
extern int calmaReadScale1; extern int calmaReadScale1;
extern int calmaReadScale2; extern int calmaReadScale2;
@ -172,8 +163,8 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
#define READI2(z) \ #define READI2(z) \
{ \ { \
TwoByteInt u; \ TwoByteInt u; \
u.uc[0] = FGETC(calmaInputFile); \ u.uc[0] = getc(calmaInputFile); \
u.uc[1] = FGETC(calmaInputFile); \ u.uc[1] = getc(calmaInputFile); \
(z) = (int) ntohs(u.us); \ (z) = (int) ntohs(u.us); \
} }
@ -181,10 +172,10 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
#define READI4(z) \ #define READI4(z) \
{ \ { \
FourByteInt u; \ FourByteInt u; \
u.uc[0] = FGETC(calmaInputFile); \ u.uc[0] = getc(calmaInputFile); \
u.uc[1] = FGETC(calmaInputFile); \ u.uc[1] = getc(calmaInputFile); \
u.uc[2] = FGETC(calmaInputFile); \ u.uc[2] = getc(calmaInputFile); \
u.uc[3] = FGETC(calmaInputFile); \ u.uc[3] = getc(calmaInputFile); \
(z) = (int) ntohl(u.ul); \ (z) = (int) ntohl(u.ul); \
} }
@ -197,10 +188,10 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
calmaLApresent = FALSE; \ calmaLApresent = FALSE; \
} else { \ } else { \
READI2(nb); \ READI2(nb); \
if (FEOF(calmaInputFile)) nb = -1; \ if (feof(calmaInputFile)) nb = -1; \
else { \ else { \
(rt) = FGETC(calmaInputFile); \ (rt) = getc(calmaInputFile); \
(void) FGETC(calmaInputFile); \ (void) getc(calmaInputFile); \
} \ } \
} \ } \
} }
@ -219,52 +210,19 @@ typedef union { char uc[4]; unsigned int ul; } FourByteInt;
UNREADRH(nb, rt); \ UNREADRH(nb, rt); \
} }
/* Structure used for sorting ports by number */
typedef struct portlabel
{
Label *pl_label;
unsigned int pl_port;
} PortLabel;
/* Other commonly used globals */ /* Other commonly used globals */
extern HashTable calmaLayerHash; extern HashTable calmaLayerHash;
extern const int calmaElementIgnore[]; extern int calmaElementIgnore[];
extern CellDef *calmaFindCell(const char *name, bool *was_called, bool *predefined); extern CellDef *calmaFindCell();
/* (Added by Nishit, 8/18/2004--8/24/2004) */ /* (Added by Nishit, 8/18/2004--8/24/2004) */
extern CellDef *calmaLookCell(char *name); extern CellDef *calmaLookCell();
extern void calmaWriteContacts(FILE *f); extern void calmaWriteContact();
extern CellDef *calmaGetContactCell(TileType type, bool lookOnly); extern CellDef *calmaGetContactCell();
extern bool calmaIsContactCell; extern bool calmaIsContactCell;
extern const char *calmaRecordName(int rtype); extern char *calmaRecordName();
extern void calmaSkipSet(const int *skipwhat); extern void calmaSkipSet();
extern bool calmaParseUnits(void);
extern int compport(const void *one, const void *two);
#define LB_EXTERNAL 0 /* Polygon external edge */
#define LB_INTERNAL 1 /* Polygon internal edge */
#define LB_INIT 2 /* Data not yet valid */
typedef struct LB1 {
char lb_type; /* Boundary Type (external or internal) */
Point lb_start; /* Start point */
struct LB1 *lb_next; /* Next point record */
} LinkedBoundary;
typedef struct BT1 {
LinkedBoundary *bt_first; /* Polygon list */
int bt_points; /* Number of points in this list */
struct BT1 *bt_next; /* Next polygon record */
} BoundaryTop;
extern int calmaAddSegment(LinkedBoundary **lbptr, bool poly_edge, int p1x, int p1y, int p2x, int p2y);
extern void calmaMergeSegments(LinkedBoundary *edge, BoundaryTop **blist, int num_points);
extern void calmaRemoveDegenerate(BoundaryTop *blist);
extern void calmaRemoveColinear(BoundaryTop *blist);
/* ------------------- Imports from CIF reading ----------------------- */ /* ------------------- Imports from CIF reading ----------------------- */
@ -274,4 +232,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

File diff suppressed because it is too large Load Diff

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"
@ -46,17 +46,11 @@
typedef struct bloat_data typedef struct bloat_data
{ {
int bl_plane; /* Plane on which a bloat or squares int bl_plane; /* Plane on which a bloat or squares
* operation is valid. If -1, then the bloat * operation is valid.
* types are CIF types.
*/ */
int bl_distance[TT_MAXTYPES]; int bl_distance[TT_MAXTYPES];
} BloatData; } BloatData;
typedef struct bridge_data
{
int br_width; /* Minimum width rule for bridge */
} BridgeData;
typedef struct squares_data typedef struct squares_data
{ {
int sq_border; int sq_border;
@ -75,7 +69,6 @@ typedef struct slots_data
int sl_lsize; int sl_lsize;
int sl_lsep; int sl_lsep;
int sl_offset; int sl_offset;
int sl_start;
} SlotsData; } SlotsData;
typedef struct cifop typedef struct cifop
@ -86,9 +79,8 @@ typedef struct cifop
* below for the legal ones. * below for the legal ones.
*/ */
int co_distance; /* Grow or shrink distance (if needed). */ int co_distance; /* Grow or shrink distance (if needed). */
ClientData co_client; /* Pointer to a BloatData, SquaresData, ClientData co_client; /* Pointer to a BloatData, SquaresData, or
* SlotsData, or BridgeData structure, * SlotsData structure, or NULL.
* or NULL.
*/ */
struct cifop *co_next; /* Next in list of operations to perform. */ struct cifop *co_next; /* Next in list of operations to perform. */
} CIFOp; } CIFOp;
@ -103,7 +95,6 @@ typedef struct cifop
* the masks. * the masks.
* CIFOP_GROW - Grow the current results uniformly by co_distance. * CIFOP_GROW - Grow the current results uniformly by co_distance.
* CIFOP_GROW_G - Grow the current results to snap to the indicated grid. * CIFOP_GROW_G - Grow the current results to snap to the indicated grid.
* CIFOP_GROWMIN - Grow result such that no dimension is less than co_distance.
* CIFOP_SHRINK - Shrink the current results uniformly by co_distance. * CIFOP_SHRINK - Shrink the current results uniformly by co_distance.
* CIFOP_BLOAT - Find layers in paintMask, then bloat selectively * CIFOP_BLOAT - Find layers in paintMask, then bloat selectively
* according to bl_distance, and OR the results into * according to bl_distance, and OR the results into
@ -130,56 +121,32 @@ typedef struct cifop
* the cell bounding box. This involves no magic type * the cell bounding box. This involves no magic type
* layers but may itself be acted upon with grow/shrink * layers but may itself be acted upon with grow/shrink
* rules. * rules.
* CIFOP_BOUNDARY - Added 6/5/19---map the FIXED_BBOX property bounding
* box coordinates into CIF layer geometry.
* CIFOP_NET - Added 11/3/08---pull an entire electrical net into * CIFOP_NET - Added 11/3/08---pull an entire electrical net into
* the CIF layer, selectively picking layers. * the CIF layer, selectively picking layers.
* CIFOP_MAXRECT - Reduce all disjoint regions to the largest internal fitting * CIFOP_MAXRECT - Reduce all areas to the largest internal fitting
* rectangle. * rectangle.
* CIFOP_INTERACT - Select all disjoint regions which overlap a given set of types
* CIFOP_COPYUP - Added 5/5/16---make and keep a copy the resulting layer, * CIFOP_COPYUP - Added 5/5/16---make and keep a copy the resulting layer,
* 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_MANHATTAN - Added 3/27/25---remove or fill nonmanhattan areas
* CIFOP_BRIDGE - Added 6/11/20---Bridge across catecorner gaps
* CIFOP_BRIDGELIM - Added 27/07/20---Bridge across catecorner gaps, but with limiting layers
* CIFOP_MASKHINTS - Added 12/14/20---Add geometry from cell properties, if any.
* 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
#define CIFOP_OR 2 #define CIFOP_OR 2
#define CIFOP_GROW 3 #define CIFOP_GROW 3
#define CIFOP_GROWMIN 4 #define CIFOP_GROW_G 4
#define CIFOP_GROW_G 5 #define CIFOP_SHRINK 5
#define CIFOP_SHRINK 6 #define CIFOP_BLOAT 6
#define CIFOP_BLOAT 7 #define CIFOP_SQUARES 7
#define CIFOP_SQUARES 8 #define CIFOP_SLOTS 8
#define CIFOP_SLOTS 9 #define CIFOP_BLOATMAX 9
#define CIFOP_BLOATMAX 10 #define CIFOP_BLOATMIN 10
#define CIFOP_BLOATMIN 11 #define CIFOP_BLOATALL 11
#define CIFOP_BLOATALL 12 #define CIFOP_ANDNOT 12
#define CIFOP_ANDNOT 13 #define CIFOP_SQUARES_G 13
#define CIFOP_SQUARES_G 14 #define CIFOP_BBOX 14
#define CIFOP_BBOX 15 #define CIFOP_NET 15
#define CIFOP_BOUNDARY 16 #define CIFOP_MAXRECT 16
#define CIFOP_NET 17 #define CIFOP_COPYUP 17
#define CIFOP_MAXRECT 18
#define CIFOP_INTERACT 19
#define CIFOP_COPYUP 20
#define CIFOP_CLOSE 21
#define CIFOP_MANHATTAN 22
#define CIFOP_BRIDGE 23
#define CIFOP_BRIDGELIM 24
#define CIFOP_MASKHINTS 25
#define CIFOP_NOTSQUARE 26
#define CIFOP_TAGGED 27
/* Definitions of bit fields used in the value of co_client for CIFOP_INTERACT */
#define CIFOP_INT_NOT 0x1 /* Inverted sense (not interacting) */
#define CIFOP_INT_TOUCHING 0x2 /* Include both touching and overlapping */
/* Added by Tim 10/21/2004 */ /* Added by Tim 10/21/2004 */
/* The following structure is used to pass information on how to draw /* The following structure is used to pass information on how to draw
@ -237,12 +204,12 @@ typedef struct
* *
* CIF_TEMP: Means that this is a temporary layer used to build * CIF_TEMP: Means that this is a temporary layer used to build
* up CIF information. It isn't output in the CIF file. * up CIF information. It isn't output in the CIF file.
* CIF_LABEL: This layer is used to generate fixed labels in the * CIF_BBOX_TOP: Indicates that the bounding box rectangle should
* output file. * only be generated if the cell is a top-level cell.
*/ */
#define CIF_TEMP 1 #define CIF_TEMP 1
#define CIF_LABEL 2 #define CIF_BBOX_TOP 2
/* The following data structure describes a complete set of CIF /* The following data structure describes a complete set of CIF
* layers. The number of CIF layers (MAXCIFLAYERS) must not be * layers. The number of CIF layers (MAXCIFLAYERS) must not be
@ -304,14 +271,6 @@ typedef struct cifstyle
* -1 means no known CIF layer for this Magic * -1 means no known CIF layer for this Magic
* layer. * layer.
*/ */
int cs_portLayer[TT_MAXTYPES];
/* Similar to cs_labelLayer, to use as
* a type for geometry attached to port labels.
*/
int cs_portText[TT_MAXTYPES];
/* Similar to cs_labelLayer, to use as
* a text type for port labels
*/
CIFLayer *cs_layers[MAXCIFLAYERS]; CIFLayer *cs_layers[MAXCIFLAYERS];
/* Describes how to generate each layer.*/ /* Describes how to generate each layer.*/
int cs_flags; /* bitmask of boolean-valued output options */ int cs_flags; /* bitmask of boolean-valued output options */
@ -323,56 +282,32 @@ typedef struct cifstyle
#define CWF_GROW_SLIVERS 0x02 #define CWF_GROW_SLIVERS 0x02
#define CWF_ANGSTROMS 0x04 #define CWF_ANGSTROMS 0x04
#define CWF_GROW_EUCLIDEAN 0x08 #define CWF_GROW_EUCLIDEAN 0x08
#define CWF_SEE_NO_VENDOR 0x10 /* Hide magic's GDS from vendor cells */ #define CWF_SEE_VENDOR 0x10 /* Override vendor GDS flag in cells */
#define CWF_NO_ERRORS 0x20 /* Do not generate error msgs and fdbk */ #define CWF_NO_ERRORS 0x20 /* Do not generate error msgs and fdbk */
#define CWF_STRING_LIMIT 0x40 /* Use older Calma format character limit */
#define CWF_MINIMUM_GRID 0x80 /* Force minimum grid scaling */
/* procedures */ /* procedures */
extern bool CIFNameToMask(char *name, TileTypeBitMask *result, TileTypeBitMask *depend); extern bool CIFNameToMask();
extern void CIFGenSubcells(CellDef *def, Rect *area, Plane **output); extern void CIFGenSubcells();
extern void CIFGenArrays(CellDef *def, Rect *area, Plane **output); extern void CIFGenArrays();
extern void CIFGen(CellDef *cellDef, CellDef *origDef, const Rect *area, Plane **planes, TileTypeBitMask *layers, extern void CIFGen();
bool replace, bool genAllPlanes, bool hier, ClientData clientdata); extern void CIFClearPlanes();
extern void CIFClearPlanes(Plane **planes); extern Plane *CIFGenLayer();
extern Plane *CIFGenLayer(CIFOp *op, const Rect *area, CellDef *cellDef, CellDef *origDef, Plane *temps[], extern void CIFInitCells();
bool hier, ClientData clientdata); extern int cifHierCopyFunc();
extern void CIFInitCells(void); extern void CIFLoadStyle();
extern int cifHierCopyFunc(Tile *tile, TileType dinfo, TreeContext *cxp);
extern void CIFLoadStyle(char *stylename);
extern int CIFCopyMaskHints(SearchContext *scx, CellDef *targetDef);
/* C99 compat */
extern void CIFCoverageLayer(CellDef *rootDef, Rect *area, char *layer, bool dolist);
extern bool CIFWriteFlat(CellDef *rootDef, FILE *f);
extern void CIFScalePlanes(int scalen, int scaled, Plane **planearray);
extern void CIFInputRescale(int n, int d);
extern int CIFScaleCoord(int cifCoord, int snap_type);
extern int cifGrowSliver(Tile *tile, TileType dinfo, Rect *area);
extern int cifHierElementFunc(CellUse *use, Transform *transform, int x, int y, Rect *checkArea);
extern int cifSquareFunc(Rect *area, CIFOp *op, int *rows, int *columns, Rect *cut);
extern int cifSquareGridFunc(Rect *area, CIFOp *op, int *rows, int *columns, Rect *cut);
extern int cifSlotFunc(Rect *area, CIFOp *op, int *numY, int *numX, Rect *cut, bool vertical);
extern int CIFParseScale(char *true_scale, int *expander);
extern int cifParseCalmaNums(char *str, int *numArray, int numNums);
extern bool CIFReadTechLimitScale(int ns, int ds);
/* Shared variables and structures: */ /* Shared variables and structures: */
extern Plane *CIFPlanes[]; /* Normal place to store CIF. */ extern Plane *CIFPlanes[]; /* Normal place to store CIF. */
extern CIFKeep *CIFStyleList; /* List of all CIF styles. */ extern CIFKeep *CIFStyleList; /* List of all CIF styles. */
extern CIFStyle *CIFCurStyle; /* Current style being used. */ extern CIFStyle *CIFCurStyle; /* Current style being used. */
extern CIFStyle *CIFDRCStyle; /* CIF style for DRC checking (optional) */
extern CellUse *CIFComponentUse; /* Flatten stuff in here if needed. */ extern CellUse *CIFComponentUse; /* Flatten stuff in here if needed. */
extern CellDef *CIFComponentDef; /* Corresponds to CIFComponentUse. */ extern CellDef *CIFComponentDef; /* Corresponds to CIFComponentUse. */
extern CellUse *CIFDummyUse; /* Used to dummy up a CellUse for a 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,
@ -387,13 +322,13 @@ extern int CIFHierRects;
/* Tables used for painting and erasing CIF. */ /* Tables used for painting and erasing CIF. */
extern const PaintResultType CIFPaintTable[], CIFEraseTable[]; extern PaintResultType CIFPaintTable[], CIFEraseTable[];
/* Procedures and variables for reporting errors. */ /* Procedures and variables for reporting errors. */
extern int CIFErrorLayer; extern int CIFErrorLayer;
extern CellDef *CIFErrorDef; extern CellDef *CIFErrorDef;
extern void CIFError(Rect *area, char *message); extern void CIFError();
/* The following determines the tile type used to hold the CIF /* The following determines the tile type used to hold the CIF
* information on its paint plane. * information on its paint plane.
@ -402,4 +337,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

@ -17,7 +17,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFmain.c,v 1.3 2009/01/15 15:44:34 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFmain.c,v 1.3 2009/01/15 15:44:34 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -76,7 +76,7 @@ static int cifTotalHierRects = 0;
global CellDef *CIFErrorDef; /* Definition in which to record errors. */ global CellDef *CIFErrorDef; /* Definition in which to record errors. */
global int CIFErrorLayer; /* Index of CIF layer associated with errors.*/ global int CIFErrorLayer; /* Index of CIF layer associated with errors.*/
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -95,7 +95,7 @@ global int CIFErrorLayer; /* Index of CIF layer associated with errors.*/
*/ */
void void
CIFPrintStats(void) CIFPrintStats()
{ {
TxPrintf("CIF statistics (recent/total):\n"); TxPrintf("CIF statistics (recent/total):\n");
cifTotalTileOps += CIFTileOps; cifTotalTileOps += CIFTileOps;
@ -136,8 +136,8 @@ CIFPrintStats(void)
*/ */
float float
CIFGetOutputScale( CIFGetOutputScale(convert)
int convert) int convert;
{ {
if (CIFCurStyle == NULL) return 1.0; if (CIFCurStyle == NULL) return 1.0;
@ -145,28 +145,6 @@ CIFGetOutputScale(
(float)(CIFCurStyle->cs_expander * convert)); (float)(CIFCurStyle->cs_expander * convert));
} }
/*
* ----------------------------------------------------------------------------
*
* CIFGetScale --
*
* Same as the above routine, but provides the scalefactor to get CIF
* units from centimicrons (which generally means just returning the
* expander value to show if units have been declared in nanometers or
* angstroms).
*
* ----------------------------------------------------------------------------
*/
float
CIFGetScale(
int convert)
{
if (CIFCurStyle == NULL) return 1.0;
return (1.0 / (float)(CIFCurStyle->cs_expander * convert));
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -185,10 +163,10 @@ CIFGetScale(
*/ */
void void
CIFPrintStyle( CIFPrintStyle(dolist, doforall, docurrent)
bool dolist, /* Return as a list if true */ bool dolist; /* Return as a list if true */
bool doforall, /* Print all known styles if true */ bool doforall; /* Print all known styles if true */
bool docurrent) /* Print current style if true */ bool docurrent; /* Print current style if true */
{ {
CIFKeep *style; CIFKeep *style;
@ -234,7 +212,7 @@ CIFPrintStyle(
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -254,13 +232,12 @@ CIFPrintStyle(
*/ */
void void
CIFSetStyle( CIFSetStyle(name)
char *name) /* Name of the new style. If NULL, just char *name; /* Name of the new style. If NULL, just
* print out the valid styles. * print out the valid styles.
*/ */
{ {
CIFKeep *style, *match, *exactmatch; CIFKeep *style, *match;
bool ambiguous = FALSE;
int length; int length;
if (name == NULL) return; if (name == NULL) return;
@ -270,25 +247,18 @@ CIFSetStyle(
for (style = CIFStyleList; style != NULL; style = style->cs_next) for (style = CIFStyleList; style != NULL; style = style->cs_next)
{ {
if (!strcmp(name, style->cs_name)) { if (strncmp(name, style->cs_name, length) == 0)
match = style;
ambiguous = FALSE;
break;
}
else if (!strncmp(name, style->cs_name, length))
{ {
if (match != NULL) ambiguous = TRUE; if (match != NULL)
{
TxError("CIF output style \"%s\" is ambiguous.\n", name);
CIFPrintStyle(FALSE, TRUE, TRUE);
return;
}
match = style; match = style;
} }
} }
if (ambiguous)
{
TxError("CIF output style \"%s\" is ambiguous.\n", name);
CIFPrintStyle(FALSE, TRUE, TRUE);
return;
}
if (match != NULL) if (match != NULL)
{ {
CIFLoadStyle(match->cs_name); CIFLoadStyle(match->cs_name);
@ -299,7 +269,7 @@ CIFSetStyle(
TxError("\"%s\" is not one of the CIF output styles Magic knows.\n", name); TxError("\"%s\" is not one of the CIF output styles Magic knows.\n", name);
CIFPrintStyle(FALSE, TRUE, TRUE); CIFPrintStyle(FALSE, TRUE, TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -320,10 +290,10 @@ CIFSetStyle(
*/ */
bool bool
CIFNameToMask( CIFNameToMask(name, result, depend)
char *name, char *name;
TileTypeBitMask *result, TileTypeBitMask *result;
TileTypeBitMask *depend) TileTypeBitMask *depend;
{ {
int i, j; int i, j;
CIFOp *op; CIFOp *op;
@ -357,23 +327,7 @@ CIFNameToMask(
{ {
cl = CIFCurStyle->cs_layers[j]; cl = CIFCurStyle->cs_layers[j];
for (op = cl->cl_ops; op != NULL; op = op->co_next) for (op = cl->cl_ops; op != NULL; op = op->co_next)
{
TTMaskSetMask(depend, &op->co_cifMask); TTMaskSetMask(depend, &op->co_cifMask);
/* Bloat layers may depend on CIF layers */
/* Currently supported only with bloat-all */
if (op->co_opcode == CIFOP_BLOATALL)
{
BloatData *bloats = (BloatData *)op->co_client;
TileType ttype;
if (bloats->bl_plane < 0) /* Use CIF types */
for (ttype = 0; ttype < TT_MAXTYPES; ttype++)
if (bloats->bl_distance[ttype] > 0)
TTMaskSetType(depend, ttype);
}
}
} }
} }
return TRUE; return TRUE;
@ -392,7 +346,7 @@ CIFNameToMask(
TxError(".\n"); TxError(".\n");
return FALSE; return FALSE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -414,11 +368,11 @@ CIFNameToMask(
*/ */
void void
CIFError( CIFError(area, message)
Rect *area, /* Place in CIFErrorDef where there was a Rect *area; /* Place in CIFErrorDef where there was a
* problem in generating CIFErrorLayer. * problem in generating CIFErrorLayer.
*/ */
char *message) /* Short note about what went wrong. */ char *message; /* Short note about what went wrong. */
{ {
char msg[200]; char msg[200];
@ -431,7 +385,7 @@ CIFError(
DBWFeedbackAdd(area, msg, CIFErrorDef, CIFCurStyle->cs_scaleFactor, DBWFeedbackAdd(area, msg, CIFErrorDef, CIFCurStyle->cs_scaleFactor,
STYLE_PALEHIGHLIGHTS); STYLE_PALEHIGHLIGHTS);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -452,7 +406,7 @@ CIFError(
*/ */
int int
CIFOutputScaleFactor(void) CIFOutputScaleFactor()
{ {
if (CIFCurStyle == NULL) return 1; if (CIFCurStyle == NULL) return 1;
return CIFCurStyle->cs_scaleFactor; return CIFCurStyle->cs_scaleFactor;

File diff suppressed because it is too large Load Diff

View File

@ -17,11 +17,10 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpoly.c,v 1.3 2010/06/24 12:37:15 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpoly.c,v 1.3 2010/06/24 12:37:15 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> /* For qsort() */
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/geometry.h" #include "utils/geometry.h"
#include "tiles/tile.h" #include "tiles/tile.h"
@ -29,13 +28,12 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "database/database.h" #include "database/database.h"
#include "cif/CIFint.h" #include "cif/CIFint.h"
#include "cif/CIFread.h" #include "cif/CIFread.h"
#include "calma/calma.h"
#include "utils/malloc.h" #include "utils/malloc.h"
#define HEDGE 0 /* Horizontal edge */ #define HEDGE 0 /* Horizontal edge */
#define REDGE 1 /* Rising edge */ #define REDGE 1 /* Rising edge */
#define FEDGE -1 /* Falling edge */ #define FEDGE -1 /* Falling edge */
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -55,14 +53,10 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
*/ */
int int
cifLowX( cifLowX(a, b)
const void *aa, CIFPath **a, **b;
const void *bb)
{ {
const CIFPath **a = (const CIFPath **)aa; Point *p, *q;
const CIFPath **b = (const CIFPath **)bb;
const Point *p, *q;
p = &(*a)->cifp_point; p = &(*a)->cifp_point;
q = &(*b)->cifp_point; q = &(*b)->cifp_point;
@ -72,7 +66,7 @@ cifLowX(
return (1); return (1);
return (0); return (0);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -92,19 +86,16 @@ cifLowX(
*/ */
int int
cifLowY( cifLowY(a, b)
const void *aa, Point **a, **b;
const void *bb)
{ {
const Point **a = (const Point **)aa;
const Point **b = (const Point **)bb;
if ((*a)->p_y < (*b)->p_y) if ((*a)->p_y < (*b)->p_y)
return (-1); return (-1);
if ((*a)->p_y > (*b)->p_y) if ((*a)->p_y > (*b)->p_y)
return (1); return (1);
return (0); return (0);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -126,10 +117,10 @@ cifLowY(
*/ */
bool bool
cifOrient( cifOrient(edges, nedges, dir)
CIFPath *edges[], /* Array of edges to be categorized. */ CIFPath *edges[]; /* Array of edges to be categorized. */
int nedges, /* Size of arrays. */ int dir[]; /* Array to hold directions. */
int dir[]) /* Array to hold directions. */ int nedges; /* Size of arrays. */
{ {
Point *p, *q; Point *p, *q;
int n; int n;
@ -166,7 +157,7 @@ cifOrient(
} }
return (TRUE); return (TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -186,11 +177,10 @@ cifOrient(
*/ */
bool bool
cifCross( cifCross(edge, dir, ybot, ytop)
CIFPath *edge, /* Pointer to first of 2 path points in edge */ CIFPath *edge; /* Pointer to first of 2 path points in edge */
int dir, /* Direction of edge */ int dir; /* Direction of edge */
int ybot, int ybot, ytop; /* Range of interest */
int ytop) /* Range of interest */
{ {
int ebot, etop; int ebot, etop;
@ -210,7 +200,7 @@ cifCross(
return (FALSE); return (FALSE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -231,12 +221,11 @@ cifCross(
*/ */
LinkedRect * LinkedRect *
CIFPolyToRects( CIFPolyToRects(path, plane, resultTbl, ui)
CIFPath *path, /* Path describing a polygon. */ CIFPath *path; /* Path describing a polygon. */
Plane *plane, /* Plane to draw on */ Plane *plane; /* Plane to draw on */
const PaintResultType *resultTbl, PaintResultType *resultTbl;
PaintUndoInfo *ui, PaintUndoInfo *ui;
bool isCalma) /* TRUE for Calma, FALSE for CIF */
{ {
int npts = 0, n, *dir, curr, wrapno; int npts = 0, n, *dir, curr, wrapno;
int xbot, xtop, ybot, ytop; int xbot, xtop, ybot, ytop;
@ -250,9 +239,6 @@ CIFPolyToRects(
if ((tail->cifp_x != path->cifp_x) || (tail->cifp_y != path->cifp_y)) if ((tail->cifp_x != path->cifp_x) || (tail->cifp_y != path->cifp_y))
{ {
if (isCalma)
CalmaReadError("Boundary is not closed.\n" );
p = (CIFPath *) mallocMagic ((unsigned) sizeof (CIFPath)); p = (CIFPath *) mallocMagic ((unsigned) sizeof (CIFPath));
p->cifp_x = path->cifp_x; p->cifp_x = path->cifp_x;
p->cifp_y = path->cifp_y; p->cifp_y = path->cifp_y;

View File

@ -18,11 +18,10 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpt.c,v 1.2 2010/06/24 12:37:15 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdpt.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <ctype.h> #include <ctype.h>
#include <math.h> /* for wire path-to-poly path conversion */ #include <math.h> /* for wire path-to-poly path conversion */
@ -37,9 +36,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "cif/CIFint.h" #include "cif/CIFint.h"
#include "cif/CIFread.h" #include "cif/CIFread.h"
/* C99 compat */
#include "textio/textio.h"
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -65,7 +62,7 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
*/ */
bool bool
CIFParseBox(void) CIFParseBox()
{ {
Point center; Point center;
Point direction; Point direction;
@ -149,7 +146,7 @@ CIFParseBox(void)
DBPaintPlane(cifReadPlane, &r2, CIFPaintTable, (PaintUndoInfo *) NULL); DBPaintPlane(cifReadPlane, &r2, CIFPaintTable, (PaintUndoInfo *) NULL);
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -176,7 +173,7 @@ CIFParseBox(void)
*/ */
bool bool
CIFParseFlash(void) CIFParseFlash()
{ {
int diameter; int diameter;
int savescale; int savescale;
@ -221,86 +218,6 @@ CIFParseFlash(void)
return TRUE; return TRUE;
} }
/*
* ----------------------------------------------------------------------------
*
* CIFPropRecordPath --
*
* Generate a property in the current edit cell and set it to a string
* containing the values in the list at pathheadp.
*
* If "iswire" is TRUE, then all values in the path are assumed to be
* double the actual value (because path centerlines can be on half-
* lambda).
* ----------------------------------------------------------------------------
*/
void
CIFPropRecordPath(
CellDef *def,
CIFPath *pathheadp,
bool iswire,
char *propname)
{
extern float CIFGetOutputScale(int convert);
CIFPath *pathp;
char *namestr = NULL;
int components, i, x, y, mult, pathnum;
PropertyRecord *proprec;
bool propfound;
/* If "name" is a property, then append a suffix to it to ensure uniqueness */
DBPropGet(def, propname, &propfound);
if (propfound)
{
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;
components = 0;
while (pathp != NULL)
{
components++;
pathp = pathp->cifp_next;
}
/* Allocate enough space to hold 2 * N points. */
proprec = (PropertyRecord *)mallocMagic(sizeof(PropertyRecord) +
((components - 1) * 2) * sizeof(int));
proprec->prop_type = PROPERTY_TYPE_DIMENSION;
proprec->prop_len = components * 2;
pathp = pathheadp;
i = 0;
while (pathp != NULL)
{
x = pathp->cifp_x >> mult;
y = pathp->cifp_y >> mult;
proprec->prop_value.prop_integer[i] = x;
proprec->prop_value.prop_integer[i + 1] = y;
i += 2;
pathp = pathp->cifp_next;
}
if (namestr)
{
DBPropPut(def, namestr, proprec);
freeMagic(namestr);
}
else
DBPropPut(def, propname, proprec);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -337,13 +254,13 @@ CIFPropRecordPath(
*/ */
void void
CIFPaintWirePath( CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
CIFPath *pathheadp, CIFPath *pathheadp;
int width, int width;
bool endcap, bool endcap;
Plane *plane, Plane *plane;
const PaintResultType *ptable, PaintResultType *ptable;
PaintUndoInfo *ui) PaintUndoInfo *ui;
{ {
CIFPath *pathp, *previousp, *nextp, *polypath; CIFPath *pathp, *previousp, *nextp, *polypath;
CIFPath *returnpath, *newpath, *savepath; CIFPath *returnpath, *newpath, *savepath;
@ -359,20 +276,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,8 +377,7 @@ CIFPaintWirePath(
/* Wire reverses direction. Break wire here, */ /* Wire reverses direction. Break wire here, */
/* draw, and start new polygon. */ /* draw, and start new polygon. */
TxError("Warning: direction reversal in path at (%d, %d).\n", TxError("Warning: direction reversal in path.\n");
pathp->cifp_x, pathp->cifp_y);
phi = theta; phi = theta;
if (endcap) if (endcap)
@ -475,8 +389,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;
} }
@ -506,16 +419,14 @@ CIFPaintWirePath(
/* Slow draw for non-Manhattan paths: */ /* Slow draw for non-Manhattan paths: */
/* Break the area up into triangles and rectangles */ /* Break the area up into triangles and rectangles */
rectp = CIFPolyToRects(polypath, plane, ptable, ui, FALSE); rectp = CIFPolyToRects(polypath, plane, ptable, ui);
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
@ -589,13 +500,13 @@ CIFPaintWirePath(
*/ */
LinkedRect * LinkedRect *
PaintPolygon( PaintPolygon(pointlist, number, plane, ptable, ui, keep)
Point *pointlist, /* Array of Point structures */ Point *pointlist; /* Array of Point structures */
int number, /* total number of points */ int number; /* total number of points */
Plane *plane, /* Plane structure to paint into */ Plane *plane; /* Plane structure to paint into */
PaintResultType *ptable, /* Paint result table */ PaintResultType *ptable; /* Paint result table */
PaintUndoInfo *ui, /* Undo record */ PaintUndoInfo *ui; /* Undo record */
bool keep) /* Return list of rects if true */ bool keep; /* Return list of rects if true */
{ {
LinkedRect *rectp, *rectlist; LinkedRect *rectp, *rectlist;
CIFPath *newpath, *cifpath = (CIFPath *)NULL; CIFPath *newpath, *cifpath = (CIFPath *)NULL;
@ -610,16 +521,14 @@ PaintPolygon(
cifpath = newpath; cifpath = newpath;
} }
rectlist = CIFPolyToRects(cifpath, plane, ptable, ui, FALSE); rectlist = CIFPolyToRects(cifpath, plane, ptable, ui);
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;
} }
@ -646,14 +555,14 @@ PaintPolygon(
*/ */
void void
PaintWireList( PaintWireList(pointlist, number, width, endcap, plane, ptable, ui)
Point *pointlist, /* Array of Point structures */ Point *pointlist; /* Array of Point structures */
int number, /* total number of points */ int number; /* total number of points */
int width, /* Route width of path */ int width; /* Route width of path */
bool endcap, /* Whether or not to add 1/2 width endcaps */ bool endcap; /* Whether or not to add 1/2 width endcaps */
Plane *plane, /* Plane structure to paint into */ Plane *plane; /* Plane structure to paint into */
PaintResultType *ptable, /* Paint result table */ PaintResultType *ptable; /* Paint result table */
PaintUndoInfo *ui) /* Undo record */ PaintUndoInfo *ui; /* Undo record */
{ {
CIFPath *newpath, *cifpath = (CIFPath *)NULL; CIFPath *newpath, *cifpath = (CIFPath *)NULL;
int i; int i;
@ -669,7 +578,7 @@ PaintWireList(
CIFPaintWirePath(cifpath, width, endcap, plane, ptable, ui); CIFPaintWirePath(cifpath, width, endcap, plane, ptable, ui);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -690,7 +599,7 @@ PaintWireList(
*/ */
bool bool
CIFParseWire(void) CIFParseWire()
{ {
int width; int width;
CIFPath *pathheadp, *polypath; CIFPath *pathheadp, *polypath;
@ -716,8 +625,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();
@ -731,7 +639,7 @@ CIFParseWire(void)
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -751,7 +659,7 @@ CIFParseWire(void)
*/ */
bool bool
CIFParseLayer(void) CIFParseLayer()
{ {
#define MAXCHARS 4 #define MAXCHARS 4
char name[MAXCHARS+1]; char name[MAXCHARS+1];
@ -794,7 +702,7 @@ CIFParseLayer(void)
CIFSkipToSemi(); CIFSkipToSemi();
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -814,7 +722,7 @@ CIFParseLayer(void)
*/ */
bool bool
CIFParsePoly(void) CIFParsePoly()
{ {
CIFPath *pathheadp; CIFPath *pathheadp;
LinkedRect *rectp; LinkedRect *rectp;
@ -827,8 +735,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();
@ -838,7 +745,7 @@ CIFParsePoly(void)
/* Convert the polygon to rectangles. */ /* Convert the polygon to rectangles. */
rectp = CIFPolyToRects(pathheadp, cifReadPlane, CIFPaintTable, rectp = CIFPolyToRects(pathheadp, cifReadPlane, CIFPaintTable,
(PaintUndoInfo *)NULL, FALSE); (PaintUndoInfo *)NULL);
CIFFreePath(pathheadp); CIFFreePath(pathheadp);
if (rectp == NULL) if (rectp == NULL)
{ {
@ -848,13 +755,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

@ -18,7 +18,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdtech.c,v 1.4 2010/09/15 15:45:30 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdtech.c,v 1.4 2010/09/15 15:45:30 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -40,9 +40,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "calma/calmaInt.h" #include "calma/calmaInt.h"
#include "utils/malloc.h" #include "utils/malloc.h"
/* C99 compat */
#include "cif/cif.h"
/* Pointer to a list of all the CIF-reading styles: */ /* Pointer to a list of all the CIF-reading styles: */
CIFReadKeep *cifReadStyleList = NULL; CIFReadKeep *cifReadStyleList = NULL;
@ -62,8 +59,8 @@ CIFReadLayer *cifCurReadLayer; /* Current layer being processed. */
CIFOp *cifCurReadOp; /* Last geometric operation seen. */ CIFOp *cifCurReadOp; /* Last geometric operation seen. */
/* Forward declarations */ /* Forward declarations */
void cifReadStyleInit(void); void cifReadStyleInit();
void CIFReadLoadStyle(char *stylename); void CIFReadLoadStyle();
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -90,9 +87,8 @@ void CIFReadLoadStyle(char *stylename);
*/ */
bool bool
CIFReadTechLimitScale( CIFReadTechLimitScale(ns, ds)
int ns, int ns, ds;
int ds)
{ {
int gridup, scaledown; int gridup, scaledown;
int scale, limit, mult; int scale, limit, mult;
@ -132,9 +128,9 @@ CIFReadTechLimitScale(
*/ */
int int
CIFReadNameToType( CIFReadNameToType(name, newOK)
char *name, /* Name of a CIF layer. */ char *name; /* Name of a CIF layer. */
bool newOK) /* TRUE means OK to create a new layer if this bool newOK; /* TRUE means OK to create a new layer if this
* name is one we haven't seen before. * name is one we haven't seen before.
*/ */
{ {
@ -177,7 +173,7 @@ CIFReadNameToType(
cifNReadLayers += 1; cifNReadLayers += 1;
return cifNReadLayers-1; return cifNReadLayers-1;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -197,40 +193,40 @@ CIFReadNameToType(
*/ */
int int
CIFCalmaLayerToCifLayer( CIFCalmaLayerToCifLayer(layer, datatype, calmaStyle)
int layer, /* Calma layer number */ int layer; /* Calma layer number */
int datatype, /* Calma datatype */ int datatype; /* Calma datatype */
CIFReadStyle *calmaStyle) CIFReadStyle *calmaStyle;
{ {
CalmaLayerType clt; CalmaLayerType clt;
HashEntry *he; HashEntry *he;
clt.clt_layer = layer; clt.clt_layer = layer;
clt.clt_type = datatype; clt.clt_type = datatype;
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))) if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
return ((spointertype) HashGetValue(he)); return ((spointertype) HashGetValue(he));
/* Try wildcarding the datatype */ /* Try wildcarding the datatype */
clt.clt_type = -1; clt.clt_type = -1;
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))) if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
return ((spointertype) HashGetValue(he)); return ((spointertype) HashGetValue(he));
/* Try wildcarding the layer */ /* Try wildcarding the layer */
clt.clt_layer = -1; clt.clt_layer = -1;
clt.clt_type = datatype; clt.clt_type = datatype;
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))) if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
return ((spointertype) HashGetValue(he)); return ((spointertype) HashGetValue(he));
/* Try wildcarding them both, for a default value */ /* Try wildcarding them both, for a default value */
clt.clt_layer = -1; clt.clt_layer = -1;
clt.clt_type = -1; clt.clt_type = -1;
if ((he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))) if (he = HashLookOnly(&(calmaStyle->cifCalmaToCif), (char *) &clt))
return ((spointertype) HashGetValue(he)); return ((spointertype) HashGetValue(he));
/* No luck */ /* No luck */
return (-1); return (-1);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -252,10 +248,9 @@ CIFCalmaLayerToCifLayer(
*/ */
void void
CIFParseReadLayers( CIFParseReadLayers(string, mask)
char *string, /* Comma-separated list of CIF layers. */ char *string; /* Comma-separated list of CIF layers. */
TileTypeBitMask *mask, /* Where to store bit mask. */ TileTypeBitMask *mask; /* Where to store bit mask. */
bool newok) /* If TRUE, create new layers if they don't exist */
{ {
int i; int i;
char *p; char *p;
@ -270,10 +265,10 @@ CIFParseReadLayers(
if (p != NULL) if (p != NULL)
*p = 0; *p = 0;
i = CIFReadNameToType(string, newok); i = CIFReadNameToType(string, TRUE);
if (i >= 0) if (i >= 0)
TTMaskSetType(mask, i); TTMaskSetType(mask, i);
else if (newok) else
{ {
HashEntry *he; HashEntry *he;
TileTypeBitMask *amask; TileTypeBitMask *amask;
@ -285,15 +280,13 @@ CIFParseReadLayers(
TTMaskSetMask(mask, amask); TTMaskSetMask(mask, amask);
} }
} }
else
TxError("Error: CIF layer \"%s\" is unknown.\n", string);
if (p == NULL) break; if (p == NULL) break;
*p = ','; *p = ',';
for (string = p; *string == ','; string += 1) /* do nothing */; for (string = p; *string == ','; string += 1) /* do nothing */;
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -314,7 +307,7 @@ CIFParseReadLayers(
*/ */
void void
cifNewReadStyle(void) cifNewReadStyle()
{ {
int i; int i;
CIFOp *op; CIFOp *op;
@ -324,20 +317,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);
} }
} }
@ -361,7 +347,7 @@ cifNewReadStyle(void)
*/ */
void void
cifReadStyleInit(void) cifReadStyleInit()
{ {
int i; int i;
@ -379,11 +365,11 @@ cifReadStyleInit(void)
for (i = 0; i < MAXCIFRLAYERS; i++) for (i = 0; i < MAXCIFRLAYERS; i++)
{ {
cifCurReadStyle->crs_labelLayer[i] = TT_SPACE; cifCurReadStyle->crs_labelLayer[i] = TT_SPACE;
cifCurReadStyle->crs_labelSticky[i] = LABEL_TYPE_NONE; cifCurReadStyle->crs_labelSticky[i] = FALSE;
cifCurReadStyle->crs_layers[i] = NULL; cifCurReadStyle->crs_layers[i] = NULL;
} }
} }
/* /*
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
@ -403,7 +389,7 @@ cifReadStyleInit(void)
*/ */
void void
CIFReadTechInit(void) CIFReadTechInit()
{ {
CIFReadKeep *style; CIFReadKeep *style;
@ -415,13 +401,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;
} }
@ -443,14 +427,14 @@ CIFReadTechInit(void)
*/ */
void void
CIFReadTechStyleInit(void) CIFReadTechStyleInit()
{ {
cifNReadLayers = 0; cifNReadLayers = 0;
cifCurReadLayer = NULL; cifCurReadLayer = NULL;
cifCurReadOp = NULL; cifCurReadOp = NULL;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -470,10 +454,10 @@ CIFReadTechStyleInit(void)
*/ */
/* ARGSUSED */ /* ARGSUSED */
bool bool
CIFReadTechLine( CIFReadTechLine(sectionName, argc, argv)
char *sectionName, /* Name of this section ("cifinput"). */ char *sectionName; /* Name of this section ("cifinput"). */
int argc, /* Number of fields on line. */ int argc; /* Number of fields on line. */
char *argv[]) /* Values of fields. */ char *argv[]; /* Values of fields. */
{ {
CIFOp *newOp = NULL; CIFOp *newOp = NULL;
CIFReadKeep *newStyle, *p; CIFReadKeep *newStyle, *p;
@ -481,7 +465,6 @@ CIFReadTechLine(
CalmaLayerType clt; CalmaLayerType clt;
int calmaLayers[CALMA_LAYER_MAX], calmaTypes[CALMA_LAYER_MAX]; int calmaLayers[CALMA_LAYER_MAX], calmaTypes[CALMA_LAYER_MAX];
int nCalmaLayers, nCalmaTypes, l, t, j; int nCalmaLayers, nCalmaTypes, l, t, j;
int calmaLabelType = LABEL_TYPE_NONE;
if (argc <= 0) return TRUE; if (argc <= 0) return TRUE;
else if (argc >= 2) l = strlen(argv[1]); else if (argc >= 2) l = strlen(argv[1]);
@ -637,10 +620,8 @@ CIFReadTechLine(
if (argc >= 3) if (argc >= 3)
{ {
if (!strncmp(argv[argc - 1], "nanom", 5)) if(!strncmp(argv[argc - 1], "nanom", 5))
cifCurReadStyle->crs_multiplier = 10; cifCurReadStyle->crs_multiplier = 10;
else if (!strncmp(argv[argc - 1], "angstr", 6))
cifCurReadStyle->crs_multiplier = 100;
} }
if (cifCurReadStyle->crs_scaleFactor <= 0) if (cifCurReadStyle->crs_scaleFactor <= 0)
@ -759,7 +740,7 @@ CIFReadTechLine(
cifCurReadOp = (CIFOp *) mallocMagic(sizeof(CIFOp)); cifCurReadOp = (CIFOp *) mallocMagic(sizeof(CIFOp));
cifCurReadOp->co_opcode = CIFOP_OR; cifCurReadOp->co_opcode = CIFOP_OR;
cifCurReadOp->co_client = (ClientData)NULL; cifCurReadOp->co_client = (ClientData)NULL;
CIFParseReadLayers(argv[2], &cifCurReadOp->co_cifMask, TRUE); CIFParseReadLayers(argv[2], &cifCurReadOp->co_cifMask);
TTMaskZero(&cifCurReadOp->co_paintMask); TTMaskZero(&cifCurReadOp->co_paintMask);
cifCurReadOp->co_next = NULL; cifCurReadOp->co_next = NULL;
cifCurReadOp->co_distance = 0; cifCurReadOp->co_distance = 0;
@ -809,7 +790,7 @@ CIFReadTechLine(
cifCurReadOp = (CIFOp *) mallocMagic(sizeof(CIFOp)); cifCurReadOp = (CIFOp *) mallocMagic(sizeof(CIFOp));
cifCurReadOp->co_opcode = CIFOP_OR; cifCurReadOp->co_opcode = CIFOP_OR;
cifCurReadOp->co_client = (ClientData)NULL; cifCurReadOp->co_client = (ClientData)NULL;
CIFParseReadLayers(argv[2], &cifCurReadOp->co_cifMask, TRUE); CIFParseReadLayers(argv[2], &cifCurReadOp->co_cifMask);
TTMaskZero(&cifCurReadOp->co_paintMask); TTMaskZero(&cifCurReadOp->co_paintMask);
cifCurReadOp->co_next = NULL; cifCurReadOp->co_next = NULL;
cifCurReadOp->co_distance = 0; cifCurReadOp->co_distance = 0;
@ -867,52 +848,21 @@ CIFReadTechLine(
{ {
if (argc == 3) if (argc == 3)
{ {
if (!strcmp(argv[2], "text")) if (strcmp(argv[2], "text"))
calmaLabelType = LABEL_TYPE_TEXT;
else if (!strcmp(argv[2], "sticky"))
calmaLabelType = LABEL_TYPE_TEXT;
else if (!strcmp(argv[2], "port"))
calmaLabelType = LABEL_TYPE_PORT;
else if (!strncmp(argv[2], "cell", 4))
calmaLabelType = LABEL_TYPE_CELLID;
else
goto wrongNumArgs; goto wrongNumArgs;
} }
else else
goto wrongNumArgs; goto wrongNumArgs;
} }
CIFParseReadLayers(argv[1], &mask, TRUE); CIFParseReadLayers(argv[1], &mask);
for (i = 0; i < MAXCIFRLAYERS; i++) for (i=0; i<MAXCIFRLAYERS; i+=1)
{ {
if (TTMaskHasType(&mask, i)) if (TTMaskHasType(&mask,i))
{ {
/* Only one magic type can be assigned to a GDS layer, so
* multiple assignments should be flagged as errors. BUT,
* this is a common historic error. Since reattachments
* should be handled rationally (by code added 10/17/2023
* to DBlabel.c), there is no urgent need to flag an issue
* unless the new layer does not exist on the same plane
* as the old one.
*/
if (cifCurReadStyle->crs_labelLayer[i] != TT_SPACE)
{
int p1, p2;
p1 = DBPlane(cifCurReadLayer->crl_magicType);
p2 = DBPlane(cifCurReadStyle->crs_labelLayer[i]);
if (!DBTypeOnPlane(cifCurReadLayer->crl_magicType, p2) &&
!DBTypeOnPlane(cifCurReadStyle->crs_labelLayer[i], p1))
TechError("Labels on layer \"%s\" attached to \"%s\" "
"supersedes prior attachment to \"%s\".\n",
cifReadLayers[i],
DBTypeLongNameTbl[cifCurReadLayer->crl_magicType],
DBTypeLongNameTbl[cifCurReadStyle->crs_labelLayer[i]]);
}
cifCurReadStyle->crs_labelLayer[i] cifCurReadStyle->crs_labelLayer[i]
= cifCurReadLayer->crl_magicType; = cifCurReadLayer->crl_magicType;
if (argc == 3) if (argc == 3)
cifCurReadStyle->crs_labelSticky[i] = calmaLabelType; cifCurReadStyle->crs_labelSticky[i] = TRUE;
} }
} }
return TRUE; return TRUE;
@ -930,10 +880,10 @@ CIFReadTechLine(
int i; int i;
if (argc != 2) goto wrongNumArgs; if (argc != 2) goto wrongNumArgs;
CIFParseReadLayers(argv[1], &mask, TRUE); CIFParseReadLayers(argv[1], &mask);
/* trash the value in crs_labelLayer so that any labels on this /* trash the value in crs_labelLayer so that any labels on this
* layer get junked, also. dcs 4/11/90 layer get junked, also. dcs 4/11/90
*/ */
for (i=0; i < cifNReadLayers; i++) for (i=0; i < cifNReadLayers; i++)
{ {
if (TTMaskHasType(&mask,i)) if (TTMaskHasType(&mask,i))
@ -949,15 +899,14 @@ CIFReadTechLine(
/* miscellaneous cif-reading boolean options */ /* miscellaneous cif-reading boolean options */
if (strcmp(argv[0], "options") == 0) { if(strcmp(argv[0], "options") == 0) {
int i; int i;
if (argc < 2) goto wrongNumArgs; if (argc < 2) goto wrongNumArgs;
for (i = 1; i < argc; i++) { for(i = 1; i < argc; i++) {
if (strcmp(argv[i], "ignore-unknown-layer-labels") == 0) if(strcmp(argv[i], "ignore-unknown-layer-labels") == 0)
cifCurReadStyle->crs_flags |= CRF_IGNORE_UNKNOWNLAYER_LABELS; cifCurReadStyle->crs_flags |= CRF_IGNORE_UNKNOWNLAYER_LABELS;
/* Allow "no-reconnect-labels", although it has been deprecated */ if(strcmp(argv[i], "no-reconnect-labels") == 0)
else if (strcmp(argv[i], "no-reconnect-labels") != 0) cifCurReadStyle->crs_flags |= CRF_NO_RECONNECT_LABELS;
TechError("Unknown cifinput option \"%s\".\n", argv[i]);
} }
return TRUE; return TRUE;
} }
@ -993,14 +942,6 @@ CIFReadTechLine(
newOp->co_opcode = CIFOP_SHRINK; newOp->co_opcode = CIFOP_SHRINK;
else if (strcmp(argv[0], "copyup") == 0) else if (strcmp(argv[0], "copyup") == 0)
newOp->co_opcode = CIFOP_COPYUP; newOp->co_opcode = CIFOP_COPYUP;
else if (strcmp(argv[0], "boundary") == 0)
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]);
@ -1014,8 +955,9 @@ CIFReadTechLine(
case CIFOP_OR: case CIFOP_OR:
case CIFOP_COPYUP: case CIFOP_COPYUP:
if (argc != 2) goto wrongNumArgs; if (argc != 2) goto wrongNumArgs;
CIFParseReadLayers(argv[1], &newOp->co_cifMask, TRUE); CIFParseReadLayers(argv[1], &newOp->co_cifMask);
break; break;
case CIFOP_GROW: case CIFOP_GROW:
case CIFOP_GROW_G: case CIFOP_GROW_G:
case CIFOP_SHRINK: case CIFOP_SHRINK:
@ -1027,15 +969,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 != 3) goto wrongNumArgs;
newOp->co_client = (ClientData)StrDup((char **)NULL, argv[1]);
CIFParseReadLayers(argv[2], &newOp->co_cifMask, TRUE);
break;
} }
/* Link the new CIFOp onto the list. */ /* Link the new CIFOp onto the list. */
@ -1056,7 +989,7 @@ CIFReadTechLine(
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1076,7 +1009,7 @@ CIFReadTechLine(
*/ */
void void
CIFReadTechFinal(void) CIFReadTechFinal()
{ {
/* Reduce the scale by the multiplier, as much as possible while */ /* Reduce the scale by the multiplier, as much as possible while */
/* keeping all CIF input ops in integer units. */ /* keeping all CIF input ops in integer units. */
@ -1119,10 +1052,9 @@ CIFReadTechFinal(void)
* *
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
void void
CIFReadLoadStyle( CIFReadLoadStyle(stylename)
char *stylename) char *stylename;
{ {
SectionID invcifr; SectionID invcifr;
@ -1138,68 +1070,6 @@ CIFReadLoadStyle(
CIFTechInputScale(DBLambda[0], DBLambda[1], TRUE); CIFTechInputScale(DBLambda[0], DBLambda[1], TRUE);
} }
/*
* ----------------------------------------------------------------------------
*
* CIFReadGetGrowSize --
*
* Parse the rules for the given CIF/GDS layer "type" and return the
* amount that it needs to be grown to create the magic contact layer
* type. This assumes that the input manipulations are straightforward.
* It is expected that any "and" or "and-not" operations are to separate
* the via type from other via types, and that the amount to grow is the
* sum of all grow and shrink operations.
*
* Note that the routine works to determine simple grow rules for any
* layer but is specifically designed to determine how to convert cut
* layers from a LEF file into magic contact types.
*
* Results:
* Grow length, in magic units
*
* Side effects:
* None
*
* ----------------------------------------------------------------------------
*/
int
CIFReadGetGrowSize(
TileType type)
{
CIFReadStyle *istyle = cifCurReadStyle;
CIFOp *op;
int i, dist = 0;
if (istyle == NULL) return 0;
for (i = 0; i < istyle->crs_nLayers; i++)
{
/* Don't confuse CIF types with magic types! */
if (istyle->crs_layers[i]->crl_flags & CIFR_TEMPLAYER) continue;
if (istyle->crs_layers[i]->crl_magicType == type)
{
dist = 0;
for (op = istyle->crs_layers[i]->crl_ops; op != NULL;
op = op->co_next)
{
if (op->co_opcode == CIFOP_GROW ||
op->co_opcode == CIFOP_GROW_G)
{
dist += op->co_distance;
}
if (op->co_opcode == CIFOP_SHRINK)
{
dist -= op->co_distance;
}
}
if (dist > 0) break;
}
}
return dist;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1219,8 +1089,8 @@ CIFReadGetGrowSize(
*/ */
float float
CIFGetInputScale( CIFGetInputScale(convert)
int convert) int convert;
{ {
/* Avoid divide-by-0 error if there is no cif input style */ /* Avoid divide-by-0 error if there is no cif input style */
/* in the tech file. */ /* in the tech file. */
@ -1252,10 +1122,10 @@ CIFGetInputScale(
*/ */
void void
CIFPrintReadStyle( CIFPrintReadStyle(dolist, doforall, docurrent)
bool dolist, /* Return as a list if true */ bool dolist; /* Return as a list if true */
bool doforall, /* Return list of all styles if true */ bool doforall; /* Return list of all styles if true */
bool docurrent) /* Return current style if true */ bool docurrent; /* Return current style if true */
{ {
CIFReadKeep *style; CIFReadKeep *style;
@ -1302,7 +1172,7 @@ CIFPrintReadStyle(
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1323,8 +1193,8 @@ CIFPrintReadStyle(
*/ */
void void
CIFSetReadStyle( CIFSetReadStyle(name)
char *name) /* Name of the new style. If NULL, char *name; /* Name of the new style. If NULL,
* just print the name of the current * just print the name of the current
* style. * style.
*/ */
@ -1360,7 +1230,7 @@ CIFSetReadStyle(
TxError("\"%s\" is not one of the CIF input styles Magic knows.\n", name); TxError("\"%s\" is not one of the CIF input styles Magic knows.\n", name);
CIFPrintReadStyle(FALSE, TRUE, TRUE); CIFPrintReadStyle(FALSE, TRUE, TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1384,10 +1254,10 @@ CIFSetReadStyle(
*/ */
int int
cifParseCalmaNums( cifParseCalmaNums(str, numArray, numNums)
char *str, /* String to parse */ char *str; /* String to parse */
int *numArray, /* Array to fill in */ int *numArray; /* Array to fill in */
int numNums) /* Maximum number of entries in numArray */ int numNums; /* Maximum number of entries in numArray */
{ {
int numFilled, num; int numFilled, num;
@ -1447,10 +1317,9 @@ cifParseCalmaNums(
*/ */
int int
CIFTechInputScale( CIFTechInputScale(n, d, opt)
int n, int n, d;
int d, bool opt;
bool opt)
{ {
CIFReadStyle *istyle = cifCurReadStyle; CIFReadStyle *istyle = cifCurReadStyle;
CIFReadLayer *cl; CIFReadLayer *cl;

View File

@ -19,7 +19,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdutils.c,v 1.4 2010/06/24 12:37:15 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFrdutils.c,v 1.4 2010/06/24 12:37:15 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -27,12 +27,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include <stdarg.h> #include <stdarg.h>
#include <ctype.h> #include <ctype.h>
/*
* C99 compat
* Mind: tcltk/tclmagic.h must be included prior to all the other headers
*/
#include "tcltk/tclmagic.h"
#include "utils/magic.h" #include "utils/magic.h"
#include "utils/geometry.h" #include "utils/geometry.h"
#include "tiles/tile.h" #include "tiles/tile.h"
@ -46,16 +40,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "utils/undo.h" #include "utils/undo.h"
#include "utils/malloc.h" #include "utils/malloc.h"
/* C99 compat */
#include "lef/lef.h"
#include "drc/drc.h"
#include "extract/extract.h"
#include "wiring/wiring.h"
#include "router/router.h"
#include "mzrouter/mzrouter.h"
#include "irouter/irouter.h"
#include "plow/plow.h"
/* The following variables are used to provide one character of /* The following variables are used to provide one character of
* lookahead. cifParseLaAvail is TRUE if cifParseLaChar contains * lookahead. cifParseLaAvail is TRUE if cifParseLaChar contains
* a valid character, FALSE otherwise. The PEEK and TAKE macros * a valid character, FALSE otherwise. The PEEK and TAKE macros
@ -76,7 +60,6 @@ FILE *cifErrorFile;
int cifLineNumber; /* Number of current line. */ int cifLineNumber; /* Number of current line. */
int cifTotalWarnings; /* Number of warnings detected */ int cifTotalWarnings; /* Number of warnings detected */
int cifTotalErrors; /* Number of errors detected */ int cifTotalErrors; /* Number of errors detected */
bool cifSeenSnapWarning; /* Track this to prevent excessive messaging */
/* The variables used below hold general information about what /* The variables used below hold general information about what
* we're currently working on. * we're currently working on.
@ -109,7 +92,7 @@ Plane *cifReadPlane; /* Plane into which to paint material
* NULL means no layer command has * NULL means no layer command has
* been seen for the current cell. * been seen for the current cell.
*/ */
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -129,7 +112,7 @@ Plane *cifReadPlane; /* Plane into which to paint material
/* VARARGS1 */ /* VARARGS1 */
void void
CIFReadError(const char *format, ...) CIFReadError(char *format, ...)
{ {
va_list args; va_list args;
@ -137,10 +120,7 @@ CIFReadError(const char *format, ...)
if (CIFWarningLevel == CIF_WARN_NONE) return; if (CIFWarningLevel == CIF_WARN_NONE) return;
if ((cifTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT)) if ((cifTotalErrors < 100) || (CIFWarningLevel != CIF_WARN_LIMIT))
{ {
if (cifLineNumber > 0) TxError("Error at line %d of CIF file: ", cifLineNumber);
TxError("Error at line %d of CIF file: ", cifLineNumber);
else
TxError("CIF file read error: ");
va_start(args, format); va_start(args, format);
Vfprintf(stderr, format, args); Vfprintf(stderr, format, args);
va_end(args); va_end(args);
@ -150,10 +130,10 @@ CIFReadError(const char *format, ...)
TxError("Error limit set: Remaining errors will not be reported.\n"); TxError("Error limit set: Remaining errors will not be reported.\n");
} }
} }
void void
CIFReadWarning(const char *format, ...) CIFReadWarning(char *format, ...)
{ {
va_list args; va_list args;
@ -161,10 +141,7 @@ CIFReadWarning(const char *format, ...)
if (CIFWarningLevel == CIF_WARN_NONE) return; if (CIFWarningLevel == CIF_WARN_NONE) return;
if ((cifTotalWarnings < 100) || (CIFWarningLevel != CIF_WARN_LIMIT)) if ((cifTotalWarnings < 100) || (CIFWarningLevel != CIF_WARN_LIMIT))
{ {
if (cifLineNumber > 0) TxError("Warning at line %d of CIF file: ", cifLineNumber);
TxError("Warning at line %d of CIF file: ", cifLineNumber);
else
TxError("CIF file read warning: ");
va_start(args, format); va_start(args, format);
Vfprintf(stderr, format, args); Vfprintf(stderr, format, args);
va_end(args); va_end(args);
@ -205,9 +182,9 @@ CIFReadWarning(const char *format, ...)
*/ */
int int
CIFScaleCoord( CIFScaleCoord(cifCoord, snap_type)
int cifCoord, /* A coordinate in CIF units. */ int cifCoord; /* A coordinate in CIF units. */
int snap_type) /* How to deal with fractional results */ int snap_type; /* How to deal with fractional results */
{ {
int result, scale, remain, denom; int result, scale, remain, denom;
int mult, mfactor; int mult, mfactor;
@ -235,14 +212,13 @@ CIFScaleCoord(
switch (snap_type) switch (snap_type)
{ {
case COORD_EXACT: case COORD_EXACT:
if (!cifSeenSnapWarning) CIFReadWarning("Input off lambda grid by %d/%d; grid redefined.\n",
CIFReadWarning("Input off lambda grid by %d/%d; grid redefined.\n",
remain, denom); remain, denom);
cifSeenSnapWarning = TRUE;
CIFTechInputScale(1, denom, FALSE); CIFTechInputScale(1, denom, FALSE);
CIFTechOutputScale(1, denom); CIFTechOutputScale(1, denom);
DRCTechScale(1, denom); DRCTechScale(1, denom);
PlowAfterTech();
ExtTechScale(1, denom); ExtTechScale(1, denom);
WireTechScale(1, denom); WireTechScale(1, denom);
#ifdef LEF_MODULE #ifdef LEF_MODULE
@ -262,10 +238,8 @@ CIFScaleCoord(
case COORD_HALF_U: case COORD_HALF_L: case COORD_HALF_U: case COORD_HALF_L:
if (denom > 2) if (denom > 2)
{ {
if (!cifSeenSnapWarning) CIFReadWarning("Input off lambda grid by %d/%d; grid redefined.\n",
CIFReadWarning("Input off lambda grid by %d/%d; " remain, denom);
"grid redefined.\n", remain, denom);
cifSeenSnapWarning = TRUE;
/* scale to nearest half-lambda */ /* scale to nearest half-lambda */
if (!(denom & 0x1)) denom >>= 1; if (!(denom & 0x1)) denom >>= 1;
@ -276,10 +250,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
@ -300,10 +272,8 @@ CIFScaleCoord(
break; break;
case COORD_ANY: case COORD_ANY:
if (!cifSeenSnapWarning) CIFReadWarning("Input off lambda grid by %d/%d; snapped to grid.\n",
CIFReadWarning("Input off lambda grid by %d/%d; snapped to grid.\n", abs(remain), abs(denom));
abs(remain), abs(denom));
cifSeenSnapWarning = TRUE;
/* Careful: must round down a bit more for negative numbers, in /* Careful: must round down a bit more for negative numbers, in
* order to ensure that a point exactly halfway between Magic units * order to ensure that a point exactly halfway between Magic units
@ -325,7 +295,7 @@ CIFScaleCoord(
return result; return result;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -345,8 +315,8 @@ CIFScaleCoord(
*/ */
bool bool
cifIsBlank( cifIsBlank(ch)
int ch) int ch;
{ {
if ( isdigit(ch) || isupper(ch) if ( isdigit(ch) || isupper(ch)
@ -358,7 +328,7 @@ cifIsBlank(
} }
else return TRUE; else return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -378,7 +348,7 @@ cifIsBlank(
*/ */
void void
CIFSkipBlanks(void) CIFSkipBlanks()
{ {
while (cifIsBlank(PEEK())) { while (cifIsBlank(PEEK())) {
@ -388,7 +358,7 @@ CIFSkipBlanks(void)
} }
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -407,7 +377,7 @@ CIFSkipBlanks(void)
*/ */
void void
CIFSkipSep(void) CIFSkipSep()
{ {
int ch; int ch;
@ -418,7 +388,7 @@ CIFSkipSep(void)
} }
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -437,7 +407,7 @@ CIFSkipSep(void)
*/ */
void void
CIFSkipToSemi(void) CIFSkipToSemi()
{ {
int ch; int ch;
@ -448,7 +418,7 @@ CIFSkipToSemi(void)
} }
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -466,7 +436,7 @@ CIFSkipToSemi(void)
*/ */
void void
CIFSkipSemi(void) CIFSkipSemi()
{ {
CIFSkipBlanks(); CIFSkipBlanks();
@ -477,7 +447,7 @@ CIFSkipSemi(void)
TAKE(); TAKE();
CIFSkipBlanks(); CIFSkipBlanks();
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -497,8 +467,8 @@ CIFSkipSemi(void)
*/ */
bool bool
CIFParseSInteger( CIFParseSInteger(valuep)
int *valuep) int *valuep;
{ {
bool is_signed; bool is_signed;
char buffer[ BUFSIZ ]; char buffer[ BUFSIZ ];
@ -523,7 +493,7 @@ CIFParseSInteger(
*valuep = -(*valuep); *valuep = -(*valuep);
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -542,8 +512,8 @@ CIFParseSInteger(
*/ */
bool bool
CIFParseInteger( CIFParseInteger(valuep)
int *valuep) int *valuep;
{ {
if (!CIFParseSInteger(valuep)) if (!CIFParseSInteger(valuep))
@ -583,9 +553,9 @@ CIFParseInteger(
*/ */
bool bool
CIFParsePoint( CIFParsePoint(pointp, iscale)
Point *pointp, Point *pointp;
int iscale) int iscale;
{ {
int rescale; int rescale;
@ -641,7 +611,7 @@ CIFParsePoint(
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -651,11 +621,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 +638,17 @@ CIFParsePoint(
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
CIFPath * bool
CIFParsePath( CIFParsePath(pathheadpp, iscale)
int iscale) CIFPath **pathheadpp;
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 +660,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 +676,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 +693,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);
} }
/* /*
@ -744,9 +716,9 @@ CIFParsePath(
*/ */
bool bool
test_insideness( test_insideness(start, tpoint)
CIFPath *start, CIFPath *start;
Point *tpoint) Point *tpoint;
{ {
Rect tmprect, irect; Rect tmprect, irect;
@ -782,11 +754,10 @@ test_insideness(
*/ */
bool bool
seg_intersect( seg_intersect(tstart, bf, bs, respt)
CIFPath *tstart, CIFPath *tstart;
Point *bf, Point *bf, *bs;
Point *bs, Point *respt;
Point *respt)
{ {
int afx = tstart->cifp_x; int afx = tstart->cifp_x;
int afy = tstart->cifp_y; int afy = tstart->cifp_y;
@ -849,10 +820,9 @@ seg_intersect(
*/ */
bool bool
path_intersect( path_intersect(pathHead, start, respt)
CIFPath *pathHead, CIFPath *pathHead, *start;
CIFPath *start, Point *respt;
Point *respt)
{ {
CIFPath *path, *segcrossed, *new; CIFPath *path, *segcrossed, *new;
Point tmppt; Point tmppt;
@ -906,8 +876,6 @@ path_intersect(
} }
} }
} }
else if (diagonal == FALSE)
continue;
} }
else if (diagonal == FALSE) else if (diagonal == FALSE)
continue; continue;
@ -955,8 +923,8 @@ path_intersect(
*/ */
bool bool
is_clockwise( is_clockwise(pathHead)
CIFPath *pathHead) CIFPath *pathHead;
{ {
CIFPath *path, *midx = NULL, *last; CIFPath *path, *midx = NULL, *last;
Point *p1, *p2, *p3; Point *p1, *p2, *p3;
@ -1049,11 +1017,11 @@ is_clockwise(
*/ */
void void
CIFMakeManhattanPath( CIFMakeManhattanPath(pathHead, plane, resultTbl, ui)
CIFPath *pathHead, CIFPath *pathHead;
Plane *plane, Plane *plane;
const PaintResultType *resultTbl, PaintResultType *resultTbl;
PaintUndoInfo *ui) PaintUndoInfo *ui;
{ {
CIFPath *new, *new2, *next, *path; CIFPath *new, *new2, *next, *path;
int xinit, xdiff, xincr, xlast, x; int xinit, xdiff, xincr, xlast, x;
@ -1156,15 +1124,11 @@ CIFMakeManhattanPath(
/* Final check---ensure that rectangle is not degenerate */ /* Final check---ensure that rectangle is not degenerate */
if (plane && (tr.r_xtop - tr.r_xbot > 0) && (tr.r_ytop - tr.r_ybot > 0)) if (plane && (tr.r_xtop - tr.r_xbot > 0) && (tr.r_ytop - tr.r_ybot > 0))
{
DBNMPaintPlane(plane, type, &tr, resultTbl, ui); DBNMPaintPlane(plane, type, &tr, resultTbl, ui);
GEO_EXPAND(&tr, 1, &tr);
DBMergeNMTiles(plane, &tr, ui);
}
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1187,9 +1151,8 @@ CIFMakeManhattanPath(
*/ */
int int
CIFEdgeDirection( CIFEdgeDirection(first, last)
CIFPath *first, CIFPath *first, *last; /* Edge to be categorized. */
CIFPath *last) /* Edge to be categorized. */
{ {
if (first->cifp_x < last->cifp_x) if (first->cifp_x < last->cifp_x)
@ -1214,7 +1177,7 @@ CIFEdgeDirection(
return CIF_DOWN; return CIF_DOWN;
return CIF_ZERO; return CIF_ZERO;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1236,8 +1199,8 @@ CIFEdgeDirection(
*/ */
void void
CIFCleanPath( CIFCleanPath(pathHead)
CIFPath *pathHead) CIFPath *pathHead;
{ {
CIFPath *next, *path, *prev, *last; CIFPath *next, *path, *prev, *last;
int dir1, dir2; int dir1, dir2;
@ -1256,7 +1219,7 @@ CIFCleanPath(
if (!path) return; if (!path) return;
} }
while ((next = path->cifp_next)) while (next = path->cifp_next)
{ {
if ((dir2 = CIFEdgeDirection(path, next)) == CIF_ZERO) if ((dir2 = CIFEdgeDirection(path, next)) == CIF_ZERO)
{ {
@ -1317,7 +1280,7 @@ path_inc:
} }
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1335,18 +1298,16 @@ path_inc:
*/ */
void void
CIFFreePath( CIFFreePath(path)
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);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1366,13 +1327,13 @@ CIFFreePath(
*/ */
void void
cifCommandError(void) cifCommandError()
{ {
CIFReadError("unknown command `%c'; ignored.\n" , PEEK()); CIFReadError("unknown command `%c'; ignored.\n" , PEEK());
CIFSkipToSemi(); CIFSkipToSemi();
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1391,7 +1352,7 @@ cifCommandError(void)
*/ */
bool bool
cifParseEnd(void) cifParseEnd()
{ {
TAKE(); TAKE();
CIFSkipBlanks(); CIFSkipBlanks();
@ -1402,7 +1363,7 @@ cifParseEnd(void)
} }
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1420,7 +1381,7 @@ cifParseEnd(void)
*/ */
bool bool
cifParseComment(void) cifParseComment()
{ {
int opens; int opens;
int ch; int ch;
@ -1449,7 +1410,7 @@ cifParseComment(void)
} while (opens > 0); } while (opens > 0);
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1471,9 +1432,9 @@ cifParseComment(void)
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
const Transform * Transform *
CIFDirectionToTrans( CIFDirectionToTrans(point)
const Point *point) /* Direction vector from origin. */ Point *point; /* Direction vector from origin. */
{ {
if ((point->p_x != 0) && (point->p_y == 0)) if ((point->p_x != 0) && (point->p_y == 0))
{ {
@ -1491,7 +1452,7 @@ CIFDirectionToTrans(
point->p_x, point->p_y); point->p_x, point->p_y);
return &GeoIdentityTransform; return &GeoIdentityTransform;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1512,8 +1473,8 @@ CIFDirectionToTrans(
*/ */
bool bool
CIFParseTransform( CIFParseTransform(transformp)
Transform *transformp) Transform *transformp;
{ {
char ch; char ch;
Point point; Point point;
@ -1586,7 +1547,7 @@ CIFParseTransform(
return TRUE; return TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1606,8 +1567,8 @@ CIFParseTransform(
*/ */
void void
CIFReadFile( CIFReadFile(file)
FILE *file) /* File from which to read CIF. */ FILE *file; /* File from which to read CIF. */
{ {
/* We will use 1-word CIF numbers as keys in this hash table */ /* We will use 1-word CIF numbers as keys in this hash table */
CIFReadCellInit(1); CIFReadCellInit(1);
@ -1623,7 +1584,6 @@ CIFReadFile(
cifTotalWarnings = 0; cifTotalWarnings = 0;
cifTotalErrors = 0; cifTotalErrors = 0;
CifPolygonCount = 0; CifPolygonCount = 0;
cifSeenSnapWarning = FALSE;
cifInputFile = file; cifInputFile = file;
cifReadScale1 = 1; cifReadScale1 = 1;
@ -1699,6 +1659,6 @@ CIFReadFile(
CIFReadError("no \"End\" statement.\n"); CIFReadError("no \"End\" statement.\n");
done: done:
CIFReadCellCleanup(FILE_CIF); CIFReadCellCleanup(0);
UndoEnable(); UndoEnable();
} }

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"
@ -54,8 +54,8 @@ typedef struct
* the "crl_magicType" should be interpreted as a CIF layer. * the "crl_magicType" should be interpreted as a CIF layer.
*/ */
#define CIFR_SIMPLE 1 #define CIFR_SIMPLE 1
#define CIFR_TEMPLAYER 2 #define CIFR_TEMPLAYER 2
/* The following structure defines a complete CIF read-in style. /* The following structure defines a complete CIF read-in style.
* The constant MAXCIFRLAYERS must be less than TT_MAXTYPES, and * The constant MAXCIFRLAYERS must be less than TT_MAXTYPES, and
@ -104,10 +104,8 @@ typedef struct cifrstyle
/* Gives the Magic layer to use for labels /* Gives the Magic layer to use for labels
* on each possible CIF layer. * on each possible CIF layer.
*/ */
/* enum labelType */ unsigned char crs_labelSticky[MAXCIFRLAYERS]; bool crs_labelSticky[MAXCIFRLAYERS];
/* Marker if label layer makes sticky labels /* Marker if label layer makes sticky labels */
* enum labelType LABEL_TYPE_xxxxxx
*/
CIFReadLayer *crs_layers[MAXCIFRLAYERS]; CIFReadLayer *crs_layers[MAXCIFRLAYERS];
HashTable cifCalmaToCif; /* Table mapping from Calma layer numbers to HashTable cifCalmaToCif; /* Table mapping from Calma layer numbers to
* CIF layers * CIF layers
@ -117,6 +115,7 @@ typedef struct cifrstyle
/* option bitmasks used in crs_flags */ /* option bitmasks used in crs_flags */
#define CRF_IGNORE_UNKNOWNLAYER_LABELS 1 #define CRF_IGNORE_UNKNOWNLAYER_LABELS 1
#define CRF_NO_RECONNECT_LABELS 2
/* Methods to deal with fractional results of conversion from CIF to magic */ /* Methods to deal with fractional results of conversion from CIF to magic */
/* units (see routine CIFScaleCoord() for details). */ /* units (see routine CIFScaleCoord() for details). */
@ -154,45 +153,22 @@ typedef struct cifpath
/* Procedures */ /* Procedures */
extern bool CIFParseBox(void); extern bool CIFParseBox(), CIFParseWire(), CIFParsePoly();
extern bool CIFParseWire(void); extern bool CIFParseFlash(), CIFParseLayer(), CIFParseStart();
extern bool CIFParsePoly(void); extern bool CIFParseFinish(), CIFParseDelete(), CIFParseUser();
extern bool CIFParseFlash(void); extern bool CIFParseCall(), CIFParseTransform(), CIFParseInteger();
extern bool CIFParseLayer(void); extern bool CIFParsePath(), CIFParsePoint(), CIFParseSInteger();
extern bool CIFParseStart(void); extern void CIFSkipToSemi(), CIFSkipSep(), CIFSkipBlanks();
extern bool CIFParseFinish(void); extern void CIFFreePath(), CIFCleanPath();
extern bool CIFParseDelete(void); extern void CIFReadCellInit(), CIFReadCellCleanup();
extern bool CIFParseUser(void); extern LinkedRect *CIFPolyToRects();
extern bool CIFParseCall(void); extern Transform *CIFDirectionToTrans();
extern bool CIFParseTransform(Transform *transformp); extern int CIFReadNameToType();
extern bool CIFParseInteger(int *valuep);
extern CIFPath *CIFParsePath(int iscale);
extern bool CIFParsePoint(Point *pointp, int iscale);
extern bool CIFParseSInteger(int *valuep);
extern void CIFSkipToSemi(void);
extern void CIFSkipSep(void);
extern void CIFSkipBlanks(void);
extern void CIFFreePath(CIFPath *path);
extern void CIFCleanPath(CIFPath *pathHead);
extern void CIFReadCellInit(int ptrkeys);
extern void CIFReadCellCleanup(int filetype);
extern LinkedRect *CIFPolyToRects(CIFPath *path, Plane *plane, const PaintResultType *resultTbl,
PaintUndoInfo *ui, bool isCalma);
extern const Transform *CIFDirectionToTrans(const Point *point);
extern int CIFReadNameToType(char *name, bool newOK);
extern int CIFCalmaLayerToCifLayer(int layer, int datatype, CIFReadStyle *calmaStyle);
extern void CIFPropRecordPath(CellDef *def, CIFPath *pathheadp, bool iswire, char *propname);
extern void CIFPaintWirePath(CIFPath *pathheadp, int width, bool endcap, Plane *plane,
const PaintResultType *ptable, PaintUndoInfo *ui);
extern void CIFMakeManhattanPath(CIFPath *pathHead, Plane *plane, const PaintResultType *resultTbl, PaintUndoInfo *ui);
extern int CIFEdgeDirection(CIFPath *first, CIFPath *last);
/* Variable argument procedures require complete prototype */ /* Variable argument procedures require complete prototype */
extern void CIFReadError(const char *format, ...) ATTR_FORMAT_PRINTF_1; extern void CIFReadError(char *format, ...);
extern void CIFReadWarning(const char *format, ...) ATTR_FORMAT_PRINTF_1; extern void CIFReadWarning(char *format, ...);
/* Variables shared by the CIF-reading modules, see CIFreadutils.c /* Variables shared by the CIF-reading modules, see CIFreadutils.c
* for more details: * for more details:
@ -221,4 +197,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

@ -17,11 +17,10 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFsee.c,v 1.5 2010/06/24 12:37:15 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFsee.c,v 1.5 2010/06/24 12:37:15 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.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"
@ -35,9 +34,6 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "textio/textio.h" #include "textio/textio.h"
#include "utils/undo.h" #include "utils/undo.h"
/* C99 compat */
#include "drc/drc.h"
/* The following variable holds the CellDef into which feedback /* The following variable holds the CellDef into which feedback
* is to be placed for displaying CIF. * is to be placed for displaying CIF.
*/ */
@ -76,10 +72,9 @@ typedef struct {
*/ */
int int
cifPaintDBFunc( cifPaintDBFunc(tile, pld)
Tile *tile, /* Tile of CIF information. */ Tile *tile; /* Tile of CIF information. */
TileType dinfo, PaintLayerData *pld;
PaintLayerData *pld)
{ {
Rect area; Rect area;
int pNum; int pNum;
@ -107,7 +102,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);
} }
@ -133,14 +128,14 @@ cifPaintDBFunc(
*/ */
void void
CIFPaintLayer( CIFPaintLayer(rootDef, area, cifLayer, magicLayer, paintDef)
CellDef *rootDef, /* Cell for which to generate CIF. Must be CellDef *rootDef; /* Cell for which to generate CIF. Must be
* the rootDef of a window. * the rootDef of a window.
*/ */
Rect *area, /* Area in which to generate CIF. */ Rect *area; /* Area in which to generate CIF. */
char *cifLayer, /* CIF layer to highlight on the screen. */ char *cifLayer; /* CIF layer to highlight on the screen. */
int magicLayer, /* Magic layer to paint with the result */ int magicLayer; /* Magic layer to paint with the result */
CellDef *paintDef) /* CellDef to paint into (may be NULL) */ CellDef *paintDef; /* CellDef to paint into (may be NULL) */
{ {
int oldCount, i; int oldCount, i;
char msg[100]; char msg[100];
@ -166,15 +161,9 @@ CIFPaintLayer(
scx.scx_use = CIFDummyUse; scx.scx_use = CIFDummyUse;
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFCopyMaskHints(&scx, CIFComponentDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
(ClientData)CIFComponentDef);
oldCount = DBWFeedbackCount; oldCount = DBWFeedbackCount;
CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE);
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, FALSE,
(ClientData)NULL);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
/* Report any errors that occurred. */ /* Report any errors that occurred. */
@ -218,10 +207,9 @@ CIFPaintLayer(
*/ */
int int
cifSeeFunc( cifSeeFunc(tile, sld)
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 +223,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;
} }
@ -260,12 +248,12 @@ cifSeeFunc(
*/ */
void void
CIFSeeLayer( CIFSeeLayer(rootDef, area, layer)
CellDef *rootDef, /* Cell for which to generate CIF. Must be CellDef *rootDef; /* Cell for which to generate CIF. Must be
* the rootDef of a window. * the rootDef of a window.
*/ */
Rect *area, /* Area in which to generate CIF. */ Rect *area; /* Area in which to generate CIF. */
char *layer) /* CIF layer to highlight on the screen. */ char *layer; /* CIF layer to highlight on the screen. */
{ {
int oldCount, i; int oldCount, i;
char msg[100]; char msg[100];
@ -287,14 +275,9 @@ CIFSeeLayer(
scx.scx_use = CIFDummyUse; scx.scx_use = CIFDummyUse;
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFCopyMaskHints(&scx, CIFComponentDef);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
(ClientData)CIFComponentDef);
oldCount = DBWFeedbackCount; oldCount = DBWFeedbackCount;
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE, CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE);
FALSE, (ClientData)NULL);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
/* Report any errors that occurred. */ /* Report any errors that occurred. */
@ -328,7 +311,7 @@ CIFSeeLayer(
} }
UndoEnable(); UndoEnable();
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -350,14 +333,14 @@ CIFSeeLayer(
*/ */
void void
CIFSeeHierLayer( CIFSeeHierLayer(rootDef, area, layer, arrays, subcells)
CellDef *rootDef, /* Def in which to compute CIF. Must be CellDef *rootDef; /* Def in which to compute CIF. Must be
* the root definition of a window. * the root definition of a window.
*/ */
Rect *area, /* Area in which to generate CIF. */ Rect *area; /* Area in which to generate CIF. */
char *layer, /* CIF layer to be highlighted. */ char *layer; /* CIF layer to be highlighted. */
bool arrays, /* TRUE means show array interactions. */ bool arrays; /* TRUE means show array interactions. */
bool subcells) /* TRUE means show subcell interactions. */ bool subcells; /* TRUE means show subcell interactions. */
{ {
int i, oldCount; int i, oldCount;
SeeLayerData sld; SeeLayerData sld;
@ -428,11 +411,10 @@ typedef struct {
} coverstats; } coverstats;
void void
CIFCoverageLayer( CIFCoverageLayer(rootDef, area, layer)
CellDef *rootDef, /* Def in which to compute CIF coverage */ CellDef *rootDef; /* Def in which to compute CIF coverage */
Rect *area, /* Area in which to compute coverage */ Rect *area; /* Area in which to compute coverage */
char *layer, /* CIF layer for coverage computation. */ char *layer; /* CIF layer for coverage computation. */
bool dolist) /* If TRUE, report only the value, in decimal */
{ {
coverstats cstats; coverstats cstats;
int i, scale; int i, scale;
@ -440,11 +422,9 @@ CIFCoverageLayer(
SearchContext scx; SearchContext scx;
TileTypeBitMask mask, depend; TileTypeBitMask mask, depend;
float fcover; float fcover;
int cifCoverageFunc();
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;
@ -459,13 +439,8 @@ CIFCoverageLayer(
scx.scx_use = CIFDummyUse; scx.scx_use = CIFDummyUse;
scx.scx_trans = GeoIdentityTransform; scx.scx_trans = GeoIdentityTransform;
(void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0, (void) DBTreeSrTiles(&scx, &DBAllButSpaceAndDRCBits, 0,
cifHierCopyFunc, (ClientData) CIFComponentDef); cifHierCopyFunc, (ClientData) CIFComponentDef);
CIFCopyMaskHints(&scx, CIFComponentDef); CIFGen(CIFComponentDef, area, CIFPlanes, &depend, TRUE, TRUE);
DBTreeSrCells(&scx, 0, CIFCopyMaskHints,
(ClientData)CIFComponentDef);
CIFGen(CIFComponentDef, rootDef, area, CIFPlanes, &depend, TRUE, TRUE,
FALSE, (ClientData)NULL);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
cstats.coverage = 0; cstats.coverage = 0;
@ -491,39 +466,24 @@ CIFCoverageLayer(
atotal = (long long)(cstats.bounds.r_xtop - cstats.bounds.r_xbot); atotal = (long long)(cstats.bounds.r_xtop - cstats.bounds.r_xbot);
atotal *= (long long)(cstats.bounds.r_ytop - cstats.bounds.r_ybot); atotal *= (long long)(cstats.bounds.r_ytop - cstats.bounds.r_ybot);
if (dolist) TxPrintf("%s Area = %lld CIF units^2\n", doBox ? "Cursor Box" :
{
#ifdef MAGIC_WRAPPER
Tcl_Obj *pobj;
pobj = Tcl_NewDoubleObj((double)fcover);
Tcl_SetObjResult(magicinterp, pobj);
#else
TxPrintf("%g\n", fcover);
#endif
}
else
{
TxPrintf("%s Area = %"DLONG_PREFIX"d 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);
}
} }
int int
cifCoverageFunc( cifCoverageFunc(tile, arg)
Tile *tile, Tile *tile;
TileType dinfo, /* (unused) */ ClientData *arg;
ClientData *arg)
{ {
coverstats *cstats = (coverstats *)arg; coverstats *cstats = (coverstats *)arg;
Rect r; Rect r;
TiToRect(tile, &r); TiToRect(tile, &r);
cstats->coverage += (long long)(r.r_xtop - r.r_xbot) * (long long)(r.r_ytop - r.r_ybot); cstats->coverage += (long long)((r.r_xtop - r.r_xbot) * (r.r_ytop - r.r_ybot));
GeoInclude(&r, &cstats->bounds); GeoInclude(&r, &cstats->bounds);
return(0); return(0);

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFwrite.c,v 1.2 2010/06/24 12:37:15 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cif/CIFwrite.c,v 1.2 2010/06/24 12:37:15 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdlib.h> #include <stdlib.h>
@ -44,15 +44,14 @@ 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); extern int cifWriteInitFunc();
extern int cifWriteMarkFunc(CellUse *use); extern int cifWriteMarkFunc();
extern int cifWritePaintFunc(Tile *tile, TileType dinfo, FILE *f); extern int cifWritePaintFunc();
extern int cifWriteLabelFunc(Tile *tile, TileType dinfo, FILE *f); extern int cifWriteUseFunc();
extern int cifWriteUseFunc(CellUse *use, FILE *f); extern void cifOutPreamble();
extern void cifOutPreamble(FILE *outf, CellDef *cell); extern void cifOut();
extern void cifOut(FILE *outf); extern void cifOutFunc();
extern void cifOutFunc(CellDef *def, FILE *f); extern int GrClipTriangle();
extern void GrClipTriangle(Rect *r, Rect *c, int clipped, TileType dinfo, Point *points, int *np);
/* Current cell number in CIF numbering scheme */ /* Current cell number in CIF numbering scheme */
@ -87,7 +86,7 @@ char *CIFPathPrefix = NULL;
bool CIFHierWriteDisable = FALSE; bool CIFHierWriteDisable = FALSE;
bool CIFArrayWriteDisable = FALSE; bool CIFArrayWriteDisable = FALSE;
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -118,13 +117,12 @@ bool CIFArrayWriteDisable = FALSE;
*/ */
bool bool
CIFWrite( CIFWrite(rootDef, f)
CellDef *rootDef, /* Pointer to CellDef to be written */ CellDef *rootDef; /* Pointer to CellDef to be written */
FILE *f) /* Open output file */ FILE *f; /* Open output file */
{ {
bool good; bool good;
int oldCount = DBWFeedbackCount; int oldCount = DBWFeedbackCount;
CellDef *err_def;
CellUse dummy; CellUse dummy;
/* /*
@ -134,20 +132,14 @@ CIFWrite(
*/ */
dummy.cu_def = rootDef; dummy.cu_def = rootDef;
err_def = DBCellReadArea(&dummy, &rootDef->cd_bbox, TRUE); DBCellReadArea(&dummy, &rootDef->cd_bbox);
if (err_def != NULL)
{
TxError("Failure to read in entire subtree of the cell.\n");
TxError("Failed on cell %s.\n", err_def->cd_name);
return (FALSE);
}
DBFixMismatch(); DBFixMismatch();
if (CIFCurStyle->cs_reducer == 0) if (CIFCurStyle->cs_reducer == 0)
{ {
TxError("The current CIF output style can only be used for writing\n"); TxError("The current CIF output style can only be used for writing\n");
TxError("Calma output. Try picking another output style.\n"); TxError("Calma output. Try picking another output style.\n");
return (FALSE); return (TRUE);
} }
/* /*
@ -167,8 +159,8 @@ CIFWrite(
cifOutPreamble(f, rootDef); cifOutPreamble(f, rootDef);
cifOut(f); cifOut(f);
StackFree(cifStack); StackFree(cifStack);
if ((int) CD2INT(rootDef->cd_client) < 0) if ((int) rootDef->cd_client < 0)
rootDef->cd_client = INT2CD(- (int) CD2INT(rootDef->cd_client)); rootDef->cd_client = (ClientData) (- (int) rootDef->cd_client);
/* See if any problems occurred. */ /* See if any problems occurred. */
@ -182,11 +174,11 @@ CIFWrite(
* Now we are almost done. * Now we are almost done.
* Just output a call on the root cell * Just output a call on the root cell
*/ */
fprintf(f, "C %d;\nEnd\n", (int) CD2INT(rootDef->cd_client)); fprintf(f, "C %d;\nEnd\n", (int) rootDef->cd_client);
good = !ferror(f); good = !ferror(f);
return (good); return (good);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -205,13 +197,13 @@ CIFWrite(
*/ */
int int
cifWriteInitFunc( cifWriteInitFunc(def)
CellDef *def) CellDef *def;
{ {
def->cd_client = (ClientData) 0; def->cd_client = (ClientData) 0;
return (0); return (0);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -229,16 +221,16 @@ cifWriteInitFunc(
*/ */
int int
cifWriteMarkFunc( cifWriteMarkFunc(use)
CellUse *use) CellUse *use;
{ {
if (use->cu_def->cd_client != (ClientData) 0) return 0; if (use->cu_def->cd_client != (ClientData) 0) return 0;
use->cu_def->cd_client = INT2CD(cifCellNum); use->cu_def->cd_client = (ClientData) cifCellNum;
cifCellNum -= 1; cifCellNum -= 1;
StackPush((ClientData) use->cu_def, cifStack); StackPush((ClientData) use->cu_def, cifStack);
return (0); return (0);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -255,9 +247,9 @@ cifWriteMarkFunc(
*/ */
void void
cifOutPreamble( cifOutPreamble(outf, cell)
FILE *outf, FILE *outf;
CellDef *cell) CellDef *cell;
{ {
extern char *MagicVersion; extern char *MagicVersion;
extern char *MagicCompileTime; extern char *MagicCompileTime;
@ -285,7 +277,7 @@ cifOutPreamble(
fprintf(outf,"( @@style : %s );\n", CIFCurStyle->cs_name); fprintf(outf,"( @@style : %s );\n", CIFCurStyle->cs_name);
fprintf(outf,"( @@date : %s );\n", now); fprintf(outf,"( @@date : %s );\n", now);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -304,24 +296,24 @@ cifOutPreamble(
*/ */
void void
cifOut( cifOut(outf)
FILE *outf) FILE *outf;
{ {
CellDef *def; CellDef *def;
bool needHier;
while (!StackEmpty(cifStack)) while (!StackEmpty(cifStack))
{ {
def = (CellDef *) StackPop(cifStack); def = (CellDef *) StackPop(cifStack);
if ((int) CD2INT(def->cd_client) >= 0) continue; /* Already output */ if ((int) def->cd_client >= 0) continue; /* Already output */
if (SigInterruptPending) continue; if (SigInterruptPending) continue;
def->cd_client = INT2CD(- (int) CD2INT(def->cd_client)); def->cd_client = (ClientData) (- (int) def->cd_client);
/* Read the cell in if it is not already available. */ /* Read the cell in if it is not already available. */
if ((def->cd_flags & CDAVAILABLE) == 0) if ((def->cd_flags & CDAVAILABLE) == 0)
if (!DBCellRead(def, TRUE, TRUE, NULL)) {
continue; if (!DBCellRead(def, (char *) NULL, TRUE, NULL)) continue;
}
/* Add any subcells to the stack. This must be done before /* Add any subcells to the stack. This must be done before
* outputting CIF to make sure that the subcells all have * outputting CIF to make sure that the subcells all have
@ -335,7 +327,7 @@ cifOut(
cifOutFunc(def, outf); cifOutFunc(def, outf);
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -353,16 +345,16 @@ cifOut(
*/ */
void void
cifOutFunc( cifOutFunc(def, f)
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 */
{ {
Rect bigArea; Rect bigArea;
Label *lab; Label *lab;
int type; int type;
CIFLayer *layer; CIFLayer *layer;
fprintf(f, "DS %d %d %d;\n", (int) CD2INT(def->cd_client), fprintf(f, "DS %d %d %d;\n", (int) def->cd_client,
CIFCurStyle->cs_reducer, 2 * CIFCurStyle->cs_expander); CIFCurStyle->cs_reducer, 2 * CIFCurStyle->cs_expander);
if (def->cd_name != (char *) NULL) if (def->cd_name != (char *) NULL)
@ -385,28 +377,20 @@ cifOutFunc(
GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea); GEO_EXPAND(&def->cd_bbox, CIFCurStyle->cs_radius, &bigArea);
CIFErrorDef = def; CIFErrorDef = def;
CIFGen(def, def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE, FALSE, CIFGen(def, &bigArea, CIFPlanes, &DBAllTypeBits, TRUE, TRUE);
(ClientData)NULL);
if (!CIFHierWriteDisable) if (!CIFHierWriteDisable)
CIFGenSubcells(def, &bigArea, CIFPlanes); CIFGenSubcells(def, &bigArea, CIFPlanes);
if (!CIFArrayWriteDisable) if (!CIFArrayWriteDisable)
CIFGenArrays(def, &bigArea, CIFPlanes); CIFGenArrays(def, &bigArea, CIFPlanes);
for (type = 0; type < CIFCurStyle->cs_nLayers; type++) for (type = 0; type < CIFCurStyle->cs_nLayers; type++)
{ {
layer = CIFCurStyle->cs_layers[type]; layer = CIFCurStyle->cs_layers[type];
if (layer->cl_flags & CIF_TEMP) continue; if (layer->cl_flags & CIF_TEMP) continue;
cifPaintLayerName = layer->cl_name; cifPaintLayerName = layer->cl_name;
cifPaintScale = 1; cifPaintScale = 1;
if (layer->cl_flags & CIF_LABEL) (void) DBSrPaintArea((Tile *) NULL, CIFPlanes[type],
DBSrPaintArea((Tile *) NULL, CIFPlanes[type], &TiPlaneRect, &CIFSolidBits, cifWritePaintFunc,
&TiPlaneRect, &CIFSolidBits, cifWriteLabelFunc, (ClientData) f);
(ClientData) f);
else
DBSrPaintArea((Tile *) NULL, CIFPlanes[type],
&TiPlaneRect, &CIFSolidBits, cifWritePaintFunc,
(ClientData) f);
} }
/* Output labels */ /* Output labels */
@ -465,7 +449,7 @@ cifOutFunc(
(void) DBCellEnum(def, cifWriteUseFunc, (ClientData) f); (void) DBCellEnum(def, cifWriteUseFunc, (ClientData) f);
fprintf(f, "DF;\n"); fprintf(f, "DF;\n");
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -484,16 +468,16 @@ cifOutFunc(
*/ */
int int
cifWriteUseFunc( cifWriteUseFunc(use, f)
CellUse *use, CellUse *use;
FILE *f) FILE *f;
{ {
int x, y, topx, topy; int x, y, topx, topy;
int realx, realy; int realx, realy;
Transform *t; Transform *t;
int cifnum; int cifnum;
cifnum = (int) CD2INT(use->cu_def->cd_client); cifnum = (int) use->cu_def->cd_client;
if (cifnum < 0) cifnum = (-cifnum); if (cifnum < 0) cifnum = (-cifnum);
topx = use->cu_xhi - use->cu_xlo; topx = use->cu_xhi - use->cu_xlo;
if (topx < 0) topx = -topx; if (topx < 0) topx = -topx;
@ -562,69 +546,7 @@ cifWriteUseFunc(
} }
return 0; return 0;
} }
/*
* ----------------------------------------------------------------------------
*
* cifWriteLabelFunc --
*
* Filter function used to write out a label corresponding to a
* single paint tile. The CIF layer name is used as the label to
* output.
*
* Results:
* Always return 0
*
* Side effects:
* Writes to the disk file.
*
* ----------------------------------------------------------------------------
*/
int
cifWriteLabelFunc(
Tile *tile, /* Tile to be written out. */
TileType dinfo, /* Split tile information (unused) */
FILE *f) /* File in which to write. */
{
Rect r;
int type;
Point center, size;
if (IsSplit(tile)) return 0; /* Ignore non-manhattan tiles */
if (cifPaintLayerName == NULL) return 0; /* Shouldn't happen */
TiToRect(tile, &r);
type = CIFCurStyle->cs_labelLayer[TiGetType(tile)];
center.p_x = r.r_xbot + r.r_xtop;
center.p_y = r.r_ybot + r.r_ytop;
center.p_x *= CIFCurStyle->cs_scaleFactor;
center.p_x /= CIFCurStyle->cs_reducer;
center.p_y *= CIFCurStyle->cs_scaleFactor;
center.p_y /= CIFCurStyle->cs_reducer;
if (CIFDoAreaLabels)
{
size.p_x = r.r_xtop - r.r_xbot;
size.p_y = r.r_ytop - r.r_ybot;
size.p_x *= 2 * CIFCurStyle->cs_scaleFactor;
size.p_x /= CIFCurStyle->cs_reducer;
size.p_y *= 2 * CIFCurStyle->cs_scaleFactor;
size.p_y /= CIFCurStyle->cs_reducer;
fprintf(f, "95 %s %d %d %d %d;\n",
cifPaintLayerName, size.p_x, size.p_y, center.p_x, center.p_y);
}
else
{
fprintf(f, "94 %s %d %d;\n",
cifPaintLayerName, center.p_x, center.p_y);
}
return 0;
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -642,10 +564,9 @@ cifWriteLabelFunc(
*/ */
int int
cifWritePaintFunc( cifWritePaintFunc(tile, f)
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;
@ -664,7 +585,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 */
@ -693,7 +614,7 @@ cifWritePaintFunc(
CIFRects += 1; CIFRects += 1;
return 0; return 0;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -724,9 +645,9 @@ cifWritePaintFunc(
*/ */
bool bool
CIFWriteFlat( CIFWriteFlat(rootDef, f)
CellDef *rootDef, /* Pointer to CellDef to be written */ CellDef *rootDef; /* Pointer to CellDef to be written */
FILE *f) /* Open output file */ FILE *f; /* Open output file */
{ {
bool good; bool good;
int oldCount = DBWFeedbackCount; int oldCount = DBWFeedbackCount;
@ -775,7 +696,7 @@ CIFWriteFlat(
* Just output a call on the root cell * Just output a call on the root cell
*/ */
fprintf(f, "C %d;\nEnd\n", (int) CD2INT(CIFComponentDef->cd_client)); fprintf(f, "C %d;\nEnd\n", (int) CIFComponentDef->cd_client);
DBCellClearDef(CIFComponentDef); DBCellClearDef(CIFComponentDef);
good = !ferror(f); good = !ferror(f);

45
cif/Depend Normal file
View File

@ -0,0 +1,45 @@
CIFgen.o: CIFgen.c ../utils/magic.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../database/database.h ../cif/CIFint.h ../calma/calma.h \
../commands/commands.h ../windows/windows.h ../select/selInt.h \
../utils/stack.h ../utils/malloc.h ../utils/maxrect.h
CIFhier.o: CIFhier.c ../utils/magic.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../database/database.h ../cif/CIFint.h ../cif/cif.h \
../drc/drc.h ../textio/textio.h ../utils/undo.h ../utils/malloc.h \
../utils/signals.h
CIFmain.o: CIFmain.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../cif/CIFint.h ../textio/textio.h \
../windows/windows.h ../dbwind/dbwind.h ../utils/styles.h
CIFrdcl.o: CIFrdcl.c ../utils/magic.h ../utils/malloc.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h ../utils/undo.h \
../database/database.h ../cif/CIFint.h ../cif/CIFread.h ../utils/utils.h \
../windows/windows.h ../dbwind/dbwind.h ../utils/main.h ../drc/drc.h
CIFrdpt.o: CIFrdpt.c ../utils/magic.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../utils/malloc.h ../database/database.h \
../windows/windows.h ../utils/main.h ../cif/CIFint.h ../cif/CIFread.h
CIFrdpoly.o: CIFrdpoly.c ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../cif/CIFint.h \
../cif/CIFread.h ../utils/malloc.h
CIFrdtech.o: CIFrdtech.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../utils/tech.h ../textio/textio.h \
../utils/utils.h ../cif/CIFint.h ../cif/CIFread.h ../calma/calmaInt.h \
../utils/malloc.h
CIFrdutils.o: CIFrdutils.c ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/hash.h ../database/database.h ../cif/CIFint.h \
../cif/CIFread.h ../cif/cif.h ../textio/textio.h ../utils/signals.h \
../utils/undo.h ../utils/malloc.h
CIFsee.o: CIFsee.c ../utils/magic.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../database/database.h ../windows/windows.h \
../graphics/graphics.h ../dbwind/dbwind.h ../utils/styles.h \
../cif/CIFint.h ../textio/textio.h ../utils/undo.h
CIFtech.o: CIFtech.c ../utils/magic.h ../utils/geometry.h ../tiles/tile.h \
../utils/hash.h ../database/database.h ../utils/tech.h ../utils/utils.h \
../utils/styles.h ../cif/CIFint.h ../calma/calmaInt.h ../textio/textio.h \
../utils/malloc.h ../cif/cif.h ../drc/drc.h
CIFwrite.o: CIFwrite.c ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/utils.h ../utils/hash.h ../database/database.h \
../database/databaseInt.h ../utils/tech.h ../utils/stack.h \
../utils/undo.h ../cif/cif.h ../cif/CIFint.h ../utils/signals.h \
../windows/windows.h ../dbwind/dbwind.h ../utils/styles.h \
../textio/textio.h

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"
@ -30,10 +30,6 @@
* depends on the size of the layout. * depends on the size of the layout.
*/ */
/* Passed to CIFPaintCurrent() for print statement formatting */
#define FILE_CIF 0
#define FILE_CALMA 1
/* Exported global variables (commands/CmdCD.c) */ /* Exported global variables (commands/CmdCD.c) */
extern int CIFWarningLevel; extern int CIFWarningLevel;
@ -51,48 +47,42 @@ extern bool CIFUnfracture;
/* Procedures that parse the cif sections of a technology file. */ /* Procedures that parse the cif sections of a technology file. */
extern void CIFTechStyleInit(void); extern void CIFTechStyleInit();
extern void CIFTechInit(void); extern void CIFTechInit();
extern bool CIFTechLine(char *sectionName, int argc, char *argv[]); extern bool CIFTechLine();
extern void CIFTechFinal(void); extern void CIFTechFinal();
extern void CIFTechOutputScale(int n, int d); extern void CIFTechOutputScale();
extern int CIFTechInputScale(int n, int d, bool opt); extern void CIFTechInputScale();
extern bool CIFTechLimitScale(int ns, int ds); extern bool CIFTechLimitScale();
extern void CIFReadTechStyleInit(void); extern void CIFReadTechStyleInit();
extern void CIFReadTechInit(void); extern void CIFReadTechInit();
extern bool CIFReadTechLine(char *sectionName, int argc, char *argv[]); extern bool CIFReadTechLine();
extern void CIFReadTechFinal(void); extern void CIFReadTechFinal();
extern void CIFParseReadLayers(char *string, TileTypeBitMask *mask, bool newok);
/* Externally-visible procedures: */ /* Externally-visible procedures: */
extern float CIFGetOutputScale(int convert); extern float CIFGetOutputScale();
extern float CIFGetScale(int convert); extern float CIFGetInputScale();
extern float CIFGetInputScale(int convert); extern int CIFGetDefaultContactSize();
extern int CIFPaintCurrent(int filetype); extern int CIFPaintCurrent();
extern void CIFSeeLayer(CellDef *rootDef, Rect *area, char *layer); extern void CIFSeeLayer();
extern void CIFPaintLayer(CellDef *rootDef, Rect *area, char *cifLayer, int magicLayer, CellDef *paintDef); extern void CIFPaintLayer();
extern void CIFSeeHierLayer(CellDef *rootDef, Rect *area, char *layer, int arrays, int subcells); extern void CIFSeeHierLayer();
extern void CIFPrintStats(void); extern void CIFPrintStats();
extern bool CIFWrite(CellDef *rootDef, FILE *f); extern bool CIFWrite();
extern void CIFReadFile(FILE *file); extern void CIFReadFile();
extern void CIFSetStyle(char *name); extern void CIFSetStyle();
extern void CIFSetReadStyle(char *name); extern void CIFSetReadStyle();
extern void CIFPrintStyle(bool dolist, bool doforall, bool docurrent); extern void CIFPrintStyle();
extern void CIFPrintReadStyle(bool dolist, bool doforall, bool docurrent); extern void CIFPrintReadStyle();
extern int CIFOutputScaleFactor(void); extern int CIFOutputScaleFactor();
extern void PaintWireList(Point *pointlist, int number, int width, int endcap, Plane *plane, extern void PaintWireList();
PaintResultType *ptable, PaintUndoInfo *ui); extern LinkedRect *PaintPolygon();
extern LinkedRect *PaintPolygon(Point *pointlist, int number, Plane *plane, PaintResultType *ptable,
PaintUndoInfo *ui, int keep);
/* C99 compat */ #endif /* _CIF_H */
extern int CIFGetContactSize(TileType type, int *edge, int *spacing, int *border);
#endif /* _MAGIC__CIF__CIF_H */

View File

@ -17,7 +17,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWcmmnds.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWcmmnds.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -43,11 +43,10 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
/* Forward declarations: */ /* Forward declarations: */
extern void cmwButtonUp(MagWindow *w, Point *p, int button); extern void cmwButtonUp(), cmwButtonDown();
extern void cmwButtonDown(MagWindow *w, Point *p, int button); extern void cbUpdate();
extern void cbUpdate(MagWindow *w, int code, double x, int replace); extern void RGBxHSV();
extern bool RGBxHSV(double r, double g, double b, double *h, double *s, double *v); extern void HSVxRGB();
extern void HSVxRGB(double h, double s, double v, double *r, double *g, double *b);
/* If a button is pressed over the top box in the window, which /* If a button is pressed over the top box in the window, which
* displays the current color, we must save the window in which * displays the current color, we must save the window in which
@ -65,7 +64,7 @@ bool cmwWatchButtonUp;
bool cmwModified = FALSE; bool cmwModified = FALSE;
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -85,9 +84,9 @@ bool cmwModified = FALSE;
*/ */
void void
CMWcommand( CMWcommand(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
switch (cmd->tx_button) switch (cmd->tx_button)
{ {
@ -138,13 +137,13 @@ CMWcommand(
*/ */
void void
cmwButtonDown( cmwButtonDown(w, p, button)
MagWindow *w, /* Window where the button was pressed. */ MagWindow *w; /* Window where the button was pressed. */
Point *p, Point *p;
int button) int button;
{ {
const ColorBar *cb; ColorBar *cb;
const ColorPump *cp; ColorPump *cp;
Point surfacePoint; Point surfacePoint;
int x; int x;
double dx; double dx;
@ -225,14 +224,14 @@ cmwButtonDown(
*/ */
void void
cmwButtonUp( cmwButtonUp(w, p, button)
MagWindow *w, /* Window where the button was released */ MagWindow *w; /* Window where the button was released */
Point *p, /* Point where button was released, in window coords.*/ Point *p; /* Point where button was released, in window coords.*/
int button) /* Button that was released. */ int button; /* Button that was released. */
{ {
CMWclientRec *crec; CMWclientRec *crec;
int r, g, b, color, oldR, oldG, oldB; int r, g, b, color, oldR, oldG, oldB;
extern int cmwRedisplayFunc(MagWindow *w, int color); extern int cmwRedisplayFunc();
/* If the button wasn't depressed over the top box in the window /* If the button wasn't depressed over the top box in the window
* (the one displaying the current color), then we ignore the * (the one displaying the current color), then we ignore the
@ -297,12 +296,12 @@ cmwButtonUp(
*/ */
void void
cmwPushbutton( cmwPushbutton(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int button; int button;
static const char * const cmwButton[] = {"left", "middle", "right", NULL}; static char *cmwButton[] = {"left", "middle", "right", NULL};
if (cmd->tx_argc != 2) if (cmd->tx_argc != 2)
{ {
@ -356,9 +355,9 @@ cmwPushbutton(
*/ */
void void
cmwColor( cmwColor(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int color, r, g, b; int color, r, g, b;
CMWclientRec *crec; CMWclientRec *crec;
@ -373,7 +372,7 @@ cmwColor(
} }
else if (cmd->tx_argc == 2) else if (cmd->tx_argc == 2)
{ {
if (sscanf(cmd->tx_argv[1], "%i", &color) != 1) if (sscanf(cmd->tx_argv[1], "%i", &color) == 0)
{ {
/* Invalid color---allow keywords "next" and "last" */ /* Invalid color---allow keywords "next" and "last" */
crec = (CMWclientRec *) w->w_clientData; crec = (CMWclientRec *) w->w_clientData;
@ -430,7 +429,7 @@ cmwColor(
else else
TxError("Usage: color [#|next|last|get|rgb]\n"); TxError("Usage: color [#|next|last|get|rgb]\n");
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -451,9 +450,9 @@ cmwColor(
*/ */
void void
cmwSave( cmwSave(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
bool ok; bool ok;
if ((cmd->tx_argc != 1) && (cmd->tx_argc != 4)) if ((cmd->tx_argc != 1) && (cmd->tx_argc != 4))
@ -474,7 +473,7 @@ cmwSave(
} }
if (ok) cmwModified = FALSE; if (ok) cmwModified = FALSE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -496,9 +495,9 @@ cmwSave(
*/ */
void void
cmwLoad( cmwLoad(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
if ((cmd->tx_argc != 1) && (cmd->tx_argc != 4)) if ((cmd->tx_argc != 1) && (cmd->tx_argc != 4))
{ {
@ -515,7 +514,7 @@ cmwLoad(
else (void) GrReadCMap(DBWStyleType, (char *) NULL, else (void) GrReadCMap(DBWStyleType, (char *) NULL,
MainMonType, ".", SysLibPath); MainMonType, ".", SysLibPath);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -538,18 +537,18 @@ cmwLoad(
*/ */
void void
cbUpdate( cbUpdate(w, code, x, replace)
MagWindow *w, /* Window whose color is to be changed. */ MagWindow *w; /* Window whose color is to be changed. */
int code, /* Indicates which color component to change. */ int code; /* Indicates which color component to change. */
double x, /* Gives increment or new value for color. */ double x; /* Gives increment or new value for color. */
int replace) /* TRUE means replace component with x, FALSE int replace; /* TRUE means replace component with x, FALSE
* means increment component by x. * means increment component by x.
*/ */
{ {
CMWclientRec *cr = (CMWclientRec *) w->w_clientData; CMWclientRec *cr = (CMWclientRec *) w->w_clientData;
double values[6]; double values[6];
int r, g, b, nr, ng, nb; int r, g, b, nr, ng, nb;
extern int cmwRedisplayFunc(MagWindow *w, int color); extern int cmwRedisplayFunc();
/* Get current color map values */ /* Get current color map values */
(void) GrGetColor(cr->cmw_color, &r, &g, &b); (void) GrGetColor(cr->cmw_color, &r, &g, &b);
@ -592,14 +591,14 @@ cbUpdate(
} }
int int
cmwRedisplayFunc( cmwRedisplayFunc(w, color)
MagWindow *w, /* Window that may have to be redisplayed. */ MagWindow *w; /* Window that may have to be redisplayed. */
int color) /* If this color is in window, redisplay the int color; /* If this color is in window, redisplay the
* color bars in the window. * color bars in the window.
*/ */
{ {
const ColorBar *cb; ColorBar *cb;
const ColorPump *cp; ColorPump *cp;
Rect screenR; Rect screenR;
CMWclientRec *cr = (CMWclientRec *) w->w_clientData; CMWclientRec *cr = (CMWclientRec *) w->w_clientData;
@ -645,11 +644,11 @@ cmwRedisplayFunc(
*/ */
bool bool
CMWCheckWritten(void) CMWCheckWritten()
{ {
bool indx; bool indx;
char *prompt; char *prompt;
static const char * const yesno[] = {"no", "yes", NULL}; static char *(yesno[]) = {"no", "yes", NULL};
if (!cmwModified) return TRUE; if (!cmwModified) return TRUE;
prompt = TxPrintString("The color map has been modified.\n" prompt = TxPrintString("The color map has been modified.\n"

View File

@ -18,7 +18,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWmain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWmain.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -44,12 +44,12 @@ global WindClient CMWclientID;
/* Forward and external declarations */ /* Forward and external declarations */
extern void cmwColor(MagWindow *w, TxCommand *cmd); extern void cmwColor();
extern void cmwSave(MagWindow *w, TxCommand *cmd); extern void cmwSave();
extern void cmwLoad(MagWindow *w, TxCommand *cmd); extern void cmwLoad();
extern void cmwPushbutton(MagWindow *w, TxCommand *cmd); extern void cmwPushbutton();
extern bool RGBxHSV(double r, double g, double b, double *h, double *s, double *v); extern void RGBxHSV();
extern void CMWundoInit(void); extern void CMWundoInit();
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */
@ -89,48 +89,48 @@ extern void CMWundoInit(void);
* which pump is hit and which mouse button is used to hit it. * which pump is hit and which mouse button is used to hit it.
*/ */
const ColorBar colorBars[] = ColorBar colorBars[] =
{ {
{"Red", CB_RED, STYLE_RED, {{ 2000, 8000}, {10000, 9000}}, "Red", CB_RED, STYLE_RED, {2000, 8000, 10000, 9000},
{{ 2000, 9500}, {10000, 10500}}}, {2000, 9500, 10000, 10500},
{"Green", CB_GREEN, STYLE_GREEN, {{ 2000, 5000}, {10000, 6000}}, "Green", CB_GREEN, STYLE_GREEN, {2000, 5000, 10000, 6000},
{{ 2000, 6500}, {10000, 7500}}}, {2000, 6500, 10000, 7500},
{"Blue", CB_BLUE, STYLE_BLUE, {{ 2000, 2000}, {10000, 3000}}, "Blue", CB_BLUE, STYLE_BLUE, {2000, 2000, 10000, 3000},
{{ 2000, 3500}, {10000, 4500}}}, {2000, 3500, 10000, 4500},
{"Hue", CB_HUE, STYLE_YELLOW, {{14000, 8000}, {22000, 9000}}, "Hue", CB_HUE, STYLE_YELLOW, {14000, 8000, 22000, 9000},
{{14000, 9500}, {22000, 10500}}}, {14000, 9500, 22000, 10500},
{"Saturation", CB_SAT, STYLE_GRAY, {{14000, 5000}, {22000, 6000}}, "Saturation", CB_SAT, STYLE_GRAY, {14000, 5000, 22000, 6000},
{{14000, 6500}, {22000, 7500}}}, {14000, 6500, 22000, 7500},
{"Value", CB_VALUE, STYLE_BROWN1, {{14000, 2000}, {22000, 3000}}, "Value", CB_VALUE, STYLE_BROWN1, {14000, 2000, 22000, 3000},
{{14000, 3500}, {22000, 4500}}}, {14000, 3500, 22000, 4500},
{0} 0
}; };
const ColorPump colorPumps[] = ColorPump colorPumps[] =
{ {
{CB_RED, -.0078, {{ 500, 8000}, { 1500, 9000}}}, CB_RED, -.0078, {500, 8000, 1500, 9000},
{CB_RED, .0078, {{10500, 8000}, {11500, 9000}}}, CB_RED, .0078, {10500, 8000, 11500, 9000},
{CB_GREEN, -.0078, {{ 500, 5000}, { 1500, 6000}}}, CB_GREEN, -.0078, {500, 5000, 1500, 6000},
{CB_GREEN, .0078, {{10500, 5000}, {11500, 6000}}}, CB_GREEN, .0078, {10500, 5000, 11500, 6000},
{CB_BLUE, -.0078, {{ 500, 2000}, { 1500, 3000}}}, CB_BLUE, -.0078, {500, 2000, 1500, 3000},
{CB_BLUE, .0078, {{10500, 2000}, {11500, 3000}}}, CB_BLUE, .0078, {10500, 2000, 11500, 3000},
{CB_HUE, -.01, {{12500, 8000}, {13500, 9000}}}, CB_HUE, -.01, {12500, 8000, 13500, 9000},
{CB_HUE, .01, {{22500, 8000}, {23500, 9000}}}, CB_HUE, .01, {22500, 8000, 23500, 9000},
{CB_SAT, -.01, {{12500, 5000}, {13500, 6000}}}, CB_SAT, -.01, {12500, 5000, 13500, 6000},
{CB_SAT, .01, {{22500, 5000}, {23500, 6000}}}, CB_SAT, .01, {22500, 5000, 23500, 6000},
{CB_VALUE, -.01, {{12500, 2000}, {13500, 3000}}}, CB_VALUE, -.01, {12500, 2000, 13500, 3000},
{CB_VALUE, .01, {{22500, 2000}, {23500, 3000}}}, CB_VALUE, .01, {22500, 2000, 23500, 3000},
{-1} -1
}; };
const Rect cmwCurrentColorArea = {{6000, 12000}, {18000, 15000}}; Rect cmwCurrentColorArea = {{6000, 12000}, {18000, 15000}};
const Rect cmwCurrentColorTextBox = {{6000, 15500}, {18000, 16500}}; Rect cmwCurrentColorTextBox = {{6000, 15500}, {18000, 16500}};
const char * const cmwCurrentColorText = "Color Being Edited"; char *cmwCurrentColorText = "Color Being Edited";
/* Bounding rectangle for entire window */ /* Bounding rectangle for entire window */
const Rect colorWindowRect = {{0, 1500}, {24000, 17000}}; Rect colorWindowRect = {{0, 1500}, {24000, 17000}};
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -149,13 +149,13 @@ const Rect colorWindowRect = {{0, 1500}, {24000, 17000}};
*/ */
bool bool
CMWcreate( CMWcreate(window, argc, argv)
MagWindow *window, MagWindow *window;
int argc, int argc;
char *argv[]) char *argv[];
{ {
CMWclientRec *crec; CMWclientRec *crec;
unsigned int color; int color;
crec = (CMWclientRec *) mallocMagic(sizeof(CMWclientRec)); crec = (CMWclientRec *) mallocMagic(sizeof(CMWclientRec));
window->w_clientData = (ClientData) crec; window->w_clientData = (ClientData) crec;
@ -171,7 +171,7 @@ CMWcreate(
CMWloadWindow(window, color); CMWloadWindow(window, color);
return (TRUE); return (TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -189,8 +189,8 @@ CMWcreate(
*/ */
bool bool
CMWdelete( CMWdelete(window)
MagWindow *window) MagWindow *window;
{ {
CMWclientRec *cr; CMWclientRec *cr;
@ -200,7 +200,7 @@ CMWdelete(
freeMagic((char *) cr); freeMagic((char *) cr);
return (TRUE); return (TRUE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -218,16 +218,16 @@ CMWdelete(
*/ */
void void
CMWreposition( CMWreposition(window, newScreenArea, final)
MagWindow *window, MagWindow *window;
Rect *newScreenArea, Rect *newScreenArea;
bool final) bool final;
{ {
if (final) if (final)
WindMove(window, &colorWindowRect); WindMove(window, &colorWindowRect);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -244,14 +244,14 @@ CMWreposition(
*/ */
void void
CMWredisplay( CMWredisplay(w, rootArea, clipArea)
MagWindow *w, /* The window containing the area. */ MagWindow *w; /* The window containing the area. */
Rect *rootArea, /* Redisplay area in surface coordinates. */ Rect *rootArea; /* Redisplay area in surface coordinates. */
Rect *clipArea) /* An area on the screen to clip to. */ Rect *clipArea; /* An area on the screen to clip to. */
{ {
CMWclientRec *cr; CMWclientRec *cr;
const ColorBar *cb; ColorBar *cb;
const ColorPump *cp; ColorPump *cp;
Rect rect, screenR; Rect rect, screenR;
Point screenP; Point screenP;
double values[6], x; double values[6], x;
@ -353,7 +353,7 @@ CMWredisplay(
GrUnlock(w); GrUnlock(w);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -372,9 +372,9 @@ CMWredisplay(
*/ */
void void
CMWloadWindow( CMWloadWindow(w, color)
MagWindow *w, /* Identifies window to which color is to be bound */ MagWindow *w; /* Identifies window to which color is to be bound */
int color) /* New color to be bound to this window. */ int color; /* New color to be bound to this window. */
{ {
CMWclientRec *cr = (CMWclientRec *) w->w_clientData; CMWclientRec *cr = (CMWclientRec *) w->w_clientData;
char caption[40]; char caption[40];
@ -389,7 +389,7 @@ CMWloadWindow(
/* move the contents of the window so the color bars show */ /* move the contents of the window so the color bars show */
WindMove(w, &colorWindowRect); WindMove(w, &colorWindowRect);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -407,7 +407,7 @@ CMWloadWindow(
*/ */
void void
CMWinit(void) CMWinit()
{ {
CMWclientID = WindAddClient("color", CMWcreate, CMWdelete, CMWclientID = WindAddClient("color", CMWcreate, CMWdelete,
CMWredisplay, CMWcommand, CMWredisplay, CMWcommand,

View File

@ -18,7 +18,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWrgbhsv.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWrgbhsv.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -45,13 +45,9 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
*/ */
bool bool
RGBxHSV( RGBxHSV( r, g, b, h, s, v)
double r, double r, g, b;
double g, double *h, *s, *v;
double b,
double *h,
double *s,
double *v)
{ {
double max, delta; double max, delta;
double mr,mg,mb; double mr,mg,mb;
@ -94,14 +90,10 @@ RGBxHSV(
#define SETRGB(rr,gg,bb) *r=rr;*g=gg;*b=bb #define SETRGB(rr,gg,bb) *r=rr;*g=gg;*b=bb
void void
HSVxRGB( HSVxRGB( h,s,v,r,g,b)
double h, double h,s,v;
double s, double *r,*g,*b;
double v, {
double *r,
double *g,
double *b)
{
double f,m,n,k; double f,m,n,k;
int i; int i;
double vs,vsf; double vs,vsf;
@ -133,13 +125,9 @@ HSVxRGB(
*/ */
bool bool
RGBxHSL( RGBxHSL( r, g, b, h, s, l )
double r, double r, g, b;
double g, double *h, *s, *l;
double b,
double *h,
double *s,
double *l)
{ {
double min, max; double min, max;
double delta, mr, mg, mb; double delta, mr, mg, mb;
@ -196,13 +184,9 @@ RGBxHSL(
*/ */
void void
HSLxRGB( HSLxRGB( h, s, l, r, g, b )
double h, double h, s, l;
double s, double *r, *g, *b;
double l,
double *r,
double *g,
double *b)
{ {
double min; double min;
double v; double v;
@ -251,11 +235,9 @@ HSLxRGB(
*/ */
void void
Correct_chromaticity( Correct_chromaticity(x, y, wx, wy)
double *x, double *x,*y;
double *y, double wx,wy;
double wx,
double wy)
{ {
double oldx,oldy; double oldx,oldy;
double slope; double slope;
@ -279,13 +261,9 @@ Correct_chromaticity(
*/ */
void void
xyz_to_mrgb( xyz_to_mrgb(x, y, z, mr, mg, mb)
double x, double x, y, z;
double y, double *mr, *mg, *mb;
double z,
double *mr,
double *mg,
double *mb)
{ {
*mr = 2.4513*x - 1.2249*y - 0.3237*z; *mr = 2.4513*x - 1.2249*y - 0.3237*z;
*mg = -1.4746*x + 2.5052*y + 0.0596*z; *mg = -1.4746*x + 2.5052*y + 0.0596*z;
@ -303,10 +281,8 @@ xyz_to_mrgb(
*/ */
void void
Make_mRGB_Nice( Make_mRGB_Nice(mR,mG,mB)
double *mR, double *mR,*mG,*mB;
double *mG,
double *mB)
{ {
double min,max; double min,max;
double mr, mg, mb; double mr, mg, mb;

View File

@ -17,7 +17,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWundo.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWundo.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -35,6 +35,12 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
*/ */
UndoType cmwUndoClientID; UndoType cmwUndoClientID;
/*
* Functions to play events forward/backward.
*/
void cmwUndoForw(), cmwUndoBack();
void cmwUndoStart(), cmwUndoDone();
/* /*
* A single undo event for the * A single undo event for the
* color map module. * color map module.
@ -51,15 +57,7 @@ UndoType cmwUndoClientID;
* of an undo/redo command. * of an undo/redo command.
*/ */
bool cmwColorsChanged[256]; bool cmwColorsChanged[256];
/*
* Functions to play events forward/backward.
*/
void cmwUndoForw(colorUE *up);
void cmwUndoBack(colorUE *up);
void cmwUndoStart(void);
void cmwUndoDone(void);
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -79,13 +77,13 @@ void cmwUndoDone(void);
*/ */
void void
CMWundoInit(void) CMWundoInit()
{ {
cmwUndoClientID = UndoAddClient(cmwUndoStart, cmwUndoDone, NULL, NULL, cmwUndoClientID = UndoAddClient(cmwUndoStart, cmwUndoDone, NULL, NULL,
cmwUndoForw, cmwUndoBack, "color map"); cmwUndoForw, cmwUndoBack, "color map");
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -104,21 +102,21 @@ CMWundoInit(void)
*/ */
void void
cmwUndoForw( cmwUndoForw(up)
colorUE *up) colorUE *up;
{ {
(void) GrPutColor(up->cue_color, up->new_r, up->new_g, up->new_b); (void) GrPutColor(up->cue_color, up->new_r, up->new_g, up->new_b);
cmwColorsChanged[up->cue_color] = TRUE; cmwColorsChanged[up->cue_color] = TRUE;
} }
void void
cmwUndoBack( cmwUndoBack(up)
colorUE *up) colorUE *up;
{ {
(void) GrPutColor(up->cue_color, up->old_r, up->old_g, up->old_b); (void) GrPutColor(up->cue_color, up->old_r, up->old_g, up->old_b);
cmwColorsChanged[up->cue_color] = TRUE; cmwColorsChanged[up->cue_color] = TRUE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -136,14 +134,10 @@ cmwUndoBack(
*/ */
void void
cmwUndoColor( cmwUndoColor(color, oldr, oldg, oldb, newr, newg, newb)
int color, int color;
int oldr, int oldr, oldg, oldb;
int oldg, int newr, newg, newb;
int oldb,
int newr,
int newg,
int newb)
{ {
colorUE *up; colorUE *up;
@ -159,7 +153,7 @@ cmwUndoColor(
up->new_g = newg; up->new_g = newg;
up->new_b = newb; up->new_b = newb;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -177,14 +171,14 @@ cmwUndoColor(
*/ */
void void
cmwUndoStart(void) cmwUndoStart()
{ {
int i; int i;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
cmwColorsChanged[i] = FALSE; cmwColorsChanged[i] = FALSE;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -204,13 +198,13 @@ cmwUndoStart(void)
*/ */
void void
cmwUndoDone(void) cmwUndoDone()
{ {
int i; int i;
extern int cmwRedisplayFunc(MagWindow *w, int color); extern int cmwRedisplayFunc();
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
if (cmwColorsChanged[i]) if (cmwColorsChanged[i])
(void) WindSearch(CMWclientID, (ClientData) NULL, (Rect *) NULL, (void) WindSearch(CMWclientID, (ClientData) NULL, (Rect *) NULL,
cmwRedisplayFunc, INT2CD(i)); cmwRedisplayFunc, (ClientData) i);
} }

16
cmwind/Depend Normal file
View File

@ -0,0 +1,16 @@
CMWmain.o: CMWmain.c ../utils/magic.h ../utils/geometry.h \
../windows/windows.h ../database/database.h ../tiles/tile.h \
../utils/hash.h ../utils/main.h ../commands/commands.h \
../cmwind/cmwind.h ../textio/txcommands.h ../graphics/graphicsInt.h \
../graphics/graphics.h ../textio/textio.h ../utils/utils.h \
../utils/styles.h ../graphics/glyphs.h ../utils/malloc.h
CMWcmmnds.o: CMWcmmnds.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../windows/windows.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../dbwind/dbwind.h ../utils/main.h \
../commands/commands.h ../cmwind/cmwind.h ../textio/txcommands.h \
../graphics/graphics.h ../textio/textio.h ../utils/utils.h \
../utils/styles.h ../utils/undo.h
CMWundo.o: CMWundo.c ../utils/magic.h ../utils/geometry.h \
../graphics/graphics.h ../windows/windows.h ../cmwind/cmwind.h \
../textio/txcommands.h ../utils/undo.h
CMWrgbhsv.o: CMWrgbhsv.c ../utils/magic.h

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"
@ -69,16 +69,12 @@ typedef struct
extern void CMWloadWindow(MagWindow *, int); extern void CMWloadWindow(MagWindow *, int);
extern void CMWcommand(MagWindow *, TxCommand *); extern void CMWcommand(MagWindow *, TxCommand *);
extern const Rect colorWindowRect; extern Rect colorWindowRect;
extern WindClient CMWclientID; extern WindClient CMWclientID;
extern const ColorBar colorBars[]; extern ColorBar colorBars[];
extern const ColorPump colorPumps[]; extern ColorPump colorPumps[];
extern const Rect cmwCurrentColorArea; extern Rect cmwCurrentColorArea;
extern void cmwUndoColor(int, int, int, int, int, int, int); extern void cmwUndoColor(int, int, int, int, int, int, int);
extern bool CMWCheckWritten(void); extern bool CMWCheckWritten(void);
/* C99 compat */ #endif /* _CMWIND_H */
extern void CMWinit(void);
#endif /* _MAGIC__CMWIND__CMWIND_H */

View File

@ -17,7 +17,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdAB.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdAB.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -44,13 +44,13 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "utils/netlist.h" #include "utils/netlist.h"
#include "select/select.h" #include "select/select.h"
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* *
* CmdAddPath -- * CmdAddPath --
* *
* Implement the "addpath" command: append to the global cell search path. * Implement the "addpath" command: append to the global cell search path.
* (Usage superseded by extended "path" command; retained for compatibility) * (Usage superceded by extended "path" command; retained for compatibility)
* *
* Usage: * Usage:
* addpath path * addpath path
@ -70,9 +70,9 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
/*ARGSUSED*/ /*ARGSUSED*/
void void
CmdAddPath( CmdAddPath( w, cmd )
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
if (cmd->tx_argc != 2) { if (cmd->tx_argc != 2) {
TxError("Usage: %s appended_search_path\n", cmd->tx_argv[0]); TxError("Usage: %s appended_search_path\n", cmd->tx_argv[0]);
@ -80,71 +80,7 @@ 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 */
@ -194,11 +130,11 @@ typedef struct LA1
#define ARRAY_DEFAULT 6 #define ARRAY_DEFAULT 6
void void
CmdArray( CmdArray(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
static const char * const cmdArrayOption[] = { static char *cmdArrayOption[] = {
"count [[xlo] xhi [ylo] yhi] array subcells", "count [[xlo] xhi [ylo] yhi] array subcells",
"width [value] set or return array x-spacing", "width [value] set or return array x-spacing",
"height [value] set or return array y-spacing", "height [value] set or return array y-spacing",
@ -208,7 +144,7 @@ CmdArray(
NULL NULL
}; };
const char * const *msg; char **msg;
int option, locargc, argstart; int option, locargc, argstart;
bool doList = FALSE; bool doList = FALSE;
ArrayInfo a; ArrayInfo a;
@ -220,7 +156,7 @@ CmdArray(
Tcl_Obj *tobj; Tcl_Obj *tobj;
#endif #endif
extern int selGetArrayFunc(CellUse *selUse, CellUse *use, Transform *trans, LinkedArray **arg); extern int selGetArrayFunc();
locargc = cmd->tx_argc; locargc = cmd->tx_argc;
argstart = 1; argstart = 1;
@ -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;
while (la != NULL)
{ {
la = lahead; freeMagic((char *)la);
while (la != NULL) la = la->ar_next;
{
free_magic1_t mm1 = freeMagic1_init();
freeMagic1(&mm1, (char *)la);
la = la->ar_next;
freeMagic1_end(&mm1);
}
} }
return; return;
} }
@ -564,11 +480,11 @@ freelist:
*/ */
int int
selGetArrayFunc( selGetArrayFunc(selUse, use, trans, arg)
CellUse *selUse, CellUse *selUse;
CellUse *use, CellUse *use;
Transform *trans, Transform *trans;
LinkedArray **arg) LinkedArray **arg;
{ {
/* Check "use" for array information and pass this to arrayInfo */ /* Check "use" for array information and pass this to arrayInfo */
@ -615,7 +531,7 @@ selGetArrayFunc(
return 0; return 0;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -629,8 +545,6 @@ selGetArrayFunc(
* box size [width height] * box size [width height]
* box position [llx lly] [-edit] * box position [llx lly] [-edit]
* box values [llx lly urx ury] [-edit] * box values [llx lly urx ury] [-edit]
* box remove
* box select
* *
* box <direction> <distance> | cursor * box <direction> <distance> | cursor
* *
@ -666,29 +580,25 @@ selGetArrayFunc(
#define BOX_SIZE 2 #define BOX_SIZE 2
#define BOX_POSITION 3 #define BOX_POSITION 3
#define BOX_VALUES 4 #define BOX_VALUES 4
#define BOX_REMOVE 5 #define BOX_MOVE 5
#define BOX_SELECT 6 #define BOX_GROW 6
#define BOX_MOVE 7 #define BOX_SHRINK 7
#define BOX_GROW 8 #define BOX_CORNER 8
#define BOX_SHRINK 9 #define BOX_EXISTS 9
#define BOX_CORNER 10 #define BOX_HELP 10
#define BOX_EXISTS 11 #define BOX_DEFAULT 11
#define BOX_HELP 12
#define BOX_DEFAULT 13
void void
CmdBox( CmdBox(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
static const char * const cmdBoxOption[] = { static char *cmdBoxOption[] = {
"width [value] set or return box width", "width [value] set or return box width",
"height [value] set or return box height", "height [value] set or return box height",
"size [width height] set or return box size", "size [width height] set or return box size",
"position [llx lly] [-edit] set or return box position", "position [llx lly] [-edit] set or return box position",
"values [llx lly urx ury] [-edit] set or return box coordinates", "values [llx lly urx ury] [-edit] set or return box coordinates",
"remove remove cursor box from display",
"select set box to selection bounding box",
"move <direction> <distance> move box position", "move <direction> <distance> move box position",
"grow <direction> <distance> expand box size", "grow <direction> <distance> expand box size",
"shrink <direction> <distance> shrink box size", "shrink <direction> <distance> shrink box size",
@ -699,7 +609,7 @@ CmdBox(
}; };
CellDef *rootBoxDef; CellDef *rootBoxDef;
Rect rootBox, editbox, savebox, *boxptr; Rect rootBox, editbox, *boxptr;
Point ll; Point ll;
int option, direction, distancex, distancey; int option, direction, distancex, distancey;
int width, height; int width, height;
@ -710,7 +620,7 @@ CmdBox(
bool needBox = TRUE; /* require that box be defined */ bool needBox = TRUE; /* require that box be defined */
bool refEdit = FALSE; /* referenced to edit cell coordinates */ bool refEdit = FALSE; /* referenced to edit cell coordinates */
bool cursorRef = FALSE; /* reference position is the cursor */ bool cursorRef = FALSE; /* reference position is the cursor */
const char * const *msg; char **msg;
argc = cmd->tx_argc; argc = cmd->tx_argc;
if (argc > 7) goto badusage; if (argc > 7) goto badusage;
@ -748,12 +658,6 @@ CmdBox(
windCheckOnlyWindow(&w, DBWclientID); windCheckOnlyWindow(&w, DBWclientID);
if (option == BOX_REMOVE)
{
DBWSetBox((CellDef *)NULL, &GeoNullRect);
return;
}
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
/* Check for the command options which do not require a box */ /* Check for the command options which do not require a box */
/* to be present. */ /* to be present. */
@ -779,8 +683,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
@ -840,7 +744,6 @@ CmdBox(
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
boxptr = (refEdit) ? &editbox : &rootBox; boxptr = (refEdit) ? &editbox : &rootBox;
savebox = *boxptr;
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
/* Parse arguments according to class */ /* Parse arguments according to class */
@ -881,25 +784,15 @@ CmdBox(
ToolMoveCorner(tcorner, &cmd->tx_p, TRUE, rootBoxDef); ToolMoveCorner(tcorner, &cmd->tx_p, TRUE, rootBoxDef);
break; break;
} }
/* Recast command as "box values" for logging purposes */
ToolGetBox(&rootBoxDef, &rootBox);
sprintf(cmd->tx_argstring, "box values %di %di %di %di",
rootBox.r_xbot, rootBox.r_ybot,
rootBox.r_xtop, rootBox.r_ytop);
TxRebuildCommand(cmd);
return; 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 +820,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 +840,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 +861,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 +885,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;
} }
@ -1028,48 +907,20 @@ CmdBox(
boxptr->r_ytop = boxptr->r_ybot + height; boxptr->r_ytop = boxptr->r_ybot + height;
break; break;
case BOX_SELECT:
if (argc == 2)
{
Rect selarea;
GeoTransRect(&SelectUse->cu_transform, &SelectDef->cd_bbox, &selarea);
boxptr->r_xbot = selarea.r_xbot;
boxptr->r_ybot = selarea.r_ybot;
boxptr->r_xtop = selarea.r_xtop;
boxptr->r_ytop = selarea.r_ytop;
}
else goto badusage;
break;
case BOX_VALUES: case BOX_VALUES:
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;
} }
@ -1242,13 +1093,13 @@ CmdBox(
if (area > 0) if (area > 0)
TxPrintf(" area (units^2)"); TxPrintf(" area (units^2)");
TxPrintf("\n\nmicrons: %6.3f x %-6.3f (% 6.3f, % -6.3f), " TxPrintf("\n\nmicrons: %6.2f x %-6.2f (% 6.2f, % -6.2f), "
"(% 6.3f, % -6.3f)", "(% 6.2f, % -6.2f)",
(float)width *oscale, (float)height * oscale, (float)width *oscale, (float)height * oscale,
(float)boxptr->r_xbot * oscale, (float)boxptr->r_ybot * oscale, (float)boxptr->r_xbot * oscale, (float)boxptr->r_ybot * oscale,
(float)boxptr->r_xtop * oscale, (float)boxptr->r_ytop * oscale); (float)boxptr->r_xtop * oscale, (float)boxptr->r_ytop * oscale);
if (area > 0) if (area > 0)
TxPrintf(" %-10.3f", (float)area * oscale * oscale); TxPrintf(" %-10.2f", (float)area * oscale * oscale);
TxPrintf("\nlambda:"); TxPrintf("\nlambda:");
if (DBLambda[0] != DBLambda[1]) if (DBLambda[0] != DBLambda[1])
@ -1271,7 +1122,7 @@ CmdBox(
boxptr->r_xbot, boxptr->r_ybot, boxptr->r_xbot, boxptr->r_ybot,
boxptr->r_xtop, boxptr->r_ytop); boxptr->r_xtop, boxptr->r_ytop);
if (area > 0) if (area > 0)
TxPrintf(" %-10"DLONG_PREFIX"d", area); TxPrintf(" %-10lld", area);
TxPrintf("\n"); TxPrintf("\n");
break; break;
@ -1291,18 +1142,6 @@ badusage:
if (refEdit) if (refEdit)
GeoTransRect(&EditToRootTransform, &editbox, &rootBox); GeoTransRect(&EditToRootTransform, &editbox, &rootBox);
/*----------------------------------------------------------*/
/* Check for numerical overflow in box values */
/*----------------------------------------------------------*/
if (boxptr->r_ll.p_x < (MINFINITY + 2) || boxptr->r_ll.p_x > (INFINITY - 2) ||
boxptr->r_ll.p_y < (MINFINITY + 2) || boxptr->r_ll.p_y > (INFINITY - 2))
{
*boxptr = savebox;
TxError("Box out of bounds.\n");
return;
}
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/
/* Change the position of the box in the layout window */ /* Change the position of the box in the layout window */
/*----------------------------------------------------------*/ /*----------------------------------------------------------*/

View File

@ -48,9 +48,9 @@
*/ */
void void
CmdAutoExtToSim( CmdAutoExtToSim(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int result; int result;
@ -83,9 +83,9 @@ CmdAutoExtToSim(
*/ */
void void
CmdAutoExtToSpice( CmdAutoExtToSpice(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int result; int result;
@ -119,9 +119,9 @@ CmdAutoExtToSpice(
*/ */
void void
CmdAutoRoute( CmdAutoRoute(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int result; int result;
@ -154,9 +154,9 @@ CmdAutoRoute(
*/ */
void void
CmdAutoPlot( CmdAutoPlot(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int result; int result;
@ -189,9 +189,9 @@ CmdAutoPlot(
*/ */
void void
CmdAutoLef( CmdAutoLef(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int result; int result;

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,7 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdE.c,v 1.4 2010/06/17 14:38:33 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdE.c,v 1.4 2010/06/17 14:38:33 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
@ -42,13 +42,9 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
#include "drc/drc.h" #include "drc/drc.h"
#include "textio/txcommands.h" #include "textio/txcommands.h"
#include "extract/extract.h" #include "extract/extract.h"
#include "extract/extractInt.h"
#include "select/select.h" #include "select/select.h"
/* C99 compat */
#include "dbwind/dbwtech.h"
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -56,12 +52,10 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
* *
* Implement the "edit" command. * Implement the "edit" command.
* Use the cell that is currently selected as the edit cell. If more than * Use the cell that is currently selected as the edit cell. If more than
* one cell is selected, use the point to choose between them. If the * one cell is selected, use the point to choose between them.
* optional argument "<instname>" is provided, then edit the specified
* instance (if it exists in the current layout window).
* *
* Usage: * Usage:
* edit [<instname>] * edit
* *
* Results: * Results:
* None. * None.
@ -79,29 +73,18 @@ static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magi
static bool cmdFoundNewEdit; static bool cmdFoundNewEdit;
void void
CmdEdit( CmdEdit(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
Rect area, pointArea; Rect area, pointArea;
CellUse *usave, *use = NULL; CellUse *usave;
CellDef *csave; CellDef *csave;
int cmdEditRedisplayFunc(MagWindow *w, Rect *area); /* Forward declaration. */ int cmdEditRedisplayFunc(); /* Forward declaration. */
int cmdEditEnumFunc(CellUse *selUse, CellUse *use, Transform *transform, Rect *area); /* Forward declaration. */ int cmdEditEnumFunc(); /* Forward declaration. */
bool noCurrentUse = FALSE; bool noCurrentUse = FALSE;
if ((w != NULL) && (cmd->tx_argc == 2)) if (cmd->tx_argc > 1)
{
CellUse *rootUse;
SearchContext scx;
rootUse = (CellUse *)w->w_surfaceID;
bzero(&scx, sizeof(SearchContext));
DBTreeFindUse(cmd->tx_argv[1], rootUse, &scx);
use = scx.scx_use;
}
if ((use == NULL) && (cmd->tx_argc > 1))
{ {
TxError("Usage: edit\nMaybe you want the \"load\" command\n"); TxError("Usage: edit\nMaybe you want the \"load\" command\n");
return; return;
@ -134,18 +117,10 @@ CmdEdit(
cmdFoundNewEdit = FALSE; cmdFoundNewEdit = FALSE;
csave = EditRootDef; csave = EditRootDef;
usave = EditCellUse; usave = EditCellUse;
EditCellUse = NULL;
if (use == NULL) (void) SelEnumCells(FALSE, (bool *) NULL, (SearchContext *) NULL,
{ cmdEditEnumFunc, (ClientData) &pointArea);
EditCellUse = NULL;
SelEnumCells(FALSE, (bool *) NULL, (SearchContext *) NULL,
cmdEditEnumFunc, (ClientData) &pointArea);
}
else
{
EditCellUse = use;
cmdFoundNewEdit = TRUE;
}
if (EditCellUse == (CellUse *)NULL) if (EditCellUse == (CellUse *)NULL)
{ {
@ -155,7 +130,7 @@ CmdEdit(
return; return;
} }
else if (!(EditCellUse->cu_def->cd_flags & CDAVAILABLE)) else if (!(EditCellUse->cu_def->cd_flags & CDAVAILABLE))
DBCellRead(EditCellUse->cu_def, TRUE, TRUE, NULL); DBCellRead(EditCellUse->cu_def, (char *)NULL, TRUE, NULL);
if (EditCellUse->cu_def->cd_flags & CDNOEDIT) if (EditCellUse->cu_def->cd_flags & CDNOEDIT)
{ {
@ -179,14 +154,6 @@ CmdEdit(
GeoTransRect(&EditToRootTransform, &(EditCellUse->cu_def->cd_bbox), &area); GeoTransRect(&EditToRootTransform, &(EditCellUse->cu_def->cd_bbox), &area);
(void) WindSearch(DBWclientID, (ClientData) NULL, (void) WindSearch(DBWclientID, (ClientData) NULL,
(Rect *) NULL, cmdEditRedisplayFunc, (ClientData) &area); (Rect *) NULL, cmdEditRedisplayFunc, (ClientData) &area);
if ((cmd->tx_argc == 1) && cmdFoundNewEdit)
{
/* Recast the command with the instance name for logging */
sprintf(cmd->tx_argstring, "edit %s", EditCellUse->cu_id);
TxRebuildCommand(cmd);
}
} }
/* Search function to handle redisplays for CmdEdit: it checks to /* Search function to handle redisplays for CmdEdit: it checks to
@ -197,11 +164,11 @@ CmdEdit(
*/ */
int int
cmdEditRedisplayFunc( cmdEditRedisplayFunc(w, area)
MagWindow *w, /* Window containing edit cell. */ MagWindow *w; /* Window containing edit cell. */
Rect *area) /* Area to be redisplayed. */ Rect *area; /* Area to be redisplayed. */
{ {
static const Rect origin = {{-1, -1}, {1, 1}}; static Rect origin = {-1, -1, 1, 1};
Rect tmp; Rect tmp;
DBWclientRec *crec = (DBWclientRec *) w->w_clientData; DBWclientRec *crec = (DBWclientRec *) w->w_clientData;
@ -226,13 +193,13 @@ cmdEditRedisplayFunc(
*/ */
int int
cmdEditEnumFunc( cmdEditEnumFunc(selUse, use, transform, area)
CellUse *selUse, /* Use from selection (not used). */ CellUse *selUse; /* Use from selection (not used). */
CellUse *use, /* Use from layout that corresponds to CellUse *use; /* Use from layout that corresponds to
* selUse (could be an array!). * selUse (could be an array!).
*/ */
Transform *transform, /* Transform from use->cu_def to root coords. */ Transform *transform; /* Transform from use->cu_def to root coords. */
Rect *area) /* We're looking for a use containing this Rect *area; /* We're looking for a use containing this
* area, in root coords. * area, in root coords.
*/ */
{ {
@ -305,20 +272,20 @@ cmdEditEnumFunc(
#define OPTION_FLAGS 3 #define OPTION_FLAGS 3
void void
CmdElement( CmdElement(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
int option, type; int option, type;
const char * const *msg; char **msg;
Rect area; Rect area;
int style; int style;
CellDef *def; CellDef *def;
CellUse *use; CellUse *use;
bool getopt; bool getopt;
static const char * const cmdElementOption[] = { static char *cmdElementOption[] = {
"add create a new element", "add create a new element",
"delete delete an existing element", "delete delete an existing element",
"configure configure or query an existing element", "configure configure or query an existing element",
@ -328,14 +295,14 @@ CmdElement(
NULL NULL
}; };
static const char * const cmdElementType[] = { static char *cmdElementType[] = {
"line name style x1 y1 x2 y2", "line name style x1 y1 x2 y2",
"rectangle name style llx lly urx ury", "rectangle name style llx lly urx ury",
"text name style cx cy label", "text name style cx cy label",
NULL NULL
}; };
static const char * const cmdConfigureType[] = { static char *cmdConfigureType[] = {
"text get (or) replace <string>", "text get (or) replace <string>",
"style get (or) add <style> (or) remove <style>", "style get (or) add <style> (or) remove <style>",
"position get (or) <point> (or) <rect>", "position get (or) <point> (or) <rect>",
@ -390,8 +357,10 @@ CmdElement(
return; return;
} }
} }
area.r_xbot = cmdParseCoord(w, cmd->tx_argv[5], FALSE, TRUE); if (!StrIsInt(cmd->tx_argv[5])) goto badusage;
area.r_ybot = cmdParseCoord(w, cmd->tx_argv[6], FALSE, FALSE); area.r_xbot = atoi(cmd->tx_argv[5]);
if (!StrIsInt(cmd->tx_argv[6])) goto badusage;
area.r_ybot = atoi(cmd->tx_argv[6]);
switch (type) switch (type)
{ {
@ -402,8 +371,10 @@ CmdElement(
cmdElementType[ELEMENT_LINE]); cmdElementType[ELEMENT_LINE]);
return; return;
} }
area.r_xtop = cmdParseCoord(w, cmd->tx_argv[7], FALSE, TRUE); if (!StrIsInt(cmd->tx_argv[7])) goto badusage;
area.r_ytop = cmdParseCoord(w, cmd->tx_argv[8], FALSE, FALSE); area.r_xtop = atoi(cmd->tx_argv[7]);
if (!StrIsInt(cmd->tx_argv[8])) goto badusage;
area.r_ytop = atoi(cmd->tx_argv[8]);
DBWElementAddLine(w, cmd->tx_argv[3], &area, def, style); DBWElementAddLine(w, cmd->tx_argv[3], &area, def, style);
break; break;
case ELEMENT_RECT: case ELEMENT_RECT:
@ -413,8 +384,10 @@ CmdElement(
cmdElementType[ELEMENT_RECT]); cmdElementType[ELEMENT_RECT]);
return; return;
} }
area.r_xtop = cmdParseCoord(w, cmd->tx_argv[7], FALSE, TRUE); if (!StrIsInt(cmd->tx_argv[7])) goto badusage;
area.r_ytop = cmdParseCoord(w, cmd->tx_argv[8], FALSE, FALSE); area.r_xtop = atoi(cmd->tx_argv[7]);
if (!StrIsInt(cmd->tx_argv[8])) goto badusage;
area.r_ytop = atoi(cmd->tx_argv[8]);
DBWElementAddRect(w, cmd->tx_argv[3], &area, def, style); DBWElementAddRect(w, cmd->tx_argv[3], &area, def, style);
break; break;
case ELEMENT_TEXT: case ELEMENT_TEXT:
@ -528,19 +501,21 @@ CmdElement(
if (cmd->tx_argc >= 6) if (cmd->tx_argc >= 6)
{ {
crect.r_xbot = cmdParseCoord(w, cmd->tx_argv[4], if (!StrIsInt(cmd->tx_argv[4]) ||
FALSE, TRUE); !StrIsInt(cmd->tx_argv[5]))
crect.r_ybot = cmdParseCoord(w, cmd->tx_argv[5], goto badrect;
FALSE, FALSE); crect.r_xbot = atoi(cmd->tx_argv[4]);
crect.r_ybot = atoi(cmd->tx_argv[5]);
crect.r_xtop = crect.r_xbot; /* placeholder */ crect.r_xtop = crect.r_xbot; /* placeholder */
crect.r_ytop = crect.r_ybot; /* placeholder */ crect.r_ytop = crect.r_ybot; /* placeholder */
} }
if (cmd->tx_argc == 8) if (cmd->tx_argc == 8)
{ {
crect.r_xtop = cmdParseCoord(w, cmd->tx_argv[6], if (!StrIsInt(cmd->tx_argv[6]) ||
FALSE, TRUE); !StrIsInt(cmd->tx_argv[7]))
crect.r_ytop = cmdParseCoord(w, cmd->tx_argv[7], goto badrect;
FALSE, FALSE); crect.r_xtop = atoi(cmd->tx_argv[6]);
crect.r_ytop = atoi(cmd->tx_argv[7]);
} }
if (cmd->tx_argc == 6 || cmd->tx_argc == 8) if (cmd->tx_argc == 6 || cmd->tx_argc == 8)
@ -595,7 +570,7 @@ badusage:
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -606,7 +581,7 @@ badusage:
* EditCellUse->cu_def. * EditCellUse->cu_def.
* *
* Usage: * Usage:
* erase [layers | cursor | pick x y] * erase [layers | cursor]
* *
* Results: * Results:
* None. * None.
@ -627,39 +602,24 @@ static CellUse *cmdEraseCells[MAXCELLS];
static int cmdEraseCount; static int cmdEraseCount;
void void
CmdErase( CmdErase(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
Rect editRect, areaReturn; Rect editRect, areaReturn;
TileTypeBitMask mask, errorLayersForErasure, activeLayersForErasure; TileTypeBitMask mask;
extern int cmdEraseCellsFunc(SearchContext *scx, ClientData cdarg); extern int cmdEraseCellsFunc();
windCheckOnlyWindow(&w, DBWclientID); windCheckOnlyWindow(&w, DBWclientID);
if (w == (MagWindow *) NULL) return; if (w == (MagWindow *) NULL) return;
if ((cmd->tx_argc == 4) && !strcmp(cmd->tx_argv[1], "pick"))
{
Point editPoint, rootPoint;
editPoint.p_x = cmdParseCoord(w, cmd->tx_argv[2], FALSE, TRUE);
editPoint.p_y = cmdParseCoord(w, cmd->tx_argv[3], FALSE, FALSE);
GeoTransPoint(&EditToRootTransform, &editPoint, &rootPoint);
CmdPaintEraseButton(w, &rootPoint, FALSE, FALSE);
return;
}
if (cmd->tx_argc > 2) if (cmd->tx_argc > 2)
{ {
TxError("Usage: %s [<layers> | cursor | pick x y]\n", cmd->tx_argv[0]); TxError("Usage: %s [<layers> | cursor]\n", cmd->tx_argv[0]);
return; return;
} }
if (!ToolGetEditBox(&editRect)) return; if (!ToolGetEditBox(&editRect)) return;
if (EditCellUse == NULL)
{
TxError("No cell def being edited!\n");
return;
}
/* /*
* Erase with no arguments is the same as erasing * Erase with no arguments is the same as erasing
@ -671,16 +631,7 @@ CmdErase(
(void) CmdParseLayers("*,label", &mask); (void) CmdParseLayers("*,label", &mask);
else if (!strncmp(cmd->tx_argv[1], "cursor", 6)) else if (!strncmp(cmd->tx_argv[1], "cursor", 6))
{ {
Point editPoint, rootPoint; CmdPaintEraseButton(w, &cmd->tx_p, FALSE);
CmdPaintEraseButton(w, &cmd->tx_p, FALSE, TRUE);
/* Recast the command as "erase pick x y" for logging purposes */
CmdGetRootPoint(&rootPoint, (Rect *)NULL);
GeoTransPoint(&RootToEditTransform, &rootPoint, &editPoint);
sprintf(cmd->tx_argstring, "erase pick %di %di", editPoint.p_x,
editPoint.p_y);
TxRebuildCommand(cmd);
return; return;
} }
else if (!CmdParseLayers(cmd->tx_argv[1], &mask)) else if (!CmdParseLayers(cmd->tx_argv[1], &mask))
@ -692,21 +643,10 @@ CmdErase(
if (TTMaskIsZero(&mask)) if (TTMaskIsZero(&mask))
return; return;
/* Split the mask into active and error layers. This restores */ TTMaskAndMask(&mask, &DBActiveLayerBits);
/* functionality lost since magic version 7.1. Modified by BIM */
/* (Iain McNally) 8/18/2018 */
TTMaskAndMask3(&activeLayersForErasure, &mask, &DBActiveLayerBits);
TTMaskClearMask3(&errorLayersForErasure, &mask, &DBAllButSpaceAndDRCBits);
/* Erase paint. */ /* Erase paint. */
DBEraseValid(EditCellUse->cu_def, &editRect, &activeLayersForErasure, 0); DBEraseValid(EditCellUse->cu_def, &editRect, &mask, 0);
/* Erase error layers if selected. */
if (!TTMaskIsZero(&errorLayersForErasure))
{
DBEraseMask(EditCellUse->cu_def, &editRect, &errorLayersForErasure);
}
/* Erase labels. */ /* Erase labels. */
areaReturn = editRect; areaReturn = editRect;
@ -759,9 +699,9 @@ CmdErase(
} }
int int
cmdEraseCellsFunc( cmdEraseCellsFunc(scx, cdarg)
SearchContext *scx, /* Indicates cell found. */ SearchContext *scx; /* Indicates cell found. */
ClientData cdarg) /* Not used. */ ClientData cdarg; /* Not used. */
{ {
/* All this procedure does is to remember cells that are /* All this procedure does is to remember cells that are
* found, up to MAXCELLS of them. * found, up to MAXCELLS of them.
@ -772,7 +712,7 @@ cmdEraseCellsFunc(
cmdEraseCount += 1; cmdEraseCount += 1;
return 2; return 2;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -781,82 +721,39 @@ 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(w, cmd)
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(); /* Forward reference. */
int cmdExpandFunc(CellUse *use, int windowMask); /* Forward reference. */ if (cmd->tx_argc > 2 || (cmd->tx_argc == 2
&& (strncmp(cmd->tx_argv[1], "toggle", strlen(cmd->tx_argv[1])) != 0)))
static const char * const cmdExpandOption[] = {
"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)
{ {
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 +784,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;
} }
} DBExpandAll(rootBoxUse, &rootRect, windowMask,
TRUE, cmdExpandFunc, (ClientData)(pointertype) windowMask);
switch (option)
{
case EXPAND_SELECTION:
SelectExpand(windowMask,
(doToggle) ? DB_EXPAND_TOGGLE : DB_EXPAND,
(Rect *)NULL, FALSE);
break;
case EXPAND_OVERLAP:
if (doToggle)
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND_TOGGLE | DB_EXPAND_OVERLAP,
&rootRect, FALSE);
}
else
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
&rootRect, FALSE);
}
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, TRUE);
}
else
{
DBExpandAll(rootBoxUse, &rootRect, windowMask,
DB_EXPAND | DB_EXPAND_SURROUND,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_SURROUND,
&rootRect, TRUE);
}
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, FALSE);
}
else
{
DBExpandAll(rootBoxUse, &TiPlaneRect, windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
cmdExpandFunc, (ClientData)(pointertype)windowMask);
SelectExpand(windowMask,
DB_EXPAND | DB_EXPAND_OVERLAP,
(Rect *)NULL, FALSE);
}
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.
@ -984,16 +809,16 @@ badusage:
*/ */
int int
cmdExpandFunc( cmdExpandFunc(use, windowMask)
CellUse *use, /* Use that was just expanded. */ CellUse *use; /* Use that was just expanded. */
int windowMask) /* Window where it was expanded. */ int windowMask; /* Window where it was expanded. */
{ {
if (use->cu_parent == NULL) return 0; if (use->cu_parent == NULL) return 0;
DBWAreaChanged(use->cu_parent, &use->cu_bbox, windowMask, DBWAreaChanged(use->cu_parent, &use->cu_bbox, windowMask,
&DBAllButSpaceBits); &DBAllButSpaceBits);
return 0; return 0;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1019,17 +844,14 @@ cmdExpandFunc(
#define EXTALL 0 #define EXTALL 0
#define EXTCELL 1 #define EXTCELL 1
#define EXTDO 2 #define EXTDO 2
#define EXTHALO 3 #define EXTHELP 3
#define EXTHELP 4 #define EXTLENGTH 4
#define EXTLENGTH 5 #define EXTNO 5
#define EXTNO 6 #define EXTPARENTS 6
#define EXTPARENTS 7 #define EXTSHOWPARENTS 7
#define EXTPATH 8 #define EXTSTYLE 8
#define EXTSHOWPARENTS 9 #define EXTUNIQUE 9
#define EXTSTEPSIZE 10 #define EXTWARN 10
#define EXTSTYLE 11
#define EXTUNIQUE 12
#define EXTWARN 13
#define WARNALL 0 #define WARNALL 0
#define WARNDUP 1 #define WARNDUP 1
@ -1040,14 +862,8 @@ 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 DORESISTANCE 5
#define DOLOCAL 6
#define DORESISTANCE 7
#define DOLABELCHECK 8
#define DOALIASES 9
#define DOUNIQUE 10
#define DOEXTRESIST2 11
#define LENCLEAR 0 #define LENCLEAR 0
#define LENDRIVER 1 #define LENDRIVER 1
@ -1056,27 +872,23 @@ cmdExpandFunc(
#define UNIQALL 0 #define UNIQALL 0
#define UNIQTAGGED 1 #define UNIQTAGGED 1
#define UNIQNOPORTS 2 #define UNIQNOPORTS 2
#define UNIQNOTOPPORTS 3
void void
CmdExtract( CmdExtract(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
const char * const *msg; char **msg, *namep, *arg;
char *namep, *arg;
int option, warn, len, n, all; int option, warn, len, n, all;
int dist;
bool no; bool no;
CellUse *selectedUse; CellUse *selectedUse;
CellDef *selectedDef; CellDef *selectedDef;
bool dolist = FALSE; bool dolist = FALSE;
bool doforall = FALSE; bool doforall = FALSE;
bool doLocal = FALSE;
int argc = cmd->tx_argc; int argc = cmd->tx_argc;
char **argv = cmd->tx_argv; char **argv = cmd->tx_argv;
static const char * const cmdExtWarn[] = static char *cmdExtWarn[] =
{ {
"all enable all warnings", "all enable all warnings",
"dup warn when different nodes have the same name", "dup warn when different nodes have the same name",
@ -1084,57 +896,44 @@ CmdExtract(
"labels warn when subcell nodes are unlabelled", "labels warn when subcell nodes are unlabelled",
NULL NULL
}; };
static const char * const cmdExtOption[] = static char *cmdExtOption[] =
{ {
"adjust compensate R and C hierarchically", "adjust compensate R and C hierarchically",
"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", "resistance estimate resistance",
"lumped estimate lumped resistance",
"labelcheck check for connections through sticky labels",
"aliases output all net name aliases",
"unique ensure unique node names during extraction",
"resistance extract resistance (same as \"do extresist\")",
NULL NULL
}; };
static const char * const cmdExtLength[] = static char *cmdExtLength[] =
{ {
"clear clear the driver and receiver tables", "clear clear the driver and receiver tables",
"driver termName(s) identify a driving (output) terminal", "driver termName(s) identify a driving (output) terminal",
"receiver termName(s) identify a receiving (input) terminal", "receiver termName(s) identify a receiving (input) terminal",
NULL NULL
}; };
static char *cmdExtUniq[] =
/* These must match definitions EXT_UNIQ_* in extract/extract.h: */
static const char * const cmdExtUniq[] =
{ {
"all extract matching labels as unique nodes", "all extract matching labels as unique nodes",
"# extract tagged labels as unique nodes", "# extract tagged labels as unique nodes",
"noports ignore ports when making labels unique", "noports ignore ports when making labels unique",
"notopports ignore top-level ports when making labels unique",
NULL NULL
}; };
static const char * const cmdExtCmd[] = static char *cmdExtCmd[] =
{ {
"all extract root cell and all its children", "all extract root cell and all its children",
"cell name extract selected cell into file \"name\"", "cell name extract selected cell into file \"name\"",
"do [option] enable extractor option", "do [option] enable extractor option",
"halo [value] print or set the sidewall halo distance",
"help print this help information", "help print this help information",
"length [option] control pathlength extraction information", "length [option] control pathlength extraction information",
"no [option] disable extractor option", "no [option] disable extractor option",
"parents extract selected cell and all its parents", "parents extract selected cell and all its parents",
"path [path] if set, extract into the indicated path",
"showparents show all parents of selected cell", "showparents show all parents of selected cell",
"stepsize [value] print or set the extraction step size",
"style [stylename] set current extraction parameter style", "style [stylename] set current extraction parameter style",
"unique [option] generate unique names when different nodes\n\ "unique [option] generate unique names when different nodes\n\
have the same name", have the same name",
"warn [ [no] option] enable/disable reporting of non-serious errors", "warn [ [no] option] enable/disable reporting of non-fatal errors",
NULL NULL
}; };
@ -1181,10 +980,7 @@ CmdExtract(
if (argc == 1) if (argc == 1)
{ {
if (!strcmp(selectedUse->cu_def->cd_name, UNNAMED)) ExtIncremental(selectedUse);
TxError("Please name the cell before extracting.\n");
else
ExtIncremental(selectedUse);
return; return;
} }
} }
@ -1215,10 +1011,7 @@ CmdExtract(
break; break;
case EXTALL: case EXTALL:
if (!strcmp(selectedUse->cu_def->cd_name, UNNAMED)) ExtAll(selectedUse);
TxError("Please name the cell before extracting.\n");
else
ExtAll(selectedUse);
return; return;
case EXTCELL: case EXTCELL:
@ -1230,70 +1023,9 @@ CmdExtract(
TxError("No cell selected\n"); TxError("No cell selected\n");
return; return;
} }
ExtractOneCell(selectedUse->cu_def, namep, FALSE); ExtCell(selectedUse->cu_def, namep, FALSE);
return; return;
case EXTHALO:
if (ExtCurStyle == NULL)
{
TxError("No extraction style set.\n");
return;
}
else if (argc == 2)
{
char *halodisp;
halodisp = DBWPrintValue(ExtCurStyle->exts_sideCoupleHalo,
w, TRUE);
#ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(halodisp, -1));
#else
TxPrintf("Side overlap halo is %s\n", halodisp);
#endif
return;
}
else if (argc != 3) goto wrongNumArgs;
/* argv[2] is a halo distance */
dist = cmdParseCoord(w, argv[2], TRUE, TRUE);
if (dist < 0)
{
TxError("Bad halo distance. Halo must be non-negative.");
return;
}
else
ExtCurStyle->exts_sideCoupleHalo = dist;
break;
case EXTSTEPSIZE:
if (ExtCurStyle == NULL)
{
TxError("No extraction style set.\n");
return;
}
else if (argc == 2)
{
char *stepdisp;
stepdisp = DBWPrintValue(ExtCurStyle->exts_stepSize, w, TRUE);
#ifdef MAGIC_WRAPPER
Tcl_SetObjResult(magicinterp, Tcl_NewStringObj(stepdisp, -1));
#else
TxPrintf("Extraction step size is %s\n", stepdisp);
#endif
return;
}
else if (argc != 3) goto wrongNumArgs;
/* argv[2] is a step size */
dist = cmdParseCoord(w, argv[2], TRUE, TRUE);
if (dist <= 0)
{
TxError("Bad step size. Step size must be strictly positive.");
return;
}
else
ExtCurStyle->exts_stepSize = dist;
break;
case EXTPARENTS: case EXTPARENTS:
selectedUse = CmdGetSelectedCell((Transform *) NULL); selectedUse = CmdGetSelectedCell((Transform *) NULL);
if (selectedUse == NULL) if (selectedUse == NULL)
@ -1301,10 +1033,7 @@ CmdExtract(
TxError("No cell selected\n"); TxError("No cell selected\n");
return; return;
} }
if (!strcmp(selectedUse->cu_def->cd_name, UNNAMED)) ExtParents(selectedUse);
TxError("Please name the cell before extracting.\n");
else
ExtParents(selectedUse);
return; return;
case EXTSHOWPARENTS: case EXTSHOWPARENTS:
@ -1317,13 +1046,6 @@ CmdExtract(
ExtShowParents(selectedUse); ExtShowParents(selectedUse);
return; return;
case EXTPATH:
if (argc == 2)
ExtPrintPath(dolist);
else
ExtSetPath(argv[2]);
return;
case EXTSTYLE: case EXTSTYLE:
if (argc == 2) if (argc == 2)
ExtPrintStyle(dolist, doforall, !doforall); ExtPrintStyle(dolist, doforall, !doforall);
@ -1399,11 +1121,7 @@ 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 aliases\n", OPTSET(EXT_DOALIASES));
TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE));
TxPrintf("%s resistance (extresist)\n", OPTSET(EXT_DOEXTRESIST));
return; return;
#undef OPTSET #undef OPTSET
} }
@ -1431,21 +1149,6 @@ CmdExtract(
case DOCOUPLING: option = EXT_DOCOUPLING; break; case DOCOUPLING: option = EXT_DOCOUPLING; break;
case DOLENGTH: option = EXT_DOLENGTH; break; case DOLENGTH: option = EXT_DOLENGTH; break;
case DORESISTANCE: option = EXT_DORESISTANCE; break; case DORESISTANCE: option = EXT_DORESISTANCE; break;
case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
case DOALIASES: option = EXT_DOALIASES; break;
case DOUNIQUE: option = EXT_DOUNIQUE; break;
case DOEXTRESIST:
case DOEXTRESIST2: option = EXT_DOEXTRESIST; break;
case DOLOCAL:
/* "extract do local" and "extract no local" are kept for
* backwards compatibility, but now effectively implement
* "extract path ." and "extract path none", respectively.
*/
if (no)
StrDup(&ExtLocalPath, NULL);
else
StrDup(&ExtLocalPath, ".");
return;
} }
if (no) ExtOptions &= ~option; if (no) ExtOptions &= ~option;
else ExtOptions |= option; else ExtOptions |= option;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -20,11 +20,10 @@
*/ */
#ifndef lint #ifndef lint
static const char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdWizard.c,v 1.2 2008/02/10 19:30:19 tim Exp $"; static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/commands/CmdWizard.c,v 1.2 2008/02/10 19:30:19 tim Exp $";
#endif /* not lint */ #endif /* not lint */
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
@ -47,20 +46,13 @@ 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 */
#include "extract/extract.h"
/* Forward declarations */ /* Forward declarations */
extern void cmdPsearchStats(char *str, struct tms *tl, struct tms *td, int count); extern void cmdPsearchStats();
void cmdStatsHier(CellDef *, int, CellDef *); void cmdStatsHier(CellDef *, int, CellDef *);
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -83,9 +75,9 @@ void cmdStatsHier(CellDef *, int, CellDef *);
*/ */
void void
CmdCoord( CmdCoord(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
MagWindow *pointW = (MagWindow *) NULL; MagWindow *pointW = (MagWindow *) NULL;
Rect editRect, rootRect; Rect editRect, rootRect;
@ -163,7 +155,7 @@ CmdCoord(
editRect.r_xtop, editRect.r_ytop); editRect.r_xtop, editRect.r_ytop);
TxPrintf("\n"); TxPrintf("\n");
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -185,243 +177,15 @@ CmdCoord(
#ifndef NO_EXT #ifndef NO_EXT
void void
CmdExtractTest( CmdExtractTest(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
ExtractTest(w, cmd); ExtractTest(w, cmd);
} }
#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);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -444,9 +208,9 @@ CmdShowmem(
*/ */
void void
showTech( showTech(outf, verbose)
FILE *outf, /* File to which information is to be output */ FILE *outf; /* File to which information is to be output */
bool verbose) /* If TRUE, output detailed erase table */ bool verbose; /* If TRUE, output detailed erase table */
{ {
int i, j; int i, j;
int pNum; int pNum;
@ -464,7 +228,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);
@ -591,9 +355,9 @@ showTech(
} }
void void
CmdShowtech( CmdShowtech(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
FILE *outf; FILE *outf;
bool verbose; bool verbose;
@ -633,7 +397,7 @@ CmdShowtech(
(void) fclose(outf); (void) fclose(outf);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -659,16 +423,16 @@ CmdShowtech(
*/ */
void void
CmdTilestats( CmdTilestats(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
CellUse *selectedUse; CellUse *selectedUse;
FILE *outf = stdout; FILE *outf = stdout;
bool allDefs = FALSE; bool allDefs = FALSE;
char **av = cmd->tx_argv + 1; char **av = cmd->tx_argv + 1;
int ac = cmd->tx_argc - 1; int ac = cmd->tx_argc - 1;
int cmdStatsFunc(CellDef *def, FILE *outf); int cmdStatsFunc();
if (ac > 2) if (ac > 2)
{ {
@ -743,12 +507,11 @@ int totalTiles[TT_MAXTYPES];
*/ */
int int
cmdStatsFunc( cmdStatsFunc(def, outf)
CellDef *def, CellDef *def;
FILE *outf) FILE *outf;
{ {
int cmdStatsCount(CellDef *def, struct countClient *cc); int cmdStatsCount(), cmdStatsOutput();
int cmdStatsOutput(CellDef *def, struct countClient *cc);
struct countClient cc; struct countClient cc;
int total; int total;
TileType t; TileType t;
@ -797,17 +560,15 @@ cmdStatsFunc(
*/ */
int int
cmdStatsCount( cmdStatsCount(def, cc)
CellDef *def, CellDef *def;
struct countClient *cc) struct countClient *cc;
{ {
int cmdStatsCountTile();
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);
@ -830,10 +591,9 @@ cmdStatsCount(
} }
int int
cmdStatsCountTile( cmdStatsCountTile(tile, ci)
Tile *tile, Tile *tile;
TileType dinfo, /* (unused) */ struct cellInfo *ci;
struct cellInfo *ci)
{ {
TileType type = TiGetType(tile); TileType type = TiGetType(tile);
@ -874,10 +634,9 @@ cmdStatsCountTile(
*/ */
void void
cmdStatsHier( cmdStatsHier(parent, nuses, child)
CellDef *parent, CellDef *parent, *child;
int nuses, int nuses;
CellDef *child)
{ {
struct cellInfo *pi, *ci; struct cellInfo *pi, *ci;
TileType t; TileType t;
@ -922,9 +681,9 @@ cmdStatsHier(
*/ */
int int
cmdStatsOutput( cmdStatsOutput(def, cc)
CellDef *def, CellDef *def;
struct countClient *cc) struct countClient *cc;
{ {
TileType t; TileType t;
struct cellInfo *ci; struct cellInfo *ci;
@ -962,7 +721,7 @@ cmdStatsOutput(
freeMagic((char *) ci); freeMagic((char *) ci);
return (0); return (0);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -987,11 +746,11 @@ cmdStatsOutput(
*/ */
void void
CmdPsearch( CmdPsearch(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
char *RunStats(int flags, struct tms *lastt, struct tms *deltat); char *RunStats();
static struct tms tlast, tdelta; static struct tms tlast, tdelta;
Point p; Point p;
Plane *plane; Plane *plane;
@ -1053,13 +812,12 @@ CmdPsearch(
} }
void void
cmdPsearchStats( cmdPsearchStats(str, tl, td, count)
char *str, char *str;
struct tms *tl, struct tms *tl, *td;
struct tms *td, int count;
int count)
{ {
char *RunStats(int flags, struct tms *lastt, struct tms *deltat); char *RunStats();
char *rstatp; char *rstatp;
int us, ups; int us, ups;
@ -1068,13 +826,13 @@ cmdPsearchStats(
ups = us / count; ups = us / count;
TxPrintf("%s: %d searches, %d us/search [%s]\n", str, count, ups, rstatp); TxPrintf("%s: %d searches, %d us/search [%s]\n", str, count, ups, rstatp);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* CmdTsearch -- * CmdTsearch --
* *
* Call DBSrPaintArea() a number of times over an area the size and shape of * Call TiSrArea() a number of times over an area the size and shape of
* that specified by the box, each time over a different area in the * that specified by the box, each time over a different area in the
* edit cell. * edit cell.
* *
@ -1099,22 +857,20 @@ int numTilesFound;
bool cmdTsearchDebug = FALSE; bool cmdTsearchDebug = FALSE;
void void
CmdTsearch( CmdTsearch(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
char *rstatp; int cmdTsrFunc();
char *RunStats(), *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");
@ -1187,12 +943,18 @@ CmdTsearch(
if (cmd->tx_argc < 5) if (cmd->tx_argc < 5)
{ {
(void) DBSrPaintArea((Tile *) NULL, plane, &rsearch, &DBAllTypeBits, (void) TiSrArea((Tile *) NULL, plane, &rsearch,
cmdTsrFunc, (ClientData) 0); cmdTsrFunc, (ClientData) 0);
} }
else else
{ {
(void) DBSrPaintArea((Tile *) NULL, plane, &rsearch, &mask, /****
if (strcmp(cmd->tx_argv[4], "mayo") == 0)
(void) TiSrAreaNR2((Tile *) NULL, plane, &rsearch, &mask,
cmdTsrFunc, (ClientData) 0);
else
****/
(void) DBSrPaintArea((Tile *) NULL, plane, &rsearch, &mask,
cmdTsrFunc, (ClientData) 0); cmdTsrFunc, (ClientData) 0);
} }
} }
@ -1213,17 +975,15 @@ CmdTsearch(
} }
int int
cmdTsrFunc( cmdTsrFunc(tp)
Tile *tp, Tile *tp;
TileType dinfo, /* (unused) */
ClientData clientdata) /* (unused) */
{ {
if (cmdTsearchDebug) if (cmdTsearchDebug)
TxPrintf("%lx\n", (intptr_t) tp); TxPrintf("%x\n", tp);
numTilesFound++; numTilesFound++;
return 0; return 0;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -1242,9 +1002,9 @@ cmdTsrFunc(
*/ */
void void
CmdWatch( CmdWatch(w, cmd)
MagWindow *w, MagWindow *w;
TxCommand *cmd) TxCommand *cmd;
{ {
DBWclientRec *crec; DBWclientRec *crec;
int pNum; int pNum;
@ -1285,7 +1045,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++) {
@ -1295,16 +1055,8 @@ CmdWatch(
}; };
return; return;
} }
if (EditCellUse != NULL) crec->dbw_watchDef = EditCellUse->cu_def;
{ crec->dbw_watchTrans = EditToRootTransform;
crec->dbw_watchDef = EditCellUse->cu_def;
crec->dbw_watchTrans = EditToRootTransform;
}
else
{
crec->dbw_watchDef = ((CellUse *)w->w_surfaceID)->cu_def;
crec->dbw_watchTrans = ((CellUse *)w->w_surfaceID)->cu_transform;
}
} }
crec->dbw_watchPlane = pNum; crec->dbw_watchPlane = pNum;

62
commands/Depend Normal file
View File

@ -0,0 +1,62 @@
CmdSubrs.o: CmdSubrs.c ../utils/magic.h ../utils/geometry.h \
../utils/utils.h ../database/database.h ../tiles/tile.h ../utils/hash.h \
../windows/windows.h ../dbwind/dbwind.h ../utils/main.h \
../commands/commands.h ../textio/textio.h ../cif/cif.h ../drc/drc.h \
../textio/txcommands.h ../utils/undo.h ../utils/macros.h ../sim/sim.h \
../select/select.h
CmdAB.o: CmdAB.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/hash.h ../database/database.h \
../windows/windows.h ../dbwind/dbwind.h ../utils/main.h \
../commands/commands.h ../utils/utils.h ../textio/textio.h ../drc/drc.h \
../cif/cif.h ../graphics/graphics.h ../textio/txcommands.h \
../utils/malloc.h ../utils/netlist.h ../select/select.h
CmdCD.o: CmdCD.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/geometry.h \
../tiles/tile.h ../utils/hash.h ../database/database.h \
../windows/windows.h ../dbwind/dbwind.h ../utils/main.h \
../commands/commands.h ../utils/utils.h ../textio/textio.h ../drc/drc.h \
../graphics/graphics.h ../textio/txcommands.h ../cif/cif.h \
../calma/calma.h ../utils/styles.h ../router/rtrDcmpose.h \
../select/select.h ../utils/signals.h ../utils/malloc.h ../cif/CIFint.h \
../cif/CIFread.h
CmdE.o: CmdE.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/styles.h \
../utils/geometry.h ../utils/utils.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../windows/windows.h ../graphics/graphics.h \
../dbwind/dbwind.h ../utils/main.h ../commands/commands.h \
../textio/textio.h ../utils/macros.h ../drc/drc.h ../textio/txcommands.h \
../extract/extract.h ../select/select.h
CmdFI.o: CmdFI.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/geometry.h \
../utils/utils.h ../utils/undo.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../windows/windows.h ../dbwind/dbwind.h \
../utils/main.h ../commands/commands.h ../textio/textio.h \
../utils/macros.h ../drc/drc.h ../textio/txcommands.h ../utils/styles.h \
../graphics/graphics.h ../extract/extract.h ../utils/malloc.h \
../select/select.h ../sim/sim.h ../gcr/gcr.h
CmdLQ.o: CmdLQ.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/malloc.h \
../utils/geometry.h ../utils/utils.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../database/fonts.h ../windows/windows.h \
../dbwind/dbwind.h ../utils/main.h ../commands/commands.h \
../textio/textio.h ../graphics/graphics.h ../drc/drc.h \
../textio/txcommands.h ../utils/undo.h ../select/select.h \
../netmenu/netmenu.h
CmdRS.o: CmdRS.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/stack.h \
../utils/geometry.h ../utils/utils.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../database/fonts.h ../windows/windows.h \
../dbwind/dbwind.h ../utils/main.h ../commands/commands.h \
../textio/textio.h ../graphics/graphics.h ../utils/tech.h ../drc/drc.h \
../textio/txcommands.h ../utils/malloc.h ../utils/netlist.h \
../netmenu/netmenu.h ../select/select.h ../utils/signals.h ../sim/sim.h
CmdTZ.o: CmdTZ.c ../tcltk/tclmagic.h ../utils/magic.h ../utils/malloc.h \
../utils/geometry.h ../utils/utils.h ../tiles/tile.h ../utils/hash.h \
../database/database.h ../windows/windows.h ../dbwind/dbwind.h \
../utils/main.h ../commands/commands.h ../textio/textio.h \
../textio/txcommands.h ../utils/signals.h ../utils/undo.h \
../select/select.h ../utils/styles.h ../wiring/wiring.h \
../utils/netlist.h ../netmenu/netmenu.h ../utils/tech.h ../drc/drc.h
CmdWizard.o: CmdWizard.c ../utils/magic.h ../utils/geometry.h \
../utils/malloc.h ../tiles/tile.h ../utils/hash.h ../database/database.h \
../windows/windows.h ../dbwind/dbwind.h ../utils/main.h \
../commands/commands.h ../utils/runstats.h ../textio/textio.h \
../graphics/graphics.h ../utils/signals.h ../utils/utils.h \
../textio/txcommands.h
CmdAuto.o: CmdAuto.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../windows/windows.h ../textio/txcommands.h

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,12 +20,11 @@
* 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"
#include "textio/txcommands.h" /* TxCommand */
/* /*
* Name of default yank buffer * Name of default yank buffer
@ -51,28 +50,18 @@ extern TileTypeBitMask CmdYMAllButSpace;
/* --------------------- Global procedure headers --------------------- */ /* --------------------- Global procedure headers --------------------- */
extern MagWindow *CmdGetEditPoint(Point *point, Rect *rect); extern MagWindow *CmdGetRootBox();
extern MagWindow *CmdGetRootPoint(Point *point, Rect *rect); extern MagWindow *CmdGetEditPoint();
extern bool CmdWarnWrite(void); extern MagWindow *CmdGetRootPoint();
extern bool CmdParseLayers(char *s, TileTypeBitMask *mask); extern bool CmdWarnWrite();
extern void CmdLabelProc(char *text, int font, int size, int rotate, int offx, int offy, extern bool CmdParseLayers();
int pos, bool sticky, TileType type); extern void CmdAddSlop();
extern void CmdSetWindCaption(CellUse *newEditUse, CellDef *rootDef); extern void CmdLabelProc();
extern CellUse *CmdGetSelectedCell(Transform *pTrans); extern void CmdSetWindCaption();
extern bool CmdIllegalChars(char *string, char *illegal, char *msg); extern CellUse *CmdGetSelectedCell();
extern TileType CmdFindNetProc(char *nodename, CellUse *use, Rect *rect, bool warn_not_found, bool *isvalid); extern bool CmdIllegalChars();
extern bool CmdCheckForPaintFunc(void); extern void CmdDoMacro();
extern TileType CmdFindNetProc();
extern bool CmdCheckForPaintFunc();
/* C99 compat */ #endif /* _COMMANDS_H */
extern int cmdScaleCoord(MagWindow *w, char *arg, bool is_relative, bool is_x, int scale);
extern void FlatCopyAllLabels(SearchContext *scx, TileTypeBitMask *mask, int xMask, CellUse *targetUse);
extern bool cmdDumpParseArgs(char *cmdName, MagWindow *w, TxCommand *cmd, CellUse *dummy, SearchContext *scx);
extern void cmdFlushCell(CellDef *def, bool force_deref);
extern int cmdParseCoord(MagWindow *w, char *arg, bool is_relative, bool is_x);
extern void cmdSaveCell(CellDef *cellDef, char *newName, bool noninteractive, bool tryRename);
extern void CmdInit(void);
extern void CmdDoProperty(CellDef *def, MagWindow *w, TxCommand *cmd, int argstart);
extern void CmdPaintEraseButton(MagWindow *w, Point *refPoint, bool isPaint, bool isScreen);
#endif /* _MAGIC__COMMANDS__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

@ -25,37 +25,24 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "utils/geometry.h" #include "utils/geometry.h"
#include "database/database.h" #include "database/database.h"
#include "tiles/tile.h" #include "tiles/tile.h"
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;
@ -71,32 +58,48 @@ DBBoundCellPlane(def, extended, rect)
cbs.found = FALSE; cbs.found = FALSE;
*rect = GeoNullRect; *rect = GeoNullRect;
if (DBSrCellPlaneArea(def->cd_cellPlane, &TiPlaneRect, if (TiSrArea((Tile *)NULL, def->cd_planes[PL_CELL],
dbCellBoundFunc, (ClientData) &filter) == 0) &TiPlaneRect, dbCellBoundFunc, (ClientData) &filter) == 0)
return cbs.found; return cbs.found;
else else
return -1; return -1;
} }
int int
dbCellBoundFunc(use, fp) dbCellBoundFunc(tile, fp)
CellUse *use; Tile *tile;
TreeFilter *fp; TreeFilter *fp;
{ {
CellUse *use;
CellTileBody *body;
Rect *bbox;
DBCellBoundStruct *cbs; DBCellBoundStruct *cbs;
cbs = (DBCellBoundStruct *)fp->tf_arg; cbs = (DBCellBoundStruct *)fp->tf_arg;
if (cbs->found) for (body = (CellTileBody *) TiGetBody(tile); body != NULL;
body = body->ctb_next)
{ {
GeoInclude(&use->cu_extended, cbs->extended); use = body->ctb_use;
GeoInclude(&use->cu_bbox, cbs->area); bbox = &use->cu_bbox;
} if ((BOTTOM(tile) <= bbox->r_ybot) && (RIGHT(tile) >= bbox->r_xtop))
else {
{ if (cbs->found)
*cbs->extended = use->cu_extended; {
*cbs->area = use->cu_bbox; if (cbs->extended)
cbs->found = TRUE; GeoInclude(&use->cu_extended, cbs->area);
else
GeoInclude(&use->cu_bbox, cbs->area);
}
else
{
if (cbs->extended)
*cbs->area = use->cu_extended;
else
*cbs->area = use->cu_bbox;
cbs->found = TRUE;
}
}
} }
return 0; return 0;
} }
@ -178,7 +181,7 @@ DBBoundPlane(plane, rect)
return (TRUE); return (TRUE);
} }
/* /*
* -------------------------------------------------------------------- * --------------------------------------------------------------------
* *

View File

@ -45,7 +45,7 @@ struct searchArg
{ {
CellUse * celluse; CellUse * celluse;
Rect * rect; Rect * rect;
BPlane * bplane; Plane * plane;
}; };
#define TOPLEFT 10 #define TOPLEFT 10
@ -55,22 +55,7 @@ struct searchArg
#define TOPBOTTOMLEFTRIGHT 15 #define TOPBOTTOMLEFTRIGHT 15
int dbCellDebug = 0; int dbCellDebug = 0;
void
dbInstanceUnplace(CellUse *use)
{
ASSERT(use != (CellUse *) NULL, "dbInstanceUnplace");
/* It's important that this code run with interrupts disabled,
* or else we could leave the subcell tile plane in a weird
* state.
*/
BPDelete(use->cu_parent->cd_cellPlane, use);
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -101,73 +86,33 @@ DBCellFindDup(use, parent)
* something identical to use? * something identical to use?
*/ */
{ {
BPEnum bpe; Tile *tile;
CellUse *dupUse; CellTileBody *body;
CellUse *checkUse;
BPEnumInit(&bpe, parent->cd_cellPlane, &use->cu_bbox, BPE_EQUAL, tile = TiSrPoint((Tile *) NULL, parent->cd_planes[PL_CELL],
"DBCellFindDup"); &use->cu_bbox.r_ll);
while ((dupUse = BPEnumNext(&bpe)))
if (dupUse->cu_def == use->cu_def)
{
bool transMatch, arrayMatch, notXarray, notYarray;
/* Transforms must be equal---Aligned bounding boxes are for (body = (CellTileBody *) TiGetBody(tile);
* an insufficient measure of exact overlap. Also, array body != NULL;
* counts and separation must match for arrayed devices body = body->ctb_next)
*/ {
transMatch = ((dupUse->cu_transform.t_a == use->cu_transform.t_a) && checkUse = body->ctb_use;
(dupUse->cu_transform.t_b == use->cu_transform.t_b) && if (use->cu_def != checkUse->cu_def) continue;
(dupUse->cu_transform.t_c == use->cu_transform.t_c) && if ((use->cu_bbox.r_xbot != checkUse->cu_bbox.r_xbot)
(dupUse->cu_transform.t_d == use->cu_transform.t_d) && || (use->cu_bbox.r_xtop != checkUse->cu_bbox.r_xtop)
(dupUse->cu_transform.t_e == use->cu_transform.t_e) && || (use->cu_bbox.r_ybot != checkUse->cu_bbox.r_ybot)
(dupUse->cu_transform.t_f == use->cu_transform.t_f)); || (use->cu_bbox.r_ytop != checkUse->cu_bbox.r_ytop))
continue;
/* First check if both use and dupUse are not arrays. */ return checkUse;
notXarray = (dupUse->cu_xhi == dupUse->cu_xlo) && }
(use->cu_xhi == use->cu_xlo); return (CellUse *) NULL;
notYarray = (dupUse->cu_yhi == dupUse->cu_ylo) &&
(use->cu_yhi == use->cu_ylo);
arrayMatch = (notXarray && notYarray);
/* If they are arrays, then the array parameters must match. */
if (!notXarray && notYarray)
{
arrayMatch = ((dupUse->cu_xhi - dupUse->cu_xlo) ==
(use->cu_xhi - use->cu_xlo)) &&
(dupUse->cu_xsep == use->cu_xsep);
}
else if (!notYarray && notXarray)
{
arrayMatch = ((dupUse->cu_yhi - dupUse->cu_ylo) ==
(use->cu_yhi - use->cu_ylo)) &&
(dupUse->cu_ysep == use->cu_ysep);
}
else if (!notYarray && !notXarray)
{
arrayMatch = (((dupUse->cu_xhi - dupUse->cu_xlo) ==
(use->cu_xhi - use->cu_xlo)) &&
(dupUse->cu_xsep == use->cu_xsep)) &&
(((dupUse->cu_yhi - dupUse->cu_ylo) ==
(use->cu_yhi - use->cu_ylo)) &&
(dupUse->cu_ysep == use->cu_ysep));
}
if (transMatch && arrayMatch)
break;
}
BPEnumTerm(&bpe);
return dupUse;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
* DBPlaceCell -- * DBPlaceCell --
* DBPlaceCellNoModify --
* *
* Add a CellUse to the subcell tile plane of a CellDef. * Add a CellUse to the subcell tile plane of a CellDef.
* Assumes prior check that the new CellUse is not an exact duplicate * Assumes prior check that the new CellUse is not an exact duplicate
@ -185,74 +130,41 @@ DBCellFindDup(use, parent)
*/ */
void void
DBPlaceCell (use, def) DBPlaceCell (celluse, targetcell)
CellUse * use; /* new celluse to add to subcell tile plane */ CellUse * celluse; /* new celluse to add to subcell tile plane */
CellDef * def; /* parent cell's definition */ CellDef * targetcell; /* parent cell's definition */
{ {
Rect rect; /* argument to DBSrCellPlaneArea(), placeCellFunc() */ Rect rect; /* argument to TiSrArea(), placeCellFunc() */
BPlane *bplane; /* argument to DBSrCellPlaneArea(), placeCellFunc() */ Plane * plane; /* argument to TiSrArea(), placeCellFunc() */
struct searchArg arg; /* argument to placeCellFunc() */ struct searchArg arg; /* argument to placeCellFunc() */
ASSERT(use != (CellUse *) NULL, "DBPlaceCell"); ASSERT(celluse != (CellUse *) NULL, "DBPlaceCell");
ASSERT(def, "DBPlaceCell"); celluse->cu_parent = targetcell;
plane = targetcell->cd_planes[PL_CELL]; /* assign plane */
/* To do: Check non-duplicate placement, check non-duplicate ID */ rect = celluse->cu_bbox;
/* rect = celluse->cu_extended; */
use->cu_parent = def; arg.rect = &rect;
arg.celluse = celluse;
arg.plane = plane;
/* Be careful not to permit interrupts during this, or the /* Be careful not to permit interrupts during this, or the
* database could be left in a trashed state. * database could be left in a trashed state.
*/ */
SigDisableInterrupts(); SigDisableInterrupts();
BPAdd(def->cd_cellPlane, use); (void) TiSrArea((Tile *) NULL, plane, &rect, placeCellFunc,
def->cd_flags |= CDMODIFIED|CDGETNEWSTAMP; (ClientData) &arg);
targetcell->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
if (UndoIsEnabled()) if (UndoIsEnabled())
DBUndoCellUse(use, UNDO_CELL_PLACE); DBUndoCellUse(celluse, UNDO_CELL_PLACE);
SigEnableInterrupts(); SigEnableInterrupts();
} }
/* Like DBPlaceCell(), but don't change the flags of the parent cell. */
/* This is needed by the bounding box recalculation routine, which may */
/* cause the cell to be deleted and replaced for the purpose of */
/* capturing the bounding box information in the BPlane structure, but */
/* this does not mean that anything in the parent cell has changed. */
void
DBPlaceCellNoModify (use, def)
CellUse * use; /* new celluse to add to subcell tile plane */
CellDef * def; /* parent cell's definition */
{
Rect rect; /* argument to DBSrCellPlaneArea(), placeCellFunc() */
BPlane *bplane; /* argument to DBSrCellPlaneArea(), placeCellFunc() */
struct searchArg arg; /* argument to placeCellFunc() */
ASSERT(use != (CellUse *) NULL, "DBPlaceCell");
ASSERT(def, "DBPlaceCell");
/* To do: Check non-duplicate placement, check non-duplicate ID */
use->cu_parent = def;
/* Be careful not to permit interrupts during this, or the
* database could be left in a trashed state.
*/
SigDisableInterrupts();
BPAdd(def->cd_cellPlane, use);
if (UndoIsEnabled())
DBUndoCellUse(use, UNDO_CELL_PLACE);
SigEnableInterrupts();
}
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* DBDeleteCell -- * DBDeleteCell --
* *
* Remove a CellUse from the subcell tile plane of a CellDef. * Remove a CellUse from the subcell tile plane of a CellDef.
* If "nomodify" is TRUE, then don't set the parent cell's CDMODIFIED flag.
* This is needed when recomputing the bounding box, which should not by
* itself change the modified state.
* *
* Results: * Results:
* None. * None.
@ -264,10 +176,19 @@ DBPlaceCellNoModify (use, def)
*/ */
void void
DBDeleteCell (use) DBDeleteCell (celluse)
CellUse * use; CellUse * celluse;
{ {
ASSERT(use != (CellUse *) NULL, "DBDeleteCell"); Rect rect; /* argument to TiSrArea(), deleteCellFunc() */
Plane * plane; /* argument to TiSrArea(), deleteCellFunc() */
struct searchArg arg; /* argument to deleteCellFunc() */
ASSERT(celluse != (CellUse *) NULL, "DBDeleteCell");
plane = celluse->cu_parent->cd_planes[PL_CELL]; /* assign plane */
rect = celluse->cu_bbox;
arg.rect = &rect;
arg.plane = plane;
arg.celluse = celluse;
/* It's important that this code run with interrupts disabled, /* It's important that this code run with interrupts disabled,
* or else we could leave the subcell tile plane in a weird * or else we could leave the subcell tile plane in a weird
@ -275,47 +196,511 @@ DBDeleteCell (use)
*/ */
SigDisableInterrupts(); SigDisableInterrupts();
dbInstanceUnplace(use); (void) TiSrArea((Tile *) NULL, plane, &rect, deleteCellFunc,
use->cu_parent->cd_flags |= CDMODIFIED|CDGETNEWSTAMP; (ClientData) &arg);
celluse->cu_parent->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
if (UndoIsEnabled()) if (UndoIsEnabled())
DBUndoCellUse(use, UNDO_CELL_DELETE); DBUndoCellUse(celluse, UNDO_CELL_DELETE);
use->cu_parent = (CellDef *) NULL; celluse->cu_parent = (CellDef *) NULL;
SigEnableInterrupts(); SigEnableInterrupts();
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* DBDeleteCellNoModify -- * placeCellFunc --
* *
* Remove a CellUse from the subcell tile plane of a CellDef, as above, * Add a new subcell to a tile.
* but don't set the parent cell's CDMODIFIED flag. This is needed when * Clip the tile with respect to the subcell's bounding box.
* recomputing the bounding box, which should not by itself change the * Insert the new CellTileBody into the linked list in ascending order
* modified state. * based on the celluse pointer.
* This function is passed to TiSrArea.
*
* Results:
* 0 is always returned.
*
* Side effects:
* Modifies the subcell tile plane of the appropriate CellDef.
* Allocates a new CellTileBody.
* ----------------------------------------------------------------------------
*/
int
placeCellFunc (tile, arg)
Tile * tile; /* target tile */
struct searchArg * arg; /* celluse, rect, plane */
{
Tile * tp;
CellTileBody * body, * ctp, * ctplast;
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("placeCellFunc called %x\n",tile);
#endif /* CELLDEBUG */
tp = clipCellTile (tile, arg->plane, arg->rect);
body = (CellTileBody *) mallocMagic((unsigned) (sizeof (CellTileBody)));
body->ctb_use = arg->celluse;
ctp = (CellTileBody *) tp->ti_body;
ctplast = ctp;
while ((ctp != (CellTileBody *) NULL) && (ctp->ctb_use > body->ctb_use))
{
ctplast = ctp;
ctp = ctp->ctb_next;
}
body->ctb_next = ctp;
if (ctp == (CellTileBody *) tp->ti_body) /* empty list or front of list */
TiSetBody(tp, body);
else /* after at least one CellTileBody */
ctplast->ctb_next = body;
/* merge tiles back into the the plane */
/* requires that TiSrArea visit tiles in NW to SE wavefront */
if ( RIGHT(tp) == arg->rect->r_xtop)
{
if (BOTTOM(tp) == arg->rect->r_ybot)
cellTileMerge (tp, arg->plane, TOPBOTTOMLEFTRIGHT);
else
cellTileMerge (tp, arg->plane, TOPLEFTRIGHT);
}
else if (BOTTOM(tp) == arg->rect->r_ybot)
cellTileMerge (tp, arg->plane, TOPBOTTOMLEFT);
else
cellTileMerge (tp, arg->plane, TOPLEFT);
return 0;
}
/*
* ----------------------------------------------------------------------------
* deleteCellFunc --
*
* Remove a subcell from a tile.
* This function is passed to TiSrArea.
*
* Results:
* Always returns 0.
*
* Side effects:
* Modifies the subcell tile plane of the appropriate CellDef.
* Deallocates a CellTileBody.
* ----------------------------------------------------------------------------
*/
int
deleteCellFunc (tile, arg)
Tile * tile;
struct searchArg * arg; /* plane, rect */
{
CellTileBody * ctp; /* CellTileBody to be freed */
CellTileBody * ctplast; /* follows one behind ctp */
CellUse * celluse;
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("deleteCellFunc called %x\n",tile);
#endif /* CELLDEBUG */
celluse = arg->celluse;
/* find the appropriate CellTileBody in the linked list */
ctp = (CellTileBody *) tile->ti_body;
ctplast = ctp;
while ((ctp != (CellTileBody *) NULL) && (ctp->ctb_use != celluse))
{
ctplast = ctp;
ctp = ctp->ctb_next;
}
/* there should have been a match */
if (ctp == (CellTileBody *) NULL)
{
ASSERT (ctp != (CellTileBody *) NULL, "deleteCellFunc");
return 0;
}
/* relink the list with one CellTileBody deleted */
if (ctp == ctplast) /* front of list */
TiSetBody(tile, ctp->ctb_next);
else /* beyond front of list */
ctplast->ctb_next = ctp->ctb_next;
freeMagic((char *) ctp);
/* merge tiles back into the the plane */
/* requires that TiSrArea visit tiles in NW to SE wavefront */
if ( RIGHT(tile) == arg->rect->r_xtop)
{
if (BOTTOM(tile) == arg->rect->r_ybot)
cellTileMerge (tile, arg->plane, TOPBOTTOMLEFTRIGHT);
else
cellTileMerge (tile, arg->plane, TOPLEFTRIGHT);
}
else if (BOTTOM(tile) == arg->rect->r_ybot)
cellTileMerge (tile, arg->plane, TOPBOTTOMLEFT);
else
cellTileMerge (tile, arg->plane, TOPLEFT);
return (0);
}
/*
* ----------------------------------------------------------------------------
* clipCellTile --
*
* Clip the given tile against the given rectangle.
*
* Results:
* Returns a pointer to the clipped tile.
*
* Side effects:
* Modifies the database plane that contains the given tile.
* ----------------------------------------------------------------------------
*/
Tile *
clipCellTile (tile, plane, rect)
Tile * tile;
Plane * plane;
Rect * rect;
{
Tile * newtile;
if (TOP(tile) > rect->r_ytop)
{
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("clipCellTile calls TiSplitY TOP\n");
#endif /* CELLDEBUG */
newtile = TiSplitY (tile, rect->r_ytop); /* no merge */
dupTileBody (tile, newtile);
}
if (BOTTOM(tile) < rect->r_ybot)
{
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("clipCellTile calls TiSplitY BOTTOM\n");
#endif /* CELLDEBUG */
newtile = tile;
tile = TiSplitY (tile, rect->r_ybot); /* no merge */
dupTileBody (newtile, tile);
}
if (RIGHT(tile) > rect->r_xtop)
{
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("clipCellTile calls TiSplitX RIGHT\n");
#endif /* CELLDEBUG */
newtile = TiSplitX (tile, rect->r_xtop);
dupTileBody (tile, newtile);
cellTileMerge (newtile, plane, TOPBOTTOM);
}
if (LEFT(tile) < rect->r_xbot)
{
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("clipCellTile calls TiSplitX LEFT\n");
#endif /* CELLDEBUG */
newtile = tile;
tile = TiSplitX (tile, rect->r_xbot);
dupTileBody (newtile, tile);
cellTileMerge (newtile, plane, TOPBOTTOM);
}
return (tile);
} /* clipCellTile */
/*
* ----------------------------------------------------------------------------
* dupTileBody --
*
* Duplicate the body of an old tile as the body for a new tile.
*
* Results:
* None.
*
* Side effects:
* Allocates new CellTileBodies unless the old tile was a space tile.
* ----------------------------------------------------------------------------
*/
void
dupTileBody (oldtp, newtp)
Tile * oldtp;
Tile * newtp;
{
CellTileBody * oldctb, * newctb, * newctblast;
oldctb = (CellTileBody *) oldtp->ti_body;
if (oldctb != (CellTileBody *) NULL)
{
newctb = (CellTileBody *) mallocMagic((unsigned) (sizeof (CellTileBody)));
TiSetBody(newtp, newctb);
newctb->ctb_use = oldctb->ctb_use;
oldctb = oldctb->ctb_next;
newctblast = newctb;
while (oldctb != (CellTileBody *) NULL)
{
newctb = (CellTileBody *) mallocMagic((unsigned) (sizeof (CellTileBody)));
newctblast->ctb_next = newctb;
newctb->ctb_use = oldctb->ctb_use;
oldctb = oldctb->ctb_next;
newctblast = newctb;
}
newctblast->ctb_next = (CellTileBody *) NULL;
}
else TiSetBody(newtp, NULL);
} /* dupTileBody */
/*
* ----------------------------------------------------------------------------
* cellTileMerge --
*
* Merge the given tile with its plane in the directions specified.
* *
* Results: * Results:
* None. * None.
* *
* Side effects: * Side effects:
* Modifies the subcell tile plane of the CellDef, sets the * Modifies the database plane that contains the given tile.
* parent pointer of the deleted CellUse to NULL.
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
void void
DBDeleteCellNoModify (use) cellTileMerge (tile, plane, direction)
CellUse * use; Tile * tile;
Plane * plane;
int direction; /* TOP = 8, BOTTOM = 4, LEFT = 2, RIGHT = 1 */
{ {
ASSERT(use != (CellUse *) NULL, "DBDeleteCell"); Point topleft, bottomright;
Tile * dummy, * tpleft, * tpright, * tp1, * tp2;
/* It's important that this code run with interrupts disabled, #ifdef CELLDEBUG
* or else we could leave the subcell tile plane in a weird if (dbCellDebug) TxPrintf("cellTileMerge %x\n",tile);
* state. #endif /* CELLDEBUG */
*/
SigDisableInterrupts(); topleft.p_x = LEFT(tile);
dbInstanceUnplace(use); topleft.p_y = TOP(tile);
if (UndoIsEnabled()) bottomright.p_x = RIGHT(tile);
DBUndoCellUse(use, UNDO_CELL_DELETE); bottomright.p_y = BOTTOM(tile);
use->cu_parent = (CellDef *) NULL;
SigEnableInterrupts(); if ((direction >> 1) % 2) /* LEFT */
{
tpright = tile;
tpleft = BL(tpright);
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("LEFT %x %x\n",tpleft,tpright);
#endif /* CELLDEBUG */
while (BOTTOM(tpleft) < topleft.p_y) /* go up left edge */
{
if (ctbListMatch (tpleft, tpright))
{
if (BOTTOM(tpleft) < BOTTOM(tpright))
{
dummy = tpleft;
tpleft = TiSplitY (tpleft, BOTTOM (tpright));
dupTileBody (dummy, tpleft);
}
else if (BOTTOM(tpleft) > BOTTOM(tpright))
{
dummy = tpright;
tpright = TiSplitY (tpright, BOTTOM (tpleft));
dupTileBody (dummy, tpright);
}
if (TOP(tpleft) > TOP(tpright))
{
dummy = TiSplitY (tpleft, TOP(tpright));
dupTileBody (tpleft, dummy);
}
else if (TOP(tpright) > TOP(tpleft))
{
dummy = TiSplitY (tpright, TOP(tpleft));
dupTileBody (tpright, dummy);
}
freeCTBList (tpright);
TiJoinX (tpleft, tpright, plane); /* tpright disappears */
tpright = RT(tpleft);
if (BOTTOM(tpright) < topleft.p_y) tpleft = BL(tpright);
else tpleft = tpright; /* we're off the top of the tile */
/* this will break the while loop */
} /* if (ctbListMatch (tpleft, tpright)) */
else tpleft = RT(tpleft);
} /* while */
tile = tpleft; /* for TiSrPoint in next IF statement */
}
if (direction % 2) /* RIGHT */
{
tpright = TiSrPoint (tile, plane, &bottomright);
--(bottomright.p_x);
tpleft = TiSrPoint (tpright, plane, &bottomright);
++(bottomright.p_x);
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("RIGHT %x %x\n",tpleft,tpright);
#endif /* CELLDEBUG */
while (BOTTOM(tpright) < topleft.p_y) /* go up right edge */
{
if (ctbListMatch (tpleft, tpright))
{
if (BOTTOM(tpright) < BOTTOM(tpleft))
{
dummy = tpright;
tpright = TiSplitY (tpright, BOTTOM(tpleft));
dupTileBody (dummy, tpright);
}
else if (BOTTOM(tpleft) < BOTTOM(tpright))
{
dummy = tpleft;
tpleft = TiSplitY (tpleft, BOTTOM(tpright));
dupTileBody (dummy, tpleft);
}
if (TOP(tpright) > TOP(tpleft))
{
dummy = TiSplitY (tpright, TOP(tpleft));
dupTileBody (tpright, dummy);
}
else if (TOP(tpleft) > TOP(tpright))
{
dummy = TiSplitY (tpleft, TOP(tpright));
dupTileBody (tpleft, dummy);
}
freeCTBList (tpright);
TiJoinX (tpleft, tpright, plane); /* tpright disappears */
tpright = RT(tpleft);
while (LEFT(tpright) > bottomright.p_x) tpright = BL(tpright);
/* tpleft can be garbage if we're off the top of the loop, */
/* but it doesn't matter since the expression tests tpright */
tpleft = BL(tpright);
} /* if (ctbListMatch (tpleft, tpright)) */
else
{
tpright = RT(tpright);
while (LEFT(tpright) > bottomright.p_x) tpright = BL(tpright);
tpleft = BL(tpright); /* left side merges may have */
/* created more tiles */
}
} /* while */
tile = tpright; /* for TiSrPoint in next IF statement */
}
if ((direction >> 3) % 2) /* TOP */
{
tp1 = TiSrPoint (tile, plane, &topleft); /* merge across top */
--(topleft.p_y);
tp2 = TiSrPoint (tile, plane, &topleft);/* top slice of original tile */
++(topleft.p_y);
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("TOP %x %x\n",tp1,tp2);
#endif /* CELLDEBUG */
if ((LEFT(tp1) == LEFT(tp2) ) &&
(RIGHT(tp1) == RIGHT(tp2)) &&
(ctbListMatch (tp1, tp2) ))
{
freeCTBList (tp2);
TiJoinY (tp1, tp2, plane);
}
tile = tp1; /* for TiSrPoint in next IF statement */
}
if ((direction >> 2) % 2) /* BOTTOM */
{
--(bottomright.p_x);
/* bottom slice of orig tile */
tp1 = TiSrPoint (tile, plane, &bottomright);
--(bottomright.p_y);
tp2 = TiSrPoint (tile, plane, &bottomright); /* merge across bottom */
#ifdef CELLDEBUG
if (dbCellDebug) TxPrintf("BOTTOM %x %x\n",tp1,tp2);
#endif /* CELLDEBUG */
if ((LEFT(tp1) == LEFT(tp2) ) &&
(RIGHT(tp1) == RIGHT(tp2)) &&
(ctbListMatch (tp1, tp2) ))
{
freeCTBList (tp2);
TiJoinY (tp1, tp2, plane);
}
}
}
/*
* ----------------------------------------------------------------------------
* freeCTBList --
*
* Free all CellTileBodies attached to the give tile.
*
* Results:
* None.
*
* Side effects:
* Frees CellTileBodies.
* ----------------------------------------------------------------------------
*/
void
freeCTBList (tile)
Tile * tile;
{
CellTileBody * ctp, * ctplast;
ctp = (CellTileBody *) tile->ti_body;
while (ctp != (CellTileBody *) NULL)
{
ctplast = ctp;
ctp = ctp->ctb_next;
freeMagic((char *) ctplast);
}
TiSetBody(tile, NULL);
}
/*
* ----------------------------------------------------------------------------
* ctbListMatch --
*
* Compare two linked lists of CellTileBodies, assuming that they are
* sorted in ascending order by celluse pointers.
*
* Results:
* True if the tiles have identical lists of CellTileBodies.
*
* Side effects:
* None.
* ----------------------------------------------------------------------------
*/
bool
ctbListMatch (tp1, tp2)
Tile * tp1, * tp2;
{
CellTileBody * ctp1, * ctp2;
ctp1 = (CellTileBody *) tp1->ti_body;
ctp2 = (CellTileBody *) tp2->ti_body;
while (ctp1 && ctp2 && (ctp1->ctb_use == ctp2->ctb_use))
ctp1 = ctp1->ctb_next, ctp2 = ctp2->ctb_next;
return ((ctp1 == (CellTileBody *) NULL) && (ctp2 == (CellTileBody *) NULL));
} }

View File

@ -34,7 +34,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "dbwind/dbwind.h" #include "dbwind/dbwind.h"
#include "utils/undo.h" #include "utils/undo.h"
/* /*
*----------------------------------------------------------------------------- *-----------------------------------------------------------------------------
* *
@ -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;
@ -105,7 +105,7 @@ DBPrintUseId(
return (sp); return (sp);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -143,7 +143,7 @@ DBCellClearAvail(cellDef)
{ {
cellDef->cd_flags &= ~(CDNOTFOUND|CDAVAILABLE); cellDef->cd_flags &= ~(CDNOTFOUND|CDAVAILABLE);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -185,7 +185,7 @@ DBCellSetModified(cellDef, ismod)
if (ismod) if (ismod)
cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP; cellDef->cd_flags |= CDMODIFIED|CDGETNEWSTAMP;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -253,7 +253,7 @@ DBComputeUseBbox(use)
GeoTransRect(&use->cu_transform, &childRect, &use->cu_bbox); GeoTransRect(&use->cu_transform, &childRect, &use->cu_bbox);
GeoTransRect(&use->cu_transform, &childExtend, &use->cu_extended); GeoTransRect(&use->cu_transform, &childExtend, &use->cu_extended);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -276,7 +276,7 @@ DBIsChild(cu1, cu2)
{ {
return (cu1->cu_parent == cu2->cu_def); return (cu1->cu_parent == cu2->cu_def);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -305,7 +305,7 @@ DBSetArray(fromCellUse, toCellUse)
toCellUse->cu_xsep = fromCellUse->cu_xsep; toCellUse->cu_xsep = fromCellUse->cu_xsep;
toCellUse->cu_ysep = fromCellUse->cu_ysep; toCellUse->cu_ysep = fromCellUse->cu_ysep;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -330,7 +330,7 @@ DBSetTrans(cellUse, trans)
cellUse->cu_transform = *trans; cellUse->cu_transform = *trans;
DBComputeUseBbox(cellUse); DBComputeUseBbox(cellUse);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -389,7 +389,7 @@ DBMakeArray(cellUse, rootToCell, xlo, ylo, xhi, yhi, xsep, ysep)
DBComputeUseBbox(cellUse); DBComputeUseBbox(cellUse);
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -545,7 +545,7 @@ DBArrayOverlap(cu, parentRect, pxlo, pxhi, pylo, pyhi)
*pyhi = outyhi; *pyhi = outyhi;
} }
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -611,17 +611,21 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
Rect rect, area, extended, *box; Rect rect, area, extended, *box;
Rect redisplayArea; Rect redisplayArea;
CellUse *use; CellUse *use;
CellDef *parent, *last; CellDef *parent;
Label *label; Label *label;
bool foundAny; bool foundAny;
int pNum; int pNum;
/* Cells which declare their bounding box to be fixed */
/* must return immediately. */
if (cellDef->cd_flags & CDFIXEDBBOX) return;
/* /*
* 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++)
if (pNum != PL_DRC_CHECK) if (pNum != PL_DRC_CHECK)
@ -635,7 +639,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 +661,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 +678,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 +692,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
@ -733,7 +728,7 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
*/ */
parent = use->cu_parent; parent = use->cu_parent;
DBDeleteCellNoModify(use); DBDeleteCell(use);
use->cu_parent = parent; use->cu_parent = parent;
} }
@ -745,15 +740,8 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
* of their respective parents. Also, redisplay the use * of their respective parents. Also, redisplay the use
* in each parent, in each window where the cell isn't * in each parent, in each window where the cell isn't
* expanded (i.e. the bounding box is no longer correct). * expanded (i.e. the bounding box is no longer correct).
*
* Because more than one cell may be in an array, avoid
* running recurseProc more than once on the same parent.
* The simple way is just wait until the parent cell changes
* to run the process, although this could be done more
* thoroughly.
*/ */
last = NULL;
for (use = cellDef->cd_parents; use != NULL; use = use->cu_nextuse) for (use = cellDef->cd_parents; use != NULL; use = use->cu_nextuse)
{ {
redisplayArea = use->cu_extended; redisplayArea = use->cu_extended;
@ -761,21 +749,16 @@ dbReComputeBboxFunc(cellDef, boundProc, recurseProc)
if ((parent = use->cu_parent) != (CellDef *) NULL) if ((parent = use->cu_parent) != (CellDef *) NULL)
{ {
parent->cd_flags |= CDBOXESCHANGED; parent->cd_flags |= CDBOXESCHANGED;
DBPlaceCellNoModify(use, parent); DBPlaceCell(use, parent);
if (last != parent) (*recurseProc)(parent);
{
if (last != NULL) (*recurseProc)(last);
last = parent;
}
(void) GeoInclude(&use->cu_extended, &redisplayArea); (void) GeoInclude(&use->cu_extended, &redisplayArea);
DBWAreaChanged(parent, &redisplayArea, (int) ~use->cu_expandMask, DBWAreaChanged(parent, &redisplayArea, (int) ~use->cu_expandMask,
&DBAllButSpaceBits); &DBAllButSpaceBits);
} }
} }
if ((last != NULL) && (parent != NULL)) (*recurseProc)(parent);
UndoEnable(); UndoEnable();
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *
@ -822,7 +805,7 @@ DBComputeArrayArea(area, cellUse, x, y, prect)
prect->r_ybot = area->r_ybot + ydelta; prect->r_ybot = area->r_ybot + ydelta;
prect->r_ytop = area->r_ytop + ydelta; prect->r_ytop = area->r_ytop + ydelta;
} }
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -55,7 +55,7 @@ struct selectArg
/* Forward declarations */ /* Forward declarations */
int dbSelectCellSr(); int dbSelectCellSr();
/* /*
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
* *

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